def setup_ui(self): self.l = l = QGridLayout(self) self.setLayout(l) self.la1 = la = QLabel(_('&Existing images in the book')) la.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) l.addWidget(la, 0, 0, 1, 2) if self.for_browsing: la.setVisible(False) self.view = v = QListView(self) v.setViewMode(v.IconMode) v.setFlow(v.LeftToRight) v.setSpacing(4) v.setResizeMode(v.Adjust) v.setUniformItemSizes(True) pi = plugins['progress_indicator'][0] if hasattr(pi, 'set_no_activate_on_click'): pi.set_no_activate_on_click(v) v.activated.connect(self.activated) v.doubleClicked.connect(self.activated) self.d = ImageDelegate(v) v.setItemDelegate(self.d) self.model = Images(self.view) self.fm = fm = QSortFilterProxyModel(self.view) self.fm.setDynamicSortFilter(self.for_browsing) fm.setSourceModel(self.model) fm.setFilterCaseSensitivity(False) v.setModel(fm) l.addWidget(v, 1, 0, 1, 2) v.pressed.connect(self.pressed) la.setBuddy(v) self.filter = f = QLineEdit(self) f.setPlaceholderText(_('Search for image by file name')) l.addWidget(f, 2, 0) self.cb = b = QToolButton(self) b.setIcon(QIcon(I('clear_left.png'))) b.clicked.connect(f.clear) l.addWidget(b, 2, 1) f.textChanged.connect(self.filter_changed) l.addWidget(self.bb, 3, 0, 1, 2) if self.for_browsing: self.bb.clear() self.bb.addButton(self.bb.Close) b = self.refresh_button = self.bb.addButton( _('&Refresh'), self.bb.ActionRole) b.clicked.connect(self.refresh) b.setIcon(QIcon(I('view-refresh.png'))) b.setToolTip(_('Refresh the displayed images')) self.setAttribute(Qt.WA_DeleteOnClose, False) else: b = self.import_button = self.bb.addButton(_('&Import image'), self.bb.ActionRole) b.clicked.connect(self.import_image) b.setIcon(QIcon(I('view-image.png'))) b.setToolTip(_('Import an image from elsewhere in your computer')) b = self.paste_button = self.bb.addButton(_('&Paste image'), self.bb.ActionRole) b.clicked.connect(self.paste_image) b.setIcon(QIcon(I('edit-paste.png'))) b.setToolTip(_('Paste an image from the clipboard'))
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = gl = QGridLayout(self) self.changed = False self.bars = b = QComboBox(self) b.addItem(_('Choose which toolbar you want to customize')) ft = _('Tools for %s editors') for name, text in ( ( 'global_book_toolbar', _('Book wide actions'), ), ( 'global_tools_toolbar', _('Book wide tools'), ), ( 'global_plugins_toolbar', _('Book wide tools from third party plugins'), ), ('editor_common_toolbar', _('Common tools for all editors')), ( 'editor_html_toolbar', ft % 'HTML', ), ( 'editor_css_toolbar', ft % 'CSS', ), ( 'editor_xml_toolbar', ft % 'XML', ), ( 'editor_format_toolbar', _('Text formatting actions'), ), ): b.addItem(text, name) self.la = la = QLabel(_('&Toolbar to customize:')) la.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) la.setBuddy(b) gl.addWidget(la), gl.addWidget(b, 0, 1) self.sl = l = QGridLayout() gl.addLayout(l, 1, 0, 1, -1) self.gb1 = gb1 = QGroupBox(_('A&vailable actions'), self) self.gb2 = gb2 = QGroupBox(_('&Current actions'), self) gb1.setFlat(True), gb2.setFlat(True) gb1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) gb2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) l.addWidget(gb1, 0, 0, -1, 1), l.addWidget(gb2, 0, 2, -1, 1) self.available, self.current = ToolbarList(self), ToolbarList(self) self.ub = b = QToolButton(self) connect_lambda(b.clicked, self, lambda self: self.move(up=True)) b.setToolTip(_('Move selected action up')), b.setIcon( QIcon(I('arrow-up.png'))) self.db = b = QToolButton(self) connect_lambda(b.clicked, self, lambda self: self.move(up=False)) b.setToolTip(_('Move selected action down')), b.setIcon( QIcon(I('arrow-down.png'))) self.gl1 = gl1 = QVBoxLayout() gl1.addWidget(self.available), gb1.setLayout(gl1) self.gl2 = gl2 = QGridLayout() gl2.addWidget(self.current, 0, 0, -1, 1) gl2.addWidget(self.ub, 0, 1), gl2.addWidget(self.db, 2, 1) gb2.setLayout(gl2) self.lb = b = QToolButton(self) b.setToolTip(_('Add selected actions to the toolbar')), b.setIcon( QIcon(I('forward.png'))) l.addWidget(b, 1, 1), b.clicked.connect(self.add_action) self.rb = b = QToolButton(self) b.setToolTip(_('Remove selected actions from the toolbar')), b.setIcon( QIcon(I('back.png'))) l.addWidget(b, 3, 1), b.clicked.connect(self.remove_action) self.si = QSpacerItem(20, 10, hPolicy=QSizePolicy.Preferred, vPolicy=QSizePolicy.Expanding) l.setRowStretch(0, 10), l.setRowStretch(2, 10), l.setRowStretch(4, 10) l.addItem(self.si, 4, 1) self.read_settings() self.toggle_visibility(False) self.bars.currentIndexChanged.connect(self.bar_changed) self.toolbar_icon_size = ics = QSpinBox(self) ics.setMinimum(16), ics.setMaximum(128), ics.setSuffix( ' px'), ics.setValue(tprefs['toolbar_icon_size']) ics.setToolTip('<p>' + _('Adjust the size of icons on all toolbars')) self.h = h = QHBoxLayout() gl.addLayout(h, gl.rowCount(), 0, 1, -1) self.toolbar_icon_size_label = la = QLabel(_('Toolbar &icon size:')) la.setBuddy(ics) h.addWidget(la), h.addWidget(ics), h.addStretch(10)
def init_layout_mixin(self): self.vl_tabs = VLTabs(self) self.centralwidget.layout().addWidget(self.vl_tabs) if config['gui_layout'] == 'narrow': # narrow {{{ self.book_details = BookDetails(False, self) self.stack = Stack(self) self.bd_splitter = Splitter('book_details_splitter', _('Book details'), I('book.png'), orientation=Qt.Vertical, parent=self, side_index=1, shortcut='Shift+Alt+D') self.bd_splitter.addWidget(self.stack) self.bd_splitter.addWidget(self.book_details) self.bd_splitter.setCollapsible(self.bd_splitter.other_index, False) self.centralwidget.layout().addWidget(self.bd_splitter) button_order = ('sb', 'tb', 'bd', 'gv', 'cb', 'qv') # }}} else: # wide {{{ self.bd_splitter = Splitter('book_details_splitter', _('Book details'), I('book.png'), initial_side_size=200, orientation=Qt.Horizontal, parent=self, side_index=1, shortcut='Shift+Alt+D') self.stack = Stack(self) self.bd_splitter.addWidget(self.stack) self.book_details = BookDetails(True, self) self.bd_splitter.addWidget(self.book_details) self.bd_splitter.setCollapsible(self.bd_splitter.other_index, False) self.bd_splitter.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.centralwidget.layout().addWidget(self.bd_splitter) button_order = ('sb', 'tb', 'cb', 'gv', 'qv', 'bd') # }}} # This must use the base method to find the plugin because it hasn't # been fully initialized yet self.qv = find_plugin('Quickview') if self.qv and self.qv.actual_plugin_: self.qv = self.qv.actual_plugin_ self.status_bar = StatusBar(self) stylename = unicode(self.style().objectName()) self.grid_view_button = GridViewButton(self) self.search_bar_button = SearchBarButton(self) self.grid_view_button.toggled.connect(self.toggle_grid_view) self.search_bar_button.toggled.connect(self.toggle_search_bar) self.layout_buttons = [] for x in button_order: if hasattr(self, x + '_splitter'): button = getattr(self, x + '_splitter').button else: if x == 'gv': button = self.grid_view_button elif x == 'qv': if self.qv is None: continue button = self.qv.qv_button else: button = self.search_bar_button self.layout_buttons.append(button) button.setVisible(False) if isosx and stylename != u'Calibre': button.setStyleSheet(''' QToolButton { background: none; border:none; padding: 0px; } QToolButton:checked { background: rgba(0, 0, 0, 25%); } ''') self.status_bar.addPermanentWidget(button) if gprefs['show_layout_buttons']: for b in self.layout_buttons: b.setVisible(True) self.status_bar.addPermanentWidget(b) else: self.layout_button = b = QToolButton(self) b.setAutoRaise(True), b.setCursor(Qt.PointingHandCursor) b.setPopupMode(b.InstantPopup) b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) b.setText(_('Layout')), b.setIcon(QIcon(I('config.png'))) b.setMenu(LayoutMenu(self)) b.setToolTip( _('Show and hide various parts of the calibre main window')) self.status_bar.addPermanentWidget(b) self.status_bar.addPermanentWidget(self.jobs_button) self.setStatusBar(self.status_bar) self.status_bar.update_label.linkActivated.connect( self.update_link_clicked)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QGridLayout(self) self.setLayout(l) self.enabled = c = QCheckBox(self) l.addWidget(c, l.rowCount(), 0, 1, 2) c.setVisible(False) c.stateChanged.connect(self.changed) self.l1 = l1 = QLabel('') l1.setWordWrap(True) l.addWidget(l1, l.rowCount(), 0, 1, 2) self.add_button = QPushButton(QIcon(I('plus.png')), _('&Add rule'), self) self.remove_button = QPushButton(QIcon(I('minus.png')), _('&Remove rule(s)'), self) self.add_button.clicked.connect(self.add_rule) self.remove_button.clicked.connect(self.remove_rule) l.addWidget(self.add_button, l.rowCount(), 0) l.addWidget(self.remove_button, l.rowCount() - 1, 1) self.g = g = QGridLayout() self.rules_view = QListView(self) self.rules_view.doubleClicked.connect(self.edit_rule) self.rules_view.setSelectionMode(self.rules_view.ExtendedSelection) self.rules_view.setAlternatingRowColors(True) self.rtfd = RichTextDelegate(parent=self.rules_view, max_width=400) self.rules_view.setItemDelegate(self.rtfd) g.addWidget(self.rules_view, 0, 0, 2, 1) self.up_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))) b.setToolTip(_('Move the selected rule up')) b.clicked.connect(self.move_up) g.addWidget(b, 0, 1, 1, 1, Qt.AlignTop) self.down_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))) b.setToolTip(_('Move the selected rule down')) b.clicked.connect(self.move_down) g.addWidget(b, 1, 1, 1, 1, Qt.AlignBottom) l.addLayout(g, l.rowCount(), 0, 1, 2) l.setRowStretch(l.rowCount() - 1, 10) self.add_advanced_button = b = QPushButton(QIcon(I('plus.png')), _('Add ad&vanced rule'), self) b.clicked.connect(self.add_advanced) self.hb = hb = QHBoxLayout() l.addLayout(hb, l.rowCount(), 0, 1, 2) hb.addWidget(b) hb.addStretch(10) self.export_button = b = QPushButton(_('E&xport'), self) b.clicked.connect(self.export_rules) b.setToolTip(_('Export these rules to a file')) hb.addWidget(b) self.import_button = b = QPushButton(_('&Import'), self) b.setToolTip(_('Import rules from a file')) b.clicked.connect(self.import_rules) hb.addWidget(b)
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.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.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.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.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__(self, parent=None, panel_name='search'): QWidget.__init__(self, parent) self.ignore_search_type_changes = False self.l = l = QVBoxLayout(self) l.setContentsMargins(0, 0, 0, 0) h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) l.addLayout(h) self.search_box = sb = SearchBox(self) self.panel_name = panel_name sb.initialize('viewer-{}-panel-expression'.format(panel_name)) sb.item_selected.connect(self.saved_search_selected) sb.history_saved.connect(self.history_saved) sb.cleared.connect(self.cleared) sb.lineEdit().returnPressed.connect(self.find_next) h.addWidget(sb) self.next_button = nb = QToolButton(self) h.addWidget(nb) nb.setFocusPolicy(Qt.NoFocus) nb.setIcon(QIcon(I('arrow-down.png'))) nb.clicked.connect(self.find_next) nb.setToolTip(_('Find next match')) self.prev_button = nb = QToolButton(self) h.addWidget(nb) nb.setFocusPolicy(Qt.NoFocus) nb.setIcon(QIcon(I('arrow-up.png'))) nb.clicked.connect(self.find_previous) nb.setToolTip(_('Find previous match')) h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) l.addLayout(h) self.query_type = qt = QComboBox(self) qt.setFocusPolicy(Qt.NoFocus) qt.addItem(_('Contains'), 'normal') qt.addItem(_('Whole words'), 'word') qt.addItem(_('Regex'), 'regex') qt.setToolTip(('<p>' + _( 'Choose the type of search: <ul>' '<li><b>Contains</b> will search for the entered text anywhere.' '<li><b>Whole words</b> will search for whole words that equal the entered text.' '<li><b>Regex</b> will interpret the text as a regular expression.' ))) qt.setCurrentIndex( qt.findData( vprefs.get('viewer-{}-mode'.format(self.panel_name), 'normal') or 'normal')) qt.currentIndexChanged.connect(self.save_search_type) h.addWidget(qt) self.case_sensitive = cs = QCheckBox(_('&Case sensitive'), self) cs.setFocusPolicy(Qt.NoFocus) cs.setChecked( bool( vprefs.get('viewer-{}-case-sensitive'.format(self.panel_name), False))) cs.stateChanged.connect(self.save_search_type) h.addWidget(cs) self.return_button = rb = QToolButton(self) rb.setIcon(QIcon(I('back.png'))) rb.setToolTip(_('Go back to where you were before searching')) rb.clicked.connect(self.go_back) h.addWidget(rb)
def __init__(self, parent): QWidget.__init__(self, parent) self._layout = l = QHBoxLayout() self.setLayout(self._layout) self._layout.setContentsMargins(0, 5, 0, 0) x = QToolButton(self) x.setText(_('Vi&rtual Library')) x.setIcon(QIcon(I('lt.png'))) x.setObjectName("virtual_library") x.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) l.addWidget(x) parent.virtual_library = x x = QToolButton(self) x.setIcon(QIcon(I('minus.png'))) x.setObjectName('clear_vl') l.addWidget(x) x.setVisible(False) x.setToolTip(_('Close the Virtual Library')) parent.clear_vl = x x = QLabel(self) x.setObjectName("search_count") l.addWidget(x) parent.search_count = x x.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) parent.advanced_search_button = x = QToolButton(self) parent.advanced_search_toggle_action = ac = QAction(parent) parent.addAction(ac) parent.keyboard.register_shortcut('advanced search toggle', _('Advanced search'), default_keys=("Shift+Ctrl+F", ), action=ac) ac.triggered.connect(x.click) x.setIcon(QIcon(I('search.png'))) l.addWidget(x) x.setToolTip(_("Advanced search")) x = parent.search = SearchBox2(self) x.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) x.setObjectName("search") x.setToolTip( _("<p>Search the list of books by title, author, publisher, " "tags, comments, etc.<br><br>Words separated by spaces are ANDed" )) x.setMinimumContentsLength(10) l.addWidget(x) self.search_button = QToolButton() self.search_button.setToolButtonStyle(Qt.ToolButtonTextOnly) self.search_button.setText(_('&Go!')) l.addWidget(self.search_button) self.search_button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.search_button.clicked.connect(parent.do_search_button) self.search_button.setToolTip( _('Do Quick Search (you can also press the Enter key)')) x = parent.clear_button = QToolButton(self) x.setIcon(QIcon(I('clear_left.png'))) x.setObjectName("clear_button") l.addWidget(x) x.setToolTip(_("Reset Quick Search")) x = parent.highlight_only_button = QToolButton(self) x.setIcon(QIcon(I('arrow-down.png'))) l.addWidget(x) x = parent.saved_search = SavedSearchBox(self) x.setMaximumSize(QSize(150, 16777215)) x.setMinimumContentsLength(10) x.setObjectName("saved_search") l.addWidget(x) x = parent.copy_search_button = QToolButton(self) x.setIcon(QIcon(I("search_copy_saved.png"))) x.setObjectName("copy_search_button") l.addWidget(x) x.setToolTip(_("Copy current search text (instead of search name)")) x = parent.save_search_button = QToolButton(self) x.setIcon(QIcon(I("search_add_saved.png"))) x.setObjectName("save_search_button") l.addWidget(x)
def __init__(self, parent): QWidget.__init__(self, parent) self.parent = parent self._layout = QVBoxLayout() self.setLayout(self._layout) self._layout.setContentsMargins(0, 0, 0, 0) # Set up the find box & button search_layout = QHBoxLayout() self._layout.addLayout(search_layout) self.item_search = HistoryLineEdit(parent) self.item_search.setMinimumContentsLength(5) self.item_search.setSizeAdjustPolicy( self.item_search.AdjustToMinimumContentsLengthWithIcon) try: self.item_search.lineEdit().setPlaceholderText( _('Find item in tag browser')) except: pass # Using Qt < 4.7 self.item_search.setToolTip( _('Search for items. This is a "contains" search; items containing the\n' 'text anywhere in the name will be found. You can limit the search\n' 'to particular categories using syntax similar to search. For example,\n' 'tags:foo will find foo in any tag, but not in authors etc. Entering\n' '*foo will filter all categories at once, showing only those items\n' 'containing the text "foo"')) search_layout.addWidget(self.item_search) # Not sure if the shortcut should be translatable ... sc = QShortcut(QKeySequence(_('ALT+f')), parent) sc.activated.connect(self.set_focus_to_find_box) self.search_button = QToolButton() self.search_button.setText(_('F&ind')) self.search_button.setToolTip(_('Find the first/next matching item')) search_layout.addWidget(self.search_button) self.expand_button = QToolButton() self.expand_button.setText('-') self.expand_button.setToolTip(_('Collapse all categories')) search_layout.addWidget(self.expand_button) search_layout.setStretch(0, 10) search_layout.setStretch(1, 1) search_layout.setStretch(2, 1) self.current_find_position = None self.search_button.clicked.connect(self.find) self.item_search.initialize('tag_browser_search') self.item_search.lineEdit().returnPressed.connect(self.do_find) self.item_search.lineEdit().textEdited.connect(self.find_text_changed) self.item_search.activated[str].connect(self.do_find) self.item_search.completer().setCaseSensitivity(Qt.CaseSensitive) parent.tags_view = TagsView(parent) self.tags_view = parent.tags_view self.expand_button.clicked.connect(self.tags_view.collapseAll) self._layout.addWidget(parent.tags_view) # Now the floating 'not found' box l = QLabel(self.tags_view) self.not_found_label = l l.setFrameStyle(QFrame.StyledPanel) l.setAutoFillBackground(True) l.setText( '<p><b>' + _('No More Matches.</b><p> Click Find again to go to first match')) l.setAlignment(Qt.AlignVCenter) l.setWordWrap(True) l.resize(l.sizeHint()) l.move(10, 20) l.setVisible(False) self.not_found_label_timer = QTimer() self.not_found_label_timer.setSingleShot(True) self.not_found_label_timer.timeout.connect( self.not_found_label_timer_event, type=Qt.QueuedConnection) parent.alter_tb = l = QPushButton(parent) l.setText(_('Alter Tag Browser')) l.setIcon(QIcon(I('tags.png'))) l.m = QMenu() l.setMenu(l.m) self._layout.addWidget(l) sb = l.m.addAction(_('Sort by')) sb.m = l.sort_menu = QMenu(l.m) sb.setMenu(sb.m) sb.bg = QActionGroup(sb) # Must be in the same order as db2.CATEGORY_SORTS for i, x in enumerate((_('Sort by name'), _('Sort by number of books'), _('Sort by average rating'))): a = sb.m.addAction(x) sb.bg.addAction(a) a.setCheckable(True) if i == 0: a.setChecked(True) sb.setToolTip(_('Set the sort order for entries in the Tag Browser')) sb.setStatusTip(sb.toolTip()) ma = l.m.addAction(_('Search type when selecting multiple items')) ma.m = l.match_menu = QMenu(l.m) ma.setMenu(ma.m) ma.ag = QActionGroup(ma) # Must be in the same order as db2.MATCH_TYPE for i, x in enumerate( (_('Match any of the items'), _('Match all of the items'))): a = ma.m.addAction(x) ma.ag.addAction(a) a.setCheckable(True) if i == 0: a.setChecked(True) ma.setToolTip( _('When selecting multiple entries in the Tag Browser ' 'match any or all of them')) ma.setStatusTip(ma.toolTip()) mt = l.m.addAction(_('Manage authors, tags, etc.')) mt.setToolTip( _('All of these category_managers are available by right-clicking ' 'on items in the tag browser above')) mt.m = l.manage_menu = QMenu(l.m) mt.setMenu(mt.m)
def __init__(self, color_caption): TestableWidget.__init__(self) self.setWindowFlags(Qt.Popup) self._text = self.tr("Table") main_layout = QVBoxLayout() main_layout.setContentsMargins(0, 0, 0, 0) b = "border: 1px solid #9b9b9b;" self._styles = { "border": b, "border_blue": "border: 0px solid blue;", "selection": f"QToolButton {{{b}background-color:#fee5e2;}}", "white": f"QToolButton {{{b}background-color:white;}}", "frame": 'QFrame[frameShape="4"]{color: #9b9b9b;}'} self.setStyleSheet(self._styles["frame"]) # -- CAPTION ---------------------------------- caption = QFrame(self, flags=Qt.WindowFlags()) caption_layout = QHBoxLayout() self._lbl_caption = QLabel(self._text) self._lbl_caption.setStyleSheet(self._styles["border_blue"]) caption_layout.addWidget(self._lbl_caption, alignment=Qt.Alignment()) caption.setLayout(caption_layout) caption_layout.setContentsMargins(9, 5, 9, 5) caption.setStyleSheet( f"background-color: {color_caption}; {self._styles['border']}") # -- CELLS GRID ------------------------------- cellsbox = QFrame(self, flags=Qt.WindowFlags()) cells = QGridLayout() cells.setSpacing(1) cellsbox.setLayout(cells) cells.setContentsMargins(9, 0, 9, 0) self._nn = 10 self._clrbtn = [] colors = ["white" for _ in range(self._nn ** 2)] cellsbox.leaveEvent = lambda x: self._leave_cell() for i, color in enumerate(colors): self._clrbtn.append(QToolButton()) # noinspection PyPep8Naming self._clrbtn[-1].enterEvent = lambda x, n=i: self._enter_cell(n) self._clrbtn[-1].setStyleSheet(self._styles["white"]) self._clrbtn[-1].clicked.connect( lambda x, n=i: self.select_size_(n)) # noinspection PyArgumentList cells.addWidget(self._clrbtn[-1], i // self._nn, i % self._nn) # -- SPLITTER --------------------------------- h_frame = QFrame(None, flags=Qt.WindowFlags()) h_frame.setFrameShape(QFrame.HLine) h_frame.setContentsMargins(0, 0, 0, 0) # -- BOTTOM (other color) --------------------- btns = QFrame(self, flags=Qt.WindowFlags()) btn_layout = QHBoxLayout() other = QToolButton() other.clicked.connect(self.other_size_) other.setAutoRaise(True) other.setIcon(QIcon(img("editor/table_gray"))) btn_layout.addWidget(other, alignment=Qt.Alignment()) self._lbl_other = QLabel(self.tr("insert table")) btn_layout.addWidget(self._lbl_other, alignment=Qt.Alignment()) btns.setLayout(btn_layout) btn_layout.setContentsMargins(9, 0, 9, 9) self._clrbtn.append(other) # --------------------------------------------- main_layout.addWidget(caption, alignment=Qt.Alignment()) main_layout.addWidget(cellsbox, alignment=Qt.Alignment()) main_layout.addWidget(h_frame, alignment=Qt.Alignment()) main_layout.addWidget(btns, alignment=Qt.Alignment()) self.setLayout(main_layout)
def __init__(self, plugin_action): QWidget.__init__(self) self.parent = plugin_action self.gui = get_gui() self.icon = plugin_action.icon self.opts = plugin_action.opts self.prefs = plugin_prefs self.resources_path = plugin_action.resources_path self.verbose = plugin_action.verbose self.restart_required = False self._log_location() self.l = QGridLayout() self.setLayout(self.l) self.column1_layout = QVBoxLayout() self.l.addLayout(self.column1_layout, 0, 0) self.column2_layout = QVBoxLayout() self.l.addLayout(self.column2_layout, 0, 1) # ----------------------------- Column 1 ----------------------------- # ~~~~~~~~ Create the Custom fields options group box ~~~~~~~~ self.cfg_custom_fields_gb = QGroupBox(self) self.cfg_custom_fields_gb.setTitle('Custom column assignments') self.column1_layout.addWidget(self.cfg_custom_fields_gb) self.cfg_custom_fields_qgl = QGridLayout(self.cfg_custom_fields_gb) current_row = 0 # ++++++++ Labels + HLine ++++++++ self.marvin_source_label = QLabel("Marvin source") self.cfg_custom_fields_qgl.addWidget(self.marvin_source_label, current_row, 0) self.calibre_destination_label = QLabel("calibre destination") self.cfg_custom_fields_qgl.addWidget(self.calibre_destination_label, current_row, 1) current_row += 1 self.sd_hl = QFrame(self.cfg_custom_fields_gb) self.sd_hl.setFrameShape(QFrame.HLine) self.sd_hl.setFrameShadow(QFrame.Raised) self.cfg_custom_fields_qgl.addWidget(self.sd_hl, current_row, 0, 1, 3) current_row += 1 # ++++++++ Annotations ++++++++ self.cfg_annotations_label = QLabel('Annotations') self.cfg_annotations_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_annotations_label, current_row, 0) self.annotations_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.annotations_field_comboBox.setObjectName('annotations_field_comboBox') self.annotations_field_comboBox.setToolTip('Select a custom column to store Marvin annotations') self.cfg_custom_fields_qgl.addWidget(self.annotations_field_comboBox, current_row, 1) self.cfg_highlights_wizard = QToolButton() self.cfg_highlights_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_highlights_wizard.setToolTip("Create a custom column to store Marvin annotations") self.cfg_highlights_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Annotations')) self.cfg_custom_fields_qgl.addWidget(self.cfg_highlights_wizard, current_row, 2) current_row += 1 # ++++++++ Collections ++++++++ self.cfg_collections_label = QLabel('Collections') self.cfg_collections_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_collections_label, current_row, 0) self.collection_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.collection_field_comboBox.setObjectName('collection_field_comboBox') self.collection_field_comboBox.setToolTip('Select a custom column to store Marvin collection assignments') self.cfg_custom_fields_qgl.addWidget(self.collection_field_comboBox, current_row, 1) self.cfg_collections_wizard = QToolButton() self.cfg_collections_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_collections_wizard.setToolTip("Create a custom column for Marvin collection assignments") self.cfg_collections_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Collections')) self.cfg_custom_fields_qgl.addWidget(self.cfg_collections_wizard, current_row, 2) current_row += 1 # ++++++++ Last read ++++++++ self.cfg_date_read_label = QLabel("Last read") self.cfg_date_read_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_date_read_label, current_row, 0) self.date_read_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.date_read_field_comboBox.setObjectName('date_read_field_comboBox') self.date_read_field_comboBox.setToolTip('Select a custom column to store Last read date') self.cfg_custom_fields_qgl.addWidget(self.date_read_field_comboBox, current_row, 1) self.cfg_collections_wizard = QToolButton() self.cfg_collections_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_collections_wizard.setToolTip("Create a custom column to store Last read date") self.cfg_collections_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Last read')) self.cfg_custom_fields_qgl.addWidget(self.cfg_collections_wizard, current_row, 2) current_row += 1 # ++++++++ Locked ++++++++ self.cfg_locked_label = QLabel("Locked") self.cfg_locked_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_locked_label, current_row, 0) self.locked_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.locked_field_comboBox.setObjectName('locked_field_comboBox') self.locked_field_comboBox.setToolTip('Select a custom column to store Locked status') self.cfg_custom_fields_qgl.addWidget(self.locked_field_comboBox, current_row, 1) self.cfg_locked_wizard = QToolButton() self.cfg_locked_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_locked_wizard.setToolTip("Create a custom column to store Locked status") self.cfg_locked_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Locked')) self.cfg_custom_fields_qgl.addWidget(self.cfg_locked_wizard, current_row, 2) current_row += 1 # ++++++++ Progress ++++++++ self.cfg_progress_label = QLabel('Progress') self.cfg_progress_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_progress_label, current_row, 0) self.progress_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.progress_field_comboBox.setObjectName('progress_field_comboBox') self.progress_field_comboBox.setToolTip('Select a custom column to store Marvin reading progress') self.cfg_custom_fields_qgl.addWidget(self.progress_field_comboBox, current_row, 1) self.cfg_progress_wizard = QToolButton() self.cfg_progress_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_progress_wizard.setToolTip("Create a custom column to store Marvin reading progress") self.cfg_progress_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Progress')) self.cfg_custom_fields_qgl.addWidget(self.cfg_progress_wizard, current_row, 2) current_row += 1 # ++++++++ Read flag ++++++++ self.cfg_read_label = QLabel('Read') self.cfg_read_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_read_label, current_row, 0) self.read_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.read_field_comboBox.setObjectName('read_field_comboBox') self.read_field_comboBox.setToolTip('Select a custom column to store Marvin Read status') self.cfg_custom_fields_qgl.addWidget(self.read_field_comboBox, current_row, 1) self.cfg_read_wizard = QToolButton() self.cfg_read_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_read_wizard.setToolTip("Create a custom column to store Marvin Read status") self.cfg_read_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Read')) self.cfg_custom_fields_qgl.addWidget(self.cfg_read_wizard, current_row, 2) current_row += 1 # ++++++++ Reading list flag ++++++++ self.cfg_reading_list_label = QLabel('Reading list') self.cfg_reading_list_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_reading_list_label, current_row, 0) self.reading_list_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.reading_list_field_comboBox.setObjectName('reading_list_field_comboBox') self.reading_list_field_comboBox.setToolTip('Select a custom column to store Marvin Reading list status') self.cfg_custom_fields_qgl.addWidget(self.reading_list_field_comboBox, current_row, 1) self.cfg_reading_list_wizard = QToolButton() self.cfg_reading_list_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_reading_list_wizard.setToolTip("Create a custom column to store Marvin Reading list status") self.cfg_reading_list_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Reading list')) self.cfg_custom_fields_qgl.addWidget(self.cfg_reading_list_wizard, current_row, 2) current_row += 1 # ++++++++ Word count ++++++++ self.cfg_word_count_label = QLabel('Word count') self.cfg_word_count_label.setAlignment(Qt.AlignLeft) self.cfg_custom_fields_qgl.addWidget(self.cfg_word_count_label, current_row, 0) self.word_count_field_comboBox = QComboBox(self.cfg_custom_fields_gb) self.word_count_field_comboBox.setObjectName('word_count_field_comboBox') self.word_count_field_comboBox.setToolTip('Select a custom column to store Marvin word counts') self.cfg_custom_fields_qgl.addWidget(self.word_count_field_comboBox, current_row, 1) self.cfg_word_count_wizard = QToolButton() self.cfg_word_count_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_word_count_wizard.setToolTip("Create a custom column to store Marvin word counts") self.cfg_word_count_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Word count')) self.cfg_custom_fields_qgl.addWidget(self.cfg_word_count_wizard, current_row, 2) current_row += 1 self.spacerItem1 = QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) self.column1_layout.addItem(self.spacerItem1) # ----------------------------- Column 2 ----------------------------- # ~~~~~~~~ Create the CSS group box ~~~~~~~~ self.cfg_css_options_gb = QGroupBox(self) self.cfg_css_options_gb.setTitle('CSS') self.column2_layout.addWidget(self.cfg_css_options_gb) self.cfg_css_options_qgl = QGridLayout(self.cfg_css_options_gb) current_row = 0 # ++++++++ Annotations appearance ++++++++ self.annotations_icon = QIcon(os.path.join(self.resources_path, 'icons', 'annotations_hiliter.png')) self.cfg_annotations_appearance_toolbutton = QToolButton() self.cfg_annotations_appearance_toolbutton.setIcon(self.annotations_icon) self.cfg_annotations_appearance_toolbutton.clicked.connect(self.configure_appearance) self.cfg_css_options_qgl.addWidget(self.cfg_annotations_appearance_toolbutton, current_row, 0) self.cfg_annotations_label = ClickableQLabel("Book notes, Bookmark notes and Annotations") self.cfg_annotations_label.clicked.connect(self.configure_appearance) self.cfg_css_options_qgl.addWidget(self.cfg_annotations_label, current_row, 1) current_row += 1 # ++++++++ Injected CSS ++++++++ self.css_editor_icon = QIcon(I('format-text-heading.png')) self.cfg_css_editor_toolbutton = QToolButton() self.cfg_css_editor_toolbutton.setIcon(self.css_editor_icon) self.cfg_css_editor_toolbutton.clicked.connect(self.edit_css) self.cfg_css_options_qgl.addWidget(self.cfg_css_editor_toolbutton, current_row, 0) self.cfg_css_editor_label = ClickableQLabel("Articles, Vocabulary") self.cfg_css_editor_label.clicked.connect(self.edit_css) self.cfg_css_options_qgl.addWidget(self.cfg_css_editor_label, current_row, 1) """ # ~~~~~~~~ Create the Dropbox syncing group box ~~~~~~~~ self.cfg_dropbox_syncing_gb = QGroupBox(self) self.cfg_dropbox_syncing_gb.setTitle('Dropbox') self.column2_layout.addWidget(self.cfg_dropbox_syncing_gb) self.cfg_dropbox_syncing_qgl = QGridLayout(self.cfg_dropbox_syncing_gb) current_row = 0 # ++++++++ Syncing enabled checkbox ++++++++ self.dropbox_syncing_checkbox = QCheckBox('Enable Dropbox updates') self.dropbox_syncing_checkbox.setObjectName('dropbox_syncing') self.dropbox_syncing_checkbox.setToolTip('Refresh custom column content from Marvin metadata') self.cfg_dropbox_syncing_qgl.addWidget(self.dropbox_syncing_checkbox, current_row, 0, 1, 3) current_row += 1 # ++++++++ Dropbox folder picker ++++++++ self.dropbox_folder_icon = QIcon(os.path.join(self.resources_path, 'icons', 'dropbox.png')) self.cfg_dropbox_folder_toolbutton = QToolButton() self.cfg_dropbox_folder_toolbutton.setIcon(self.dropbox_folder_icon) self.cfg_dropbox_folder_toolbutton.setToolTip("Specify Dropbox folder location on your computer") self.cfg_dropbox_folder_toolbutton.clicked.connect(self.select_dropbox_folder) self.cfg_dropbox_syncing_qgl.addWidget(self.cfg_dropbox_folder_toolbutton, current_row, 1) # ++++++++ Dropbox location lineedit ++++++++ self.dropbox_location_lineedit = QLineEdit() self.dropbox_location_lineedit.setPlaceholderText("Dropbox folder location") self.cfg_dropbox_syncing_qgl.addWidget(self.dropbox_location_lineedit, current_row, 2) """ # ~~~~~~~~ Create the General options group box ~~~~~~~~ self.cfg_runtime_options_gb = QGroupBox(self) self.cfg_runtime_options_gb.setTitle('General options') self.column2_layout.addWidget(self.cfg_runtime_options_gb) self.cfg_runtime_options_qvl = QVBoxLayout(self.cfg_runtime_options_gb) # ++++++++ Temporary markers: Duplicates ++++++++ self.duplicate_markers_checkbox = QCheckBox('Apply temporary markers to duplicate books') self.duplicate_markers_checkbox.setObjectName('apply_markers_to_duplicates') self.duplicate_markers_checkbox.setToolTip('Books with identical content will be flagged in the Library window') self.cfg_runtime_options_qvl.addWidget(self.duplicate_markers_checkbox) # ++++++++ Temporary markers: Updated ++++++++ self.updated_markers_checkbox = QCheckBox('Apply temporary markers to books with updated content') self.updated_markers_checkbox.setObjectName('apply_markers_to_updated') self.updated_markers_checkbox.setToolTip('Books with updated content will be flagged in the Library window') self.cfg_runtime_options_qvl.addWidget(self.updated_markers_checkbox) # ++++++++ Auto refresh checkbox ++++++++ self.auto_refresh_checkbox = QCheckBox('Automatically refresh custom column content') self.auto_refresh_checkbox.setObjectName('auto_refresh_at_startup') self.auto_refresh_checkbox.setToolTip('Update calibre custom column when Marvin XD is opened') self.cfg_runtime_options_qvl.addWidget(self.auto_refresh_checkbox) # ++++++++ Progress as percentage checkbox ++++++++ self.reading_progress_checkbox = QCheckBox('Show reading progress as percentage') self.reading_progress_checkbox.setObjectName('show_progress_as_percentage') self.reading_progress_checkbox.setToolTip('Display percentage in Progress column') self.cfg_runtime_options_qvl.addWidget(self.reading_progress_checkbox) # ~~~~~~~~ Create the Debug options group box ~~~~~~~~ self.cfg_debug_options_gb = QGroupBox(self) self.cfg_debug_options_gb.setTitle('Debug options') self.column2_layout.addWidget(self.cfg_debug_options_gb) self.cfg_debug_options_qvl = QVBoxLayout(self.cfg_debug_options_gb) # ++++++++ Debug logging checkboxes ++++++++ self.debug_plugin_checkbox = QCheckBox('Enable debug logging for Marvin XD') self.debug_plugin_checkbox.setObjectName('debug_plugin_checkbox') self.debug_plugin_checkbox.setToolTip('Print plugin diagnostic messages to console') self.cfg_debug_options_qvl.addWidget(self.debug_plugin_checkbox) self.debug_libimobiledevice_checkbox = QCheckBox('Enable debug logging for libiMobileDevice') self.debug_libimobiledevice_checkbox.setObjectName('debug_libimobiledevice_checkbox') self.debug_libimobiledevice_checkbox.setToolTip('Print libiMobileDevice diagnostic messages to console') self.cfg_debug_options_qvl.addWidget(self.debug_libimobiledevice_checkbox) self.spacerItem2 = QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) self.column2_layout.addItem(self.spacerItem2) # ~~~~~~~~ End of construction zone ~~~~~~~~ self.resize(self.sizeHint()) # ~~~~~~~~ Populate/restore config options ~~~~~~~~ # Annotations comboBox self.populate_annotations() self.populate_collections() self.populate_date_read() self.populate_locked() self.populate_progress() self.populate_read() self.populate_reading_list() self.populate_word_count() """ # Restore Dropbox settings, hook changes dropbox_syncing = self.prefs.get('dropbox_syncing', False) self.dropbox_syncing_checkbox.setChecked(dropbox_syncing) self.set_dropbox_syncing(dropbox_syncing) self.dropbox_syncing_checkbox.clicked.connect(partial(self.set_dropbox_syncing)) self.dropbox_location_lineedit.setText(self.prefs.get('dropbox_folder', '')) """ # Restore general settings self.duplicate_markers_checkbox.setChecked(self.prefs.get('apply_markers_to_duplicates', True)) self.updated_markers_checkbox.setChecked(self.prefs.get('apply_markers_to_updated', True)) self.auto_refresh_checkbox.setChecked(self.prefs.get('auto_refresh_at_startup', False)) self.reading_progress_checkbox.setChecked(self.prefs.get('show_progress_as_percentage', False)) # Restore debug settings, hook changes self.debug_plugin_checkbox.setChecked(self.prefs.get('debug_plugin', False)) self.debug_plugin_checkbox.stateChanged.connect(self.set_restart_required) self.debug_libimobiledevice_checkbox.setChecked(self.prefs.get('debug_libimobiledevice', False)) self.debug_libimobiledevice_checkbox.stateChanged.connect(self.set_restart_required) # Hook changes to Annotations comboBox # self.annotations_field_comboBox.currentIndexChanged.connect( # partial(self.save_combobox_setting, 'annotations_field_comboBox')) # self.connect(self.annotations_field_comboBox, # SIGNAL('currentIndexChanged(const QString &)'), # self.annotations_destination_changed) self.annotations_field_comboBox.currentIndexChanged.connect(self.annotations_destination_changed) # Launch the annotated_books_scanner field = get_cc_mapping('annotations', 'field', None) self.annotated_books_scanner = InventoryAnnotatedBooks(self.gui, field) self.annotated_books_scanner.signal.connect(self.inventory_complete) QTimer.singleShot(1, self.start_inventory)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QGridLayout(self) self.setLayout(l) self.enabled = c = QCheckBox(self) l.addWidget(c, l.rowCount(), 0, 1, 2) c.setVisible(False) c.stateChanged.connect(self.changed) self.l1 = l1 = QLabel('') l1.setWordWrap(True) l.addWidget(l1, l.rowCount(), 0, 1, 2) self.add_button = QPushButton(QIcon(I('plus.png')), _('&Add rule'), self) self.remove_button = QPushButton(QIcon(I('minus.png')), _('&Remove rule(s)'), self) self.add_button.clicked.connect(self.add_rule) self.remove_button.clicked.connect(self.remove_rule) l.addWidget(self.add_button, l.rowCount(), 0) l.addWidget(self.remove_button, l.rowCount() - 1, 1) self.g = g = QGridLayout() self.rules_view = RulesView(self, self.do_enable_convert_buttons) self.rules_view.doubleClicked.connect(self.edit_rule) self.rules_view.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.rules_view.setAlternatingRowColors(True) self.rtfd = RichTextDelegate(parent=self.rules_view, max_width=400) self.rules_view.setItemDelegate(self.rtfd) g.addWidget(self.rules_view, 0, 0, 2, 1) self.up_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))) b.setToolTip(_('Move the selected rule up')) b.clicked.connect(self.move_up) g.addWidget(b, 0, 1, 1, 1, Qt.AlignmentFlag.AlignTop) self.down_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))) b.setToolTip(_('Move the selected rule down')) b.clicked.connect(self.move_down) g.addWidget(b, 1, 1, 1, 1, Qt.AlignmentFlag.AlignBottom) l.addLayout(g, l.rowCount(), 0, 1, 2) l.setRowStretch(l.rowCount() - 1, 10) self.add_advanced_button = b = QPushButton(QIcon(I('plus.png')), _('Add ad&vanced rule'), self) b.clicked.connect(self.add_advanced) self.hb = hb = QHBoxLayout() l.addLayout(hb, l.rowCount(), 0, 1, 2) hb.addWidget(b) self.duplicate_rule_button = b = QPushButton(QIcon(I('edit-copy.png')), _('Du&plicate rule'), self) b.clicked.connect(self.duplicate_rule) b.setEnabled(False) hb.addWidget(b) self.convert_to_advanced_button = b = QPushButton(QIcon(I('modified.png')), _('Convert to advanced r&ule'), self) b.clicked.connect(self.convert_to_advanced) b.setEnabled(False) hb.addWidget(b) hb.addStretch(10) self.open_icon_folder_button = b = QPushButton(QIcon(I('icon_choose.png')), _('Open icon directory'), self) connect_lambda(b.clicked, self, lambda _: open_local_file(os.path.join(config_dir, 'cc_icons'))) hb.addWidget(b) hb.addStretch(10) self.export_button = b = QPushButton(_('E&xport'), self) b.clicked.connect(self.export_rules) b.setToolTip(_('Export these rules to a file')) hb.addWidget(b) self.import_button = b = QPushButton(_('&Import'), self) b.setToolTip(_('Import rules from a file')) b.clicked.connect(self.import_rules) hb.addWidget(b)
def setup_ui(self): self.l = l = QVBoxLayout(self) self.setLayout(l) self.h = h = QHBoxLayout() self.filter_text = ft = QLineEdit(self) ft.textChanged.connect(self.do_filter) ft.setPlaceholderText(_('Filter displayed searches')) h.addWidget(ft) self.cft = cft = QToolButton(self) cft.setToolTip(_('Clear filter')), cft.setIcon( QIcon(I('clear_left.png'))) cft.clicked.connect(ft.clear) h.addWidget(cft) l.addLayout(h) self.h2 = h = QHBoxLayout() self.searches = searches = QListView(self) searches.doubleClicked.connect(self.edit_search) self.model = SearchesModel(self.searches) self.model.dataChanged.connect(self.show_details) searches.setModel(self.model) searches.selectionModel().currentChanged.connect(self.show_details) searches.setSelectionMode(searches.ExtendedSelection) self.delegate = SearchDelegate(searches) searches.setItemDelegate(self.delegate) searches.setAlternatingRowColors(True) h.addWidget(searches, stretch=10) self.v = v = QVBoxLayout() h.addLayout(v) l.addLayout(h) def pb(text, tooltip=None): b = QPushButton(text, self) b.setToolTip(tooltip or '') b.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) return b mulmsg = '\n\n' + _( 'The entries are tried in order until the first one matches.') for text, action, tooltip in [ (_('&Find'), 'find', _('Run the search using the selected entries.') + mulmsg), (_('&Replace'), 'replace', _('Run replace using the selected entries.') + mulmsg), (_('Replace a&nd Find'), 'replace-find', _('Run replace and then find using the selected entries.') + mulmsg), (_('Replace &all'), 'replace-all', _('Run Replace All for all selected entries in the order selected' )), (_('&Count all'), 'count', _('Run Count All for all selected entries')), ]: b = pb(text, tooltip) v.addWidget(b) b.clicked.connect(partial(self.run_search, action)) self.d1 = d = QFrame(self) d.setFrameStyle(QFrame.HLine) v.addWidget(d) self.h3 = h = QHBoxLayout() self.upb = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))), b.setToolTip( _('Move selected entries up')) b.clicked.connect(partial(self.move_entry, -1)) self.dnb = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))), b.setToolTip( _('Move selected entries down')) b.clicked.connect(partial(self.move_entry, 1)) h.addWidget(self.upb), h.addWidget(self.dnb) v.addLayout(h) self.eb = b = pb(_('&Edit search'), _('Edit the currently selected search')) b.clicked.connect(self.edit_search) v.addWidget(b) self.eb = b = pb(_('Re&move search'), _('Remove the currently selected searches')) b.clicked.connect(self.remove_search) v.addWidget(b) self.eb = b = pb(_('&Add search'), _('Add a new saved search')) b.clicked.connect(self.add_search) v.addWidget(b) self.d2 = d = QFrame(self) d.setFrameStyle(QFrame.HLine) v.addWidget(d) self.where_box = wb = WhereBox(self, emphasize=True) self.where = SearchWidget.DEFAULT_STATE['where'] v.addWidget(wb) self.direction_box = db = DirectionBox(self) self.direction = SearchWidget.DEFAULT_STATE['direction'] v.addWidget(db) self.wr = wr = QCheckBox(_('&Wrap')) wr.setToolTip('<p>' + _( 'When searching reaches the end, wrap around to the beginning and continue the search' )) self.wr.setChecked(SearchWidget.DEFAULT_STATE['wrap']) v.addWidget(wr) self.description = d = QLabel(' \n \n ') d.setTextFormat(Qt.PlainText) d.setWordWrap(True) l.addWidget(d) l.addWidget(self.bb) self.bb.clear() self.bb.addButton(self.bb.Close) self.ib = b = self.bb.addButton(_('&Import'), self.bb.ActionRole) b.clicked.connect(self.import_searches) self.eb = b = self.bb.addButton(_('E&xport'), self.bb.ActionRole) self.em = m = QMenu(_('Export')) m.addAction( _('Export All'), lambda: QTimer.singleShot( 0, partial(self.export_searches, all=True))) m.addAction( _('Export Selected'), lambda: QTimer.singleShot( 0, partial(self.export_searches, all=False))) b.setMenu(m) self.searches.setFocus(Qt.OtherFocusReason)
def create_basic_metadata_widgets(self): # {{{ self.basic_metadata_widgets = [] self.languages = LanguagesEdit(self) self.basic_metadata_widgets.append(self.languages) self.title = TitleEdit(self) self.title.textChanged.connect(self.update_window_title) self.deduce_title_sort_button = QToolButton(self) self.deduce_title_sort_button.setToolTip( _('Automatically create the title sort entry based on the current ' 'title entry.\nUsing this button to create title sort will ' 'change title sort from red to green.')) self.deduce_title_sort_button.setWhatsThis( self.deduce_title_sort_button.toolTip()) self.title_sort = TitleSortEdit(self, self.title, self.deduce_title_sort_button, self.languages) self.basic_metadata_widgets.extend([self.title, self.title_sort]) self.deduce_author_sort_button = b = QToolButton(self) b.setToolTip('<p>' + _( 'Automatically create the author sort entry based on the current ' 'author entry. Using this button to create author sort will ' 'change author sort from red to green. There is a menu of ' 'functions available under this button. Click and hold ' 'on the button to see it.') + '</p>') b.m = m = QMenu() ac = m.addAction(QIcon(I('forward.png')), _('Set author sort from author')) ac2 = m.addAction(QIcon(I('back.png')), _('Set author from author sort')) ac3 = m.addAction(QIcon(I('user_profile.png')), _('Manage authors')) ac4 = m.addAction(QIcon(I('next.png')), _('Copy author to author sort')) ac5 = m.addAction(QIcon(I('previous.png')), _('Copy author sort to author')) b.setMenu(m) self.authors = AuthorsEdit(self, ac3) self.author_sort = AuthorSortEdit(self, self.authors, b, self.db, ac, ac2, ac4, ac5) self.basic_metadata_widgets.extend([self.authors, self.author_sort]) self.swap_title_author_button = QToolButton(self) self.swap_title_author_button.setIcon(QIcon(I('swap.png'))) self.swap_title_author_button.setToolTip( _('Swap the author and title')) self.swap_title_author_button.clicked.connect(self.swap_title_author) self.manage_authors_button = QToolButton(self) self.manage_authors_button.setIcon(QIcon(I('user_profile.png'))) self.manage_authors_button.setToolTip( '<p>' + _('Manage authors. Use to rename authors and correct ' 'individual author\'s sort values') + '</p>') self.manage_authors_button.clicked.connect(self.authors.manage_authors) self.series = SeriesEdit(self) self.clear_series_button = QToolButton(self) self.clear_series_button.setToolTip(_('Clear series')) self.clear_series_button.clicked.connect(self.series.clear) self.series_index = SeriesIndexEdit(self, self.series) self.basic_metadata_widgets.extend([self.series, self.series_index]) self.formats_manager = FormatsManager(self, self.copy_fmt) # We want formats changes to be committed before title/author, as # otherwise we could have data loss if the title/author changed and the # user was trying to add an extra file from the old books directory. self.basic_metadata_widgets.insert(0, self.formats_manager) self.formats_manager.metadata_from_format_button.clicked.connect( self.metadata_from_format) self.formats_manager.cover_from_format_button.clicked.connect( self.cover_from_format) self.cover = Cover(self) self.cover.download_cover.connect(self.download_cover) self.basic_metadata_widgets.append(self.cover) self.comments = CommentsEdit(self, self.one_line_comments_toolbar) self.basic_metadata_widgets.append(self.comments) self.rating = RatingEdit(self) self.clear_ratings_button = QToolButton(self) self.clear_ratings_button.setToolTip(_('Clear rating')) self.clear_ratings_button.setIcon(QIcon(I('trash.png'))) self.clear_ratings_button.clicked.connect(self.rating.zero) self.basic_metadata_widgets.append(self.rating) self.tags = TagsEdit(self) self.tags_editor_button = QToolButton(self) self.tags_editor_button.setToolTip(_('Open Tag Editor')) self.tags_editor_button.setIcon(QIcon(I('chapters.png'))) self.tags_editor_button.clicked.connect(self.tags_editor) self.clear_tags_button = QToolButton(self) self.clear_tags_button.setToolTip(_('Clear all tags')) self.clear_tags_button.setIcon(QIcon(I('trash.png'))) self.clear_tags_button.clicked.connect(self.tags.clear) self.basic_metadata_widgets.append(self.tags) self.identifiers = IdentifiersEdit(self) self.basic_metadata_widgets.append(self.identifiers) self.clear_identifiers_button = QToolButton(self) self.clear_identifiers_button.setIcon(QIcon(I('trash.png'))) self.clear_identifiers_button.setToolTip(_('Clear Ids')) self.clear_identifiers_button.clicked.connect(self.identifiers.clear) self.paste_isbn_button = QToolButton(self) self.paste_isbn_button.setToolTip( '<p>' + _('Paste the contents of the clipboard into the ' 'identifiers box prefixed with isbn:') + '</p>') self.paste_isbn_button.setIcon(QIcon(I('edit-paste.png'))) self.paste_isbn_button.clicked.connect(self.identifiers.paste_isbn) self.publisher = PublisherEdit(self) self.basic_metadata_widgets.append(self.publisher) self.timestamp = DateEdit(self) self.pubdate = PubdateEdit(self) self.basic_metadata_widgets.extend([self.timestamp, self.pubdate]) self.fetch_metadata_button = QPushButton(_('&Download metadata'), self) self.fetch_metadata_button.clicked.connect(self.fetch_metadata) self.download_shortcut.activated.connect( self.fetch_metadata_button.click) font = self.fmb_font = QFont() font.setBold(True) self.fetch_metadata_button.setFont(font) if self.use_toolbutton_for_config_metadata: self.config_metadata_button = QToolButton(self) self.config_metadata_button.setIcon(QIcon(I('config.png'))) else: self.config_metadata_button = QPushButton(self) self.config_metadata_button.setText( _('Configure download metadata')) self.config_metadata_button.setIcon(QIcon(I('config.png'))) self.config_metadata_button.clicked.connect(self.configure_metadata) self.config_metadata_button.setToolTip( _('Change how calibre downloads metadata'))
def __init__(self, parent, icon, prefs): self.parent = parent self.prefs = prefs self.icon = icon super(AnnotationsAppearance, self).__init__(parent, 'appearance_dialog') self.setWindowTitle(_('Modify appearance')) self.setWindowIcon(icon) self.l = QVBoxLayout(self) self.setLayout(self.l) # Add a label for description #self.description_label = QLabel(_("Descriptive text here")) #self.l.addWidget(self.description_label) # Add a group box, vertical layout for preview window self.preview_gb = QGroupBox(self) self.preview_gb.setTitle(_("Preview")) self.preview_vl = QVBoxLayout(self.preview_gb) self.l.addWidget(self.preview_gb) self.wv = QWebView() self.wv.setHtml('<p></p>') self.wv.setMinimumHeight(100) self.wv.setMaximumHeight(16777215) self.wv.setGeometry(0, 0, 200, 100) self.wv.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.preview_vl.addWidget(self.wv) # Create a group box, horizontal layout for the table self.css_table_gb = QGroupBox(self) self.css_table_gb.setTitle(_("Annotation elements")) self.elements_hl = QHBoxLayout(self.css_table_gb) self.l.addWidget(self.css_table_gb) # Add the group box to the main layout self.elements_table = AnnotationElementsTable( self, 'annotation_elements_tw') self.elements_hl.addWidget(self.elements_table) self.elements_table.initialize() # Options self.options_gb = QGroupBox(self) self.options_gb.setTitle(_("Options")) self.options_gl = QGridLayout(self.options_gb) self.l.addWidget(self.options_gb) current_row = 0 # <hr/> separator # addWidget(widget, row, col, rowspan, colspan) self.hr_checkbox = QCheckBox( _('Add horizontal rule between annotations')) self.hr_checkbox.stateChanged.connect(self.hr_checkbox_changed) self.hr_checkbox.setCheckState( JSONConfig('plugins/annotations').get('appearance_hr_checkbox', False)) self.options_gl.addWidget(self.hr_checkbox, current_row, 0, 1, 4) current_row += 1 # Timestamp self.timestamp_fmt_label = QLabel(_("Timestamp format:")) self.options_gl.addWidget(self.timestamp_fmt_label, current_row, 0) self.timestamp_fmt_le = QLineEdit( JSONConfig('plugins/annotations').get( 'appearance_timestamp_format', default_timestamp), parent=self) self.timestamp_fmt_le.textEdited.connect(self.timestamp_fmt_changed) self.timestamp_fmt_le.setFont(self.FONT) self.timestamp_fmt_le.setObjectName('timestamp_fmt_le') self.timestamp_fmt_le.setToolTip(_('Format string for timestamp')) self.timestamp_fmt_le.setMaximumWidth(16777215) self.timestamp_fmt_le.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.options_gl.addWidget(self.timestamp_fmt_le, current_row, 1) self.timestamp_fmt_reset_tb = QToolButton(self) self.timestamp_fmt_reset_tb.setToolTip(_("Reset to default")) self.timestamp_fmt_reset_tb.setIcon(QIcon(I('trash.png'))) self.timestamp_fmt_reset_tb.clicked.connect( self.reset_timestamp_to_default) self.options_gl.addWidget(self.timestamp_fmt_reset_tb, current_row, 2) self.timestamp_fmt_help_tb = QToolButton(self) self.timestamp_fmt_help_tb.setToolTip(_("Format string reference")) self.timestamp_fmt_help_tb.setIcon(QIcon(I('help.png'))) self.timestamp_fmt_help_tb.clicked.connect(self.show_help) self.options_gl.addWidget(self.timestamp_fmt_help_tb, current_row, 3) # Button box bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.l.addWidget(bb) # Spacer self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.l.addItem(self.spacerItem) # Sizing sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.resize_dialog()
def __init__(self, parent, db, author, series=None, title=None, dup_title=None): QDialog.__init__(self, parent) self.db = db self.setWindowTitle(_('How many empty books?')) self._layout = QGridLayout(self) self.setLayout(self._layout) self.qty_label = QLabel(_('How many empty books should be added?')) self._layout.addWidget(self.qty_label, 0, 0, 1, 2) self.qty_spinbox = QSpinBox(self) self.qty_spinbox.setRange(1, 10000) self.qty_spinbox.setValue(1) self._layout.addWidget(self.qty_spinbox, 1, 0, 1, 2) self.author_label = QLabel(_('Set the author of the new books to:')) self._layout.addWidget(self.author_label, 2, 0, 1, 2) self.authors_combo = EditWithComplete(self) self.authors_combo.setSizeAdjustPolicy( self.authors_combo.AdjustToMinimumContentsLengthWithIcon) self.authors_combo.setEditable(True) self._layout.addWidget(self.authors_combo, 3, 0, 1, 1) self.initialize_authors(db, author) self.clear_button = QToolButton(self) self.clear_button.setIcon(QIcon(I('trash.png'))) self.clear_button.setToolTip(_('Reset author to Unknown')) self.clear_button.clicked.connect(self.reset_author) self._layout.addWidget(self.clear_button, 3, 1, 1, 1) self.series_label = QLabel(_('Set the series of the new books to:')) self._layout.addWidget(self.series_label, 4, 0, 1, 2) self.series_combo = EditWithComplete(self) self.series_combo.setSizeAdjustPolicy( self.authors_combo.AdjustToMinimumContentsLengthWithIcon) self.series_combo.setEditable(True) self._layout.addWidget(self.series_combo, 5, 0, 1, 1) self.initialize_series(db, series) self.sclear_button = QToolButton(self) self.sclear_button.setIcon(QIcon(I('trash.png'))) self.sclear_button.setToolTip(_('Reset series')) self.sclear_button.clicked.connect(self.reset_series) self._layout.addWidget(self.sclear_button, 5, 1, 1, 1) self.title_label = QLabel(_('Set the title of the new books to:')) self._layout.addWidget(self.title_label, 6, 0, 1, 2) self.title_edit = QLineEdit(self) self.title_edit.setText(title or '') self._layout.addWidget(self.title_edit, 7, 0, 1, 1) self.tclear_button = QToolButton(self) self.tclear_button.setIcon(QIcon(I('trash.png'))) self.tclear_button.setToolTip(_('Reset title')) self.tclear_button.clicked.connect(self.title_edit.clear) self._layout.addWidget(self.tclear_button, 7, 1, 1, 1) self.format_label = QLabel(_('Also create an empty e-book in format:')) self._layout.addWidget(self.format_label, 8, 0, 1, 2) c = self.format_value = QComboBox(self) from calibre.ebooks.oeb.polish.create import valid_empty_formats possible_formats = [''] + sorted(x.upper() for x in valid_empty_formats) c.addItems(possible_formats) c.setToolTip(_('Also create an empty book format file that you can subsequently edit')) if gprefs.get('create_empty_epub_file', False): # Migration of the check box gprefs.set('create_empty_format_file', 'epub') del gprefs['create_empty_epub_file'] use_format = gprefs.get('create_empty_format_file', '').upper() try: c.setCurrentIndex(possible_formats.index(use_format)) except Exception: pass self._layout.addWidget(c, 9, 0, 1, 1) self.copy_formats = cf = QCheckBox(_('Also copy book &formats when duplicating a book'), self) cf.setToolTip(_( 'Also copy all e-book files into the newly created duplicate' ' books.')) cf.setChecked(gprefs.get('create_empty_copy_dup_formats', False)) self._layout.addWidget(cf, 10, 0, 1, -1) button_box = self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) self._layout.addWidget(button_box, 11, 0, 1, -1) if dup_title: self.dup_button = b = button_box.addButton(_('&Duplicate current book'), button_box.ActionRole) b.clicked.connect(self.do_duplicate_book) b.setIcon(QIcon(I('edit-copy.png'))) b.setToolTip(_( 'Make the new empty book records exact duplicates\n' 'of the current book "%s", with all metadata identical' ) % dup_title) self.resize(self.sizeHint()) self.duplicate_current_book = False
def __init__(self, parent, db, key): QDialog.__init__(self, parent) self.setWindowTitle(_('Edit permissible values for {0}').format(key)) self.db = db l = QGridLayout() bbox = QVBoxLayout() bbox.addStretch(10) self.del_button = QToolButton() self.del_button.setIcon(QIcon(I('trash.png'))) self.del_button.setToolTip(_('Remove the currently selected value')) self.ins_button = QToolButton() self.ins_button.setIcon(QIcon(I('plus.png'))) self.ins_button.setToolTip(_('Add a new permissible value')) self.move_up_button = QToolButton() self.move_up_button.setIcon(QIcon(I('arrow-up.png'))) self.move_down_button = QToolButton() self.move_down_button.setIcon(QIcon(I('arrow-down.png'))) bbox.addWidget(self.del_button) bbox.addStretch(1) bbox.addWidget(self.ins_button) bbox.addStretch(1) bbox.addWidget(self.move_up_button) bbox.addStretch(1) bbox.addWidget(self.move_down_button) bbox.addStretch(10) l.addItem(bbox, 0, 0) self.del_button.clicked.connect(self.del_line) self.all_colors = {unicode_type(s) for s in list(QColor.colorNames())} tl = QVBoxLayout() l.addItem(tl, 0, 1) self.table = t = QTableWidget(parent) t.setColumnCount(2) t.setRowCount(1) t.setHorizontalHeaderLabels([_('Value'), _('Color')]) t.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) tl.addWidget(t) self.fm = fm = db.field_metadata[key] permitted_values = fm.get('display', {}).get('enum_values', '') colors = fm.get('display', {}).get('enum_colors', '') t.setRowCount(len(permitted_values)) for i, v in enumerate(permitted_values): t.setItem(i, 0, QTableWidgetItem(v)) c = self.make_color_combobox(i, -1) if colors: c.setCurrentIndex(c.findText(colors[i])) else: c.setCurrentIndex(0) t.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeMode.Stretch) self.setLayout(l) self.bb = bb = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addWidget(bb, 1, 0, 1, 2) self.ins_button.clicked.connect(self.ins_button_clicked) self.move_down_button.clicked.connect(self.move_down_clicked) self.move_up_button.clicked.connect(self.move_up_clicked) geom = gprefs.get('enum-values-edit-geometry') if geom is not None: QApplication.instance().safe_restore_geometry(self, geom)
def __init__(self, parent, prefs): QWidget.__init__(self, parent) self.prefs = prefs l = self.l = QGridLayout() self.setLayout(l) self.tocw = t = TreeWidget(self) self.tocw.edit_item.connect(self.edit_item) l.addWidget(t, 0, 0, 7, 3) self.up_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))) b.setIconSize(QSize(ICON_SIZE, ICON_SIZE)) l.addWidget(b, 0, 3) b.setToolTip(_('Move current entry up [Ctrl+Up]')) b.clicked.connect(self.move_up) self.left_button = b = QToolButton(self) b.setIcon(QIcon(I('back.png'))) b.setIconSize(QSize(ICON_SIZE, ICON_SIZE)) l.addWidget(b, 2, 3) b.setToolTip(_('Unindent the current entry [Ctrl+Left]')) b.clicked.connect(self.tocw.move_left) self.del_button = b = QToolButton(self) b.setIcon(QIcon(I('trash.png'))) b.setIconSize(QSize(ICON_SIZE, ICON_SIZE)) l.addWidget(b, 3, 3) b.setToolTip(_('Remove all selected entries')) b.clicked.connect(self.del_items) self.right_button = b = QToolButton(self) b.setIcon(QIcon(I('forward.png'))) b.setIconSize(QSize(ICON_SIZE, ICON_SIZE)) l.addWidget(b, 4, 3) b.setToolTip(_('Indent the current entry [Ctrl+Right]')) b.clicked.connect(self.tocw.move_right) self.down_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))) b.setIconSize(QSize(ICON_SIZE, ICON_SIZE)) l.addWidget(b, 6, 3) b.setToolTip(_('Move current entry down [Ctrl+Down]')) b.clicked.connect(self.move_down) self.expand_all_button = b = QPushButton(_('&Expand all')) col = 7 l.addWidget(b, col, 0) b.clicked.connect(self.tocw.expandAll) self.collapse_all_button = b = QPushButton(_('&Collapse all')) b.clicked.connect(self.tocw.collapseAll) l.addWidget(b, col, 1) self.default_msg = _('Double click on an entry to change the text') self.hl = hl = QLabel(self.default_msg) l.addWidget(hl, col, 2, 1, -1) self.item_view = i = ItemView(self, self.prefs) self.item_view.delete_item.connect(self.delete_current_item) i.add_new_item.connect(self.add_new_item) i.create_from_xpath.connect(self.create_from_xpath) i.create_from_links.connect(self.create_from_links) i.create_from_files.connect(self.create_from_files) i.flatten_item.connect(self.flatten_item) i.flatten_toc.connect(self.flatten_toc) i.go_to_root.connect(self.go_to_root) l.addWidget(i, 0, 4, col, 1) l.setColumnStretch(2, 10)
def __init__(self, text, colors, color_caption): TestableWidget.__init__(self) self.setWindowFlags(Qt.Popup) main_layout = QVBoxLayout() main_layout.setContentsMargins(0, 0, 0, 0) border = "border: 1px solid #9b9b9b;" self.setStyleSheet('QFrame[frameShape="4"]{ color: #9b9b9b;}') # -- CAPTION ---------------------------------- caption = QFrame(self, flags=Qt.WindowFlags()) caption_layout = QHBoxLayout() self._lbl_caption = QLabel(text) self._lbl_caption.setStyleSheet("border: 0px solid blue;") caption_layout.addWidget(self._lbl_caption, alignment=Qt.Alignment()) caption.setLayout(caption_layout) caption_layout.setContentsMargins(9, 5, 9, 5) caption.setStyleSheet(f"background-color: {color_caption}; {border}") # -- COLORS GRID ------------------------------ colorbox = QFrame(self, flags=Qt.WindowFlags()) color_layout = QGridLayout() colorbox.setLayout(color_layout) color_layout.setContentsMargins(9, 0, 9, 0) nn = 7 self.clrbtn = [] for i, color in enumerate(colors): self.clrbtn.append(QToolButton()) css = (f"QToolButton {{{border}background-color:{color};}}" f"QToolButton:hover {{border: 1px solid red; }}") self.clrbtn[-1].setStyleSheet(css) self.clrbtn[-1].clicked.connect( lambda x, c=color: self.select_color_(c)) # noinspection PyArgumentList color_layout.addWidget(self.clrbtn[-1], i // nn, i % nn) # -- SPLITTER --------------------------------- h_frame = QFrame(None, flags=Qt.WindowFlags()) h_frame.setFrameShape(QFrame.HLine) h_frame.setContentsMargins(0, 0, 0, 0) # -- BOTTOM (other color) --------------------- btns = QFrame(self, flags=Qt.WindowFlags()) btn_layout = QHBoxLayout() other = QToolButton() other.clicked.connect(self.other_color_) other.setAutoRaise(True) other.setIcon(QIcon(img("editor/colorwheel"))) btn_layout.addWidget(other, alignment=Qt.Alignment()) self._lbl_other = QLabel(self.tr("other colors")) btn_layout.addWidget(self._lbl_other, alignment=Qt.Alignment()) btns.setLayout(btn_layout) btn_layout.setContentsMargins(9, 0, 9, 9) self.clrbtn.append(other) # --------------------------------------------- main_layout.addWidget(caption, alignment=Qt.Alignment()) main_layout.addWidget(colorbox, alignment=Qt.Alignment()) main_layout.addWidget(h_frame, alignment=Qt.Alignment()) main_layout.addWidget(btns, alignment=Qt.Alignment()) self.setLayout(main_layout)
def setup_ui(self): self.l = l = QGridLayout(self) self.setLayout(l) self.la1 = la = QLabel(_('&Existing images in the book')) la.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) l.addWidget(la, 0, 0, 1, 2) if self.for_browsing: la.setVisible(False) self.view = v = QListView(self) v.setViewMode(QListView.ViewMode.IconMode) v.setFlow(QListView.Flow.LeftToRight) v.setSpacing(4) v.setResizeMode(QListView.ResizeMode.Adjust) v.setUniformItemSizes(True) set_no_activate_on_click(v) v.activated.connect(self.activated) v.doubleClicked.connect(self.activated) self.d = ImageDelegate(v) v.setItemDelegate(self.d) self.model = Images(self.view) self.fm = fm = QSortFilterProxyModel(self.view) self.fm.setDynamicSortFilter(self.for_browsing) fm.setSourceModel(self.model) fm.setFilterCaseSensitivity(False) v.setModel(fm) l.addWidget(v, 1, 0, 1, 2) v.pressed.connect(self.pressed) la.setBuddy(v) self.filter = f = QLineEdit(self) f.setPlaceholderText(_('Search for image by file name')) l.addWidget(f, 2, 0) self.cb = b = QToolButton(self) b.setIcon(QIcon(I('clear_left.png'))) b.clicked.connect(f.clear) l.addWidget(b, 2, 1) f.textChanged.connect(self.filter_changed) if self.for_browsing: self.bb.clear() self.bb.addButton(self.bb.Close) b = self.refresh_button = self.bb.addButton(_('&Refresh'), self.bb.ActionRole) b.clicked.connect(self.refresh) b.setIcon(QIcon(I('view-refresh.png'))) b.setToolTip(_('Refresh the displayed images')) self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False) else: b = self.import_button = self.bb.addButton(_('&Import image'), self.bb.ActionRole) b.clicked.connect(self.import_image) b.setIcon(QIcon(I('view-image.png'))) b.setToolTip(_('Import an image from elsewhere in your computer')) b = self.paste_button = self.bb.addButton(_('&Paste image'), self.bb.ActionRole) b.clicked.connect(self.paste_image) b.setIcon(QIcon(I('edit-paste.png'))) b.setToolTip(_('Paste an image from the clipboard')) self.fullpage = f = QCheckBox(_('Full page image'), self) f.setToolTip(_('Insert the image so that it takes up an entire page when viewed in a reader')) f.setChecked(tprefs['insert_full_screen_image']) self.preserve_aspect_ratio = a = QCheckBox(_('Preserve aspect ratio')) a.setToolTip(_('Preserve the aspect ratio of the inserted image when rendering it full paged')) a.setChecked(tprefs['preserve_aspect_ratio_when_inserting_image']) f.toggled.connect(self.full_page_image_toggled) a.toggled.connect(self.par_toggled) a.setVisible(f.isChecked()) h = QHBoxLayout() l.addLayout(h, 3, 0, 1, -1) h.addWidget(f), h.addStretch(10), h.addWidget(a) b = self.bb.addButton(_('&Zoom in'), self.bb.ActionRole) b.clicked.connect(self.zoom_in) b.setIcon(QIcon(I('plus.png'))) b = self.bb.addButton(_('Zoom &out'), self.bb.ActionRole) b.clicked.connect(self.zoom_out) b.setIcon(QIcon(I('minus.png'))) l.addWidget(self.bb, 4, 0, 1, 2)
def __init__(self, opts): self.matched_ids = set() self.opts = opts self.prefs = opts.prefs super(FindAnnotationsDialog, self).__init__(self.opts.gui, 'find_annotations_dialog') self.setWindowTitle(_('Find Annotations')) self.setWindowIcon(self.opts.icon) self.l = QVBoxLayout(self) self.setLayout(self.l) self.search_criteria_gb = QGroupBox(self) self.search_criteria_gb.setTitle(_("Search criteria")) self.scgl = QGridLayout(self.search_criteria_gb) self.l.addWidget(self.search_criteria_gb) # addWidget(widget, row, col, rowspan, colspan) row = 0 # ~~~~~~~~ Create the Readers comboBox ~~~~~~~~ self.reader_label = QLabel(_('Reader')) self.reader_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.scgl.addWidget(self.reader_label, row, 0, 1, 1) self.find_annotations_reader_comboBox = QComboBox() self.find_annotations_reader_comboBox.setObjectName('find_annotations_reader_comboBox') self.find_annotations_reader_comboBox.setToolTip(_('Reader annotations to search for')) self.find_annotations_reader_comboBox.addItem(self.GENERIC_READER) racs = ReaderApp.get_reader_app_classes() for ra in sorted(racs.keys()): self.find_annotations_reader_comboBox.addItem(ra) self.scgl.addWidget(self.find_annotations_reader_comboBox, row, 1, 1, 4) row += 1 # ~~~~~~~~ Create the Styles comboBox ~~~~~~~~ self.style_label = QLabel(_('Style')) self.style_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.scgl.addWidget(self.style_label, row, 0, 1, 1) self.find_annotations_color_comboBox = QComboBox() self.find_annotations_color_comboBox.setObjectName('find_annotations_color_comboBox') self.find_annotations_color_comboBox.setToolTip(_('Annotation style to search for')) self.find_annotations_color_comboBox.addItem(self.GENERIC_STYLE) all_colors = COLOR_MAP.keys() all_colors.remove('Default') for color in sorted(all_colors): self.find_annotations_color_comboBox.addItem(color) self.scgl.addWidget(self.find_annotations_color_comboBox, row, 1, 1, 4) row += 1 # ~~~~~~~~ Create the Text LineEdit control ~~~~~~~~ self.text_label = QLabel(_('Text')) self.text_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.scgl.addWidget(self.text_label, row, 0, 1, 1) self.find_annotations_text_lineEdit = MyLineEdit() self.find_annotations_text_lineEdit.setObjectName('find_annotations_text_lineEdit') self.scgl.addWidget(self.find_annotations_text_lineEdit, row, 1, 1, 3) self.reset_text_tb = QToolButton() self.reset_text_tb.setObjectName('reset_text_tb') self.reset_text_tb.setToolTip(_('Clear search criteria')) self.reset_text_tb.setIcon(QIcon(I('trash.png'))) self.reset_text_tb.clicked.connect(self.clear_text_field) self.scgl.addWidget(self.reset_text_tb, row, 4, 1, 1) row += 1 # ~~~~~~~~ Create the Note LineEdit control ~~~~~~~~ self.note_label = QLabel(_('Note')) self.note_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.scgl.addWidget(self.note_label, row, 0, 1, 1) self.find_annotations_note_lineEdit = MyLineEdit() self.find_annotations_note_lineEdit.setObjectName('find_annotations_note_lineEdit') self.scgl.addWidget(self.find_annotations_note_lineEdit, row, 1, 1, 3) self.reset_note_tb = QToolButton() self.reset_note_tb.setObjectName('reset_note_tb') self.reset_note_tb.setToolTip(_('Clear search criteria')) self.reset_note_tb.setIcon(QIcon(I('trash.png'))) self.reset_note_tb.clicked.connect(self.clear_note_field) self.scgl.addWidget(self.reset_note_tb, row, 4, 1, 1) row += 1 # ~~~~~~~~ Create the Date range controls ~~~~~~~~ self.date_range_label = QLabel(_('Date range')) self.date_range_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.scgl.addWidget(self.date_range_label, row, 0, 1, 1) # Date 'From' self.find_annotations_date_from_dateEdit = MyDateEdit(self, datetime(1970,1,1)) self.find_annotations_date_from_dateEdit.setObjectName('find_annotations_date_from_dateEdit') #self.find_annotations_date_from_dateEdit.current_val = datetime(1970,1,1) self.find_annotations_date_from_dateEdit.clear_button.clicked.connect(self.find_annotations_date_from_dateEdit.reset_from_date) self.scgl.addWidget(self.find_annotations_date_from_dateEdit, row, 1, 1, 1) self.scgl.addWidget(self.find_annotations_date_from_dateEdit.clear_button, row, 2, 1, 1) # Date 'To' self.find_annotations_date_to_dateEdit = MyDateEdit(self, datetime.today()) self.find_annotations_date_to_dateEdit.setObjectName('find_annotations_date_to_dateEdit') #self.find_annotations_date_to_dateEdit.current_val = datetime.today() self.find_annotations_date_to_dateEdit.clear_button.clicked.connect(self.find_annotations_date_to_dateEdit.reset_to_date) self.scgl.addWidget(self.find_annotations_date_to_dateEdit, row, 3, 1, 1) self.scgl.addWidget(self.find_annotations_date_to_dateEdit.clear_button, row, 4, 1, 1) row += 1 # ~~~~~~~~ Create a horizontal line ~~~~~~~~ self.hl = QFrame(self) self.hl.setGeometry(QRect(0, 0, 1, 3)) self.hl.setFrameShape(QFrame.HLine) self.hl.setFrameShadow(QFrame.Raised) self.scgl.addWidget(self.hl, row, 0, 1, 5) row += 1 # ~~~~~~~~ Create the results label field ~~~~~~~~ self.result_label = QLabel('<p style="color:red">{0}</p>'.format(_('scanning…'))) self.result_label.setAlignment(Qt.AlignCenter) self.result_label.setWordWrap(False) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.result_label.sizePolicy().hasHeightForWidth()) self.result_label.setSizePolicy(sizePolicy) self.result_label.setMinimumSize(QtCore.QSize(250, 0)) self.scgl.addWidget(self.result_label, row, 0, 1, 5) row += 1 # ~~~~~~~~ Create the ButtonBox ~~~~~~~~ self.dialogButtonBox = QDialogButtonBox(self) self.dialogButtonBox.setOrientation(Qt.Horizontal) if False: self.update_button = QPushButton(_('Update results')) self.update_button.setDefault(True) self.update_button.setVisible(False) self.dialogButtonBox.addButton(self.update_button, QDialogButtonBox.ActionRole) self.cancel_button = self.dialogButtonBox.addButton(self.dialogButtonBox.Cancel) self.find_button = self.dialogButtonBox.addButton(self.dialogButtonBox.Ok) self.find_button.setText(_('Find Matching Books')) self.l.addWidget(self.dialogButtonBox) self.dialogButtonBox.clicked.connect(self.find_annotations_dialog_clicked) # ~~~~~~~~ Add a spacer ~~~~~~~~ self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.l.addItem(self.spacerItem) # ~~~~~~~~ Restore previously saved settings ~~~~~~~~ self.restore_settings() # ~~~~~~~~ Declare sizing ~~~~~~~~ sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.resize_dialog() # ~~~~~~~~ Connect all signals ~~~~~~~~ self.find_annotations_reader_comboBox.currentIndexChanged.connect(partial(self.update_results, 'reader')) self.find_annotations_color_comboBox.currentIndexChanged.connect(partial(self.update_results, 'color')) self.find_annotations_text_lineEdit.editingFinished.connect(partial(self.update_results, 'text')) self.find_annotations_note_lineEdit.editingFinished.connect(partial(self.update_results, 'note')) # self.connect(self.find_annotations_text_lineEdit, pyqtSignal("return_pressed"), self.return_pressed) self.find_annotations_text_lineEdit.return_pressed.connect(self.return_pressed) # self.connect(self.find_annotations_note_lineEdit, pyqtSignal("return_pressed"), self.return_pressed) self.find_annotations_note_lineEdit.return_pressed.connect(self.return_pressed) # Date range signals connected in inventory_available() # ~~~~~~~~ Allow dialog to render before doing inventory ~~~~~~~~ #field = self.prefs.get('cfg_annotations_destination_field', None) field = get_cc_mapping('annotations', 'field', None) self.annotated_books_scanner = InventoryAnnotatedBooks(self.opts.gui, field, get_date_range=True) self.annotated_books_scanner.signal.connect(self.inventory_available) QTimer.singleShot(1, self.start_inventory_scan)
def __init__(self, parent): QFrame.__init__(self, parent) self.setFrameStyle(QFrame.Shape.NoFrame) self.setObjectName('search_bar') self._layout = l = QHBoxLayout(self) l.setContentsMargins(0, 4, 0, 4) x = parent.virtual_library = QToolButton(self) x.setCursor(Qt.CursorShape.PointingHandCursor) x.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) x.setText(_('Virtual library')) x.setAutoRaise(True) x.setIcon(QIcon(I('vl.png'))) x.setObjectName("virtual_library") x.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) l.addWidget(x) x = QToolButton(self) x.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) x.setAutoRaise(True) x.setIcon(QIcon(I('minus.png'))) x.setObjectName('clear_vl') l.addWidget(x) x.setVisible(False) x.setToolTip(_('Close the Virtual library')) parent.clear_vl = x self.vl_sep = QFrame(self) self.vl_sep.setFrameStyle(QFrame.Shape.VLine | QFrame.Shadow.Sunken) l.addWidget(self.vl_sep) parent.sort_sep = QFrame(self) parent.sort_sep.setFrameStyle(QFrame.Shape.VLine | QFrame.Shadow.Sunken) parent.sort_sep.setVisible(False) parent.sort_button = self.sort_button = sb = QToolButton(self) sb.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) sb.setToolTip(_('Change how the displayed books are sorted')) sb.setCursor(Qt.CursorShape.PointingHandCursor) sb.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) sb.setAutoRaise(True) sb.setText(_('Sort')) sb.setIcon(QIcon(I('sort.png'))) sb.setMenu(QMenu(sb)) sb.menu().aboutToShow.connect(self.populate_sort_menu) sb.setVisible(False) l.addWidget(sb) l.addWidget(parent.sort_sep) x = parent.search = SearchBox2(self, as_url=search_as_url) x.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) x.setObjectName("search") x.setToolTip(_("<p>Search the list of books by title, author, publisher, " "tags, comments, etc.<br><br>Words separated by spaces are ANDed")) x.setMinimumContentsLength(10) l.addWidget(x) parent.advanced_search_toggle_action = ac = parent.search.add_action('gear.png', QLineEdit.ActionPosition.LeadingPosition) parent.addAction(ac) ac.setToolTip(_('Advanced search')) parent.keyboard.register_shortcut('advanced search toggle', _('Advanced search'), default_keys=("Shift+Ctrl+F",), action=ac) self.search_button = QToolButton() self.search_button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextOnly) self.search_button.setIcon(QIcon(I('search.png'))) self.search_button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) self.search_button.setText(_('Search')) self.search_button.setAutoRaise(True) self.search_button.setCursor(Qt.CursorShape.PointingHandCursor) l.addWidget(self.search_button) self.search_button.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) self.search_button.clicked.connect(parent.do_search_button) self.search_button.setToolTip( _('Do quick search (you can also press the Enter key)')) x = parent.highlight_only_button = QToolButton(self) x.setAutoRaise(True) x.setText(_('Highlight')) x.setCursor(Qt.CursorShape.PointingHandCursor) x.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) x.setIcon(QIcon(I('arrow-down.png'))) l.addWidget(x) x = parent.saved_search = SavedSearchBox(self) x.setMaximumSize(QSize(150, 16777215)) x.setMinimumContentsLength(10) x.setObjectName("saved_search") l.addWidget(x) x.setVisible(tweaks['show_saved_search_box']) x = parent.copy_search_button = QToolButton(self) x.setAutoRaise(True) x.setCursor(Qt.CursorShape.PointingHandCursor) x.setIcon(QIcon(I("search_copy_saved.png"))) x.setObjectName("copy_search_button") l.addWidget(x) x.setToolTip(_("Copy current search text (instead of search name)")) x.setVisible(tweaks['show_saved_search_box']) x = parent.save_search_button = RightClickButton(self) x.setAutoRaise(True) x.setCursor(Qt.CursorShape.PointingHandCursor) x.setIcon(QIcon(I("search_add_saved.png"))) x.setObjectName("save_search_button") l.addWidget(x) x.setVisible(tweaks['show_saved_search_box']) x = parent.add_saved_search_button = RightClickButton(self) x.setToolTip(_( 'Use an existing Saved search or create a new one' )) x.setText(_('Saved search')) x.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) x.setCursor(Qt.CursorShape.PointingHandCursor) x.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) x.setAutoRaise(True) x.setIcon(QIcon(I("bookmarks.png"))) l.addWidget(x) x.setVisible(not tweaks['show_saved_search_box'])
def __init__(self, parent, db, author, series=None): QDialog.__init__(self, parent) self.db = db self.setWindowTitle(_('How many empty books?')) self._layout = QGridLayout(self) self.setLayout(self._layout) self.qty_label = QLabel(_('How many empty books should be added?')) self._layout.addWidget(self.qty_label, 0, 0, 1, 2) self.qty_spinbox = QSpinBox(self) self.qty_spinbox.setRange(1, 10000) self.qty_spinbox.setValue(1) self._layout.addWidget(self.qty_spinbox, 1, 0, 1, 2) self.author_label = QLabel(_('Set the author of the new books to:')) self._layout.addWidget(self.author_label, 2, 0, 1, 2) self.authors_combo = EditWithComplete(self) self.authors_combo.setSizeAdjustPolicy( self.authors_combo.AdjustToMinimumContentsLengthWithIcon) self.authors_combo.setEditable(True) self._layout.addWidget(self.authors_combo, 3, 0, 1, 1) self.initialize_authors(db, author) self.clear_button = QToolButton(self) self.clear_button.setIcon(QIcon(I('trash.png'))) self.clear_button.setToolTip(_('Reset author to Unknown')) self.clear_button.clicked.connect(self.reset_author) self._layout.addWidget(self.clear_button, 3, 1, 1, 1) self.series_label = QLabel(_('Set the series of the new books to:')) self._layout.addWidget(self.series_label, 4, 0, 1, 2) self.series_combo = EditWithComplete(self) self.authors_combo.setSizeAdjustPolicy( self.authors_combo.AdjustToMinimumContentsLengthWithIcon) self.series_combo.setEditable(True) self._layout.addWidget(self.series_combo, 5, 0, 1, 1) self.initialize_series(db, series) self.sclear_button = QToolButton(self) self.sclear_button.setIcon(QIcon(I('trash.png'))) self.sclear_button.setToolTip(_('Reset series')) self.sclear_button.clicked.connect(self.reset_series) self._layout.addWidget(self.sclear_button, 5, 1, 1, 1) self.create_epub = c = QCheckBox( _('Create an empty EPUB file as well')) c.setChecked(gprefs.get('create_empty_epub_file', False)) c.setToolTip( _('Also create an empty EPUB file that you can subsequently edit')) self._layout.addWidget(c, 6, 0, 1, -1) button_box = self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) self._layout.addWidget(button_box, 7, 0, 1, -1) self.resize(self.sizeHint())
def __init__(self, recipe_model, parent=None): QDialog.__init__(self, parent) self.commit_on_change = True self.previous_urn = None self.setWindowIcon(QIcon(I('scheduler.png'))) self.setWindowTitle(_("Schedule news download")) self.l = l = QGridLayout(self) # Left panel self.h = h = QHBoxLayout() l.addLayout(h, 0, 0, 1, 1) self.search = s = SearchBox2(self) self.search.initialize('scheduler_search_history') self.search.setMinimumContentsLength(15) self.go_button = b = QToolButton(self) b.setText(_("Go")) b.clicked.connect(self.search.do_search) h.addWidget(s), h.addWidget(b) self.recipes = RecipesView(self) l.addWidget(self.recipes, 1, 0, 1, 1) self.recipe_model = recipe_model self.recipe_model.do_refresh() self.recipes.setModel(self.recipe_model) self.recipes.setFocus(Qt.OtherFocusReason) self.count_label = la = QLabel(_('%s news sources') % self.recipe_model.showing_count) la.setAlignment(Qt.AlignCenter) l.addWidget(la, 2, 0, 1, 1) self.search.search.connect(self.recipe_model.search) self.recipe_model.searched.connect(self.search.search_done, type=Qt.QueuedConnection) self.recipe_model.searched.connect(self.search_done) # Right Panel self.scroll_area_contents = sac = QWidget(self) self.l.addWidget(sac, 0, 1, 2, 1) sac.v = v = QVBoxLayout(sac) v.setContentsMargins(0, 0, 0, 0) self.detail_box = QTabWidget(self) self.detail_box.setVisible(False) self.detail_box.setCurrentIndex(0) v.addWidget(self.detail_box) v.addItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)) # First Tab (scheduling) self.tab = QWidget() self.detail_box.addTab(self.tab, _("&Schedule")) self.tab.v = vt = QVBoxLayout(self.tab) vt.setContentsMargins(0, 0, 0, 0) self.blurb = la = QLabel('blurb') la.setWordWrap(True), la.setOpenExternalLinks(True) vt.addWidget(la) self.frame = f = QFrame(self.tab) vt.addWidget(f) f.setFrameShape(f.StyledPanel) f.setFrameShadow(f.Raised) f.v = vf = QVBoxLayout(f) self.schedule = s = QCheckBox(_("&Schedule for download:"), f) self.schedule.stateChanged[int].connect(self.toggle_schedule_info) vf.addWidget(s) f.h = h = QHBoxLayout() vf.addLayout(h) self.days_of_week = QRadioButton(_("&Days of week"), f) self.days_of_month = QRadioButton(_("Da&ys of month"), f) self.every_x_days = QRadioButton(_("Every &x days"), f) self.days_of_week.setChecked(True) h.addWidget(self.days_of_week), h.addWidget(self.days_of_month), h.addWidget(self.every_x_days) self.schedule_stack = ss = QStackedWidget(f) self.schedule_widgets = [] for key in reversed(self.SCHEDULE_TYPES): self.schedule_widgets.insert(0, self.SCHEDULE_TYPES[key](self)) self.schedule_stack.insertWidget(0, self.schedule_widgets[0]) vf.addWidget(ss) self.last_downloaded = la = QLabel(f) la.setWordWrap(True) vf.addWidget(la) self.account = acc = QGroupBox(self.tab) acc.setTitle(_("&Account")) vt.addWidget(acc) acc.g = g = QGridLayout(acc) acc.unla = la = QLabel(_("&Username:"******"&Password:"******"&Show password"), self.account) spw.stateChanged[int].connect(self.set_pw_echo_mode) g.addWidget(spw, 2, 0, 1, 2) self.rla = la = QLabel(_("For the scheduling to work, you must leave calibre running.")) vt.addWidget(la) for b, c in iteritems(self.SCHEDULE_TYPES): b = getattr(self, b) b.toggled.connect(self.schedule_type_selected) b.setToolTip(textwrap.dedent(c.HELP)) # Second tab (advanced settings) self.tab2 = t2 = QWidget() self.detail_box.addTab(self.tab2, _("&Advanced")) self.tab2.g = g = QGridLayout(t2) g.setContentsMargins(0, 0, 0, 0) self.add_title_tag = tt = QCheckBox(_("Add &title as tag"), t2) g.addWidget(tt, 0, 0, 1, 2) t2.la = la = QLabel(_("&Extra tags:")) self.custom_tags = ct = QLineEdit(self) la.setBuddy(ct) g.addWidget(la), g.addWidget(ct, 1, 1) t2.la2 = la = QLabel(_("&Keep at most:")) la.setToolTip(_("Maximum number of copies (issues) of this recipe to keep. Set to 0 to keep all (disable).")) self.keep_issues = ki = QSpinBox(t2) tt.toggled['bool'].connect(self.keep_issues.setEnabled) ki.setMaximum(100000), la.setBuddy(ki) ki.setToolTip(_( "<p>When set, this option will cause calibre to keep, at most, the specified number of issues" " of this periodical. Every time a new issue is downloaded, the oldest one is deleted, if the" " total is larger than this number.\n<p>Note that this feature only works if you have the" " option to add the title as tag checked, above.\n<p>Also, the setting for deleting periodicals" " older than a number of days, below, takes priority over this setting.")) ki.setSpecialValueText(_("all issues")), ki.setSuffix(_(" issues")) g.addWidget(la), g.addWidget(ki, 2, 1) si = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) g.addItem(si, 3, 1, 1, 1) # Bottom area self.hb = h = QHBoxLayout() self.l.addLayout(h, 2, 1, 1, 1) self.labt = la = QLabel(_("Delete downloaded &news older than:")) self.old_news = on = QSpinBox(self) on.setToolTip(_( "<p>Delete downloaded news older than the specified number of days. Set to zero to disable.\n" "<p>You can also control the maximum number of issues of a specific periodical that are kept" " by clicking the Advanced tab for that periodical above.")) on.setSpecialValueText(_("never delete")), on.setSuffix(_(" days")) on.setMaximum(1000), la.setBuddy(on) on.setValue(gconf['oldest_news']) h.addWidget(la), h.addWidget(on) self.download_all_button = b = QPushButton(QIcon(I('news.png')), _("Download &all scheduled"), self) b.setToolTip(_("Download all scheduled news sources at once")) b.clicked.connect(self.download_all_clicked) self.l.addWidget(b, 3, 0, 1, 1) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) bb.accepted.connect(self.accept), bb.rejected.connect(self.reject) self.download_button = b = bb.addButton(_('&Download now'), bb.ActionRole) b.setIcon(QIcon(I('arrow-down.png'))), b.setVisible(False) b.clicked.connect(self.download_clicked) self.l.addWidget(bb, 3, 1, 1, 1) geom = gprefs.get('scheduler_dialog_geometry') if geom is not None: QApplication.instance().safe_restore_geometry(self, geom)
def __init__(self, field_metadata, parent=None, revert_tooltip=None, datetime_fmt='MMMM yyyy', blank_as_equal=True, fields=('title', 'authors', 'series', 'tags', 'rating', 'publisher', 'pubdate', 'identifiers', 'languages', 'comments', 'cover')): QWidget.__init__(self, parent) self.l = l = QGridLayout() l.setContentsMargins(0, 0, 0, 0) self.setLayout(l) revert_tooltip = revert_tooltip or _('Revert %s') self.current_mi = None self.changed_font = QFont(QApplication.font()) self.changed_font.setBold(True) self.changed_font.setItalic(True) self.blank_as_equal = blank_as_equal self.widgets = OrderedDict() row = 0 for field in fields: m = field_metadata[field] dt = m['datatype'] extra = None if 'series' in {field, dt}: cls = SeriesEdit elif field == 'identifiers': cls = IdentifiersEdit elif field == 'languages': cls = LanguagesEdit elif 'comments' in {field, dt}: cls = CommentsEdit elif 'rating' in {field, dt}: cls = RatingsEdit elif dt == 'datetime': extra = datetime_fmt cls = DateEdit elif field == 'cover': cls = CoverView elif dt in {'text', 'enum'}: cls = LineEdit else: continue neww = cls(field, True, self, m, extra) neww.changed.connect(partial(self.changed, field)) oldw = cls(field, False, self, m, extra) newl = QLabel('&%s:' % m['name']) newl.setBuddy(neww) button = QToolButton(self) button.setIcon(QIcon(I('back.png'))) button.clicked.connect(partial(self.revert, field)) button.setToolTip(revert_tooltip % m['name']) self.widgets[field] = Widgets(neww, oldw, newl, button) for i, w in enumerate((newl, neww, button, oldw)): c = i if i < 2 else i + 1 if w is oldw: c += 1 l.addWidget(w, row, c) row += 1 self.sep = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 2, row, 1) self.sep2 = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 4, row, 1) if 'comments' in self.widgets and not gprefs.get( 'diff_widget_show_comments_controls', True): self.widgets['comments'].new.hide_toolbars()
def __init__(self, parent): QWidget.__init__(self, parent) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) parent = parent.parent() self.l = l = QHBoxLayout(self) l.setContentsMargins(0, 0, 0, 0) self.alter_tb = parent.alter_tb = b = QToolButton(self) b.setAutoRaise(True) b.setText(_('Configure')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) b.setCursor(Qt.PointingHandCursor) b.setPopupMode(b.InstantPopup) b.setToolTip(textwrap.fill(_( 'Change how the Tag browser works, such as,' ' how it is sorted, what happens when you click' ' items, etc.' ))) b.setIcon(QIcon(I('config.png'))) b.m = QMenu() b.setMenu(b.m) self.item_search = FindBox(parent) self.item_search.setMinimumContentsLength(5) self.item_search.setSizeAdjustPolicy(self.item_search.AdjustToMinimumContentsLengthWithIcon) self.item_search.initialize('tag_browser_search') self.item_search.completer().setCaseSensitivity(Qt.CaseSensitive) self.item_search.setToolTip(_( 'Search for items. This is a "contains" search; items containing the\n' 'text anywhere in the name will be found. You can limit the search\n' 'to particular categories using syntax similar to search. For example,\n' 'tags:foo will find foo in any tag, but not in authors etc. Entering\n' '*foo will filter all categories at once, showing only those items\n' 'containing the text "foo"')) ac = QAction(parent) parent.addAction(ac) parent.keyboard.register_shortcut('tag browser find box', _('Find next match'), default_keys=(), action=ac, group=_('Tag browser')) ac.triggered.connect(self.set_focus_to_find_box) self.search_button = QToolButton() self.search_button.setAutoRaise(True) self.search_button.setCursor(Qt.PointingHandCursor) self.search_button.setIcon(QIcon(I('search.png'))) self.search_button.setToolTip(_('Find the first/next matching item')) ac = QAction(parent) parent.addAction(ac) parent.keyboard.register_shortcut('tag browser find button', _('Find in Tag browser'), default_keys=(), action=ac, group=_('Tag browser')) ac.triggered.connect(self.search_button.click) self.toggle_search_button = b = QToolButton(self) le = self.item_search.lineEdit() le.addAction(QIcon(I('window-close.png')), le.LeadingPosition).triggered.connect(self.close_find_box) b.setText(_('Find')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) b.setCursor(Qt.PointingHandCursor) b.setIcon(QIcon(I('search.png'))) b.setCheckable(True) b.setChecked(gprefs.get('tag browser search box visible', False)) b.setToolTip(_('Search for items in the Tag browser')) b.setAutoRaise(True) b.toggled.connect(self.update_searchbar_state) self.update_searchbar_state()
def create_basic_metadata_widgets(self): # {{{ self.basic_metadata_widgets = [] self.languages = LanguagesEdit(self) self.basic_metadata_widgets.append(self.languages) self.title = TitleEdit(self) self.title.textChanged.connect(self.update_window_title) self.deduce_title_sort_button = QToolButton(self) self.deduce_title_sort_button.setToolTip( _('Automatically create the title sort entry based on the current ' 'title entry.\nUsing this button to create title sort will ' 'change title sort from red to green.')) self.deduce_title_sort_button.setWhatsThis( self.deduce_title_sort_button.toolTip()) self.title_sort = TitleSortEdit(self, self.title, self.deduce_title_sort_button, self.languages) self.basic_metadata_widgets.extend([self.title, self.title_sort]) self.deduce_author_sort_button = b = RightClickButton(self) b.setToolTip('<p>' + _('Automatically create the author sort entry based on the current ' 'author entry. Using this button to create author sort will ' 'change author sort from red to green. There is a menu of ' 'functions available under this button. Click and hold ' 'on the button to see it.') + '</p>') if isosx: # Workaround for https://bugreports.qt-project.org/browse/QTBUG-41017 class Menu(QMenu): def mouseReleaseEvent(self, ev): ac = self.actionAt(ev.pos()) if ac is not None: ac.trigger() return QMenu.mouseReleaseEvent(self, ev) b.m = m = Menu() else: b.m = m = QMenu() ac = m.addAction(QIcon(I('forward.png')), _('Set author sort from author')) ac2 = m.addAction(QIcon(I('back.png')), _('Set author from author sort')) ac3 = m.addAction(QIcon(I('user_profile.png')), _('Manage authors')) ac4 = m.addAction(QIcon(I('next.png')), _('Copy author to author sort')) ac5 = m.addAction(QIcon(I('previous.png')), _('Copy author sort to author')) b.setMenu(m) self.authors = AuthorsEdit(self, ac3) self.author_sort = AuthorSortEdit(self, self.authors, b, self.db, ac, ac2, ac4, ac5) self.basic_metadata_widgets.extend([self.authors, self.author_sort]) self.swap_title_author_button = QToolButton(self) self.swap_title_author_button.setIcon(QIcon(I('swap.png'))) self.swap_title_author_button.setToolTip(_( 'Swap the author and title') + ' [%s]' % self.swap_title_author_shortcut.key().toString(QKeySequence.NativeText)) self.swap_title_author_button.clicked.connect(self.swap_title_author) self.swap_title_author_shortcut.activated.connect(self.swap_title_author_button.click) self.manage_authors_button = QToolButton(self) self.manage_authors_button.setIcon(QIcon(I('user_profile.png'))) self.manage_authors_button.setToolTip('<p>' + _( 'Manage authors. Use to rename authors and correct ' 'individual author\'s sort values') + '</p>') self.manage_authors_button.clicked.connect(self.authors.manage_authors) self.series = SeriesEdit(self) self.clear_series_button = QToolButton(self) self.clear_series_button.setToolTip( _('Clear series')) self.clear_series_button.clicked.connect(self.series.clear) self.series_index = SeriesIndexEdit(self, self.series) self.basic_metadata_widgets.extend([self.series, self.series_index]) self.formats_manager = FormatsManager(self, self.copy_fmt) # We want formats changes to be committed before title/author, as # otherwise we could have data loss if the title/author changed and the # user was trying to add an extra file from the old books directory. self.basic_metadata_widgets.insert(0, self.formats_manager) self.formats_manager.metadata_from_format_button.clicked.connect( self.metadata_from_format) self.formats_manager.cover_from_format_button.clicked.connect( self.cover_from_format) self.cover = Cover(self) self.cover.download_cover.connect(self.download_cover) self.basic_metadata_widgets.append(self.cover) self.comments = CommentsEdit(self, self.one_line_comments_toolbar) self.basic_metadata_widgets.append(self.comments) self.rating = RatingEdit(self) self.clear_ratings_button = QToolButton(self) self.clear_ratings_button.setToolTip(_('Clear rating')) self.clear_ratings_button.setIcon(QIcon(I('trash.png'))) self.clear_ratings_button.clicked.connect(self.rating.zero) self.basic_metadata_widgets.append(self.rating) self.tags = TagsEdit(self) self.tags_editor_button = QToolButton(self) self.tags_editor_button.setToolTip(_('Open Tag Editor')) self.tags_editor_button.setIcon(QIcon(I('chapters.png'))) self.tags_editor_button.clicked.connect(self.tags_editor) self.clear_tags_button = QToolButton(self) self.clear_tags_button.setToolTip(_('Clear all tags')) self.clear_tags_button.setIcon(QIcon(I('trash.png'))) self.clear_tags_button.clicked.connect(self.tags.clear) self.basic_metadata_widgets.append(self.tags) self.identifiers = IdentifiersEdit(self) self.basic_metadata_widgets.append(self.identifiers) self.clear_identifiers_button = QToolButton(self) self.clear_identifiers_button.setIcon(QIcon(I('trash.png'))) self.clear_identifiers_button.setToolTip(_('Clear Ids')) self.clear_identifiers_button.clicked.connect(self.identifiers.clear) self.paste_isbn_button = QToolButton(self) self.paste_isbn_button.setToolTip('<p>' + _('Paste the contents of the clipboard into the ' 'identifiers box prefixed with isbn:') + '</p>') self.paste_isbn_button.setIcon(QIcon(I('edit-paste.png'))) self.paste_isbn_button.clicked.connect(self.identifiers.paste_isbn) self.publisher = PublisherEdit(self) self.basic_metadata_widgets.append(self.publisher) self.timestamp = DateEdit(self) self.pubdate = PubdateEdit(self) self.basic_metadata_widgets.extend([self.timestamp, self.pubdate]) self.fetch_metadata_button = b = RightClickButton(self) # The following rigmarole is needed so that Qt gives the button the # same height as the other buttons in the dialog. There is no way to # center the text in a QToolButton with an icon, so we cant just set an # icon b.setIcon(QIcon(I('download-metadata.png'))) b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) b.setMinimumHeight(b.sizeHint().height()) b.setIcon(QIcon()) b.setText(_('&Download metadata')), b.setPopupMode(b.DelayedPopup) b.setToolTip(_('Download metadata for this book [%s]') % self.download_shortcut.key().toString(QKeySequence.NativeText)) b.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) self.fetch_metadata_button.clicked.connect(self.fetch_metadata) self.fetch_metadata_menu = m = QMenu(self.fetch_metadata_button) m.addAction(QIcon(I('edit-undo.png')), _('Undo last metadata download'), self.undo_fetch_metadata) self.fetch_metadata_button.setMenu(m) self.download_shortcut.activated.connect(self.fetch_metadata_button.click) font = self.fmb_font = QFont() font.setBold(True) self.fetch_metadata_button.setFont(font) if self.use_toolbutton_for_config_metadata: self.config_metadata_button = QToolButton(self) self.config_metadata_button.setIcon(QIcon(I('config.png'))) else: self.config_metadata_button = QPushButton(self) self.config_metadata_button.setText(_('Configure download metadata')) self.config_metadata_button.setIcon(QIcon(I('config.png'))) self.config_metadata_button.clicked.connect(self.configure_metadata) self.config_metadata_button.setToolTip( _('Change how calibre downloads metadata'))
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)
def setup_ui(self): self.setWindowIcon(QIcon(I('diff.png'))) self.stacks = st = QStackedLayout(self) self.busy = BusyWidget(self) self.w = QWidget(self) st.addWidget(self.busy), st.addWidget(self.w) self.setLayout(st) self.l = l = QGridLayout() self.w.setLayout(l) self.view = v = DiffView(self, show_open_in_editor=self.show_open_in_editor) l.addWidget(v, l.rowCount(), 0, 1, -1) r = l.rowCount() self.bp = b = QToolButton(self) b.setIcon(QIcon(I('back.png'))) connect_lambda(b.clicked, self, lambda self: self.view.next_change(-1)) b.setToolTip(_('Go to previous change') + ' [p]') b.setText(_('&Previous change')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 0) self.bn = b = QToolButton(self) b.setIcon(QIcon(I('forward.png'))) connect_lambda(b.clicked, self, lambda self: self.view.next_change(1)) b.setToolTip(_('Go to next change') + ' [n]') b.setText(_('&Next change')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 1) self.search = s = HistoryLineEdit2(self) s.initialize('diff_search_history') l.addWidget(s, r, 2) s.setPlaceholderText(_('Search for text')) connect_lambda(s.returnPressed, self, lambda self: self.do_search(False)) self.sbn = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))) connect_lambda(b.clicked, self, lambda self: self.do_search(False)) b.setToolTip(_('Find next match')) b.setText(_('Next &match')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 3) self.sbp = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))) connect_lambda(b.clicked, self, lambda self: self.do_search(True)) b.setToolTip(_('Find previous match')) b.setText(_('P&revious match')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 4) self.lb = b = QRadioButton(_('Left panel'), self) b.setToolTip(_('Perform search in the left panel')) l.addWidget(b, r, 5) self.rb = b = QRadioButton(_('Right panel'), self) b.setToolTip(_('Perform search in the right panel')) l.addWidget(b, r, 6) b.setChecked(True) self.pb = b = QToolButton(self) b.setIcon(QIcon(I('config.png'))) b.setText(_('&Options')), b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) b.setToolTip(_('Change how the differences are displayed')) b.setPopupMode(b.InstantPopup) m = QMenu(b) b.setMenu(m) cm = self.cm = QMenu(_('Lines of context around each change')) for i in (3, 5, 10, 50): cm.addAction(_('Show %d lines of context') % i, partial(self.change_context, i)) cm.addAction(_('Show all text'), partial(self.change_context, None)) self.beautify_action = m.addAction('', self.toggle_beautify) self.set_beautify_action_text() m.addMenu(cm) l.addWidget(b, r, 7) self.hl = QHBoxLayout() l.addLayout(self.hl, l.rowCount(), 0, 1, -1) self.names = QLabel('') self.hl.addWidget(self.names, r) self.bb.setStandardButtons(self.bb.Close) if self.revert_button_msg is not None: self.rvb = b = self.bb.addButton(self.revert_button_msg, self.bb.ActionRole) b.setIcon(QIcon(I('edit-undo.png'))), b.setAutoDefault(False) b.clicked.connect(self.revert_requested) b.clicked.connect(self.reject) self.bb.button(self.bb.Close).setDefault(True) self.hl.addWidget(self.bb, r) self.view.setFocus(Qt.OtherFocusReason)
def setup_ui(self): self.l = l = QGridLayout(self) self.setLayout(l) self.bb.setStandardButtons(self.bb.Close) self.rearrange_button = b = self.bb.addButton(_('Re-arrange favorites'), self.bb.ActionRole) b.setCheckable(True) b.setChecked(False) b.setVisible(False) b.setDefault(True) self.splitter = s = QSplitter(self) s.setFocusPolicy(Qt.FocusPolicy.NoFocus) s.setChildrenCollapsible(False) self.search = h = HistoryLineEdit2(self) h.setToolTip(textwrap.fill(_( 'Search for Unicode characters by using the English names or nicknames.' ' You can also search directly using a character code. For example, the following' ' searches will all yield the no-break space character: U+A0, nbsp, no-break'))) h.initialize('charmap_search') h.setPlaceholderText(_('Search by name, nickname or character code')) self.search_button = b = QPushButton(_('&Search')) b.setFocusPolicy(Qt.FocusPolicy.NoFocus) h.returnPressed.connect(self.do_search) b.clicked.connect(self.do_search) self.clear_button = cb = QToolButton(self) cb.setIcon(QIcon(I('clear_left.png'))) cb.setFocusPolicy(Qt.FocusPolicy.NoFocus) cb.setText(_('Clear search')) cb.clicked.connect(self.clear_search) l.addWidget(h), l.addWidget(b, 0, 1), l.addWidget(cb, 0, 2) self.category_view = CategoryView(self) self.category_view.setFocusPolicy(Qt.FocusPolicy.NoFocus) l.addWidget(s, 1, 0, 1, 3) self.char_view = CharView(self) self.char_view.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.rearrange_button.toggled[bool].connect(self.set_allow_drag_and_drop) self.category_view.category_selected.connect(self.show_chars) self.char_view.show_name.connect(self.show_char_info) self.char_view.char_selected.connect(self.char_selected) s.addWidget(self.category_view), s.addWidget(self.char_view) self.char_info = la = QLabel('\xa0') la.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) l.addWidget(la, 2, 0, 1, 3) self.rearrange_msg = la = QLabel(_( 'Drag and drop characters to re-arrange them. Click the "Re-arrange" button again when you are done.')) la.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) la.setVisible(False) l.addWidget(la, 3, 0, 1, 3) self.h = h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) self.match_any = mm = QCheckBox(_('Match any word')) mm.setToolTip(_('When searching return characters whose names match any of the specified words')) mm.setChecked(tprefs.get('char_select_match_any', True)) connect_lambda(mm.stateChanged, self, lambda self: tprefs.set('char_select_match_any', self.match_any.isChecked())) h.addWidget(mm), h.addStretch(), h.addWidget(self.bb) l.addLayout(h, 4, 0, 1, 3) self.char_view.setFocus(Qt.FocusReason.OtherFocusReason)
def __init__(self, plugin_action): self.gui = plugin_action.gui self.opts = plugin_action.opts QWidget.__init__(self) self.l = QVBoxLayout() self.setLayout(self.l) # ~~~~~~~~ Create the runtime options group box ~~~~~~~~ self.cfg_runtime_options_gb = QGroupBox(self) self.cfg_runtime_options_gb.setTitle(_('Runtime options')) self.l.addWidget(self.cfg_runtime_options_gb) self.cfg_runtime_options_qvl = QVBoxLayout(self.cfg_runtime_options_gb) # ~~~~~~~~ Disable caching checkbox ~~~~~~~~ self.cfg_disable_caching_checkbox = QCheckBox(_('Disable caching')) self.cfg_disable_caching_checkbox.setObjectName('cfg_disable_caching_checkbox') self.cfg_disable_caching_checkbox.setToolTip(_('Force reload of reader database')) self.cfg_disable_caching_checkbox.setChecked(False) self.cfg_runtime_options_qvl.addWidget(self.cfg_disable_caching_checkbox) # ~~~~~~~~ plugin logging checkbox ~~~~~~~~ self.cfg_plugin_debug_log_checkbox = QCheckBox(_('Enable debug logging for Annotations plugin')) self.cfg_plugin_debug_log_checkbox.setObjectName('cfg_plugin_debug_log_checkbox') self.cfg_plugin_debug_log_checkbox.setToolTip(_('Print plugin diagnostic messages to console')) self.cfg_plugin_debug_log_checkbox.setChecked(False) self.cfg_runtime_options_qvl.addWidget(self.cfg_plugin_debug_log_checkbox) # ~~~~~~~~ libiMobileDevice logging checkbox ~~~~~~~~ self.cfg_libimobiledevice_debug_log_checkbox = QCheckBox(_('Enable debug logging for libiMobileDevice')) self.cfg_libimobiledevice_debug_log_checkbox.setObjectName('cfg_libimobiledevice_debug_log_checkbox') self.cfg_libimobiledevice_debug_log_checkbox.setToolTip(_('Print libiMobileDevice debug messages to console')) self.cfg_libimobiledevice_debug_log_checkbox.setChecked(False) self.cfg_libimobiledevice_debug_log_checkbox.setEnabled(LIBIMOBILEDEVICE_AVAILABLE) self.cfg_runtime_options_qvl.addWidget(self.cfg_libimobiledevice_debug_log_checkbox) # ~~~~~~~~ Create the Annotations options group box ~~~~~~~~ self.cfg_annotation_options_gb = QGroupBox(self) self.cfg_annotation_options_gb.setTitle(_('Annotation options')) self.l.addWidget(self.cfg_annotation_options_gb) self.cfg_annotation_options_qgl = QGridLayout(self.cfg_annotation_options_gb) current_row = 0 # Add the label/combobox for annotations destination self.cfg_annotations_destination_label = QLabel(_('<b>Add fetched annotations to<b>')) self.cfg_annotations_destination_label.setAlignment(Qt.AlignLeft) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_label, current_row, 0) current_row += 1 self.cfg_annotations_destination_comboBox = QComboBox(self.cfg_annotation_options_gb) self.cfg_annotations_destination_comboBox.setObjectName('cfg_annotations_destination_comboBox') self.cfg_annotations_destination_comboBox.setToolTip(_('Custom field to store annotations')) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_comboBox, current_row, 0) # Populate annotations_field combobox db = self.gui.current_db all_custom_fields = db.custom_field_keys() self.custom_fields = {} for custom_field in all_custom_fields: field_md = db.metadata_for_field(custom_field) if field_md['datatype'] in ['comments']: self.custom_fields[field_md['name']] = {'field': custom_field, 'datatype': field_md['datatype']} all_fields = self.custom_fields.keys() + ['Comments'] for cf in sorted(all_fields): self.cfg_annotations_destination_comboBox.addItem(cf) # Add CC Wizard self.cfg_annotations_wizard = QToolButton() self.cfg_annotations_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_annotations_wizard.setToolTip(_("Create a custom column to store annotations")) self.cfg_annotations_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Annotations')) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_wizard, current_row, 2) current_row += 1 # ~~~~~~~~ Add a horizontal line ~~~~~~~~ self.cfg_appearance_hl = QFrame(self) self.cfg_appearance_hl.setGeometry(QRect(0, 0, 1, 3)) self.cfg_appearance_hl.setFrameShape(QFrame.HLine) self.cfg_appearance_hl.setFrameShadow(QFrame.Raised) self.cfg_annotation_options_qgl.addWidget(self.cfg_appearance_hl, current_row, 0) current_row += 1 # ~~~~~~~~ Add the Modify… button ~~~~~~~~ self.cfg_annotations_appearance_pushbutton = QPushButton(_("Modify appearance…")) self.cfg_annotations_appearance_pushbutton.clicked.connect(self.configure_appearance) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_appearance_pushbutton, current_row, 0) current_row += 1 self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.cfg_annotation_options_qgl.addItem(self.spacerItem, current_row, 0, 1, 1) # ~~~~~~~~ Compilations group box ~~~~~~~~ self.cfg_compilation_options_gb = QGroupBox(self) self.cfg_compilation_options_gb.setTitle(_('Compilations')) self.l.addWidget(self.cfg_compilation_options_gb) self.cfg_compilation_options_qgl = QGridLayout(self.cfg_compilation_options_gb) current_row = 0 # News clippings self.cfg_news_clippings_checkbox = QCheckBox(_('Collect News clippings')) self.cfg_news_clippings_checkbox.setObjectName('cfg_news_clippings_checkbox') self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_checkbox, current_row, 0) self.cfg_news_clippings_lineEdit = QLineEdit() self.cfg_news_clippings_lineEdit.setObjectName('cfg_news_clippings_lineEdit') self.cfg_news_clippings_lineEdit.setToolTip(_('Title for collected news clippings')) self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_lineEdit, current_row, 1) # ~~~~~~~~ End of construction zone ~~~~~~~~ self.resize(self.sizeHint()) # Restore state of controls, populate annotations combobox self.controls = inventory_controls(self, dump_controls=False) restore_state(self) self.populate_annotations() # Hook changes to annotations_destination_combobox # self.connect(self.cfg_annotations_destination_comboBox, # pyqtSignal('currentIndexChanged(const QString &)'), # self.annotations_destination_changed) self.cfg_annotations_destination_comboBox.currentIndexChanged.connect(self.annotations_destination_changed) # Hook changes to diagnostic checkboxes self.cfg_disable_caching_checkbox.stateChanged.connect(self.restart_required) self.cfg_libimobiledevice_debug_log_checkbox.stateChanged.connect(self.restart_required) self.cfg_plugin_debug_log_checkbox.stateChanged.connect(self.restart_required) # Hook changes to News clippings, initialize self.cfg_news_clippings_checkbox.stateChanged.connect(self.news_clippings_toggled) self.news_clippings_toggled(self.cfg_news_clippings_checkbox.checkState()) self.cfg_news_clippings_lineEdit.editingFinished.connect(self.news_clippings_destination_changed) # Launch the annotated_books_scanner field = get_cc_mapping('annotations', 'field', 'Comments') self.annotated_books_scanner = InventoryAnnotatedBooks(self.gui, field) self.annotated_books_scanner.signal.connect(self.inventory_complete) # self.connect(self.annotated_books_scanner, self.annotated_books_scanner.signal, # self.inventory_complete) QTimer.singleShot(1, self.start_inventory)