def __init__(self, parent=None): super(HostQWidget, self).__init__(parent) # Fields self.actions_widget = ActionsQWidget() self.host_item = None self.service_items = None self.labels = { 'host_icon': QLabel(), 'host_name': QLabel(), 'state_icon': QLabel(), 'ls_last_check': QLabel(), 'ls_output': QLabel(), 'realm': QLabel(), 'address': QLabel(), 'business_impact': QLabel(), 'notes': QLabel() } self.activecheck_btn = ToggleQWidgetButton() self.passivecheck_btn = ToggleQWidgetButton() self.history_btn = QPushButton() self.history_widget = HistoryQWidget() self.host_history = None self.customs_widget = CustomsQWidget() self.customs_btn = QPushButton() self.spy_btn = QPushButton() self.refresh_timer = QTimer() self.refresh_counter = 0
def get_text_widget(self): """ Return text QWidget with QTextEdit :return: text QWidget :rtype: QWidget """ text_widget = QWidget() text_widget.setObjectName('dialog') text_layout = QVBoxLayout() text_widget.setLayout(text_layout) self.text_edit.setPlaceholderText(_('type your text...')) self.text_edit.setText(self.old_text) text_layout.addWidget(self.text_edit) # Accept button accept_btn = QPushButton(_('Confirm'), self) accept_btn.clicked.connect(self.accept_text) accept_btn.setObjectName('valid') accept_btn.setMinimumHeight(30) text_layout.addWidget(accept_btn) return text_widget
def get_text_widget(self, regexp): """ Return text QWidget with QTextEdit :return: text QWidget :rtype: QWidget """ text_widget = QWidget() text_widget.setObjectName('dialog') text_layout = QVBoxLayout() text_widget.setLayout(text_layout) text_layout.addWidget(self.valid_text) qreg_exp = QRegExp(regexp) self.validator.setRegExp(qreg_exp) self.line_edit.setPlaceholderText(_('type your text...')) self.line_edit.setText(self.old_text) self.line_edit.setValidator(self.validator) self.line_edit.setFixedHeight(25) self.line_edit.textChanged.connect(self.check_text) text_layout.addWidget(self.line_edit) # Accept button accept_btn = QPushButton(_('Confirm'), self) accept_btn.clicked.connect(self.accept_text) accept_btn.setObjectName('valid') accept_btn.setMinimumHeight(30) text_layout.addWidget(accept_btn) return text_widget
def setupUi(self, *args): # {{{ self.resize(990, 670) self.download_shortcut = QShortcut(self) self.download_shortcut.setKey(QKeySequence('Ctrl+D', QKeySequence.PortableText)) p = self.parent() if hasattr(p, 'keyboard'): kname = u'Interface Action: Edit Metadata (Edit Metadata) : menu action : download' sc = p.keyboard.keys_map.get(kname, None) if sc: self.download_shortcut.setKey(sc[0]) self.swap_title_author_shortcut = s = QShortcut(self) s.setKey(QKeySequence('Alt+Down', QKeySequence.PortableText)) self.button_box = bb = QDialogButtonBox(self) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.next_button = QPushButton(QIcon(I('forward.png')), _('Next'), self) self.next_button.setShortcut(QKeySequence('Alt+Right')) self.next_button.clicked.connect(self.next_clicked) self.prev_button = QPushButton(QIcon(I('back.png')), _('Previous'), self) self.prev_button.setShortcut(QKeySequence('Alt+Left')) self.button_box.addButton(self.prev_button, bb.ActionRole) self.button_box.addButton(self.next_button, bb.ActionRole) self.prev_button.clicked.connect(self.prev_clicked) bb.setStandardButtons(bb.Ok|bb.Cancel) bb.button(bb.Ok).setDefault(True) self.scroll_area = QScrollArea(self) self.scroll_area.setFrameShape(QScrollArea.NoFrame) self.scroll_area.setWidgetResizable(True) self.central_widget = QTabWidget(self) self.scroll_area.setWidget(self.central_widget) self.l = QVBoxLayout(self) self.setLayout(self.l) self.l.addWidget(self.scroll_area) ll = self.button_box_layout = QHBoxLayout() self.l.addLayout(ll) ll.addSpacing(10) ll.addWidget(self.button_box) self.setWindowIcon(QIcon(I('edit_input.png'))) self.setWindowTitle(BASE_TITLE) self.create_basic_metadata_widgets() if len(self.db.custom_column_label_map): self.create_custom_metadata_widgets() self.comments_edit_state_at_apply = {self.comments:None} self.do_layout() geom = gprefs.get('metasingle_window_geometry3', None) if geom is not None: self.restoreGeometry(bytes(geom))
def addNewFrame(self, frame): button = QPushButton("", self) button.resize(FrameList.BUTTON_WIDTH, FrameList.BUTTON_HEIGHT) button.clicked.connect(self.onMousePressed) button.show() self.buttons[button] = frame if len(self.buttons) > FrameList.MAX_LENGTH: self.start_index = len(self.buttons) - FrameList.MAX_LENGTH self.rearrangeButtons()
def initUI(self): self.resize(TimeInputLine.WIDTH + TimeInputLine.FRAME_MARGIN*2, TimeInputLine.HEIGHT + TimeInputLine.FRAME_MARGIN*2) self.setFrameStyle(QFrame.StyledPanel) self.setLineWidth(TimeInputLine.FRAME_WIDTH) component_stylesheet = """ .QPushButton { font-weight: bold; font-size: 13px; background-color:#E0E0E0; } .QPushButton:pressed { background-color:#CCCCCC; } .QDoubleSpinBox { font-weight: bold; font-size: 23px; } .QLabel { font-weight: bold; font-size: 23px; } """ self.label = QLabel("", self) self.label.resize(TimeInputLine.LABEL_SIZE_X, TimeInputLine.HEIGHT) self.label.move(TimeInputLine.FRAME_MARGIN, TimeInputLine.FRAME_MARGIN) self.label.setStyleSheet(component_stylesheet) self.label.setAlignment(Qt.AlignCenter) self.label.show() self.spinbox = QDoubleSpinBox(self) self.spinbox.setRange(TimeInputLine.MIN_VALUE, TimeInputLine.MAX_VALUE) self.spinbox.setValue(TimeInputLine.STEP) self.spinbox.setSingleStep(TimeInputLine.STEP) self.spinbox.setDecimals(TimeInputLine.DECIMAL_COUNT) self.spinbox.resize(TimeInputLine.INPUT_SIZE_X, TimeInputLine.HEIGHT) self.spinbox.move(TimeInputLine.LABEL_SIZE_X + TimeInputLine.FRAME_MARGIN, TimeInputLine.FRAME_MARGIN) self.spinbox.setStyleSheet(component_stylesheet) self.spinbox.show() self.enter = QPushButton("", self) self.enter.setIcon(assets.enter) self.enter.setIconSize(QSize(TimeInputLine.ICON_SIZE, TimeInputLine.ICON_SIZE)) self.enter.resize(TimeInputLine.ICON_BUTTON_WIDTH, TimeInputLine.HEIGHT) self.enter.move(TimeInputLine.BUTTON_BLOCK_X, TimeInputLine.FRAME_MARGIN) self.enter.setStyleSheet(component_stylesheet) self.enter.show() self.cancel = QPushButton("", self) self.cancel.setIcon(assets.exit) self.cancel.setIconSize(QSize(TimeInputLine.ICON_SIZE, TimeInputLine.ICON_SIZE)) self.cancel.resize(TimeInputLine.ICON_BUTTON_WIDTH, TimeInputLine.HEIGHT) self.cancel.move(TimeInputLine.BUTTON_BLOCK_X + TimeInputLine.ICON_BUTTON_WIDTH, TimeInputLine.FRAME_MARGIN) self.cancel.setStyleSheet(component_stylesheet) self.cancel.show()
def __init__(self, parent=None): super(AlignakQWidget, self).__init__(parent) # Fields self.backend_connected = QLabel('pending...') self.status_dialog = StatusQDialog() self.status_btn = QPushButton() self.ws_connected = QLabel() self.profile_widget = ProfileQWidget() self.profile_btn = QPushButton() self.refresh_timer = QTimer()
def initUI(self): self.setFrameStyle(QFrame.StyledPanel) self.setLineWidth(WorldToolsPanel.FRAME_WIDTH) self.resize(WorldToolsPanel.TOOLS_WIDTH + WorldToolsPanel.FRAME_MARGIN*2, WorldToolsPanel.TOOLS_HEIGHT + WorldToolsPanel.FRAME_MARGIN*2) self.setFrameRect(QRect(0, 0, WorldToolsPanel.TOOLS_WIDTH + WorldToolsPanel.FRAME_MARGIN*2, WorldToolsPanel.TOOLS_HEIGHT + WorldToolsPanel.FRAME_MARGIN*2)) button_stylesheet = """ .QPushButton { font-weight: bold; font-size: 13px; background-color:#E0E0E0; } .QPushButton:pressed { background-color:#CCCCCC; } """ self.create_stickman = QPushButton('Create Stickman', self) self.create_stickman.resize(WorldToolsPanel.BUTTON_WIDTH, WorldToolsPanel.TOOLS_HEIGHT) self.create_stickman.move(WorldToolsPanel.FRAME_WIDTH*2, WorldToolsPanel.FRAME_MARGIN) self.create_stickman.setStyleSheet(button_stylesheet) self.create_stickman.clicked.connect(self.showCreateDialog) self.create_stickman_input = InputLine(self) self.create_stickman_input.setLabelText("Enter New StickName: ") self.create_stickman_input.addOkListener(self.readCreateName) self.create_stickman_input.addCancelListener(self.hideCreateDialog) self.create_stickman_input.move(WorldToolsPanel.FRAME_MARGIN, WorldToolsPanel.FRAME_MARGIN) self.create_stickman_input.hide() self.delete_stickman = QPushButton('Delete Stickman', self) self.delete_stickman.resize(WorldToolsPanel.BUTTON_WIDTH, WorldToolsPanel.TOOLS_HEIGHT) self.delete_stickman.move(WorldToolsPanel.BUTTON_WIDTH + WorldToolsPanel.FRAME_MARGIN, WorldToolsPanel.FRAME_MARGIN) self.delete_stickman.setStyleSheet(button_stylesheet) self.delete_stickman.clicked.connect(self.showDeleteDialog) self.delete_stickman_input = InputLine(self) self.delete_stickman_input.setLabelText("Enter Name to Delete: ") self.delete_stickman_input.addOkListener(self.readDeleteName) self.delete_stickman_input.addCancelListener(self.hideDeleteDialog) self.delete_stickman_input.move(WorldToolsPanel.FRAME_MARGIN, WorldToolsPanel.FRAME_MARGIN) self.delete_stickman_input.hide() self.change_background = QPushButton('Set Background', self) self.change_background.resize(WorldToolsPanel.BUTTON_WIDTH, WorldToolsPanel.TOOLS_HEIGHT) self.change_background.move(WorldToolsPanel.BUTTON_WIDTH*2 + WorldToolsPanel.FRAME_MARGIN, WorldToolsPanel.FRAME_MARGIN) self.change_background.setStyleSheet(button_stylesheet) self.change_background.clicked.connect(self.findBackground) self.remove_background = QPushButton('Clear Background', self) self.remove_background.resize(WorldToolsPanel.BUTTON_WIDTH, WorldToolsPanel.TOOLS_HEIGHT) self.remove_background.move(WorldToolsPanel.BUTTON_WIDTH*3 + WorldToolsPanel.FRAME_MARGIN, WorldToolsPanel.FRAME_MARGIN) self.remove_background.setStyleSheet(button_stylesheet) self.remove_background.clicked.connect(self.clearBackground)
def initUI(self): component_stylesheet = """ .QPushButton { font-weight: bold; font-size: 13px; background-color:#E0E0E0; } .QPushButton:pressed { background-color:#CCCCCC; } .QLabel { padding-top: 7px; font-weight: bold; font-size: 14px; } .QLineEdit { font-weight: bold; font-size: 14px; } .QLabel#error { color: red; font-size: 12px; font-style: italic; padding-top: 0px; padding-left: 6px; } """ self.label = QLabel("", self) self.label.setStyleSheet(component_stylesheet) self.label.setAlignment(Qt.AlignRight) self.label.resize(InputLine.LABEL_WIDTH, InputLine.HEIGHT) self.label.move(0, 0) self.text = QLineEdit(self) self.text.setStyleSheet(component_stylesheet) self.text.resize(InputLine.INPUT_TEXT_WIDTH, InputLine.HEIGHT) self.text.move(InputLine.LABEL_WIDTH + InputLine.ELEMENT_GAP, 0) self.ok = QPushButton("OK", self) self.ok.setStyleSheet(component_stylesheet) self.ok.resize(InputLine.BUTTON_WIDTH, InputLine.HEIGHT) self.ok.move(InputLine.BUTTON_BLOCK_X, 0) self.cancel = QPushButton("Cancel", self) self.cancel.setStyleSheet(component_stylesheet) self.cancel.resize(InputLine.BUTTON_WIDTH, InputLine.HEIGHT) self.cancel.move(InputLine.BUTTON_BLOCK_X + InputLine.BUTTON_WIDTH + InputLine.ELEMENT_GAP, 0) self.error = QLabel("", self) self.error.setObjectName("error") self.error.setStyleSheet(component_stylesheet) self.error.resize(InputLine.ERROR_WIDTH, InputLine.HEIGHT) self.error.move(InputLine.ERROR_X, 0)
def __init__(self, plugin_action): QWidget.__init__(self) self.plugin_action = plugin_action layout = QVBoxLayout(self) self.setLayout(layout) # --- Directory Options --- directory_group_box = QGroupBox(_('Default Unpack Directory:'), self) layout.addWidget(directory_group_box) directory_group_box_layout = QVBoxLayout() directory_group_box.setLayout(directory_group_box_layout) # Directory path Textbox # Load the textbox with the current preference setting self.directory_txtBox = QLineEdit(plugin_prefs['Unpack_Folder'], self) self.directory_txtBox.setToolTip(_('<p>Default directory to extract files to')) directory_group_box_layout.addWidget(self.directory_txtBox) self.directory_txtBox.setReadOnly(True) # Folder select button directory_button = QPushButton(_('Select/Change Unpack Directory'), self) directory_button.setToolTip(_('<p>Select/Change directory to extract files to.')) # Connect button to the getDirectory function directory_button.clicked.connect(self.getDirectory) directory_group_box_layout.addWidget(directory_button) self.default_folder_check = QCheckBox(_('Always use the Default Unpack Directory'), self) self.default_folder_check.setToolTip(_('<p>When unchecked... you will be prompted to select a destination '+ 'directory for the extracted content each time you use Mobiunpack.')) directory_group_box_layout.addWidget(self.default_folder_check) # Load the checkbox with the current preference setting self.default_folder_check.setChecked(plugin_prefs['Always_Use_Unpack_Folder']) misc_group_box = QGroupBox(_('Default settings:'), self) layout.addWidget(misc_group_box) misc_group_box_layout = QVBoxLayout() misc_group_box.setLayout(misc_group_box_layout) self.use_hd_images = QCheckBox(_('Always use HD images if present'), self) self.use_hd_images.setToolTip(_('<p>When checked... any HD images present in the kindlebook '+ 'will be used for creating the ePub.')) misc_group_box_layout.addWidget(self.use_hd_images) # Load the checkbox with the current preference setting self.use_hd_images.setChecked(plugin_prefs['Use_HD_Images']) combo_label = QLabel('Select epub version output:', self) misc_group_box_layout.addWidget(combo_label) self.epub_version_combobox = QComboBox() self.epub_version_combobox.setToolTip(_('<p>Select the type of OPF file to create.')) misc_group_box_layout.addWidget(self.epub_version_combobox) self.epub_version_combobox.addItems(['Auto-detect', 'ePub2', 'ePub3']) if plugin_prefs['Epub_Version'] == 'A': self.epub_version_combobox.setCurrentIndex(0) else: self.epub_version_combobox.setCurrentIndex(int(plugin_prefs['Epub_Version'])-1)
def initUI(self): self.buttons = list() self.button_style_passive = """ .QPushButton { font-weight: bold; font-size: 20px; background-color:#D3D3D3; border: 1px solid black; } """ self.button_style_active = """ .QPushButton { font-weight: bold; font-size: 20px; background-color:#B4B4B4; border: 2px solid black; } """ getWorld().addListener(self.onStickmanListener) """ These are the buttons to control list of names scrolling. start_index is the index which points to the first entry in the button list which is currently shown at the top of the visual list. """ scroll_button_style = """ .QPushButton { font-weight: bold; font-size: 20px; background-color:#D3D3D3; } .QPushButton:pressed { background-color:#B4B4B4; } """ self.scroll_up_button = QPushButton("", self) self.scroll_up_button.setIcon(assets.up) self.scroll_up_button.setIconSize(QSize(StickmanList.ICON_SIZE*2, StickmanList.ICON_SIZE)) self.scroll_up_button.resize(StickmanList.BUTTON_WIDTH/2, StickmanList.BUTTON_HEIGHT) self.scroll_up_button.move(0, StickmanList.BUTTON_HEIGHT*(StickmanList.MAX_LENGTH + 1) + StickmanList.MARGIN_TOP) self.scroll_up_button.setStyleSheet(scroll_button_style) self.scroll_up_button.clicked.connect(self.scrollListUp) self.scroll_up_button.hide() self.scroll_down_button = QPushButton("", self) self.scroll_down_button.setIcon(assets.down) self.scroll_down_button.setIconSize(QSize(StickmanList.ICON_SIZE*2, StickmanList.ICON_SIZE)) self.scroll_down_button.resize(StickmanList.BUTTON_WIDTH/2, StickmanList.BUTTON_HEIGHT) self.scroll_down_button.move(StickmanList.BUTTON_WIDTH/2, StickmanList.BUTTON_HEIGHT*(StickmanList.MAX_LENGTH + 1) + StickmanList.MARGIN_TOP) self.scroll_down_button.setStyleSheet(scroll_button_style) self.scroll_down_button.clicked.connect(self.scrollListDown) self.scroll_down_button.hide() self.start_index = 0 #required to track the first element in the list which is shown
def get_hosts_notif_widget(self): """ Create and return notification QWidget for hosts :return: hosts notification QWidget :rtype: QWidget """ host_notif_widget = QWidget() host_notif_layout = QGridLayout() host_notif_widget.setLayout(host_notif_layout) notif_title = QLabel(_('Hosts notifications configurations')) notif_title.setObjectName('itemtitle') host_notif_layout.addWidget(notif_title, 0, 0, 1, 2) state_title = QLabel(_("Notification enabled:")) state_title.setObjectName("subtitle") host_notif_layout.addWidget(state_title, 1, 0, 1, 1) self.hostnotif_toggle_btn = ToggleQWidgetButton() self.hostnotif_toggle_btn.initialize() self.hostnotif_toggle_btn.update_btn_state( data_manager.database['user'].data['host_notifications_enabled'] ) self.hostnotif_toggle_btn.toggle_btn.clicked.connect(lambda: self.enable_notifications( 'host_notifications_enabled', self.hostnotif_toggle_btn.is_checked() )) self.hostnotif_toggle_btn.setObjectName('host_notifications_enabled') host_notif_layout.addWidget(self.hostnotif_toggle_btn, 1, 1, 1, 1) host_notif_layout.setAlignment(self.hostnotif_toggle_btn, Qt.AlignRight) period_title = QLabel(_('Notification period:')) period_title.setObjectName('subtitle') host_notif_layout.addWidget(period_title, 2, 0, 1, 1) self.labels['host_notification_period'].setText( data_manager.get_period_name( data_manager.database['user'].data['host_notification_period'] ) ) host_notif_layout.addWidget(self.labels['host_notification_period'], 2, 1, 1, 1) option_btn = QPushButton() option_btn.setIcon(QIcon(settings.get_image('options'))) option_btn.setFixedSize(64, 32) option_btn.clicked.connect(lambda: show_options_dialog( 'host', data_manager.database['user'].data['host_notification_options'] )) host_notif_layout.addWidget(option_btn, 3, 0, 1, 2) host_notif_layout.setAlignment(option_btn, Qt.AlignCenter) return host_notif_widget
def __init__(self, parent_dialog, plugin_action): QWidget.__init__(self) self.parent_dialog = parent_dialog self.plugin_action = plugin_action self.l = QVBoxLayout() self.setLayout(self.l) label = QLabel(_('Searches to use for:')) label.setWordWrap(True) self.l.addWidget(label) #self.l.addSpacing(5) scrollable = QScrollArea() scrollcontent = QWidget() scrollable.setWidget(scrollcontent) scrollable.setWidgetResizable(True) self.l.addWidget(scrollable) self.sl = QVBoxLayout() scrollcontent.setLayout(self.sl) self.sl.addWidget(QLabel(_("Search for Duplicated Books:"))) self.checkdups_search = QLineEdit(self) self.sl.addWidget(self.checkdups_search) self.checkdups_search.setText(prefs['checkdups_search']) self.checkdups_search.setToolTip(_('Default is %s')%default_prefs['checkdups_search']) self.sl.addSpacing(5) self.sl.addWidget(QLabel(_("Deleted Books (not in Library):"))) self.checknotinlibrary_search = QLineEdit(self) self.sl.addWidget(self.checknotinlibrary_search) self.checknotinlibrary_search.setText(prefs['checknotinlibrary_search']) self.checknotinlibrary_search.setToolTip(_('Default is %s')%default_prefs['checknotinlibrary_search']) self.sl.addSpacing(5) self.sl.addWidget(QLabel(_("Added Books (not on Device):"))) self.checknotondevice_search = QLineEdit(self) self.sl.addWidget(self.checknotondevice_search) self.checknotondevice_search.setText(prefs['checknotondevice_search']) self.checknotondevice_search.setToolTip(_('Default is %s')%default_prefs['checknotondevice_search']) self.sl.insertStretch(-1) self.l.addSpacing(15) restore_defaults_button = QPushButton(_('Restore Defaults'), self) restore_defaults_button.setToolTip(_('Revert all searches to the defaults.')) restore_defaults_button.clicked.connect(self.restore_defaults_button) self.l.addWidget(restore_defaults_button)
class DebugDevice(QDialog): def __init__(self, gui, parent=None): QDialog.__init__(self, parent) self.gui = gui self._layout = QVBoxLayout(self) self.setLayout(self._layout) self.log = QPlainTextEdit(self) self._layout.addWidget(self.log) self.log.setPlainText(_('Getting debug information, please wait')+'...') self.copy = QPushButton(_('Copy to &clipboard')) self.copy.setDefault(True) self.setWindowTitle(_('Debug device detection')) self.setWindowIcon(QIcon(I('debug.png'))) self.copy.clicked.connect(self.copy_to_clipboard) self.ok = QPushButton('&OK') self.ok.setAutoDefault(False) self.ok.clicked.connect(self.accept) self.bbox = QDialogButtonBox(self) self.bbox.addButton(self.copy, QDialogButtonBox.ActionRole) self.bbox.addButton(self.ok, QDialogButtonBox.AcceptRole) self._layout.addWidget(self.bbox) self.resize(750, 500) self.bbox.setEnabled(False) QTimer.singleShot(1000, self.debug) def debug(self): if self.gui.device_manager.is_device_connected: error_dialog(self, _('Device already detected'), _('A device (%s) is already detected by calibre.' ' If you wish to debug the detection of another device' ', first disconnect this device.')% self.gui.device_manager.connected_device.get_gui_name(), show=True) self.bbox.setEnabled(True) return self.gui.debug_detection(self) def __call__(self, job): if not self.isVisible(): return self.bbox.setEnabled(True) if job.failed: return error_dialog(self, _('Debugging failed'), _('Running debug device detection failed. Click Show ' 'Details for more information.'), det_msg=job.details, show=True) self.log.setPlainText(job.result) def copy_to_clipboard(self): QApplication.clipboard().setText(self.log.toPlainText())
def copyFrame(self): if not self.buttons.active == None: button = QPushButton("", self) button.resize(FrameList.BUTTON_WIDTH, FrameList.BUTTON_HEIGHT) button.clicked.connect(self.onMousePressed) button.show() index = self.buttons.index(self.buttons.active) copy_frame = getWorld().getFrame() copy_frame.time = self.buttons[self.buttons.active].time self.buttons.insertAt(index+1, button, copy_frame) if len(self.buttons) > FrameList.MAX_LENGTH: self.start_index = self.start_index + 1 self.rearrangeButtons()
def __init__(self, data, name, text, parent): QPushButton.__init__(self, text, parent) self.ic = QPixmap(self.iconSize()) color = data[name] self.data, self.name = data, name if color is not None: self.current_color = read_color(color).color() self.ic.fill(self.current_color) else: self.ic.fill(Qt.transparent) self.current_color = color self.update_tooltip() self.setIcon(QIcon(self.ic)) self.clicked.connect(self.choose_color)
def __init__(self, parent=None): super(ProblemsQWidget, self).__init__(parent) self.setWindowIcon(QIcon(settings.get_image('icon'))) # Fields self.line_search = QLineEdit() self.problems_table = ProblemsQTableView() self.problems_title = QLabel() self.actions_widget = ActionsQWidget() self.spy_widget = None self.filter_hosts_btn = ToggleQWidgetButton() self.filter_services_btn = ToggleQWidgetButton() self.spy_btn = QPushButton() self.host_btn = QPushButton() self.refresh_timer = QTimer()
def __init__(self, parent): super(CharacterDialog, self).__init__(parent) self.setWindowTitle(_("KeepKey Seed Recovery")) self.character_pos = 0 self.word_pos = 0 self.loop = QEventLoop() self.word_help = QLabel() self.char_buttons = [] vbox = QVBoxLayout(self) vbox.addWidget(WWLabel(CHARACTER_RECOVERY)) hbox = QHBoxLayout() hbox.addWidget(self.word_help) for i in range(4): char_button = CharacterButton('*') char_button.setMaximumWidth(36) self.char_buttons.append(char_button) hbox.addWidget(char_button) self.accept_button = CharacterButton(_("Accept Word")) self.accept_button.clicked.connect(partial(self.process_key, 32)) self.rejected.connect(partial(self.loop.exit, 1)) hbox.addWidget(self.accept_button) hbox.addStretch(1) vbox.addLayout(hbox) self.finished_button = QPushButton(_("Seed Entered")) self.cancel_button = QPushButton(_("Cancel")) self.finished_button.clicked.connect(partial(self.process_key, Qt.Key_Return)) self.cancel_button.clicked.connect(self.rejected) buttons = Buttons(self.finished_button, self.cancel_button) vbox.addSpacing(40) vbox.addLayout(buttons) self.refresh() self.show()
def __init__(self, window, msg, formats, show_open_with=False): QDialog.__init__(self, window) self.resize(507, 377) self.setWindowIcon(QIcon(I("mimetypes/unknown.png"))) self.setWindowTitle(_('Choose Format')) self.l = l = QVBoxLayout(self) self.msg = QLabel(msg) l.addWidget(self.msg) self.formats = QListWidget(self) self.formats.setIconSize(QSize(64, 64)) self.formats.activated[QModelIndex].connect(self.activated_slot) l.addWidget(self.formats) self.h = h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) l.addLayout(h) if show_open_with: self.owb = QPushButton(_('&Open With...'), self) h.addWidget(self.owb) self.own = QMenu(self.owb.text()) self.owb.setMenu(self.own) self.own.aboutToShow.connect(self.populate_open_with) self.buttonBox = bb = QDialogButtonBox(self) bb.setStandardButtons(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) bb.accepted.connect(self.accept), bb.rejected.connect(self.reject) h.addStretch(10), h.addWidget(self.buttonBox) for format in formats: self.formats.addItem(QListWidgetItem(file_icon_provider().icon_from_ext(format.lower()), format.upper())) self._formats = formats self.formats.setCurrentRow(0) self._format = self.open_with_format = None self.populate_open_with()
def __init__(self, parent, closeButton=True): QFrame.__init__(self, parent) self.setMaximumSize(QSize(9999999,22)) self.setObjectName("windowTitle") self.hboxlayout = QHBoxLayout(self) self.hboxlayout.setSpacing(0) self.hboxlayout.setContentsMargins(0,0,4,0) self.label = QLabel(self) self.label.setObjectName("label") self.label.setStyleSheet("padding-left:4px; font:bold 11px; color: #FFFFFF;") self.hboxlayout.addWidget(self.label) spacerItem = QSpacerItem(40,20,QSizePolicy.Expanding,QSizePolicy.Minimum) self.hboxlayout.addItem(spacerItem) if closeButton: self.pushButton = QPushButton(self) self.pushButton.setFocusPolicy(Qt.NoFocus) self.pushButton.setObjectName("pushButton") self.pushButton.setStyleSheet("font:bold;") self.pushButton.setText("X") self.hboxlayout.addWidget(self.pushButton) self.dragPosition = None self.mainwidget = self.parent() self.setStyleSheet(""" QFrame#windowTitle {background-color:#222222;color:#FFF;} """) # Initial position to top left self.dragPosition = self.mainwidget.frameGeometry().topLeft()
def initialize(self): """ Initialize QDialog for PasswordDialog """ center_widget(self) # Main status_layout main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(main_layout) main_layout.addWidget(get_logo_widget(self, _('Edit Password'))) pass_title = QLabel(_("Please type a new PASSWORD:"******"Your password must contain at least 5 characters.")) self.help_label.setWordWrap(True) pass_layout.addWidget(self.help_label) # Accept button accept_btn = QPushButton('Confirm', self) accept_btn.clicked.connect(self.handle_confirm) accept_btn.setObjectName('valid') accept_btn.setMinimumHeight(30) pass_layout.addWidget(accept_btn) main_layout.addWidget(pass_widget)
def get_search_widget(self): """ Create and return the search QWidget :return: search QWidget :rtype: QWidget """ widget = QWidget() layout = QHBoxLayout() layout.setSpacing(0) layout.setContentsMargins(5, 20, 5, 10) widget.setLayout(layout) # Search label search_lbl = QLabel(_('Search Problems')) search_lbl.setObjectName('bordertitle') search_lbl.setFixedHeight(25) search_lbl.setToolTip(_('Search Problems')) layout.addWidget(search_lbl) # QLineEdit self.line_search.setFixedHeight(search_lbl.height()) self.line_search.setPlaceholderText(_('Type text to filter problems...')) layout.addWidget(self.line_search) # Refresh button refresh_btn = QPushButton(_('Refresh')) refresh_btn.setObjectName('ok') refresh_btn.setFixedSize(120, search_lbl.height()) refresh_btn.setToolTip(_('Refresh problems')) refresh_btn.clicked.connect(self.update_problems_data) layout.addWidget(refresh_btn) return widget
def __init__(self, parent=None): QFrame.__init__(self, parent) self.setFocusPolicy(Qt.StrongFocus) self.setAutoFillBackground(True) self.capture = 0 self.setFrameShape(self.StyledPanel) self.setFrameShadow(self.Raised) self._layout = l = QGridLayout(self) self.setLayout(l) self.header = QLabel('') l.addWidget(self.header, 0, 0, 1, 2) self.use_default = QRadioButton('') self.use_custom = QRadioButton(_('Custom')) l.addWidget(self.use_default, 1, 0, 1, 3) l.addWidget(self.use_custom, 2, 0, 1, 3) self.use_custom.toggled.connect(self.custom_toggled) off = 2 for which in (1, 2): text = _('&Shortcut:') if which == 1 else _('&Alternate shortcut:') la = QLabel(text) la.setStyleSheet('QLabel { margin-left: 1.5em }') l.addWidget(la, off+which, 0, 1, 3) setattr(self, 'label%d'%which, la) button = QPushButton(_('None'), self) button.clicked.connect(partial(self.capture_clicked, which=which)) button.keyPressEvent = partial(self.key_press_event, which=which) setattr(self, 'button%d'%which, button) clear = QToolButton(self) clear.setIcon(QIcon(I('clear_left.png'))) clear.clicked.connect(partial(self.clear_clicked, which=which)) setattr(self, 'clear%d'%which, clear) l.addWidget(button, off+which, 1, 1, 1) l.addWidget(clear, off+which, 2, 1, 1) la.setBuddy(button) self.done_button = doneb = QPushButton(_('Done'), self) l.addWidget(doneb, 0, 2, 1, 1) doneb.clicked.connect(lambda : self.editing_done.emit(self)) l.setColumnStretch(0, 100) self.custom_toggled(False)
def enhance_UI(self): self.toggle_btn = QPushButton(self) self.toggle_btn.setText("Show closed projects!") self.toggle_btn.setCheckable(True) self.show_closed = False self.grid.addWidget(self.toggle_btn, 1, 0) self.toggle_btn.toggled.connect(self.on_toggleBtn_clicked) self.table.customContextMenuRequested.connect(self.open_menu)
def init_UI(self): """establish and fill the UI """ layout = QVBoxLayout(self) self.setLayout(layout) lbl = QLabel("Download example files") lbl.setStyleSheet(general.label_style_2nd) layout.addWidget(lbl) ipd_lbl = QLabel("For IPD submission:") ipd_lbl.setStyleSheet(general.label_style_normal) layout.addWidget(ipd_lbl) pretypings_btn = QPushButton("Pretypings File", self) pretypings_btn.clicked.connect(self.download_pretypings) pretypings_btn.setWhatsThis("This file contains a list of previously identified alleles for all loci for each sample to be submitted to IPD") layout.addWidget(pretypings_btn)
def create_template_widget(title, which, button): attr = which + '_template' heading = QLabel('<h2>' + title) setattr(tp, attr + '_heading', heading) l.addWidget(heading) la = QLabel() setattr(self, attr, la) l.addWidget(la), la.setTextFormat(Qt.PlainText), la.setStyleSheet('QLabel {font-family: monospace}') la.setWordWrap(True) b = QPushButton(button) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) b.clicked.connect(partial(self.change_template, which)) setattr(self, attr + '_button', b) l.addWidget(b) if which != 'footer': f = QFrame(tp) setattr(tp, attr + '_sep', f), f.setFrameShape(QFrame.HLine) l.addWidget(f) l.addSpacing(10)
def initUI(self): self.resize(AnimationPlayer.WIDTH, AnimationToolsPanel.HEIGHT) self.playing = AnimationPlayer.STOPPED button_stylesheet = """ .QPushButton { font-weight: bold; font-size: 13px; background-color:#E0E0E0; } .QPushButton:pressed { background-color:#CCCCCC; } """ self.play_button = QPushButton('', self) self.play_button.setIcon(assets.play) self.play_button.setIconSize(QSize(AnimationToolsPanel.ICON_SIZE, AnimationToolsPanel.ICON_SIZE)) self.play_button.resize(AnimationToolsPanel.ICON_BUTTON_WIDTH, AnimationToolsPanel.HEIGHT) self.play_button.move(0, 0) self.play_button.setStyleSheet(button_stylesheet) self.play_button.clicked.connect(self.onPlay) self.play_button.show() self.clock = Clock(self) self.clock.move(AnimationToolsPanel.ICON_BUTTON_WIDTH, 0) self.clock.task = self.updateAnimation self.clock.hide() self.stop_button = QPushButton('', self) self.stop_button.setIcon(assets.stop) self.stop_button.setIconSize(QSize(AnimationToolsPanel.ICON_SIZE, AnimationToolsPanel.ICON_SIZE)) self.stop_button.resize(AnimationToolsPanel.ICON_BUTTON_WIDTH, AnimationToolsPanel.HEIGHT) self.stop_button.move(AnimationPlayer.WIDTH - AnimationToolsPanel.ICON_BUTTON_WIDTH, 0) self.stop_button.setStyleSheet(button_stylesheet) self.stop_button.clicked.connect(self.onStop) self.stop_button.hide() self.old_frame = None self.current_frame = None self.next_frame = None self.steps = 0 #number of intermediate steps between two frames self.step_counter = 0 #number of steps already taken for the interpolation
def __init__(self, index, dup_check, parent=None): QFrame.__init__(self, parent) self.setFrameShape(self.StyledPanel) self.setFrameShadow(self.Raised) self.setFocusPolicy(Qt.StrongFocus) self.setAutoFillBackground(True) self.l = l = QVBoxLayout(self) self.header = la = QLabel(self) la.setWordWrap(True) l.addWidget(la) self.default_shortcuts = QRadioButton(_("&Default"), self) self.custom = QRadioButton(_("&Custom"), self) self.custom.toggled.connect(self.custom_toggled) l.addWidget(self.default_shortcuts) l.addWidget(self.custom) for which in 1, 2: la = QLabel(_("&Shortcut:") if which == 1 else _("&Alternate shortcut:")) setattr(self, 'label%d' % which, la) h = QHBoxLayout() l.addLayout(h) h.setContentsMargins(25, -1, -1, -1) h.addWidget(la) b = QPushButton(_("Click to change"), self) la.setBuddy(b) b.clicked.connect(partial(self.capture_clicked, which=which)) b.installEventFilter(self) setattr(self, 'button%d' % which, b) h.addWidget(b) c = QToolButton(self) c.setIcon(QIcon(I('clear_left.png'))) c.setToolTip(_('Clear')) h.addWidget(c) c.clicked.connect(partial(self.clear_clicked, which=which)) setattr(self, 'clear%d' % which, c) self.data_model = index.model() self.capture = 0 self.key = None self.shorcut1 = self.shortcut2 = None self.dup_check = dup_check self.custom_toggled(False)
def initialize(self): """ Initialize QDialog """ main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(get_logo_widget(self, _('User View'))) # Daemons QWidget daemons_widget = QWidget(self) daemons_widget.setLayout(self.daemons_layout) daemons = data_manager.database['alignakdaemon'] # Init QLabels self.init_daemons_labels(daemons) # Add daemons label line = 0 self.add_daemon_titles_labels(line) for daemon_item in daemons: line += 1 self.add_daemon_labels(daemon_item, line) line += 1 # Ok QPushButton ok_btn = QPushButton(_('OK')) ok_btn.setObjectName('ok') ok_btn.setFixedSize(120, 30) ok_btn.clicked.connect(self.accept) self.daemons_layout.addWidget(ok_btn, line, 0, 1, 7) self.daemons_layout.setAlignment(ok_btn, Qt.AlignCenter) main_layout.addWidget(daemons_widget) center_widget(self)
def get_message_widget(self, dialog, title, text): """ Return colored message QWidget :param dialog: type of dialog ('text' or 'error') :type dialog: str :param title: title of text to display :type title: str :param text: text to display :type text: str :return: message QWidget :rtype: QWidget """ # Token QWidget token_widget = QWidget() token_widget.setObjectName('dialog') token_layout = QVBoxLayout() token_widget.setLayout(token_layout) token_title = QLabel(title) token_title.setObjectName('itemtitle') token_layout.addWidget(token_title) token_layout.setAlignment(token_title, Qt.AlignCenter) token_label = QLabel(text) token_label.setObjectName(dialog) token_label.setTextInteractionFlags(Qt.TextSelectableByMouse) token_label.setWordWrap(True) token_layout.addWidget(token_label) # Login button accept_btn = QPushButton('OK', self) accept_btn.clicked.connect(self.accept) accept_btn.setObjectName('ok') accept_btn.setMinimumHeight(30) token_layout.addWidget(accept_btn) return token_widget
def __init__(self, parent, prefs=None): QWidget.__init__(self, parent) self.prefs = prefs or gprefs self.setLayout(QVBoxLayout()) self.la = la = QLabel( '<b>' + _('Select a destination for the Table of Contents entry')) self.layout().addWidget(la) self.splitter = sp = QSplitter(self) self.layout().addWidget(sp) self.layout().setStretch(1, 10) sp.setOpaqueResize(False) sp.setChildrenCollapsible(False) self.dest_list = dl = QListWidget(self) dl.setMinimumWidth(250) dl.currentItemChanged.connect(self.current_changed) sp.addWidget(dl) w = self.w = QWidget(self) l = w.l = QGridLayout() w.setLayout(l) self.view = WebView(self) self.view.elem_clicked.connect(self.elem_clicked) l.addWidget(self.view, 0, 0, 1, 3) sp.addWidget(w) self.search_text = s = QLineEdit(self) s.setPlaceholderText(_('Search for text...')) l.addWidget(s, 1, 0) self.ns_button = b = QPushButton(QIcon(I('arrow-down.png')), _('Find &next'), self) b.clicked.connect(self.find_next) l.addWidget(b, 1, 1) self.ps_button = b = QPushButton(QIcon(I('arrow-up.png')), _('Find &previous'), self) l.addWidget(b, 1, 2) b.clicked.connect(self.find_previous) self.f = f = QFrame() f.setFrameShape(f.StyledPanel) f.setMinimumWidth(250) l = f.l = QVBoxLayout() f.setLayout(l) sp.addWidget(f) f.la = la = QLabel('<p>' + _( 'Here you can choose a destination for the Table of Contents\' entry' ' to point to. First choose a file from the book in the left-most panel. The' ' file will open in the central panel.<p>' 'Then choose a location inside the file. To do so, simply click on' ' the place in the central panel that you want to use as the' ' destination. As you move the mouse around the central panel, a' ' thick green line appears, indicating the precise location' ' that will be selected when you click.')) la.setStyleSheet('QLabel { margin-bottom: 20px }') la.setWordWrap(True) l.addWidget(la) f.la2 = la = QLabel('<b>' + _('&Name of the ToC entry:')) l.addWidget(la) self.name = QLineEdit(self) la.setBuddy(self.name) l.addWidget(self.name) self.base_msg = '<b>' + _('Currently selected destination:') + '</b>' self.dest_label = la = QLabel(self.base_msg) la.setWordWrap(True) la.setStyleSheet('QLabel { margin-top: 20px }') l.addWidget(la) l.addStretch() state = self.prefs.get('toc_edit_splitter_state', None) if state is not None: sp.restoreState(state)
def __init__(self, parent_dialog, plugin_action): self.parent_dialog = parent_dialog self.plugin_action = plugin_action QWidget.__init__(self) self.l = QVBoxLayout() self.setLayout(self.l) label = QLabel(_('These settings control the basic features of the plugin.')) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) self.titlenavpoints = QCheckBox(_('Insert Table of Contents entry for each title?'),self) self.titlenavpoints.setToolTip(_('''If set, a new TOC entry will be made for each title and it's existing TOC nested underneath it.''')) self.titlenavpoints.setChecked(prefs['titlenavpoints']) self.l.addWidget(self.titlenavpoints) self.flattentoc = QCheckBox(_('Flatten Table of Contents?'),self) self.flattentoc.setToolTip(_('Remove nesting and make TOC all on one level.')) self.flattentoc.setChecked(prefs['flattentoc']) self.l.addWidget(self.flattentoc) self.includecomments = QCheckBox(_("Include Books' Comments?"),self) self.includecomments.setToolTip(_('''Include all the merged books' comments in the new book's comments. Default is a list of included titles only.''')) self.includecomments.setChecked(prefs['includecomments']) self.l.addWidget(self.includecomments) self.keepmeta = QCheckBox(_('Keep UnMerge Metadata?'),self) self.keepmeta.setToolTip(_('''If set, a copy of the original metadata for each merged book will be included, allowing for UnMerge. This includes your calibre custom columns. Leave off if you plan to distribute the epub to others.''')) self.keepmeta.setChecked(prefs['keepmeta']) self.l.addWidget(self.keepmeta) # self.showunmerge = QCheckBox(_('Show UnMerge Option?'),self) # self.showunmerge.setToolTip(_('''If set, the UnMerge Epub option will be shown on the EpubMerge menu. # Only Epubs merged with 'Keep UnMerge Metadata' can be UnMerged.''')) # self.showunmerge.setChecked(prefs['showunmerge']) # self.l.addWidget(self.showunmerge) horz = QHBoxLayout() horz.addWidget(QLabel(_("Add tags to merged books:"))) self.mergetags = QLineEdit(self) self.mergetags.setText(prefs['mergetags']) self.mergetags.setToolTip(_('Tags you enter here will be added to all new merged books')) horz.addWidget(self.mergetags) self.l.addLayout(horz) horz = QHBoxLayout() horz.addWidget(QLabel(_("Merged Book Word:"))) self.mergeword = QLineEdit(self) self.mergeword.setText(prefs['mergeword']) self.mergeword.setToolTip(_('''Word use to describe merged books in default title and summary. For people who don't like the word Anthology.''')) ## Defaults back to Anthology if cleared. horz.addWidget(self.mergeword) self.l.addLayout(horz) self.l.addSpacing(15) label = QLabel(_("These controls aren't plugin settings as such, but convenience buttons for setting Keyboard shortcuts and getting all the EpubMerge confirmation dialogs back again.")) label.setWordWrap(True) self.l.addWidget(label) self.l.addSpacing(5) keyboard_shortcuts_button = QPushButton(_('Keyboard shortcuts...'), self) keyboard_shortcuts_button.setToolTip(_('Edit the keyboard shortcuts associated with this plugin')) keyboard_shortcuts_button.clicked.connect(parent_dialog.edit_shortcuts) self.l.addWidget(keyboard_shortcuts_button) reset_confirmation_button = QPushButton(_('Reset disabled &confirmation dialogs'), self) reset_confirmation_button.setToolTip(_('Reset all show me again dialogs for the EpubMerge plugin')) reset_confirmation_button.clicked.connect(self.reset_dialogs) self.l.addWidget(reset_confirmation_button) view_prefs_button = QPushButton(_('View library preferences...'), self) view_prefs_button.setToolTip(_('View data stored in the library database for this plugin')) view_prefs_button.clicked.connect(self.view_prefs) self.l.addWidget(view_prefs_button) self.l.insertStretch(-1)
def __init__(self, parent=None): super(DashboardQWidget, self).__init__(parent) # Fields self.layout = QGridLayout() self.items_nb = { 'hosts_nb': QLabel(), 'services_nb': QLabel() } self.hosts_labels = { 'hosts_up': QLabel(), 'hosts_unreachable': QLabel(), 'hosts_down': QLabel(), 'hosts_not_monitored': QLabel(), 'acknowledge': QLabel(), 'downtime': QLabel() } self.services_labels = { 'services_ok': QLabel(), 'services_warning': QLabel(), 'services_critical': QLabel(), 'services_unknown': QLabel(), 'services_unreachable': QLabel(), 'services_not_monitored': QLabel(), 'acknowledge': QLabel(), 'downtime': QLabel() } self.hosts_buttons = { 'hosts_up': QPushButton(), 'hosts_unreachable': QPushButton(), 'hosts_down': QPushButton(), 'hosts_not_monitored': QPushButton(), 'acknowledge': QPushButton(), 'downtime': QPushButton() } self.services_buttons = { 'services_ok': QPushButton(), 'services_warning': QPushButton(), 'services_critical': QPushButton(), 'services_unknown': QPushButton(), 'services_unreachable': QPushButton(), 'services_not_monitored': QPushButton(), 'acknowledge': QPushButton(), 'downtime': QPushButton() } self.refresh_timer = QTimer() self.setFixedHeight(85)
def __init__(self, fm, pref_name, parent=None): QDialog.__init__(self, parent) self.fm = fm if pref_name == 'column_color_rules': self.rule_kind = 'color' rule_text = _('column coloring') elif pref_name == 'column_icon_rules': self.rule_kind = 'icon' rule_text = _('column icon') elif pref_name == 'cover_grid_icon_rules': self.rule_kind = 'emblem' rule_text = _('Cover grid emblem') self.setWindowIcon(QIcon(I('format-fill-color.png'))) self.setWindowTitle(_('Create/edit a {0} rule').format(rule_text)) self.l = l = QGridLayout(self) self.setLayout(l) self.l1 = l1 = QLabel( _('Create a {0} rule by' ' filling in the boxes below').format(rule_text)) l.addWidget(l1, 0, 0, 1, 8) self.f1 = QFrame(self) self.f1.setFrameShape(QFrame.HLine) l.addWidget(self.f1, 1, 0, 1, 8) self.l2 = l2 = QLabel( _('Add the emblem:') if self.rule_kind == 'emblem' else _('Set the')) l.addWidget(l2, 2, 0) if self.rule_kind == 'color': l.addWidget(QLabel(_('color'))) elif self.rule_kind == 'icon': self.kind_box = QComboBox(self) for tt, t in icon_rule_kinds: self.kind_box.addItem(tt, t) l.addWidget(self.kind_box, 2, 1) self.kind_box.setToolTip( textwrap.fill( _('If you choose composed icons and multiple rules match, then all the' ' matching icons will be combined, otherwise the icon from the' ' first rule to match will be used.'))) else: pass self.l3 = l3 = QLabel(_('of the column:')) l.addWidget(l3, 2, 2) self.column_box = QComboBox(self) l.addWidget(self.column_box, 2, 3) self.l4 = l4 = QLabel(_('to')) l.addWidget(l4, 2, 4) if self.rule_kind == 'emblem': l3.setVisible(False), self.column_box.setVisible( False), l4.setVisible(False) def create_filename_box(): self.filename_box = f = QComboBox() self.filenamebox_view = v = QListView() v.setIconSize(QSize(32, 32)) self.filename_box.setView(v) self.orig_filenamebox_view = f.view() f.setMinimumContentsLength(20), f.setSizeAdjustPolicy( f.AdjustToMinimumContentsLengthWithIcon) self.populate_icon_filenames() if self.rule_kind == 'color': self.color_box = ColorButton(parent=self) self.color_label = QLabel('Sample text Sample text') self.color_label.setTextFormat(Qt.RichText) l.addWidget(self.color_box, 2, 5) l.addWidget(self.color_label, 2, 6) l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7) elif self.rule_kind == 'emblem': create_filename_box() self.update_filename_box() self.filename_button = QPushButton(QIcon(I('document_open.png')), _('&Add new image')) l.addWidget(self.filename_box) l.addWidget(self.filename_button, 2, 6) l.addWidget(QLabel(_('(Images should be square-ish)')), 2, 7) l.setColumnStretch(7, 10) else: create_filename_box() vb = QVBoxLayout() self.multiple_icon_cb = QCheckBox(_('Choose more than one icon')) vb.addWidget(self.multiple_icon_cb) self.update_filename_box() self.multiple_icon_cb.clicked.connect(self.multiple_box_clicked) vb.addWidget(self.filename_box) l.addLayout(vb, 2, 5) self.filename_button = QPushButton(QIcon(I('document_open.png')), _('&Add icon')) l.addWidget(self.filename_button, 2, 6) l.addWidget(QLabel(_('Icons should be square or landscape')), 2, 7) l.setColumnStretch(7, 10) self.l5 = l5 = QLabel( _('Only if the following conditions are all satisfied:')) l.addWidget(l5, 3, 0, 1, 7) self.scroll_area = sa = QScrollArea(self) sa.setMinimumHeight(300) sa.setMinimumWidth(950) sa.setWidgetResizable(True) l.addWidget(sa, 4, 0, 1, 8) self.add_button = b = QPushButton(QIcon(I('plus.png')), _('Add another condition')) l.addWidget(b, 5, 0, 1, 8) b.clicked.connect(self.add_blank_condition) self.l6 = l6 = QLabel( _('You can disable a condition by' ' blanking all of its boxes')) l.addWidget(l6, 6, 0, 1, 8) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addWidget(bb, 7, 0, 1, 8) if self.rule_kind != 'color': self.remove_button = b = bb.addButton(_('Remove image'), bb.ActionRole) b.setIcon(QIcon(I('minus.png'))) b.setMenu(QMenu()) self.update_remove_button() self.conditions_widget = QWidget(self) sa.setWidget(self.conditions_widget) self.conditions_widget.setLayout(QVBoxLayout()) self.conditions_widget.layout().setAlignment(Qt.AlignTop) self.conditions = [] if self.rule_kind == 'color': for b in (self.column_box, ): b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon) b.setMinimumContentsLength(15) for key in sorted(displayable_columns(fm), key=lambda (k): sort_key(fm[k]['name']) if k != color_row_key else 0): if key == color_row_key and self.rule_kind != 'color': continue name = all_columns_string if key == color_row_key else fm[key][ 'name'] if name: self.column_box.addItem(name, key) self.column_box.setCurrentIndex(0) if self.rule_kind == 'color': self.color_box.color = '#000' self.update_color_label() self.color_box.color_changed.connect(self.update_color_label) else: self.rule_icon_files = [] self.filename_button.clicked.connect(self.filename_button_clicked) self.resize(self.sizeHint())
def create_gui(self): """ Layout arrangement for the dialog and its input widgets. """ self.layout = QVBoxLayout() self.layout.setSpacing(20) self.setLayout(self.layout) # Create an editable box for user to input Comic Vine API Key. self.api_layout = QHBoxLayout() self.api_msg = QLineEdit(self) self.api_msg.setFixedWidth(350) self.api_msg.setText(prefs["comic_vine_api_key"]) self.api_label = QLabel("Comic Vine API Key") self.api_label.setBuddy(self.api_msg) self.api_layout.addWidget(self.api_label) self.api_layout.addWidget(self.api_msg) # Create an editable box for user to input Tags to add to all books. self.tags_layout = QHBoxLayout() self.tags_msg = QLineEdit(self) self.tags_msg.setText(prefs["tags_to_add"]) self.tags_label = QLabel("Tags To Add") self.tags_label.setBuddy(self.tags_msg) self.tags_layout.addWidget(self.tags_label) self.tags_layout.addWidget(self.tags_msg) # Add the fields to the main layout. self.layout.addLayout(self.api_layout) self.layout.addLayout(self.tags_layout) # Option to keep current tags. self.keep_tags_cb = QCheckBox("Keep existing tags while adding new.", self) self.layout.addWidget(self.keep_tags_cb) # Separate the buttons from the input. self.btn_sep = QFrame() self.btn_sep.setFrameShape(QFrame.HLine) self.btn_sep.setFrameShadow(QFrame.Sunken) self.layout.addWidget(self.btn_sep) # Create a start button to kick off the processing with title. self.title_start = QPushButton("Using Title - Hover For Details", self) self.title_start.setToolTip( "This expects the title of a book to have a " "specific formatted string containing volume " "ID and issue#. e.g." + os.linesep + "Desired " "Title --- v1234 n0124" + os.linesep + "Where " "--- is required and the number after v " "matches Comic Vine's volume ID. The number " "after n is the issue number.") self.title_start.clicked.connect(self.title_process) self.layout.addWidget(self.title_start) # Create a start button to kick off the processing with series. self.series_start = QPushButton("Using Series - Hover For Details", self) self.series_start.setToolTip( "This expects the series name to match the " "Comic Vine volume ID and the series number " "equals issue number.") self.series_start.clicked.connect(self.series_process) self.layout.addWidget(self.series_start) # Create a start button to kick off the processing with CV IDs. self.ids_start = QPushButton("Using IDs - Hover For Details", self) self.ids_start.setToolTip( "This expects two custom columns with lookup " "comicvineissueid and comicvinevolumeid. " "These must match Comic Vine's IDs for the " "issue and the volume.") self.ids_start.clicked.connect(self.ids_process) self.layout.addWidget(self.ids_start) # Separate the progress and results. self.result_sep = QFrame() self.result_sep.setFrameShape(QFrame.HLine) self.result_sep.setFrameShadow(QFrame.Sunken) self.layout.addWidget(self.result_sep) # Create progress bar. self.progress_bar = QProgressBar() self.progress_bar.setRange(0, 100) self.progress_bar.setMinimumWidth(485) self.layout.addWidget(self.progress_bar) # Create results text area. self.result_box = QGroupBox() self.result_box.setTitle("Results") self.result_text = QLabel("Run Comicalibre to see results.") self.result_scroll = QScrollArea() self.result_scroll.setWidget(self.result_text) self.result_scroll.setWidgetResizable(True) self.result_layout = QVBoxLayout() self.result_layout.addWidget(self.result_scroll) self.result_box.setLayout(self.result_layout) self.layout.addWidget(self.result_box) self.setWindowTitle("Comicalibre") self.setWindowIcon(self.icon) self.resize(self.sizeHint())
class PunctDialog(Dialog): def __init__(self, parent): self.prefs = self.prefsPrep() self.criteria = None self.parent = parent self.help_file_name = '{0}_smarten_help.html'.format(PLUGIN_SAFE_NAME) Dialog.__init__(self, _('Smarten Punctuation (the sequel)'), 'toolbag_smarter_dialog', parent) def setup_ui(self, ): layout = QVBoxLayout(self) self.setLayout(layout) help_layout = QHBoxLayout() layout.addLayout(help_layout) # Add hyperlink to a help file at the right. We will replace the correct name when it is clicked. help_label = QLabel('<a href="http://www.foo.com/">Plugin Help</a>', self) help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) help_label.setAlignment(Qt.AlignRight) help_label.linkActivated.connect(self.help_link_activated) help_layout.addWidget(help_label) self.edu_quotes = QCheckBox(_('Smarten Quotation marks'), self) layout.addWidget(self.edu_quotes) self.edu_quotes.setChecked(self.prefs['edu_quotes']) self.edu_quotes.stateChanged.connect(self.quotes_gui_changes) exceptions_group_box = QGroupBox('', self) layout.addWidget(exceptions_group_box) exceptions_group_box_layout = QVBoxLayout() exceptions_group_box.setLayout(exceptions_group_box_layout) self.use_file = QCheckBox(_('Use custom apostrophe exceptions file'), self) exceptions_group_box_layout.addWidget(self.use_file) if not self.edu_quotes.isChecked(): self.use_file.setDisabled(True) else: self.use_file.setChecked(self.prefs['use_file']) self.use_file.stateChanged.connect(self.use_file_gui_changes) path_layout = QHBoxLayout() exceptions_group_box_layout.addLayout(path_layout) self.file_path = QLineEdit('', self) if not self.edu_quotes.isChecked() and not self.use_file.isChecked(): self.file_path.setReadOnly(True) else: self.file_path.setText(self.prefs['file_path']) self.file_path.setReadOnly(True) path_layout.addWidget(self.file_path) self.file_button = QPushButton('...', self) self.file_button.clicked.connect(self.getFile) path_layout.addWidget(self.file_button) if not self.edu_quotes.isChecked() and not self.use_file.isChecked(): self.file_button.setDisabled(True) combo_layout = QVBoxLayout() layout.addLayout(combo_layout) label = QLabel(_('(em|en)-dash settings'), self) combo_layout.addWidget(label) self.dashes_combo = QComboBox() combo_layout.addWidget(self.dashes_combo) values = [ _('Do not educate dashes'), _('-- = emdash (no endash support)'), _('-- = emdash | --- = endash'), _('--- = emdash | -- = endash') ] self.dashes_combo.addItems(values) self.dashes_combo.setCurrentIndex(self.prefs['dashes']) # self.dashes_combo.currentIndexChanged.connect(self.update_gui) self.ellipses = QCheckBox(_('Smarten ellipses'), self) layout.addWidget(self.ellipses) self.ellipses.setChecked(self.prefs['ellipses']) self.unicode = QCheckBox( _('Educate with unicode characters (instead of entities)'), self) layout.addWidget(self.unicode) self.unicode.setChecked(self.prefs['unicode']) layout.addSpacing(10) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self.reject) layout.addWidget(button_box) def getFile(self): unique_dlg_name = '{0}plugin:smarter_choose_dialog'.format( PLUGIN_SAFE_NAME) caption = _('Select custom apostrophe exceptions file') filters = [('Text files', ['txt'])] c = choose_files(self, unique_dlg_name, caption, filters, all_files=True) if c: self.file_path.setReadOnly(False) self.file_path.setText(c[0]) self.file_path.setReadOnly(True) def _ok_clicked(self): quotes_setting = 'q' if self.edu_quotes.isChecked() else '' if self.dashes_combo.currentIndex() == 0: dash_setting = '' elif self.dashes_combo.currentIndex() == 1: dash_setting = 'd' elif self.dashes_combo.currentIndex() == 2: dash_setting = 'i' elif self.dashes_combo.currentIndex() == 3: dash_setting = 'D' else: dash_setting = '' ellipses_setting = 'e' if self.ellipses.isChecked() else '' smarty_attr = quotes_setting + dash_setting + ellipses_setting if smarty_attr == '': smarty_attr = '0' self.file_path.setReadOnly(False) if self.use_file.isChecked() and not len(self.file_path.displayText()): self.file_path.setReadOnly(True) return error_dialog(self.parent, _('Error'), '<p>' + _('Must select a custom exception file'), det_msg='', show=True) if self.use_file.isChecked(): apos_exception_file = unicode(self.file_path.displayText()) if not os.path.exists(apos_exception_file): apos_exception_file = None else: apos_exception_file = None self.file_path.setReadOnly(True) apos_words_list = [] if apos_exception_file is not None: apos_words_list = self.parseExceptionsFile( os.path.normpath(apos_exception_file)) self.criteria = (smarty_attr, self.unicode.isChecked(), apos_words_list) self.savePrefs() self.accept() def getCriteria(self): return self.criteria def quotes_gui_changes(self): if self.edu_quotes.isChecked(): self.use_file.setDisabled(False) if self.use_file.isChecked(): self.file_button.setDisabled(False) else: self.use_file.setChecked(False) self.file_path.setReadOnly(False) self.file_path.clear() self.file_path.setReadOnly(True) self.use_file.setDisabled(True) self.file_button.setDisabled(True) def use_file_gui_changes(self): if self.use_file.isChecked(): self.file_button.setDisabled(False) else: self.file_path.setReadOnly(False) self.file_path.clear() self.file_path.setReadOnly(True) self.file_button.setDisabled(True) def prefsPrep(self): from calibre.utils.config import JSONConfig plugin_prefs = JSONConfig( 'plugins/{0}_SmarterPunct_settings'.format(PLUGIN_SAFE_NAME)) plugin_prefs.defaults['edu_quotes'] = True plugin_prefs.defaults['use_file'] = False plugin_prefs.defaults['file_path'] = '' plugin_prefs.defaults['dashes'] = 1 plugin_prefs.defaults['ellipses'] = True plugin_prefs.defaults['unicode'] = True return plugin_prefs def savePrefs(self): self.prefs['edu_quotes'] = self.edu_quotes.isChecked() self.prefs['use_file'] = self.use_file.isChecked() self.prefs['file_path'] = unicode(self.file_path.displayText()) if len( self.file_path.displayText()) else '' self.prefs['dashes'] = self.dashes_combo.currentIndex() self.prefs['ellipses'] = self.ellipses.isChecked() self.prefs['unicode'] = self.unicode.isChecked() def help_link_activated(self, url): def get_help_file_resource(): # Copy the HTML helpfile to the plugin directory each time the # link is clicked in case the helpfile is updated in newer plugins. file_path = os.path.join(config_dir, 'plugins', self.help_file_name) with open(file_path, 'w') as f: f.write( load_resource('resources/{}'.format(self.help_file_name))) return file_path url = 'file:///' + get_help_file_resource() open_url(QUrl(url)) def parseExceptionsFile(self, filename): import os, codecs, chardet words_list = [] bytes = min(32, os.path.getsize(filename)) raw = open(filename, 'rb').read(bytes) if raw.startswith(codecs.BOM_UTF8): enc = 'utf-8-sig' else: result = chardet.detect(raw) enc = result['encoding'] try: with codecs.open(filename, encoding=enc, mode='r') as fd: words_list = [line.rstrip() for line in fd] words_list = filter(None, words_list) print('Exceptions list:', words_list) except: pass return words_list
timeout_slider.valueChanged.connect(slider_moved) timeout_slider.sliderReleased.connect(slider_released) settings_glayout.addWidget(timeout_label, 6, 0) settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3) settings_glayout.addWidget(timeout_minutes, 6, 4) settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1) settings_layout.addLayout(settings_glayout) settings_layout.addStretch(1) # Advanced tab advanced_tab = QWidget() advanced_layout = QVBoxLayout(advanced_tab) advanced_glayout = QGridLayout() # Advanced tab - clear PIN clear_pin_button = QPushButton(_("Disable PIN")) clear_pin_button.clicked.connect(clear_pin) clear_pin_warning = QLabel( _("If you disable your PIN, anyone with physical access to your " "{} device can spend your viacoins.").format(plugin.device)) clear_pin_warning.setWordWrap(True) clear_pin_warning.setStyleSheet("color: red") advanced_glayout.addWidget(clear_pin_button, 0, 2) advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5) # Advanced tab - toggle passphrase protection passphrase_button = QPushButton() passphrase_button.clicked.connect(toggle_passphrase) passphrase_msg = WWLabel(PASSPHRASE_HELP) passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN) passphrase_warning.setStyleSheet("color: red")
def ask_link(self): class Ask(QDialog): def accept(self): if self.treat_as_image.isChecked(): url = self.url.text() if url.lower().split(':', 1)[0] in ('http', 'https'): error_dialog(self, _('Remote images not supported'), _( 'You must download the image to your computer, URLs pointing' ' to remote images are not supported.'), show=True) return QDialog.accept(self) d = Ask(self) d.setWindowTitle(_('Create link')) l = QFormLayout() l.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow) d.setLayout(l) d.url = QLineEdit(d) d.name = QLineEdit(d) d.treat_as_image = QCheckBox(d) d.setMinimumWidth(600) d.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) d.br = b = QPushButton(_('&Browse')) b.setIcon(QIcon(I('document_open.png'))) def cf(): filetypes = [] if d.treat_as_image.isChecked(): filetypes = [(_('Images'), 'png jpeg jpg gif'.split())] files = choose_files(d, 'select link file', _('Choose file'), filetypes, select_only_single_file=True) if files: path = files[0] d.url.setText(path) if path and os.path.exists(path): with lopen(path, 'rb') as f: q = what(f) is_image = q in {'jpeg', 'png', 'gif'} d.treat_as_image.setChecked(is_image) b.clicked.connect(cf) d.la = la = QLabel(_( 'Enter a URL. If you check the "Treat the URL as an image" box ' 'then the URL will be added as an image reference instead of as ' 'a link. You can also choose to create a link to a file on ' 'your computer. ' 'Note that if you create a link to a file on your computer, it ' 'will stop working if the file is moved.')) la.setWordWrap(True) la.setStyleSheet('QLabel { margin-bottom: 1.5ex }') l.setWidget(0, l.SpanningRole, la) l.addRow(_('Enter &URL:'), d.url) l.addRow(_('Treat the URL as an &image'), d.treat_as_image) l.addRow(_('Enter &name (optional):'), d.name) l.addRow(_('Choose a file on your computer:'), d.br) l.addRow(d.bb) d.bb.accepted.connect(d.accept) d.bb.rejected.connect(d.reject) d.resize(d.sizeHint()) link, name, is_image = None, None, False if d.exec_() == d.Accepted: link, name = unicode_type(d.url.text()).strip(), unicode_type(d.name.text()).strip() is_image = d.treat_as_image.isChecked() return link, name, is_image
class MetadataSingleDialogBase(ResizableDialog): view_format = pyqtSignal(object, object) cc_two_column = tweaks['metadata_single_use_2_cols_for_custom_fields'] one_line_comments_toolbar = False use_toolbutton_for_config_metadata = True def __init__(self, db, parent=None): self.db = db self.changed = set() self.books_to_refresh = set() self.rows_to_refresh = set() ResizableDialog.__init__(self, parent) def setupUi(self, *args): # {{{ self.resize(990, 670) self.download_shortcut = QShortcut(self) self.download_shortcut.setKey( QKeySequence('Ctrl+D', QKeySequence.PortableText)) p = self.parent() if hasattr(p, 'keyboard'): kname = u'Interface Action: Edit Metadata (Edit Metadata) : menu action : download' sc = p.keyboard.keys_map.get(kname, None) if sc: self.download_shortcut.setKey(sc[0]) self.button_box = bb = QDialogButtonBox(self) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.next_button = QPushButton(QIcon(I('forward.png')), _('Next'), self) self.next_button.setShortcut(QKeySequence('Alt+Right')) self.next_button.clicked.connect(self.next_clicked) self.prev_button = QPushButton(QIcon(I('back.png')), _('Previous'), self) self.prev_button.setShortcut(QKeySequence('Alt+Left')) self.button_box.addButton(self.prev_button, bb.ActionRole) self.button_box.addButton(self.next_button, bb.ActionRole) self.prev_button.clicked.connect(self.prev_clicked) bb.setStandardButtons(bb.Ok | bb.Cancel) bb.button(bb.Ok).setDefault(True) self.scroll_area = QScrollArea(self) self.scroll_area.setFrameShape(QScrollArea.NoFrame) self.scroll_area.setWidgetResizable(True) self.central_widget = QTabWidget(self) self.scroll_area.setWidget(self.central_widget) self.l = QVBoxLayout(self) self.setLayout(self.l) self.l.addWidget(self.scroll_area) ll = self.button_box_layout = QHBoxLayout() self.l.addLayout(ll) ll.addSpacing(10) ll.addWidget(self.button_box) self.setWindowIcon(QIcon(I('edit_input.png'))) self.setWindowTitle(BASE_TITLE) self.create_basic_metadata_widgets() if len(self.db.custom_column_label_map): self.create_custom_metadata_widgets() self.do_layout() geom = gprefs.get('metasingle_window_geometry3', None) if geom is not None: self.restoreGeometry(bytes(geom)) # }}} 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>') 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')) 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 create_custom_metadata_widgets(self): # {{{ self.custom_metadata_widgets_parent = w = QWidget(self) layout = QGridLayout() w.setLayout(layout) self.custom_metadata_widgets, self.__cc_spacers = \ populate_metadata_page(layout, self.db, None, parent=w, bulk=False, two_column=self.cc_two_column) self.__custom_col_layouts = [layout] # }}} def set_custom_metadata_tab_order(self, before=None, after=None): # {{{ sto = QWidget.setTabOrder if getattr(self, 'custom_metadata_widgets', []): ans = self.custom_metadata_widgets for i in range(len(ans) - 1): if before is not None and i == 0: pass if len(ans[i + 1].widgets) == 2: sto(ans[i].widgets[-1], ans[i + 1].widgets[1]) else: sto(ans[i].widgets[-1], ans[i + 1].widgets[0]) for c in range(2, len(ans[i].widgets), 2): sto(ans[i].widgets[c - 1], ans[i].widgets[c + 1]) if after is not None: pass # }}} def do_view_format(self, path, fmt): if path: self.view_format.emit(None, path) else: self.view_format.emit(self.book_id, fmt) def copy_fmt(self, fmt, f): self.db.copy_format_to(self.book_id, fmt, f, index_is_id=True) def do_layout(self): raise NotImplementedError() def __call__(self, id_): self.book_id = id_ self.books_to_refresh = set([]) for widget in self.basic_metadata_widgets: widget.initialize(self.db, id_) for widget in getattr(self, 'custom_metadata_widgets', []): widget.initialize(id_) if callable(self.set_current_callback): self.set_current_callback(id_) # Commented out as it doesn't play nice with Next, Prev buttons # self.fetch_metadata_button.setFocus(Qt.OtherFocusReason) # Miscellaneous interaction methods {{{ def update_window_title(self, *args): title = self.title.current_val if len(title) > 50: title = title[:50] + u'\u2026' self.setWindowTitle( BASE_TITLE + ' - ' + title + ' - ' + _(' [%(num)d of %(tot)d]') % dict(num=self.current_row + 1, tot=len(self.row_list))) def swap_title_author(self, *args): title = self.title.current_val self.title.current_val = authors_to_string(self.authors.current_val) self.authors.current_val = string_to_authors(title) self.title_sort.auto_generate() self.author_sort.auto_generate() def tags_editor(self, *args): self.tags.edit(self.db, self.book_id) def metadata_from_format(self, *args): mi, ext = self.formats_manager.get_selected_format_metadata( self.db, self.book_id) if mi is not None: self.update_from_mi(mi) def get_pdf_cover(self): pdfpath = self.formats_manager.get_format_path(self.db, self.book_id, 'pdf') from calibre.gui2.metadata.pdf_covers import PDFCovers d = PDFCovers(pdfpath, parent=self) if d.exec_() == d.Accepted: cpath = d.cover_path if cpath: with open(cpath, 'rb') as f: self.update_cover(f.read(), 'PDF') d.cleanup() def cover_from_format(self, *args): ext = self.formats_manager.get_selected_format() if ext is None: return if ext == 'pdf': return self.get_pdf_cover() try: mi, ext = self.formats_manager.get_selected_format_metadata( self.db, self.book_id) except (IOError, OSError) as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback fname = err.filename if err.filename else 'file' error_dialog(self, _('Permission denied'), _('Could not open %s. Is it being used by another' ' program?') % fname, det_msg=traceback.format_exc(), show=True) return raise if mi is None: return cdata = None if mi.cover and os.access(mi.cover, os.R_OK): cdata = open(mi.cover).read() elif mi.cover_data[1] is not None: cdata = mi.cover_data[1] if cdata is None: error_dialog(self, _('Could not read cover'), _('Could not read cover from %s format') % ext).exec_() return self.update_cover(cdata, ext) def update_cover(self, cdata, fmt): orig = self.cover.current_val self.cover.current_val = cdata if self.cover.current_val is None: self.cover.current_val = orig return error_dialog(self, _('Could not read cover'), _('The cover in the %s format is invalid') % fmt, show=True) return def update_from_mi(self, mi, update_sorts=True, merge_tags=True, merge_comments=False): if not mi.is_null('title'): self.title.current_val = mi.title if update_sorts: self.title_sort.auto_generate() if not mi.is_null('authors'): self.authors.current_val = mi.authors if not mi.is_null('author_sort'): self.author_sort.current_val = mi.author_sort elif update_sorts: self.author_sort.auto_generate() if not mi.is_null('rating'): try: self.rating.current_val = mi.rating except: pass if not mi.is_null('publisher'): self.publisher.current_val = mi.publisher if not mi.is_null('tags'): old_tags = self.tags.current_val tags = mi.tags if mi.tags else [] if old_tags and merge_tags: ltags, lotags = {t.lower() for t in tags}, {t.lower() for t in old_tags} tags = [t for t in tags if t.lower() in ltags - lotags ] + old_tags self.tags.current_val = tags if not mi.is_null('identifiers'): current = self.identifiers.current_val current.update(mi.identifiers) self.identifiers.current_val = current if not mi.is_null('pubdate'): self.pubdate.current_val = mi.pubdate if not mi.is_null('series') and mi.series.strip(): self.series.current_val = mi.series if mi.series_index is not None: self.series_index.reset_original() self.series_index.current_val = float(mi.series_index) if not mi.is_null('languages'): langs = [canonicalize_lang(x) for x in mi.languages] langs = [x for x in langs if x is not None] if langs: self.languages.current_val = langs if mi.comments and mi.comments.strip(): val = mi.comments if val and merge_comments: cval = self.comments.current_val if cval: val = merge_two_comments(cval, val) self.comments.current_val = val def fetch_metadata(self, *args): d = FullFetch(self.cover.pixmap(), self) ret = d.start(title=self.title.current_val, authors=self.authors.current_val, identifiers=self.identifiers.current_val) if ret == d.Accepted: from calibre.ebooks.metadata.sources.prefs import msprefs mi = d.book dummy = Metadata(_('Unknown')) for f in msprefs['ignore_fields']: if ':' not in f: setattr(mi, f, getattr(dummy, f)) if mi is not None: pd = mi.pubdate if pd is not None: # Put the downloaded published date into the local timezone # as we discard time info and the date is timezone # invariant. This prevents the as_local_timezone() call in # update_from_mi from changing the pubdate mi.pubdate = datetime(pd.year, pd.month, pd.day, tzinfo=local_tz) self.update_from_mi(mi, merge_comments=msprefs['append_comments']) if d.cover_pixmap is not None: self.cover.current_val = pixmap_to_data(d.cover_pixmap) def configure_metadata(self): from calibre.gui2.preferences import show_config_widget gui = self.parent() show_config_widget('Sharing', 'Metadata download', parent=self, gui=gui, never_shutdown=True) def download_cover(self, *args): from calibre.gui2.metadata.single_download import CoverFetch d = CoverFetch(self.cover.pixmap(), self) ret = d.start(self.title.current_val, self.authors.current_val, self.identifiers.current_val) if ret == d.Accepted: if d.cover_pixmap is not None: self.cover.current_val = pixmap_to_data(d.cover_pixmap) # }}} def to_book_metadata(self): mi = Metadata(_('Unknown')) if self.db is None: return mi mi.set_all_user_metadata( self.db.field_metadata.custom_field_metadata()) for widget in self.basic_metadata_widgets: widget.apply_to_metadata(mi) for widget in getattr(self, 'custom_metadata_widgets', []): widget.apply_to_metadata(mi) return mi def apply_changes(self): self.changed.add(self.book_id) if self.db is None: # break_cycles has already been called, don't know why this should # happen but a user reported it return True for widget in self.basic_metadata_widgets: try: if hasattr(widget, 'validate_for_commit'): title, msg, det_msg = widget.validate_for_commit() if title is not None: error_dialog(self, title, msg, det_msg=det_msg, show=True) return False widget.commit(self.db, self.book_id) self.books_to_refresh |= getattr(widget, 'books_to_refresh', set()) except (IOError, OSError) as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback fname = getattr(err, 'filename', None) p = 'Locked file: %s\n\n' % fname if fname else '' error_dialog( self, _('Permission denied'), _('Could not change the on disk location of this' ' book. Is it open in another program?'), det_msg=p + traceback.format_exc(), show=True) return False raise for widget in getattr(self, 'custom_metadata_widgets', []): self.books_to_refresh |= widget.commit(self.book_id) self.db.commit() rows = self.db.refresh_ids(list(self.books_to_refresh)) if rows: self.rows_to_refresh |= set(rows) return True def accept(self): self.save_state() if not self.apply_changes(): return ResizableDialog.accept(self) def reject(self): self.save_state() ResizableDialog.reject(self) def save_state(self): try: gprefs['metasingle_window_geometry3'] = bytearray( self.saveGeometry()) except: # Weird failure, see https://bugs.launchpad.net/bugs/995271 import traceback traceback.print_exc() # Dialog use methods {{{ def start(self, row_list, current_row, view_slot=None, set_current_callback=None): self.row_list = row_list self.current_row = current_row if view_slot is not None: self.view_format.connect(view_slot) self.set_current_callback = set_current_callback self.do_one(apply_changes=False) ret = self.exec_() self.break_cycles() return ret def next_clicked(self): if not self.apply_changes(): return self.do_one(delta=1, apply_changes=False) def prev_clicked(self): if not self.apply_changes(): return self.do_one(delta=-1, apply_changes=False) def do_one(self, delta=0, apply_changes=True): if apply_changes: self.apply_changes() self.current_row += delta prev = next_ = None if self.current_row > 0: prev = self.db.title(self.row_list[self.current_row - 1]) if self.current_row < len(self.row_list) - 1: next_ = self.db.title(self.row_list[self.current_row + 1]) if next_ is not None: tip = (_('Save changes and edit the metadata of %s') + ' [Alt+Right]') % next_ self.next_button.setToolTip(tip) self.next_button.setEnabled(next_ is not None) if prev is not None: tip = (_('Save changes and edit the metadata of %s') + ' [Alt+Left]') % prev self.prev_button.setToolTip(tip) self.prev_button.setEnabled(prev is not None) self.button_box.button(self.button_box.Ok).setDefault(True) self.button_box.button(self.button_box.Ok).setFocus( Qt.OtherFocusReason) self(self.db.id(self.row_list[self.current_row])) def break_cycles(self): # Break any reference cycles that could prevent python # from garbage collecting this dialog self.set_current_callback = self.db = None def disconnect(signal): try: signal.disconnect() except: pass # Fails if view format was never connected disconnect(self.view_format) for b in ('next_button', 'prev_button'): x = getattr(self, b, None) if x is not None: disconnect(x.clicked) for widget in self.basic_metadata_widgets: bc = getattr(widget, 'break_cycles', None) if bc is not None and callable(bc): bc() for widget in getattr(self, 'custom_metadata_widgets', []): widget.break_cycles()
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 setup_ui(self): self.setAttribute(Qt.WA_DeleteOnClose, False) self.l = l = QVBoxLayout(self) self.setLayout(l) self.bb.clear() self.bb.addButton(self.bb.Close) self.splitter = s = QSplitter(self) self.h = h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) self.install_fonts_button = b = QPushButton(_('&Install fonts'), self) h.addWidget(b), b.setIcon(QIcon(I('plus.png'))) b.setToolTip( textwrap.fill( _('Install fonts from .ttf/.otf files to make them available for embedding' ))) b.clicked.connect(self.install_fonts) l.addWidget(s), l.addLayout(h), h.addStretch(10), h.addWidget(self.bb) self.fonts_view = fv = QTableView(self) fv.doubleClicked.connect(self.show_embedding_data) self.model = m = AllFonts(fv) fv.horizontalHeader().setStretchLastSection(True) fv.setModel(m) fv.setSortingEnabled(True) fv.setShowGrid(False) fv.setAlternatingRowColors(True) fv.setSelectionMode(fv.ExtendedSelection) fv.setSelectionBehavior(fv.SelectRows) fv.horizontalHeader().setSortIndicator(1, Qt.AscendingOrder) self.container = c = QWidget() l = c.l = QVBoxLayout(c) c.setLayout(l) s.addWidget(fv), s.addWidget(c) self.cb = b = QPushButton(_('&Change selected fonts')) b.setIcon(QIcon(I('wizard.png'))) b.clicked.connect(self.change_fonts) l.addWidget(b) self.rb = b = QPushButton(_('&Remove selected fonts')) b.clicked.connect(self.remove_fonts) b.setIcon(QIcon(I('trash.png'))) l.addWidget(b) self.eb = b = QPushButton(_('&Embed all fonts')) b.setIcon(QIcon(I('embed-fonts.png'))) b.clicked.connect(self.embed_fonts) l.addWidget(b) self.sb = b = QPushButton(_('&Subset all fonts')) b.setIcon(QIcon(I('subset-fonts.png'))) b.clicked.connect(self.subset_fonts) l.addWidget(b) self.refresh_button = b = self.bb.addButton(_('&Refresh'), self.bb.ActionRole) b.setToolTip( _('Rescan the book for fonts in case you have made changes')) b.setIcon(QIcon(I('view-refresh.png'))) b.clicked.connect(self.refresh) self.la = la = QLabel('<p>' + _( ''' All the fonts declared in this book are shown to the left, along with whether they are embedded or not. You can remove or replace any selected font and also embed any declared fonts that are not already embedded.''' ) + '<p>' + _( ''' Double click any font family to see if the font is available for embedding on your computer. ''' )) la.setWordWrap(True) l.addWidget(la) l.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('show_rating_in_cover_browser', gprefs) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) if islinux or isbsd: self.opt_systray_icon.setEnabled(False) self.opt_systray_icon.setText( _('System tray icon is disabled because of bugs in Qt 5')) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) self.search_library_for_author_button.clicked.connect( lambda: self.opt_default_author_link.setText('search-calibre')) choices = set([ k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) ]) choices -= set( ['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted( ((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x: sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText) ] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText( unicode(self.fs_help_msg.text()) % (_(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton( _('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton( _('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect( partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect( partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum( self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum( self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect( self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect( self.update_aspect_ratio)
def __init__(self, parent=None): BasicSettings.__init__(self, parent) self.dictionaries_changed = self.snippets_changed = False self.l = l = QFormLayout(self) self.setLayout(l) fc = FontFamilyChooser(self) self('editor_font_family', widget=fc, getter=attrgetter('font_family'), setter=lambda x, val: setattr(x, 'font_family', val)) fc.family_changed.connect(self.emit_changed) l.addRow(_('Editor font family:'), fc) fs = self('editor_font_size') fs.setMinimum(8), fs.setSuffix(' pt'), fs.setMaximum(50) l.addRow(_('Editor font &size:'), fs) choices = self.theme_choices() theme = self.choices_widget('editor_theme', choices, 'auto', 'auto') self.custom_theme_button = b = QPushButton( _('Create/edit &custom color schemes')) b.clicked.connect(self.custom_theme) h = QHBoxLayout() h.addWidget(theme), h.addWidget(b) l.addRow(_('&Color scheme:'), h) l.labelForField(h).setBuddy(theme) tw = self('editor_tab_stop_width') tw.setMinimum(2), tw.setSuffix(_(' characters')), tw.setMaximum(20) l.addRow(_('W&idth of tabs:'), tw) self.tb = b = QPushButton(_('Change &templates')) l.addRow(_('Templates for new files:'), b) b.clicked.connect(lambda: TemplatesDialog(self).exec_()) lw = self('editor_line_wrap') lw.setText(_('&Wrap long lines in the editor')) l.addRow(lw) lw = self('replace_entities_as_typed') lw.setText(_('&Replace HTML entities as they are typed')) lw.setToolTip('<p>' + _( 'With this option, every time you type in a complete html entity, such as &hellip;' ' it is automatically replaced by its corresponding character. The replacement' ' happens only when the trailing semi-colon is typed.')) l.addRow(lw) lw = self('auto_close_tags') lw.setText(_('Auto close t&ags when typing </')) lw.setToolTip('<p>' + prepare_string_for_xml( _('With this option, every time you type </ the current HTML closing tag is auto-completed' ))) l.addRow(lw) lw = self('editor_show_char_under_cursor') lw.setText( _('Show the &name of the current character before the cursor along with the line and column number' )) l.addRow(lw) lw = self('pretty_print_on_open') lw.setText( _('Beautify individual &files automatically when they are opened')) lw.setToolTip('<p>' + _( 'This will cause the beautify current file action to be performed automatically every' ' time you open a HTML/CSS/etc. file for editing.')) l.addRow(lw) lw = self('inline_spell_check') lw.setText(_('Show &misspelled words underlined in the code view')) lw.setToolTip('<p>' + _( 'This will cause spelling errors to be highlighted in the code view' ' for easy correction as you type.')) l.addRow(lw) lw = self('editor_accepts_drops') lw.setText(_('Allow drag and drop &editing of text')) lw.setToolTip('<p>' + _( 'Allow using drag and drop to move text around in the editor.' ' It can be useful to turn this off if you have a misbehaving touchpad.' )) l.addRow(lw) self.dictionaries = d = QPushButton(_('Manage &spelling dictionaries'), self) d.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) d.clicked.connect(self.manage_dictionaries) l.addRow(d) self.snippets = s = QPushButton(_('Manage sni&ppets'), self) s.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) s.clicked.connect(self.manage_snippets) l.addRow(s)
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, window, plugin, keystore, device_id): title = _("{} Settings").format(plugin.device) super(SettingsDialog, self).__init__(window, title) self.setMaximumWidth(540) devmgr = plugin.device_manager() config = devmgr.config handler = keystore.handler thread = keystore.thread hs_rows, hs_cols = (64, 128) def invoke_client(method, *args, **kw_args): unpair_after = kw_args.pop('unpair_after', False) def task(): client = devmgr.client_by_id(device_id) if not client: raise RuntimeError("Device not connected") if method: getattr(client, method)(*args, **kw_args) if unpair_after: devmgr.unpair_id(device_id) return client.features thread.add(task, on_success=update) def update(features): self.features = features set_label_enabled() bl_hash = bh2u(features.bootloader_hash) bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] disen = [_("Disabled"), _("Enabled")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) device_label.setText(features.label) pin_set_label.setText(noyes[features.pin_protection]) passphrases_label.setText(disen[features.passphrase_protection]) bl_hash_label.setText(bl_hash) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language) def set_label_enabled(): label_apply.setEnabled(label_edit.text() != self.features.label) def rename(): invoke_client('change_label', label_edit.text()) def toggle_passphrase(): title = _("Confirm Toggle Passphrase Protection") currently_enabled = self.features.passphrase_protection if currently_enabled: msg = _("After disabling passphrases, you can only pair this " "Electrum wallet if it had an empty passphrase. " "If its passphrase was not empty, you will need to " "create a new wallet with the install wizard. You " "can use this wallet again at any time by re-enabling " "passphrases and entering its passphrase.") else: msg = _("Your current Electrum wallet can only be used with " "an empty passphrase. You must create a separate " "wallet with the install wizard for other passphrases " "as each one generates a new set of addresses.") msg += "\n\n" + _("Are you sure you want to proceed?") if not self.question(msg, title=title): return invoke_client('toggle_passphrase', unpair_after=currently_enabled) def change_homescreen(): from PIL import Image # FIXME dialog = QFileDialog(self, _("Choose Homescreen")) filename, __ = dialog.getOpenFileName() if filename: im = Image.open(str(filename)) if im.size != (hs_cols, hs_rows): raise Exception('Image must be 64 x 128 pixels') im = im.convert('1') pix = im.load() img = '' for j in range(hs_rows): for i in range(hs_cols): img += '1' if pix[i, j] else '0' img = ''.join(chr(int(img[i:i + 8], 2)) for i in range(0, len(img), 8)) invoke_client('change_homescreen', img) def clear_homescreen(): invoke_client('change_homescreen', '\x00') def set_pin(): invoke_client('set_pin', remove=False) def clear_pin(): invoke_client('set_pin', remove=True) def wipe_device(): wallet = window.wallet if wallet and sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has viacoins in it!") if not self.question(msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True) def slider_moved(): mins = timeout_slider.sliderPosition() timeout_minutes.setText(_("%2d minutes") % mins) def slider_released(): config.set_session_timeout(timeout_slider.sliderPosition() * 60) # Information tab info_tab = QWidget() info_layout = QVBoxLayout(info_tab) info_glayout = QGridLayout() info_glayout.setColumnStretch(2, 1) device_label = QLabel() pin_set_label = QLabel() passphrases_label = QLabel() version_label = QLabel() device_id_label = QLabel() bl_hash_label = QLabel() bl_hash_label.setWordWrap(True) coins_label = QLabel() coins_label.setWordWrap(True) language_label = QLabel() initialized_label = QLabel() rows = [ (_("Device Label"), device_label), (_("PIN set"), pin_set_label), (_("Passphrases"), passphrases_label), (_("Firmware Version"), version_label), (_("Device ID"), device_id_label), (_("Bootloader Hash"), bl_hash_label), (_("Supported Coins"), coins_label), (_("Language"), language_label), (_("Initialized"), initialized_label), ] for row_num, (label, widget) in enumerate(rows): info_glayout.addWidget(QLabel(label), row_num, 0) info_glayout.addWidget(widget, row_num, 1) info_layout.addLayout(info_glayout) # Settings tab settings_tab = QWidget() settings_layout = QVBoxLayout(settings_tab) settings_glayout = QGridLayout() # Settings tab - Label label_msg = QLabel(_("Name this {}. If you have multiple devices " "their labels help distinguish them.") .format(plugin.device)) label_msg.setWordWrap(True) label_label = QLabel(_("Device Label")) label_edit = QLineEdit() label_edit.setMinimumWidth(150) label_edit.setMaxLength(plugin.MAX_LABEL_LEN) label_apply = QPushButton(_("Apply")) label_apply.clicked.connect(rename) label_edit.textChanged.connect(set_label_enabled) settings_glayout.addWidget(label_label, 0, 0) settings_glayout.addWidget(label_edit, 0, 1, 1, 2) settings_glayout.addWidget(label_apply, 0, 3) settings_glayout.addWidget(label_msg, 1, 1, 1, -1) # Settings tab - PIN pin_label = QLabel(_("PIN Protection")) pin_button = QPushButton() pin_button.clicked.connect(set_pin) settings_glayout.addWidget(pin_label, 2, 0) settings_glayout.addWidget(pin_button, 2, 1) pin_msg = QLabel(_("PIN protection is strongly recommended. " "A PIN is your only protection against someone " "stealing your viacoins if they obtain physical " "access to your %s.") % plugin.device) "stealing your viacoins if they obtain physical " "access to your {}.").format(plugin.device))
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 = b = RightClickButton(self) b.setToolTip('<p>' + _('Paste the contents of the clipboard into the ' 'identifiers prefixed with isbn:. Or right click, ' 'to choose a different prefix.') + '</p>') b.setIcon(QIcon(I('edit-paste.png'))) b.clicked.connect(self.identifiers.paste_identifier) b.setPopupMode(b.DelayedPopup) b.setMenu(QMenu()) self.update_paste_identifiers_menu() 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')) for w in self.basic_metadata_widgets: w.data_changed.connect(self.data_changed)
def setup_ui(self, ): layout = QVBoxLayout(self) self.setLayout(layout) help_layout = QHBoxLayout() layout.addLayout(help_layout) # Add hyperlink to a help file at the right. We will replace the correct name when it is clicked. help_label = QLabel('<a href="http://www.foo.com/">Plugin Help</a>', self) help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) help_label.setAlignment(Qt.AlignRight) help_label.linkActivated.connect(self.help_link_activated) help_layout.addWidget(help_label) self.edu_quotes = QCheckBox(_('Smarten Quotation marks'), self) layout.addWidget(self.edu_quotes) self.edu_quotes.setChecked(self.prefs['edu_quotes']) self.edu_quotes.stateChanged.connect(self.quotes_gui_changes) exceptions_group_box = QGroupBox('', self) layout.addWidget(exceptions_group_box) exceptions_group_box_layout = QVBoxLayout() exceptions_group_box.setLayout(exceptions_group_box_layout) self.use_file = QCheckBox(_('Use custom apostrophe exceptions file'), self) exceptions_group_box_layout.addWidget(self.use_file) if not self.edu_quotes.isChecked(): self.use_file.setDisabled(True) else: self.use_file.setChecked(self.prefs['use_file']) self.use_file.stateChanged.connect(self.use_file_gui_changes) path_layout = QHBoxLayout() exceptions_group_box_layout.addLayout(path_layout) self.file_path = QLineEdit('', self) if not self.edu_quotes.isChecked() and not self.use_file.isChecked(): self.file_path.setReadOnly(True) else: self.file_path.setText(self.prefs['file_path']) self.file_path.setReadOnly(True) path_layout.addWidget(self.file_path) self.file_button = QPushButton('...', self) self.file_button.clicked.connect(self.getFile) path_layout.addWidget(self.file_button) if not self.edu_quotes.isChecked() and not self.use_file.isChecked(): self.file_button.setDisabled(True) combo_layout = QVBoxLayout() layout.addLayout(combo_layout) label = QLabel(_('(em|en)-dash settings'), self) combo_layout.addWidget(label) self.dashes_combo = QComboBox() combo_layout.addWidget(self.dashes_combo) values = [ _('Do not educate dashes'), _('-- = emdash (no endash support)'), _('-- = emdash | --- = endash'), _('--- = emdash | -- = endash') ] self.dashes_combo.addItems(values) self.dashes_combo.setCurrentIndex(self.prefs['dashes']) # self.dashes_combo.currentIndexChanged.connect(self.update_gui) self.ellipses = QCheckBox(_('Smarten ellipses'), self) layout.addWidget(self.ellipses) self.ellipses.setChecked(self.prefs['ellipses']) self.unicode = QCheckBox( _('Educate with unicode characters (instead of entities)'), self) layout.addWidget(self.unicode) self.unicode.setChecked(self.prefs['unicode']) layout.addSpacing(10) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self.reject) layout.addWidget(button_box)
class BookInfo(QDialog): closed = pyqtSignal(object) open_cover_with = pyqtSignal(object, object) def __init__(self, parent, view, row, link_delegate): QDialog.__init__(self, parent) self.normal_brush = QBrush(Qt.white) self.marked_brush = QBrush(Qt.lightGray) self.marked = None self.gui = parent self.splitter = QSplitter(self) self._l = l = QVBoxLayout(self) self.setLayout(l) l.addWidget(self.splitter) self.cover = Cover(self, show_size=gprefs['bd_overlay_cover_size']) self.cover.resizeEvent = self.cover_view_resized self.cover.cover_changed.connect(self.cover_changed) self.cover.open_with_requested.connect(self.open_with) self.cover.choose_open_with_requested.connect(self.choose_open_with) self.cover_pixmap = None self.cover.sizeHint = self.details_size_hint self.splitter.addWidget(self.cover) self.details = Details(parent.book_details.book_info, self) self.details.anchor_clicked.connect(self.on_link_clicked) self.link_delegate = link_delegate self.details.setAttribute(Qt.WA_OpaquePaintEvent, False) palette = self.details.palette() self.details.setAcceptDrops(False) palette.setBrush(QPalette.Base, Qt.transparent) self.details.setPalette(palette) self.c = QWidget(self) self.c.l = l2 = QGridLayout(self.c) l2.setContentsMargins(0, 0, 0, 0) self.c.setLayout(l2) l2.addWidget(self.details, 0, 0, 1, -1) self.splitter.addWidget(self.c) self.fit_cover = QCheckBox(_('Fit &cover within view'), self) self.fit_cover.setChecked( gprefs.get('book_info_dialog_fit_cover', True)) self.hl = hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) l2.addLayout(hl, l2.rowCount(), 0, 1, -1) hl.addWidget(self.fit_cover), hl.addStretch() self.clabel = QLabel( '<div style="text-align: right"><a href="calibre:conf" title="{}" style="text-decoration: none">{}</a>' .format(_('Configure this view'), _('Configure'))) self.clabel.linkActivated.connect(self.configure) hl.addWidget(self.clabel) self.previous_button = QPushButton(QIcon(I('previous.png')), _('&Previous'), self) self.previous_button.clicked.connect(self.previous) l2.addWidget(self.previous_button, l2.rowCount(), 0) self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self) self.next_button.clicked.connect(self.next) l2.addWidget(self.next_button, l2.rowCount() - 1, 1) self.view = view self.path_to_book = None self.current_row = None self.refresh(row) self.view.model().new_bookdisplay_data.connect(self.slave) self.fit_cover.stateChanged.connect(self.toggle_cover_fit) self.ns = QShortcut(QKeySequence('Alt+Right'), self) self.ns.activated.connect(self.next) self.ps = QShortcut(QKeySequence('Alt+Left'), self) self.ps.activated.connect(self.previous) self.next_button.setToolTip( _('Next [%s]') % unicode_type(self.ns.key().toString(QKeySequence.NativeText))) self.previous_button.setToolTip( _('Previous [%s]') % unicode_type(self.ps.key().toString(QKeySequence.NativeText))) geom = QCoreApplication.instance().desktop().availableGeometry(self) screen_height = geom.height() - 100 screen_width = geom.width() - 100 self.resize(max(int(screen_width / 2), 700), screen_height) saved_layout = gprefs.get('book_info_dialog_layout', None) if saved_layout is not None: try: QApplication.instance().safe_restore_geometry( self, saved_layout[0]) self.splitter.restoreState(saved_layout[1]) except Exception: pass from calibre.gui2.ui import get_gui ema = get_gui().iactions['Edit Metadata'].menuless_qaction a = self.ema = QAction('edit metadata', self) a.setShortcut(ema.shortcut()) self.addAction(a) a.triggered.connect(self.edit_metadata) def edit_metadata(self): if self.current_row is not None: book_id = self.view.model().id(self.current_row) get_gui().iactions['Edit Metadata'].edit_metadata_for( [self.current_row], [book_id], bulk=False) def configure(self): d = Configure(get_gui().current_db, self) if d.exec_() == d.Accepted: if self.current_row is not None: mi = self.view.model().get_book_display_info(self.current_row) if mi is not None: self.refresh(self.current_row, mi=mi) def on_link_clicked(self, qurl): link = unicode_type(qurl.toString(NO_URL_FORMATTING)) self.link_delegate(link) def done(self, r): saved_layout = (bytearray(self.saveGeometry()), bytearray(self.splitter.saveState())) gprefs.set('book_info_dialog_layout', saved_layout) ret = QDialog.done(self, r) self.view.model().new_bookdisplay_data.disconnect(self.slave) self.view = self.link_delegate = self.gui = None self.closed.emit(self) return ret def cover_changed(self, data): if self.current_row is not None: id_ = self.view.model().id(self.current_row) self.view.model().db.set_cover(id_, data) self.gui.refresh_cover_browser() ci = self.view.currentIndex() if ci.isValid(): self.view.model().current_changed(ci, ci) def details_size_hint(self): return QSize(350, 550) def toggle_cover_fit(self, state): gprefs.set('book_info_dialog_fit_cover', self.fit_cover.isChecked()) self.resize_cover() def cover_view_resized(self, event): QTimer.singleShot(1, self.resize_cover) def slave(self, mi): self.refresh(mi.row_number, mi) def move(self, delta=1): idx = self.view.currentIndex() if idx.isValid(): m = self.view.model() ni = m.index(idx.row() + delta, idx.column()) if ni.isValid(): if self.view.isVisible(): self.view.scrollTo(ni) self.view.setCurrentIndex(ni) def next(self): self.move() def previous(self): self.move(-1) def resize_cover(self): if self.cover_pixmap is None: return pixmap = self.cover_pixmap if self.fit_cover.isChecked(): scaled, new_width, new_height = fit_image( pixmap.width(), pixmap.height(), self.cover.size().width() - 10, self.cover.size().height() - 10) if scaled: try: dpr = self.devicePixelRatioF() except AttributeError: dpr = self.devicePixelRatio() pixmap = pixmap.scaled(int(dpr * new_width), int(dpr * new_height), Qt.KeepAspectRatio, Qt.SmoothTransformation) pixmap.setDevicePixelRatio(dpr) self.cover.set_pixmap(pixmap) self.update_cover_tooltip() def update_cover_tooltip(self): tt = '' if self.marked: tt += _('This book is marked') if self.marked in { True, 'true' } else _('This book is marked as: %s') % self.marked tt += '\n\n' if self.path_to_book is not None: tt += textwrap.fill(_('Path: {}').format(self.path_to_book)) tt += '\n\n' if self.cover_pixmap is not None: sz = self.cover_pixmap.size() tt += _('Cover size: %(width)d x %(height)d pixels') % dict( width=sz.width(), height=sz.height()) self.cover.setToolTip(tt) self.cover.pixmap_size = sz.width(), sz.height() def refresh(self, row, mi=None): if isinstance(row, QModelIndex): row = row.row() if row == self.current_row and mi is None: return mi = self.view.model().get_book_display_info(row) if mi is None else mi if mi is None: # Indicates books was deleted from library, or row numbers have # changed return self.previous_button.setEnabled(False if row == 0 else True) self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex()) - 1 else True) self.current_row = row self.setWindowTitle(mi.title) self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1]) self.path_to_book = getattr(mi, 'path', None) try: dpr = self.devicePixelRatioF() except AttributeError: dpr = self.devicePixelRatio() self.cover_pixmap.setDevicePixelRatio(dpr) self.resize_cover() html = render_html(mi, True, self, pref_name='popup_book_display_fields') set_html(mi, html, self.details) self.marked = mi.marked self.cover.setBackgroundBrush( self.marked_brush if mi.marked else self.normal_brush) self.update_cover_tooltip() def open_with(self, entry): id_ = self.view.model().id(self.current_row) self.open_cover_with.emit(id_, entry) def choose_open_with(self): from calibre.gui2.open_with import choose_program entry = choose_program('cover_image', self) if entry is not None: self.open_with(entry)
class Result(QWidget): result_exit_sg = pyqtSignal() def __init__(self, parent=None): super(Result, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.back1_wi = QWidget(self) self.resexit_but = QPushButton(self) self.role1 = QWidget(self.back1_wi) self.role1_head = QLabel(self.role1) self.role1_detail = QWidget(self.role1) self.role1_special = QLabel(self.role1_detail) self.role2 = QWidget(self.back1_wi) self.role2_head = QLabel(self.role2) self.role2_detail = QWidget(self.role2) self.role2_special = QLabel(self.role2_detail) self.role3 = QWidget(self.back1_wi) self.role3_head = QLabel(self.role3) self.role3_detail = QWidget(self.role3) self.role3_special = QLabel(self.role3_detail) self.role4 = QWidget(self.back1_wi) self.role4_head = QLabel(self.role4) self.role4_detail = QWidget(self.role4) self.role4_special = QLabel(self.role4_detail) self.set_ui() with open('result.qss', 'r') as f: self.setStyleSheet(f.read()) def set_ui(self): self.setWindowTitle('Result') self.setObjectName('result') self.resize(self.w, self.h) effect = QGraphicsDropShadowEffect() effect.setOffset(10, 10) effect.setColor(QColor(0, 0, 0, 80)) effect.setBlurRadius(20) self.back1_wi.setObjectName('back') self.back1_wi.resize(self.xr * 793, self.yr * 534) self.back1_wi.move(self.xr * 69, self.yr * 53) self.back1_wi.setGraphicsEffect(effect) back_x = 69 back_y = 53 effect1 = QGraphicsDropShadowEffect() effect1.setOffset(10, 10) effect1.setColor(QColor(0, 0, 0, 80)) effect1.setBlurRadius(20) effect2 = QGraphicsDropShadowEffect() effect2.setOffset(10, 10) effect2.setColor(QColor(0, 0, 0, 80)) effect2.setBlurRadius(20) effect3 = QGraphicsDropShadowEffect() effect3.setOffset(10, 10) effect3.setColor(QColor(0, 0, 0, 80)) effect3.setBlurRadius(20) effect4 = QGraphicsDropShadowEffect() effect4.setOffset(10, 10) effect4.setColor(QColor(0, 0, 0, 80)) effect4.setBlurRadius(20) self.resexit_but.setObjectName('resexit') self.resexit_but.resize(self.zr * 38, self.zr * 38) self.resexit_but.move(self.xr * 834, self.yr * 36) self.resexit_but.clicked.connect(self.result_exit) self.resexit_but.setStyleSheet('border-radius:{}px;'.format(self.zr * 18)) self.role1.setObjectName('role') self.role1.resize(self.xr * 716, self.yr * 87) self.role1.move(self.xr * (108 - back_x), self.yr * (77 - back_y)) self.role1.setGraphicsEffect(effect1) self.role1_head.setObjectName('role_head') self.role1_head.resize(self.xr * 90, self.yr * 50) self.role1_head.move(self.xr * 10, self.yr * 16) # self.role1_head.setText('test') self.role1_head.setAlignment(Qt.AlignCenter) self.role1_detail.setObjectName('role_detail') self.role1_detail.resize(self.xr * 606, self.yr * 87) self.role1_detail.move(self.xr * 110, self.yr * 0) self.role1_special.setObjectName('role_special') self.role1_special.resize(self.xr * 88, self.yr * 36) self.role1_special.move(self.xr * 10, self.yr * 26) # self.role1_special.setText('test') self.role1_special.setAlignment(Qt.AlignCenter) self.role2.setObjectName('role') self.role2.resize(self.xr * 716, self.yr * 87) self.role2.move(self.xr * (108 - back_x), self.yr * (207 - back_y)) self.role2.setGraphicsEffect(effect2) self.role2_head.setObjectName('role_head') self.role2_head.resize(self.xr * 90, self.yr * 50) self.role2_head.move(self.xr * 10, self.yr * 16) self.role2_head.setAlignment(Qt.AlignCenter) self.role2_detail.setObjectName('role_detail') self.role2_detail.resize(self.xr * 606, self.yr * 87) self.role2_detail.move(self.xr * 110, self.yr * 0) self.role2_special.setObjectName('role_special') self.role2_special.resize(self.xr * 88, self.yr * 36) self.role2_special.move(self.xr * 10, self.yr * 26) self.role2_special.setAlignment(Qt.AlignCenter) self.role3.setObjectName('role') self.role3.resize(self.xr * 716, self.yr * 87) self.role3.move(self.xr * (108 - back_x), self.yr * (337 - back_y)) self.role3.setGraphicsEffect(effect3) self.role3_head.setObjectName('role_head') self.role3_head.resize(self.xr * 90, self.yr * 50) self.role3_head.move(self.xr * 10, self.yr * 16) self.role3_head.setAlignment(Qt.AlignCenter) self.role3_detail.setObjectName('role_detail') self.role3_detail.resize(self.xr * 606, self.yr * 87) self.role3_detail.move(self.xr * 110, self.yr * 0) self.role3_special.setObjectName('role_special') self.role3_special.resize(self.xr * 88, self.yr * 36) self.role3_special.move(self.xr * 10, self.yr * 26) self.role3_special.setAlignment(Qt.AlignCenter) self.role4.setObjectName('role') self.role4.resize(self.xr * 716, self.yr * 87) self.role4.move(self.xr * (108 - back_x), self.yr * (467 - back_y)) self.role4.setGraphicsEffect(effect4) self.role4_head.setObjectName('role_head') self.role4_head.resize(self.xr * 90, self.yr * 50) self.role4_head.move(self.xr * 10, self.yr * 16) self.role4_head.setAlignment(Qt.AlignCenter) self.role4_detail.setObjectName('role_detail') self.role4_detail.resize(self.xr * 606, self.yr * 87) self.role4_detail.move(self.xr * 110, self.yr * 0) self.role4_special.setObjectName('role_special') self.role4_special.resize(self.xr * 88, self.yr * 36) self.role4_special.move(self.xr * 10, self.yr * 26) self.role4_special.setAlignment(Qt.AlignCenter) for i in range(1, 14): if i >= 9: xp = 416 t = 9 elif i >= 4: xp = 239 t = 4 else: xp = 108 t = 1 if i == 3 or i == 8 or i == 13: exec('self.role1_lv{}=QLabel(self.role1_detail)'.format(i)) exec('self.role1_lv{}.resize(self.xr*46,self.yr*67)'.format(i)) exec( 'self.role1_lv{}.move(self.xr*(xp+({}-t)*20)+95,self.yr*10)' .format(i, i)) exec('self.role1_lv{}.setStyleSheet("font-size:{}px;")'.format( i, int(self.zr * 17))) exec('self.role1_lv{}.setAlignment(Qt.AlignCenter)'.format(i)) exec('self.role2_lv{}=QLabel(self.role2_detail)'.format(i)) exec('self.role2_lv{}.resize(self.xr*46,self.yr*67)'.format(i)) exec( 'self.role2_lv{}.move(self.xr*(xp+({}-t)*20)+95,self.yr*10)' .format(i, i)) exec('self.role2_lv{}.setStyleSheet("font-size:{}px;")'.format( i, int(self.zr * 17))) exec('self.role2_lv{}.setAlignment(Qt.AlignCenter)'.format(i)) exec('self.role3_lv{}=QLabel(self.role3_detail)'.format(i)) exec('self.role3_lv{}.resize(self.xr*46,self.yr*67)'.format(i)) exec( 'self.role3_lv{}.move(self.xr*(xp+({}-t)*20)+95,self.yr*10)' .format(i, i)) exec('self.role3_lv{}.setStyleSheet("font-size:{}px;")'.format( i, int(self.zr * 17))) exec('self.role3_lv{}.setAlignment(Qt.AlignCenter)'.format(i)) exec('self.role4_lv{}=QLabel(self.role4_detail)'.format(i)) exec('self.role4_lv{}.resize(self.xr*46,self.yr*67)'.format(i)) exec( 'self.role4_lv{}.move(self.xr*(xp+({}-t)*20)+95,self.yr*10)' .format(i, i)) exec('self.role4_lv{}.setStyleSheet("font-size:{}px;")'.format( i, int(self.zr * 17))) exec('self.role4_lv{}.setAlignment(Qt.AlignCenter)'.format(i)) exec('self.role1_card{}=QLabel(self.role1_detail)'.format(i)) exec('self.role1_card{}.setObjectName("card")'.format(i)) exec('self.role1_card{}.resize(self.xr*46,self.yr*67)'.format(i)) exec('self.role1_card{}.move(self.xr*(xp+({}-t)*20),self.yr*10)'. format(i, i)) exec('self.role1_card{}.setScaledContents(True)'.format(i)) exec('self.role2_card{}=QLabel(self.role2_detail)'.format(i)) exec('self.role2_card{}.setObjectName("card")'.format(i)) exec('self.role2_card{}.resize(self.xr*46,self.yr*67)'.format(i)) exec('self.role2_card{}.move(self.xr*(xp+({}-t)*20),self.yr*10)'. format(i, i)) exec('self.role2_card{}.setScaledContents(True)'.format(i)) exec('self.role3_card{}=QLabel(self.role3_detail)'.format(i)) exec('self.role3_card{}.setObjectName("card")'.format(i)) exec('self.role3_card{}.resize(self.xr*46,self.yr*67)'.format(i)) exec('self.role3_card{}.move(self.xr*(xp+({}-t)*20),self.yr*10)'. format(i, i)) exec('self.role3_card{}.setScaledContents(True)'.format(i)) exec('self.role4_card{}=QLabel(self.role4_detail)'.format(i)) exec('self.role4_card{}.setObjectName("card")'.format(i)) exec('self.role4_card{}.resize(self.xr*46,self.yr*67)'.format(i)) exec('self.role4_card{}.move(self.xr*(xp+({}-t)*20),self.yr*10)'. format(i, i)) exec('self.role4_card{}.setScaledContents(True)'.format(i)) self.back1_wi.setStyleSheet('#back{border-radius:' + str(self.zr * 25) + 'px;}#role{border-radius:' + str(self.zr * 18) + 'px;}#role_head{border-radius:' + str(self.zr * 15) + 'px;font-size:' + str(int(self.zr * 20)) + 'px;}#role_special{font-size:' + str(int(self.zr * 18)) + 'px;}') def result_exit(self): self.result_exit_sg.emit() def set_role(self, info): i = 1 # print(info) for role in info: exec('self.role{}_head.setText("{}")'.format(i, role['name'])) exec('self.role{}_special.setText("{}")'.format( i, str(role['score']) + '分')) # t = 3 j = 1 for de in role['cards']: # exec('self.role{}_lv{}.setText("{}")'.format(i, t, de['lv'])) for card in de["card"]: exec( 'self.role{}_card{}.setPixmap(QPixmap("./resource/image/{}.jpg"))' .format(i, j, card)) j += 1 # t += 5 i += 1
def setup_ui(self): self.setWindowIcon(QIcon(I('modified.png'))) self.l = l = QVBoxLayout(self) self.stack = s = QStackedLayout() l.addLayout(s), l.addWidget(self.bb) self.listc = c = QWidget(self) s.addWidget(c) c.l = l = QVBoxLayout(c) c.h = h = QHBoxLayout() l.addLayout(h) self.search_bar = sb = QLineEdit(self) sb.setPlaceholderText(_('Search for a snippet')) h.addWidget(sb) self.next_button = b = QPushButton(_('&Next')) b.clicked.connect(self.find_next) h.addWidget(b) c.h2 = h = QHBoxLayout() l.addLayout(h) self.snip_list = sl = QListWidget(self) sl.doubleClicked.connect(self.edit_snippet) h.addWidget(sl) c.l2 = l = QVBoxLayout() h.addLayout(l) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('plus.png'))), b.setText( _('&Add snippet')), b.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.add_snippet) l.addWidget(b) self.edit_button = b = QToolButton(self) b.setIcon(QIcon(I('modified.png'))), b.setText( _('&Edit snippet')), b.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.edit_snippet) l.addWidget(b) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('minus.png'))), b.setText( _('&Remove snippet')), b.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.remove_snippet) l.addWidget(b) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('config.png'))), b.setText( _('Change &built-in')), b.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.change_builtin) l.addWidget(b) for i, snip in enumerate( sorted(user_snippets.get('snippets', []), key=itemgetter('trigger'))): item = self.snip_to_item(snip) if i == 0: self.snip_list.setCurrentItem(item) self.edit_snip = es = EditSnippet(self) self.stack.addWidget(es)
def button(icon, text, tt, target): b = QPushButton(QIcon(I(icon)), text, self) b.setToolTip(tt) b.setFocusPolicy(Qt.FocusPolicy.NoFocus) b.clicked.connect(target) return b
def __init__(self, plugin_action): QWidget.__init__(self) self.plugin_action = plugin_action layout = QVBoxLayout(self) self.setLayout(layout) # --- Directory Options --- directory_group_box = QGroupBox(_('Default Unpack Directory:'), self) layout.addWidget(directory_group_box) directory_group_box_layout = QVBoxLayout() directory_group_box.setLayout(directory_group_box_layout) # Directory path Textbox # Load the textbox with the current preference setting self.directory_txtBox = QLineEdit(plugin_prefs['Unpack_Folder'], self) self.directory_txtBox.setToolTip( _('<p>Default directory to extract files to')) directory_group_box_layout.addWidget(self.directory_txtBox) self.directory_txtBox.setReadOnly(True) # Folder select button directory_button = QPushButton(_('Select/Change Unpack Directory'), self) directory_button.setToolTip( _('<p>Select/Change directory to extract files to.')) # Connect button to the getDirectory function directory_button.clicked.connect(self.getDirectory) directory_group_box_layout.addWidget(directory_button) self.default_folder_check = QCheckBox( _('Always use the Default Unpack Directory'), self) self.default_folder_check.setToolTip( _('<p>When unchecked... you will be prompted to select a destination ' + 'directory for the extracted content each time you use Mobiunpack.' )) directory_group_box_layout.addWidget(self.default_folder_check) # Load the checkbox with the current preference setting self.default_folder_check.setChecked( plugin_prefs['Always_Use_Unpack_Folder']) misc_group_box = QGroupBox(_('Default settings:'), self) layout.addWidget(misc_group_box) misc_group_box_layout = QVBoxLayout() misc_group_box.setLayout(misc_group_box_layout) self.use_hd_images = QCheckBox(_('Always use HD images if present'), self) self.use_hd_images.setToolTip( _('<p>When checked... any HD images present in the kindlebook ' + 'will be used for creating the ePub.')) misc_group_box_layout.addWidget(self.use_hd_images) # Load the checkbox with the current preference setting self.use_hd_images.setChecked(plugin_prefs['Use_HD_Images']) combo_label = QLabel(_('Select epub version output:'), self) misc_group_box_layout.addWidget(combo_label) self.epub_version_combobox = QComboBox() self.epub_version_combobox.setToolTip( _('<p>Select the type of OPF file to create.')) misc_group_box_layout.addWidget(self.epub_version_combobox) self.epub_version_combobox.addItems( [_('Auto-detect'), _('ePub2'), _('ePub3')]) if plugin_prefs['Epub_Version'] == 'A': self.epub_version_combobox.setCurrentIndex(0) else: self.epub_version_combobox.setCurrentIndex( int(plugin_prefs['Epub_Version']) - 1) # --- ZIP mod Options --- zip_mod_group_box = QGroupBox(_('ZIP mod settings:'), self) layout.addWidget(zip_mod_group_box) zip_mod_group_box_layout = QVBoxLayout() zip_mod_group_box.setLayout(zip_mod_group_box_layout) zip_mod_combo_label = QLabel(_('Select zip compress type:'), self) zip_mod_group_box_layout.addWidget(zip_mod_combo_label) self.zip_compress_type_combobox = QComboBox() self.zip_compress_type_combobox.setToolTip( _('<p>Select the type of zip compress.')) zip_mod_group_box_layout.addWidget(self.zip_compress_type_combobox) self.zip_compress_type_combobox.addItems([_('STORE'), _('DEFLATE')]) if plugin_prefs['Zip_Compress_Type'] == 'S': self.zip_compress_type_combobox.setCurrentIndex(0) else: self.zip_compress_type_combobox.setCurrentIndex(1) # Directory path Textbox # Load the textbox with the current preference setting kindle_directory_label = QLabel(_('Kindle Content Directory:'), self) zip_mod_group_box_layout.addWidget(kindle_directory_label) self.kindle_directory_txtBox = QLineEdit( plugin_prefs['Kindle_Content_Folder'], self) self.kindle_directory_txtBox.setToolTip( _('<p>Kindle Content directory.')) zip_mod_group_box_layout.addWidget(self.kindle_directory_txtBox) self.kindle_directory_txtBox.setReadOnly(True) # Folder select button kindle_directory_button = QPushButton( _('Select/Change Kindle Content Directory'), self) kindle_directory_button.setToolTip( _('<p>Select/Change Kindle Content directory.')) # Connect button to the getDirectory function kindle_directory_button.clicked.connect(self.getDirectoryKindleContent) zip_mod_group_box_layout.addWidget(kindle_directory_button) self.delete_temp_files = QCheckBox(_('Always delete temporary files'), self) self.delete_temp_files.setToolTip( _('<p>When checked... Delete temporary files at end of unpack.')) zip_mod_group_box_layout.addWidget(self.delete_temp_files) # Load the checkbox with the current preference setting self.delete_temp_files.setChecked( plugin_prefs['Always_Delete_Temp_Files'])
def __init__(self, parent, view, row, link_delegate): QDialog.__init__(self, parent) self.normal_brush = QBrush(Qt.white) self.marked_brush = QBrush(Qt.lightGray) self.marked = None self.gui = parent self.splitter = QSplitter(self) self._l = l = QVBoxLayout(self) self.setLayout(l) l.addWidget(self.splitter) self.cover = Cover(self, show_size=gprefs['bd_overlay_cover_size']) self.cover.resizeEvent = self.cover_view_resized self.cover.cover_changed.connect(self.cover_changed) self.cover.open_with_requested.connect(self.open_with) self.cover.choose_open_with_requested.connect(self.choose_open_with) self.cover_pixmap = None self.cover.sizeHint = self.details_size_hint self.splitter.addWidget(self.cover) self.details = Details(parent.book_details.book_info, self) self.details.anchor_clicked.connect(self.on_link_clicked) self.link_delegate = link_delegate self.details.setAttribute(Qt.WA_OpaquePaintEvent, False) palette = self.details.palette() self.details.setAcceptDrops(False) palette.setBrush(QPalette.Base, Qt.transparent) self.details.setPalette(palette) self.c = QWidget(self) self.c.l = l2 = QGridLayout(self.c) l2.setContentsMargins(0, 0, 0, 0) self.c.setLayout(l2) l2.addWidget(self.details, 0, 0, 1, -1) self.splitter.addWidget(self.c) self.fit_cover = QCheckBox(_('Fit &cover within view'), self) self.fit_cover.setChecked( gprefs.get('book_info_dialog_fit_cover', True)) self.hl = hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) l2.addLayout(hl, l2.rowCount(), 0, 1, -1) hl.addWidget(self.fit_cover), hl.addStretch() self.clabel = QLabel( '<div style="text-align: right"><a href="calibre:conf" title="{}" style="text-decoration: none">{}</a>' .format(_('Configure this view'), _('Configure'))) self.clabel.linkActivated.connect(self.configure) hl.addWidget(self.clabel) self.previous_button = QPushButton(QIcon(I('previous.png')), _('&Previous'), self) self.previous_button.clicked.connect(self.previous) l2.addWidget(self.previous_button, l2.rowCount(), 0) self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self) self.next_button.clicked.connect(self.next) l2.addWidget(self.next_button, l2.rowCount() - 1, 1) self.view = view self.path_to_book = None self.current_row = None self.refresh(row) self.view.model().new_bookdisplay_data.connect(self.slave) self.fit_cover.stateChanged.connect(self.toggle_cover_fit) self.ns = QShortcut(QKeySequence('Alt+Right'), self) self.ns.activated.connect(self.next) self.ps = QShortcut(QKeySequence('Alt+Left'), self) self.ps.activated.connect(self.previous) self.next_button.setToolTip( _('Next [%s]') % unicode_type(self.ns.key().toString(QKeySequence.NativeText))) self.previous_button.setToolTip( _('Previous [%s]') % unicode_type(self.ps.key().toString(QKeySequence.NativeText))) geom = QCoreApplication.instance().desktop().availableGeometry(self) screen_height = geom.height() - 100 screen_width = geom.width() - 100 self.resize(max(int(screen_width / 2), 700), screen_height) saved_layout = gprefs.get('book_info_dialog_layout', None) if saved_layout is not None: try: QApplication.instance().safe_restore_geometry( self, saved_layout[0]) self.splitter.restoreState(saved_layout[1]) except Exception: pass from calibre.gui2.ui import get_gui ema = get_gui().iactions['Edit Metadata'].menuless_qaction a = self.ema = QAction('edit metadata', self) a.setShortcut(ema.shortcut()) self.addAction(a) a.triggered.connect(self.edit_metadata)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout(self) self.la = la = QLabel( _( 'calibre contains an internet server that allows you to' ' access your book collection using a browser from anywhere' ' in the world. Any changes to the settings will only take' ' effect after a server restart.' ) ) la.setWordWrap(True) l.addWidget(la) l.addSpacing(10) self.fl = fl = QFormLayout() l.addLayout(fl) self.opt_port = sb = QSpinBox(self) if options['port'].longdoc: sb.setToolTip(options['port'].longdoc) sb.setRange(1, 65535) sb.valueChanged.connect(self.changed_signal.emit) fl.addRow(options['port'].shortdoc + ':', sb) l.addSpacing(25) self.opt_auth = cb = QCheckBox( _('Require &username and password to access the content server') ) l.addWidget(cb) self.auth_desc = la = QLabel(self) la.setStyleSheet('QLabel { font-size: small; font-style: italic }') la.setWordWrap(True) l.addWidget(la) l.addSpacing(25) self.opt_autolaunch_server = al = QCheckBox( _('Run server &automatically when calibre starts') ) l.addWidget(al) l.addSpacing(25) self.h = h = QHBoxLayout() l.addLayout(h) for text, name in [(_('&Start server'), 'start_server'), (_('St&op server'), 'stop_server'), (_('&Test server'), 'test_server'), (_('Show server &logs'), 'show_logs')]: b = QPushButton(text) b.clicked.connect(getattr(self, name).emit) setattr(self, name + '_button', b) if name == 'show_logs': h.addStretch(10) h.addWidget(b) self.ip_info = QLabel(self) self.update_ip_info() from calibre.gui2.ui import get_gui gui = get_gui() if gui is not None: gui.iactions['Connect Share'].share_conn_menu.server_state_changed_signal.connect(self.update_ip_info) l.addSpacing(10) l.addWidget(self.ip_info) if set_run_at_startup is not None: self.run_at_start_button = b = QPushButton('', self) self.set_run_at_start_text() b.clicked.connect(self.toggle_run_at_startup) l.addSpacing(10) l.addWidget(b) l.addSpacing(10) l.addStretch(10)
class UserDefinedDevice(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self._layout = QVBoxLayout(self) self.setLayout(self._layout) self.log = QPlainTextEdit(self) self._layout.addWidget(self.log) self.log.setPlainText(_('Getting device information')+'...') self.copy = QPushButton(_('Copy to &clipboard')) self.copy.setDefault(True) self.setWindowTitle(_('User-defined device information')) self.setWindowIcon(QIcon(I('debug.png'))) self.copy.clicked.connect(self.copy_to_clipboard) self.ok = QPushButton('&OK') self.ok.setAutoDefault(False) self.ok.clicked.connect(self.accept) self.bbox = QDialogButtonBox(self) self.bbox.addButton(self.copy, QDialogButtonBox.ActionRole) self.bbox.addButton(self.ok, QDialogButtonBox.AcceptRole) self._layout.addWidget(self.bbox) self.resize(750, 500) self.bbox.setEnabled(False) QTimer.singleShot(1000, self.device_info) def device_info(self): try: from calibre.devices import device_info r = step_dialog(self.parent(), _('Device Detection'), _('Ensure your device is disconnected, then press OK')) if r: self.close() return before = device_info() r = step_dialog(self.parent(), _('Device Detection'), _('Ensure your device is connected, then press OK')) if r: self.close() return after = device_info() new_devices = after['device_set'] - before['device_set'] res = '' if len(new_devices) == 1: def fmtid(x): x = x or 0 if isinstance(x, numbers.Integral): x = hex(x) if not x.startswith('0x'): x = '0x' + x return x for d in new_devices: res = _('USB Vendor ID (in hex)') + ': ' + \ fmtid(after['device_details'][d][0]) + '\n' res += _('USB Product ID (in hex)') + ': ' + \ fmtid(after['device_details'][d][1]) + '\n' res += _('USB Revision ID (in hex)') + ': ' + \ fmtid(after['device_details'][d][2]) + '\n' trailer = _( 'Copy these values to the clipboard, paste them into an ' 'editor, then enter them into the USER_DEVICE by ' 'customizing the device plugin in Preferences->Advanced->Plugins. ' 'Remember to also enter the folders where you want the books to ' 'be put. You must restart calibre for your changes ' 'to take effect.\n') self.log.setPlainText(res + '\n\n' + trailer) finally: self.bbox.setEnabled(True) def copy_to_clipboard(self): QApplication.clipboard().setText(self.log.toPlainText())
class CharacterDialog(WindowModalDialog): def __init__(self, parent): super(CharacterDialog, self).__init__(parent) self.setWindowTitle(_("KeepKey Seed Recovery")) self.character_pos = 0 self.word_pos = 0 self.loop = QEventLoop() self.word_help = QLabel() self.char_buttons = [] vbox = QVBoxLayout(self) vbox.addWidget(WWLabel(CHARACTER_RECOVERY)) hbox = QHBoxLayout() hbox.addWidget(self.word_help) for i in range(4): char_button = CharacterButton('*') char_button.setMaximumWidth(36) self.char_buttons.append(char_button) hbox.addWidget(char_button) self.accept_button = CharacterButton(_("Accept Word")) self.accept_button.clicked.connect(partial(self.process_key, 32)) self.rejected.connect(partial(self.loop.exit, 1)) hbox.addWidget(self.accept_button) hbox.addStretch(1) vbox.addLayout(hbox) self.finished_button = QPushButton(_("Seed Entered")) self.cancel_button = QPushButton(_("Cancel")) self.finished_button.clicked.connect(partial(self.process_key, Qt.Key_Return)) self.cancel_button.clicked.connect(self.rejected) buttons = Buttons(self.finished_button, self.cancel_button) vbox.addSpacing(40) vbox.addLayout(buttons) self.refresh() self.show() def refresh(self): self.word_help.setText("Enter seed word %2d:" % (self.word_pos + 1)) self.accept_button.setEnabled(self.character_pos >= 3) self.finished_button.setEnabled((self.word_pos in (11, 17, 23) and self.character_pos >= 3)) for n, button in enumerate(self.char_buttons): button.setEnabled(n == self.character_pos) if n == self.character_pos: button.setFocus() def is_valid_alpha_space(self, key): # Auto-completion requires at least 3 characters if key == ord(' ') and self.character_pos >= 3: return True # Firmware aborts protocol if the 5th character is non-space if self.character_pos >= 4: return False return (key >= ord('a') and key <= ord('z') or (key >= ord('A') and key <= ord('Z'))) def process_key(self, key): self.data = None if key == Qt.Key_Return and self.finished_button.isEnabled(): self.data = {'done': True} elif key == Qt.Key_Backspace and (self.word_pos or self.character_pos): self.data = {'delete': True} elif self.is_valid_alpha_space(key): self.data = {'character': chr(key).lower()} if self.data: self.loop.exit(0) def keyPressEvent(self, event): self.process_key(event.key()) if not self.data: QDialog.keyPressEvent(self, event) def get_char(self, word_pos, character_pos): self.word_pos = word_pos self.character_pos = character_pos self.refresh() if self.loop.exec_(): self.data = None # User cancelled
def genesis(self, gui): self.gui = gui if not ismacos and not iswindows: self.label_widget_style.setVisible(False) self.opt_ui_style.setVisible(False) db = gui.library_view.model().db r = self.register try: self.icon_theme_title = json.loads(I('icon-theme.json', data=True))['name'] except Exception: self.icon_theme_title = _('Default icons') self.icon_theme.setText( _('Icon theme: <b>%s</b>') % self.icon_theme_title) self.commit_icon_theme = None self.icon_theme_button.clicked.connect(self.choose_icon_theme) self.default_author_link = DefaultAuthorLink( self.default_author_link_container) self.default_author_link.changed_signal.connect(self.changed_signal) r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('hidpi', gprefs, restart_required=True, choices=[(_('Automatic'), 'auto'), (_('On'), 'on'), (_('Off'), 'off')]) if ismacos: self.opt_hidpi.setVisible(False), self.label_hidpi.setVisible( False) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('dnd_merge', gprefs) r('wrap_toolbar_text', gprefs, restart_required=True) r('show_layout_buttons', gprefs, restart_required=True) r('row_numbers_in_book_list', gprefs) r('tag_browser_old_look', gprefs) r('tag_browser_hide_empty_categories', gprefs) r('tag_browser_always_autocollapse', gprefs) r('tag_browser_show_tooltips', gprefs) r('tag_browser_allow_keyboard_focus', gprefs) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('tag_browser_show_counts', gprefs) r('tag_browser_item_padding', gprefs) r('qv_respects_vls', gprefs) r('qv_dclick_changes_column', gprefs) r('qv_retkey_changes_column', gprefs) r('qv_follows_column', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('cover_browser_title_template', db.prefs) fm = db.field_metadata r('cover_browser_subtitle_field', db.prefs, choices=[(_('No subtitle'), 'none')] + sorted( (fm[k].get('name'), k) for k in fm.all_field_keys() if fm[k].get('name'))) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) r('booklist_grid', gprefs) r('book_details_comments_heading_pos', gprefs, choices=[(_('Never'), 'hide'), (_('Above text'), 'above'), (_('Beside text'), 'side')]) self.cover_browser_title_template_button.clicked.connect( self.edit_cb_title_template) self.id_links_button.clicked.connect(self.edit_id_link_rules) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(key=lambda x: x[1].lower()) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('tags_browser_collapse_fl_at', gprefs) choices = { k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) } choices |= {'search'} r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList, choices=sorted(choices, key=sort_key)) choices -= {'authors', 'publisher', 'formats', 'news', 'identifiers'} self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(choices, key=sort_key)) fm = db.field_metadata choices = sorted( ((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x: sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) connect_lambda( self.df_up_button.clicked, self, lambda self: move_field_up( self.field_display_order, self.display_model)) connect_lambda( self.df_down_button.clicked, self, lambda self: move_field_down( self.field_display_order, self.display_model)) self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_order) self.qv_display_model.dataChanged.connect(self.changed_signal) self.qv_display_order.setModel(self.qv_display_model) connect_lambda( self.qv_up_button.clicked, self, lambda self: move_field_up( self.qv_display_order, self.qv_display_model)) connect_lambda( self.qv_down_button.clicked, self, lambda self: move_field_down( self.qv_display_order, self.qv_display_model)) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column &coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column &icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.SequenceFormat.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.SequenceFormat.PortableText) ] keys = [ unicode_type(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in keys ] self.fs_help_msg.setText( unicode_type(self.fs_help_msg.text()) % (_(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.ConnectionType.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton( _('Change &background image'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton( _('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) connect_lambda(self.cover_grid_smaller_cover.clicked, self, lambda self: self.resize_cover(True)) connect_lambda(self.cover_grid_larger_cover.clicked, self, lambda self: self.resize_cover(False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum( self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum( self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect( self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect( self.update_aspect_ratio) self.opt_book_details_css.textChanged.connect(self.changed_signal) from calibre.gui2.tweak_book.editor.text import get_highlighter, get_theme self.css_highlighter = get_highlighter('css')() self.css_highlighter.apply_theme(get_theme(None)) self.css_highlighter.set_document(self.opt_book_details_css.document())
def __init__(self, text=None): QPushButton.__init__(self, text)
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 __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)