def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext = u"", wineprefix = None): QDialog.__init__(self,parent) self.parent = parent self.key_type_name = key_type_name self.plugin_keys = plugin_keys self.create_key = create_key self.keyfile_ext = keyfile_ext self.import_key = (keyfile_ext != u"") self.binary_file = (keyfile_ext == u"der") self.json_file = (keyfile_ext == u"k4i") self.android_file = (keyfile_ext == u"k4a") self.wineprefix = wineprefix self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name)) # Start Qt Gui dialog layout 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/">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) keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self) layout.addWidget(keys_group_box) keys_group_box_layout = QHBoxLayout() keys_group_box.setLayout(keys_group_box_layout) self.listy = QListWidget(self) self.listy.setToolTip(u"{0}s that will be used to decrypt ebooks".format(self.key_type_name)) self.listy.setSelectionMode(QAbstractItemView.SingleSelection) self.populate_list() keys_group_box_layout.addWidget(self.listy) button_layout = QVBoxLayout() keys_group_box_layout.addLayout(button_layout) self._add_key_button = QtGui.QToolButton(self) self._add_key_button.setIcon(QIcon(I('plus.png'))) self._add_key_button.setToolTip(u"Create new {0}".format(self.key_type_name)) self._add_key_button.clicked.connect(self.add_key) button_layout.addWidget(self._add_key_button) self._delete_key_button = QtGui.QToolButton(self) self._delete_key_button.setToolTip(_(u"Delete highlighted key")) self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) self._delete_key_button.clicked.connect(self.delete_key) button_layout.addWidget(self._delete_key_button) if type(self.plugin_keys) == dict and self.import_key: self._rename_key_button = QtGui.QToolButton(self) self._rename_key_button.setToolTip(_(u"Rename highlighted key")) self._rename_key_button.setIcon(QIcon(I('edit-select-all.png'))) self._rename_key_button.clicked.connect(self.rename_key) button_layout.addWidget(self._rename_key_button) self.export_key_button = QtGui.QToolButton(self) self.export_key_button.setToolTip(u"Save highlighted key to a .{0} file".format(self.keyfile_ext)) self.export_key_button.setIcon(QIcon(I('save.png'))) self.export_key_button.clicked.connect(self.export_key) button_layout.addWidget(self.export_key_button) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) if self.wineprefix is not None: layout.addSpacing(5) wineprefix_layout = QHBoxLayout() layout.addLayout(wineprefix_layout) wineprefix_layout.setAlignment(Qt.AlignCenter) self.wp_label = QLabel(u"WINEPREFIX:") wineprefix_layout.addWidget(self.wp_label) self.wp_lineedit = QLineEdit(self) wineprefix_layout.addWidget(self.wp_lineedit) self.wp_label.setBuddy(self.wp_lineedit) self.wp_lineedit.setText(self.wineprefix) layout.addSpacing(5) migrate_layout = QHBoxLayout() layout.addLayout(migrate_layout) if self.import_key: migrate_layout.setAlignment(Qt.AlignJustify) self.migrate_btn = QPushButton(u"Import Existing Keyfiles", self) self.migrate_btn.setToolTip(u"Import *.{0} files (created using other tools).".format(self.keyfile_ext)) self.migrate_btn.clicked.connect(self.migrate_wrapper) migrate_layout.addWidget(self.migrate_btn) migrate_layout.addStretch() self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) migrate_layout.addWidget(self.button_box) self.resize(self.sizeHint())
def __init__(self, all_authors, parent): QListWidget.__init__(self, parent) self.setDragEnabled(True) self.setSelectionMode(self.ExtendedSelection) self.setDropIndicatorShown(True) self.setDragDropMode(self.InternalMove) self.setAlternatingRowColors(True) self.d = ItemDelegate(all_authors, self) self.d.edited.connect(self.edited, type=Qt.QueuedConnection) self.setItemDelegate(self.d)
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_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(False) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._apply_changes) button_box.rejected.connect(self.reject) self.clear_button = button_box.addButton('Clear', QDialogButtonBox.ResetRole) self.clear_button.setIcon(get_icon('trash.png')) self.clear_button.setToolTip('Clear all settings for this plugin') self.clear_button.clicked.connect(self._clear_settings) layout.addWidget(button_box)
def __init__(self, names, txt, parent=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout(self) self.setLayout(l) self.la = la = QLabel(_('Create a Virtual Library based on %s') % txt) l.addWidget(la) self._names = QListWidget(self) self._names.addItems(sorted(names, key=sort_key)) self._names.setSelectionMode(self._names.ExtendedSelection) l.addWidget(self._names) self._or = QRadioButton(_('Match any of the selected %s names')%txt) self._and = QRadioButton(_('Match all of the selected %s names')%txt) self._or.setChecked(True) l.addWidget(self._or) l.addWidget(self._and) self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) l.addWidget(self.bb) self.resize(self.sizeHint())
class ChoosePluginToolbarsDialog(QDialog): def __init__(self, parent, plugin, locations): QDialog.__init__(self, parent) self.locations = locations self.setWindowTitle( _('Add "%s" to toolbars or menus')%plugin.name) self._layout = QVBoxLayout(self) self.setLayout(self._layout) self._header_label = QLabel( _('Select the toolbars and/or menus to add <b>%s</b> to:') % plugin.name) self._layout.addWidget(self._header_label) self._locations_list = QListWidget(self) self._locations_list.setSelectionMode(QAbstractItemView.MultiSelection) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self._locations_list.setSizePolicy(sizePolicy) for key, text in locations: self._locations_list.addItem(text) if key in {'toolbar', 'toolbar-device'}: self._locations_list.item(self._locations_list.count()-1 ).setSelected(True) self._layout.addWidget(self._locations_list) self._footer_label = QLabel( _('You can also customise the plugin locations ' 'using <b>Preferences -> Customise the toolbar</b>')) self._layout.addWidget(self._footer_label) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) self._layout.addWidget(button_box) self.resize(self.sizeHint()) def selected_locations(self): selected = [] for row in self._locations_list.selectionModel().selectedRows(): selected.append(self.locations[row.row()]) return selected
def __init__(self, parent=None): super(ServicesQWidget, self).__init__(parent) # Fields self.services = None self.services_tree_widget = QTreeWidget() self.services_list_widget = QListWidget() self.service_data_widget = ServiceDataQWidget() self.services_dashboard = ServicesDashboardQWidget()
def __init__(self, parent=None): QListWidget.__init__(self, parent) self.setDragEnabled(True) self.setDragDropMode(self.InternalMove) self.setDefaultDropAction(Qt.MoveAction) self.setAlternatingRowColors(True) self.setStyleSheet('QListView::item { padding: 0.5ex }') self.viewport().setAcceptDrops(True) self.setDropIndicatorShown(True) self.setContextMenuPolicy(Qt.ActionsContextMenu) self.ac_edit = ac = QAction(QIcon(I('edit_input.png')), _('Edit this bookmark'), self) self.addAction(ac) self.ac_delete = ac = QAction(QIcon(I('trash.png')), _('Remove this bookmark'), self) self.addAction(ac) self.ac_sort = ac = QAction(_('Sort by name'), self) self.addAction(ac) self.ac_sort_pos = ac = QAction(_('Sort by position in book'), self) self.addAction(ac)
def change_builtin(self): d = QDialog(self) lw = QListWidget(d) for (trigger, syntaxes), snip in iteritems(builtin_snippets): snip = copy.deepcopy(snip) snip['trigger'], snip['syntaxes'] = trigger, syntaxes i = QListWidgetItem(self.snip_to_text(snip), lw) i.setData(Qt.UserRole, snip) d.l = l = QVBoxLayout(d) l.addWidget(QLabel(_('Choose the built-in snippet to modify:'))) l.addWidget(lw) lw.itemDoubleClicked.connect(d.accept) d.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) l.addWidget(bb) bb.accepted.connect(d.accept), bb.rejected.connect(d.reject) if d.exec_() == d.Accepted and lw.currentItem() is not None: self.stack.setCurrentIndex(1) self.edit_snip.apply_snip(lw.currentItem().data(Qt.UserRole), creating_snippet=True)
def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext = u""): QDialog.__init__(self,parent) self.parent = parent self.key_type_name = key_type_name self.plugin_keys = plugin_keys self.create_key = create_key self.keyfile_ext = keyfile_ext self.json_file = (keyfile_ext == u"k4i") self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name)) # Start Qt Gui dialog layout layout = QVBoxLayout(self) self.setLayout(layout) keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self) layout.addWidget(keys_group_box) keys_group_box_layout = QHBoxLayout() keys_group_box.setLayout(keys_group_box_layout) self.listy = QListWidget(self) self.listy.setToolTip(u"{0}s that will be used to decrypt ebooks".format(self.key_type_name)) self.listy.setSelectionMode(QAbstractItemView.SingleSelection) self.populate_list() keys_group_box_layout.addWidget(self.listy) button_layout = QVBoxLayout() keys_group_box_layout.addLayout(button_layout) self._add_key_button = QtGui.QToolButton(self) self._add_key_button.setIcon(QIcon(I('plus.png'))) self._add_key_button.setToolTip(u"Create new {0}".format(self.key_type_name)) self._add_key_button.clicked.connect(self.add_key) button_layout.addWidget(self._add_key_button) self._delete_key_button = QtGui.QToolButton(self) self._delete_key_button.setToolTip(_(u"Delete highlighted key")) self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) self._delete_key_button.clicked.connect(self.delete_key) button_layout.addWidget(self._delete_key_button) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) layout.addSpacing(5) migrate_layout = QHBoxLayout() layout.addLayout(migrate_layout) migrate_layout.addStretch() self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) migrate_layout.addWidget(self.button_box) self.resize(self.sizeHint())
def keyPressEvent(self, ev): if ev.key() in (Qt.Key_Enter, Qt.Key_Return): i = self.currentItem() if i is not None: self.bookmark_activated.emit(i) ev.accept() return if ev.key() in (Qt.Key_Delete, Qt.Key_Backspace): i = self.currentItem() if i is not None: self.ac_delete.trigger() ev.accept() return return QListWidget.keyPressEvent(self, ev)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout(self) self.la = la = QLabel(_('Fields to include in output:')) la.setWordWrap(True) l.addWidget(la) self.db_fields = QListWidget(self) l.addWidget(self.db_fields) self.la2 = la = QLabel(_('Drag and drop to re-arrange fields')) l.addWidget(la) self.db_fields.setDragEnabled(True) self.db_fields.setDragDropMode(QListWidget.InternalMove) self.db_fields.setDefaultDropAction(Qt.MoveAction) self.db_fields.setAlternatingRowColors(True) self.db_fields.setObjectName("db_fields")
class SelectNames(QDialog): # {{{ def __init__(self, names, txt, parent=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout(self) self.setLayout(l) self.la = la = QLabel(_('Create a Virtual Library based on %s') % txt) l.addWidget(la) self._names = QListWidget(self) self._names.addItems(sorted(names, key=sort_key)) self._names.setSelectionMode(self._names.ExtendedSelection) l.addWidget(self._names) self._or = QRadioButton(_('Match any of the selected %s names')%txt) self._and = QRadioButton(_('Match all of the selected %s names')%txt) self._or.setChecked(True) l.addWidget(self._or) l.addWidget(self._and) self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) l.addWidget(self.bb) self.resize(self.sizeHint()) @property def names(self): for item in self._names.selectedItems(): yield unicode(item.data(Qt.DisplayRole) or '') @property def match_type(self): return ' and ' if self._and.isChecked() else ' or '
def __init__(self, gui, icon, do_user_config): QDialog.__init__(self, gui) self.gui = gui self.do_user_config = do_user_config self.db = gui.current_db self.l = QVBoxLayout() self.setLayout(self.l) self.header = QLabel(prefs['searchinbookbrainz']) self.l.addWidget(self.header) self.img = QLabel() pixmap = QPixmap("images/BBt.svg") self.img.setPixmap(pixmap) self.l.addWidget(self.img) # QCol = QColor() # QCol.setRed(220) # QCol.setGreen(255) # QCol.setBlue(240) self.setWindowTitle('Calibre Book Brainz Integration') self.setWindowIcon(icon) self.search_space = QLineEdit() self.selected_button = QPushButton('Use title from selected book', self) self.selected_button.clicked.connect(self.exporttitlefromselected) self.l.addWidget(self.selected_button) self.search_space = QLineEdit() self.l.addWidget(self.search_space) self.listWidget = QListWidget() self.l.addWidget(self.listWidget) self.searchExecutionButton = QPushButton('Search', self) self.searchExecutionButton.clicked.connect(self.search) self.l.addWidget(self.searchExecutionButton) self.aboutButton = QPushButton('About', self) self.aboutButton.clicked.connect(self.about) self.l.addWidget(self.aboutButton) self.resize(400, 600) self.search_space.setFocus()
def setup_ui(self): from calibre.gui2.ui import get_gui db = get_gui().current_db self.l = l = QVBoxLayout(self) b = self.bb.addButton(_('&Add search'), self.bb.ActionRole) b.setIcon(QIcon(I('plus.png'))) b.clicked.connect(self.add_search) b = self.bb.addButton(_('&Remove search'), self.bb.ActionRole) b.setIcon(QIcon(I('minus.png'))) b.clicked.connect(self.del_search) b = self.bb.addButton(_('&Edit search'), self.bb.ActionRole) b.setIcon(QIcon(I('modified.png'))) b.clicked.connect(self.edit_search) self.slist = QListWidget(self) self.slist.setStyleSheet('QListView::item { padding: 3px }') self.slist.activated.connect(self.edit_search) self.slist.setAlternatingRowColors(True) self.searches = {name: db.saved_search_lookup(name) for name in db.saved_search_names()} self.populate_search_list() if self.initial_search is not None and self.initial_search in self.searches: self.select_search(self.initial_search) elif self.searches: self.slist.setCurrentRow(0) self.slist.currentItemChanged.connect(self.current_index_changed) l.addWidget(self.slist) self.desc = la = QLabel('\xa0') la.setWordWrap(True) l.addWidget(la) l.addWidget(self.bb) self.current_index_changed(self.slist.currentItem()) self.setMinimumHeight(500) self.setMinimumWidth(600)
def _init_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(True) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok) button_box.accepted.connect(self.accept) self.clear_button = button_box.addButton(_('Clear'), QDialogButtonBox.ResetRole) self.clear_button.setIcon(get_icon('trash.png')) self.clear_button.setToolTip(_('Clear all settings for this plugin')) self.clear_button.clicked.connect(self._clear_settings) if DEBUG: self.edit_button = button_box.addButton(_('Edit'), QDialogButtonBox.ResetRole) self.edit_button.setIcon(get_icon('edit_input.png')) self.edit_button.setToolTip(_('Edit settings.')) self.edit_button.clicked.connect(self._edit_settings) self.save_button = button_box.addButton(_('Save'), QDialogButtonBox.ResetRole) self.save_button.setIcon(get_icon('save.png')) self.save_button.setToolTip(_('Save setting for this plugin')) self.save_button.clicked.connect(self._save_settings) self.save_button.setEnabled(False) layout.addWidget(button_box)
def dropEvent(self, ev): QListWidget.dropEvent(self, ev) if ev.isAccepted(): self.changed.emit()
def addItems(self, *args): try: return QListWidget.addItems(self, *args) finally: self.mark_as_editable()
def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext=u""): QDialog.__init__(self, parent) self.parent = parent self.key_type_name = key_type_name self.plugin_keys = plugin_keys self.create_key = create_key self.keyfile_ext = keyfile_ext self.json_file = (keyfile_ext == u"k4i") self.setWindowTitle("{0} {1}: Manage {2}s".format( PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name)) # Start Qt Gui dialog layout layout = QVBoxLayout(self) self.setLayout(layout) keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self) layout.addWidget(keys_group_box) keys_group_box_layout = QHBoxLayout() keys_group_box.setLayout(keys_group_box_layout) self.listy = QListWidget(self) self.listy.setToolTip( u"{0}s that will be used to decrypt ebooks".format( self.key_type_name)) self.listy.setSelectionMode(QAbstractItemView.SingleSelection) self.populate_list() keys_group_box_layout.addWidget(self.listy) button_layout = QVBoxLayout() keys_group_box_layout.addLayout(button_layout) self._add_key_button = QtGui.QToolButton(self) self._add_key_button.setIcon(QIcon(I('plus.png'))) self._add_key_button.setToolTip(u"Create new {0}".format( self.key_type_name)) self._add_key_button.clicked.connect(self.add_key) button_layout.addWidget(self._add_key_button) self._delete_key_button = QtGui.QToolButton(self) self._delete_key_button.setToolTip(_(u"Delete highlighted key")) self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) self._delete_key_button.clicked.connect(self.delete_key) button_layout.addWidget(self._delete_key_button) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) layout.addSpacing(5) migrate_layout = QHBoxLayout() layout.addLayout(migrate_layout) migrate_layout.addStretch() self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) migrate_layout.addWidget(self.button_box) self.resize(self.sizeHint())
def __init__(self): super(EventsQWidget, self).__init__() self.setObjectName('events') # Fields self.events_list = QListWidget() self.timer = QTimer()
class ServicesQWidget(QWidget): """ Class wo create services QWidget """ def __init__(self, parent=None): super(ServicesQWidget, self).__init__(parent) # Fields self.services = None self.services_tree_widget = QTreeWidget() self.services_list_widget = QListWidget() self.service_data_widget = ServiceDataQWidget() self.services_dashboard = ServicesDashboardQWidget() def initialize(self): """ Initialize QWidget """ layout = QGridLayout() self.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) # Services dashboard self.services_dashboard.initialize() for state in self.services_dashboard.states_btns: self.services_dashboard.states_btns[state].clicked.connect( lambda _, s=state: self.filter_services(state=s)) layout.addWidget(self.services_dashboard, 0, 0, 1, 2) layout.addWidget(get_frame_separator(), 1, 0, 1, 2) # Services QTreeWidget self.services_tree_widget.setIconSize(QSize(32, 32)) self.services_tree_widget.setAlternatingRowColors(True) self.services_tree_widget.header().close() layout.addWidget(self.services_tree_widget, 2, 0, 1, 1) # Services QListWidget self.services_list_widget.clicked.connect(self.update_service_data) self.services_list_widget.hide() layout.addWidget(self.services_list_widget, 2, 0, 1, 1) # Service DataWidget self.service_data_widget.initialize() layout.addWidget(self.service_data_widget, 2, 1, 1, 1) def filter_services(self, state): """ Filter services with the wanted state :param state: state of service: OK, WARNING, NOT_MONITORED, DOWNTIME :return: """ # Clear QListWidget and update filter buttons of services dashboard self.services_list_widget.clear() for btn_state in self.services_dashboard.states_btns: if btn_state != state: self.services_dashboard.states_btns[btn_state].setChecked( False) # Update QWidgets if self.sender().isChecked(): self.set_filter_items(state) self.services_tree_widget.hide() self.services_list_widget.show() else: self.services_tree_widget.show() self.services_list_widget.hide() def set_filter_items(self, state): """ Add filter items to QListWidget corresponding to "state" :param state: state of service to filter :type state: str """ services_added = False if state in 'NOT_MONITORED': for service in self.services: if not service.data['active_checks_enabled'] and \ not service.data['passive_checks_enabled']and \ not service.data['ls_downtimed'] and \ not service.data['ls_acknowledged']: self.add_filter_item(service) services_added = True elif state in 'DOWNTIME': for service in self.services: if service.data['ls_downtimed']: self.add_filter_item(service) services_added = True elif state in 'ACKNOWLEDGE': for service in self.services: if service.data['ls_acknowledged']: self.add_filter_item(service) services_added = True else: for service in self.services: if service.data['ls_state'] in state: self.add_filter_item(service) services_added = True if not services_added: not_added_item = QListWidgetItem() not_added_item.setData(Qt.DecorationRole, QIcon(settings.get_image('services_ok'))) not_added_item.setData(Qt.DisplayRole, _('No such services to display...')) self.services_list_widget.addItem(not_added_item) def add_filter_item(self, filter_item): """ Add filter item to QListWidget :param filter_item: filter item (service) :type filter_item: alignak_app.items.service.Service """ item = QListWidgetItem() monitored = \ filter_item.data['passive_checks_enabled'] + filter_item.data['active_checks_enabled'] icon_name = get_icon_name(filter_item.item_type, filter_item.data['ls_state'], filter_item.data['ls_acknowledged'], filter_item.data['ls_downtimed'], monitored) item.setData(Qt.DecorationRole, QIcon(settings.get_image(icon_name))) item.setData(Qt.DisplayRole, filter_item.get_display_name()) item.setData(Qt.UserRole, filter_item.item_id) item.setToolTip(filter_item.get_tooltip()) self.services_list_widget.addItem(item) def update_widget(self, services): """ Update the QTreeWidget and its items :param services: list of :class:`Services <alignak_app.items.service.Service>` items :type services: list """ self.services = services # Update services dashboard self.services_dashboard.update_widget(self.services) # Clear QTreeWidget self.services_tree_widget.clear() self.services_tree_widget.setIconSize(QSize(16, 16)) if self.services: # Set as "Global" aggregation who are empty for service in self.services: if not service.data['aggregation']: service.data['aggregation'] = 'Global' # First sort list by state then by aggregation newlist = sorted(self.services, key=lambda s: itemgetter( 'ls_state', 'ls_acknowledged', 'aggregation') (s.data)) self.services = newlist # Get list of aggregations aggregations = [] for service in self.services: if service.data['aggregation'] not in aggregations: aggregations.append(service.data['aggregation']) # Add QTreeWidgetItems for aggregation in aggregations: main_tree = QTreeWidgetItem() main_tree.setText(0, aggregation) main_tree.setIcon(0, QIcon(settings.get_image('tree'))) main_tree.setToolTip(0, aggregation) for service in self.services: if service.data['aggregation'] == aggregation: service_tree = ServiceTreeItem() service_tree.initialize(service) service_tree.setToolTip(0, service.get_tooltip()) self.services_tree_widget.clicked.connect( self.update_service_data) main_tree.addChild(service_tree) self.services_tree_widget.addTopLevelItem(main_tree) self.service_data_widget.hide() else: # If no services, reset service item to None and hide data widget self.service_data_widget.service_item = None self.service_data_widget.hide() def update_service_data(self): # pragma: no cover """ Update ServiceDataqWidget """ service_item = self.sender().currentItem() if isinstance(service_item, (ServiceTreeItem, QListWidgetItem)): service = None # Get service if isinstance(service_item, ServiceTreeItem): service = data_manager.get_item('service', '_id', service_item.service_id) elif isinstance(service_item, QListWidgetItem): service = data_manager.get_item('service', '_id', service_item.data(Qt.UserRole)) if not service: service = self.service_data_widget.service_item # Update QWidgets self.services_tree_widget.setMaximumWidth(self.width() * 0.5) self.services_list_widget.setMaximumWidth(self.width() * 0.5) self.service_data_widget.setMaximumWidth(self.width() * 0.5) self.service_data_widget.update_widget(service) self.services_dashboard.update_widget(self.services) self.service_data_widget.show() # Update Service Items (ServiceTreeItem, QListWidgetItem) if isinstance(service_item, ServiceTreeItem): service_item.update_item() else: monitored = \ service.data['passive_checks_enabled'] + service.data['active_checks_enabled'] icon_name = get_icon_name('service', service.data['ls_state'], service.data['ls_acknowledged'], service.data['ls_downtimed'], monitored) service_item.setData(Qt.DecorationRole, QIcon(settings.get_image(icon_name))) service_item.setData(Qt.DisplayRole, service.get_display_name()) service_item.setToolTip(service.get_tooltip())
def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext = u"", wineprefix = None): QDialog.__init__(self,parent) self.parent = parent self.key_type_name = key_type_name self.plugin_keys = plugin_keys self.create_key = create_key self.keyfile_ext = keyfile_ext self.import_key = (keyfile_ext != u"") self.binary_file = (keyfile_ext == "der") self.json_file = (keyfile_ext == "k4i") self.android_file = (keyfile_ext == "k4a") self.wineprefix = wineprefix self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name)) # Start Qt Gui dialog layout 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/">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) keys_group_box = QGroupBox(_("{0}s".format(self.key_type_name)), self) layout.addWidget(keys_group_box) keys_group_box_layout = QHBoxLayout() keys_group_box.setLayout(keys_group_box_layout) self.listy = QListWidget(self) self.listy.setToolTip("{0}s that will be used to decrypt ebooks".format(self.key_type_name)) self.listy.setSelectionMode(QAbstractItemView.SingleSelection) self.populate_list() keys_group_box_layout.addWidget(self.listy) button_layout = QVBoxLayout() keys_group_box_layout.addLayout(button_layout) self._add_key_button = QtGui.QToolButton(self) self._add_key_button.setIcon(QIcon(I('plus.png'))) self._add_key_button.setToolTip("Create new {0}".format(self.key_type_name)) self._add_key_button.clicked.connect(self.add_key) button_layout.addWidget(self._add_key_button) self._delete_key_button = QtGui.QToolButton(self) self._delete_key_button.setToolTip(_("Delete highlighted key")) self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) self._delete_key_button.clicked.connect(self.delete_key) button_layout.addWidget(self._delete_key_button) if type(self.plugin_keys) == dict and self.import_key: self._rename_key_button = QtGui.QToolButton(self) self._rename_key_button.setToolTip(_("Rename highlighted key")) self._rename_key_button.setIcon(QIcon(I('edit-select-all.png'))) self._rename_key_button.clicked.connect(self.rename_key) button_layout.addWidget(self._rename_key_button) self.export_key_button = QtGui.QToolButton(self) self.export_key_button.setToolTip("Save highlighted key to a .{0} file".format(self.keyfile_ext)) self.export_key_button.setIcon(QIcon(I('save.png'))) self.export_key_button.clicked.connect(self.export_key) button_layout.addWidget(self.export_key_button) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) if self.wineprefix is not None: layout.addSpacing(5) wineprefix_layout = QHBoxLayout() layout.addLayout(wineprefix_layout) wineprefix_layout.setAlignment(Qt.AlignCenter) self.wp_label = QLabel("WINEPREFIX:") wineprefix_layout.addWidget(self.wp_label) self.wp_lineedit = QLineEdit(self) wineprefix_layout.addWidget(self.wp_lineedit) self.wp_label.setBuddy(self.wp_lineedit) self.wp_lineedit.setText(self.wineprefix) layout.addSpacing(5) migrate_layout = QHBoxLayout() layout.addLayout(migrate_layout) if self.import_key: migrate_layout.setAlignment(Qt.AlignJustify) self.migrate_btn = QPushButton("Import Existing Keyfiles", self) self.migrate_btn.setToolTip("Import *.{0} files (created using other tools).".format(self.keyfile_ext)) self.migrate_btn.clicked.connect(self.migrate_wrapper) migrate_layout.addWidget(self.migrate_btn) migrate_layout.addStretch() self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) migrate_layout.addWidget(self.button_box) self.resize(self.sizeHint())
class MoveBooksDialog(SizePersistedDialog): def __init__(self, parent, lists_in_use, list_names): SizePersistedDialog.__init__(self, parent, 'reading list plugin:move books dialog') self.setWindowTitle('Move Books') layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, 'images/reading_list.png', 'Move books between lists') layout.addLayout(title_layout) main_layout = QGridLayout() layout.addLayout(main_layout) self.remove_from_label = QLabel('Select list(s) to remove from', self) main_layout.addWidget(self.remove_from_label, 0, 0, 1, 2) self.remove_from_list = QListWidget(self) self.remove_from_list.setSelectionMode( QAbstractItemView.ExtendedSelection) main_layout.addWidget(self.remove_from_list, 1, 0, 1, 2) self.select_all_button = QPushButton('Select &All', self) self.select_all_button.clicked.connect(self.remove_from_list.selectAll) main_layout.addWidget(self.select_all_button, 2, 0, 1, 1) self.select_none_button = QPushButton('Select &None', self) self.select_none_button.clicked.connect( self.remove_from_list.clearSelection) main_layout.addWidget(self.select_none_button, 2, 1, 1, 1) self.dest_list_label = QLabel('Select list to add to', self) main_layout.addWidget(self.dest_list_label, 0, 2, 1, 1) self.dest_list = QListWidget(self) self.dest_list.setSelectionMode(QAbstractItemView.ExtendedSelection) main_layout.addWidget(self.dest_list, 1, 2, 1, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) layout.addWidget(button_box) # Cause our dialog size to be restored from prefs or created on first usage self.resize_dialog() self._populate_list(self.remove_from_list, lists_in_use) self._populate_list(self.dest_list, list_names, set_selected=False) self.dest_list.item(0).setSelected(True) def _populate_list(self, list_widget, list_names, set_selected=True): list_widget.clear() for list_name in list_names: item = QListWidgetItem(list_name, list_widget) list_widget.addItem(item) item.setSelected(set_selected) def select_no_items(self): for item in self.remove_from_list.items(): item.setSelected(False) def get_source_list_names(self): values = [] for item in self.remove_from_list.selectedItems(): values.append(unicode(item.text())) return values def get_dest_list_names(self): values = [] for item in self.dest_list.selectedItems(): values.append(unicode(item.text())) return values
class PrefsViewerDialog(SizePersistedDialog): def __init__(self, gui, namespace): SizePersistedDialog.__init__(self, gui, _('Prefs Viewer dialog')) self.setWindowTitle(_('Preferences for: ') + namespace) self.gui = gui self.db = gui.current_db self.namespace = namespace self._init_controls() self.resize_dialog() self._populate_settings() if self.keys_list.count(): self.keys_list.setCurrentRow(0) def _init_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(True) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok) button_box.accepted.connect(self.accept) self.clear_button = button_box.addButton(_('Clear'), QDialogButtonBox.ResetRole) self.clear_button.setIcon(get_icon('trash.png')) self.clear_button.setToolTip(_('Clear all settings for this plugin')) self.clear_button.clicked.connect(self._clear_settings) layout.addWidget(button_box) def _populate_settings(self): self.keys_list.clear() ns_prefix = self._get_ns_prefix() keys = sorted([ k[len(ns_prefix):] for k in self.db.prefs.iterkeys() if k.startswith(ns_prefix) ]) for key in keys: self.keys_list.addItem(key) self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0)) self.keys_list.currentRowChanged[int].connect( self._current_row_changed) def _current_row_changed(self, new_row): if new_row < 0: self.value_text.clear() return key = unicode(self.keys_list.currentItem().text()) val = self.db.prefs.get_namespaced(self.namespace, key, '') self.value_text.setPlainText(self.db.prefs.to_raw(val)) def _get_ns_prefix(self): return 'namespaced:%s:' % self.namespace def _clear_settings(self): from calibre.gui2.dialogs.confirm_delete import confirm message = '<p>' + _('Are you sure you want to clear your settings in this library for this plugin?') + '</p>' \ + '<p>' + _('Any settings in other libraries or stored in a JSON file in your calibre plugins folder will not be touched.') + '</p>' \ + '<p>' + _('You must restart calibre afterwards.') + '</p>' if not confirm(message, self.namespace + '_clear_settings', self): return ns_prefix = self._get_ns_prefix() keys = [k for k in self.db.prefs.iterkeys() if k.startswith(ns_prefix)] for k in keys: del self.db.prefs[k] self._populate_settings() d = info_dialog(self, 'Settings deleted', '<p>' + _('All settings for this plugin in this library have been cleared.') + '</p>' \ + '<p>' + _('Please restart calibre now.') + '</p>', show_copy_button=False) b = d.bb.addButton(_('Restart calibre now'), d.bb.AcceptRole) b.setIcon(QIcon(I('lt.png'))) d.do_restart = False def rf(): d.do_restart = True b.clicked.connect(rf) d.set_details('') d.exec_() b.clicked.disconnect() self.close() if d.do_restart: self.gui.quit(restart=True)
class UndoMenu(QMenu): """ Popup menu for UndoAction. [internal usage] """ triggered = pyqtSignal(int) """ Signal: emitted when 1 or more items is selected in menu. Arguments: selected (int): Number of selected items. """ def __init__(self, parent=None): """ Create menu object. `UndoMenu` class shows list of child items in the plain list, suitable for undo / redo operations. Items are inserted to menu with `setItems()` method. Methods `setMaxWidth()` and `setLength()` allow to limit the width (in pixels) and height (as a number of shown items) of menu. To customize summary label (shown in the bottom area of menu), use `setComment()` method. Top-most item can be obtained with `lastItem()` method. Arguments: parent (Optional[QWidget]): Parent widget. Defaults to None. """ QMenu.__init__(self, parent) v_layout = QVBoxLayout(self) v_layout.setContentsMargins(0, 0, 0, 0) frame = QFrame(self) frame.setFrameStyle(QFrame.Panel | QFrame.Plain) v_layout.addWidget(frame) v_layout = QVBoxLayout(frame) v_layout.setContentsMargins(0, 0, 0, 0) v_layout.setSpacing(1) self._list = QListWidget(frame) self._list.setFrameStyle(QListWidget.NoFrame) self._list.setSelectionMode(QListWidget.MultiSelection) self._list.setVerticalScrollMode(QListWidget.ScrollPerItem) self._list.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self._list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._list.setResizeMode(QListWidget.Adjust) self._list.setFocusPolicy(Qt.NoFocus) self._list.viewport().installEventFilter(self) self._list.installEventFilter(self) self._list.viewport().setMouseTracking(True) self._label = QLabel(frame) self._label.setAlignment(Qt.AlignCenter) v_layout.addWidget(self._list) v_layout.addWidget(HLine(frame)) v_layout.addWidget(self._label) self._comment = "%d" self._length = 10 self._max_width = 0 self._updateComment() def setItems(self, items): """ Assign items to the list. Arguments: items (list[str]): Items to be displayed in menu. """ self.clear() for item in items: self._list.addItem(item) def lastItem(self): """ Get topmost shown menu item. Returns: str: Topmost menu item's text. """ return self._list.item(0).text() if self._list.count() > 0 else "" def clear(self): """Clear menu.""" self._list.clear() def setMaxWidth(self, max_width): """ Set maximum width of the menu. Default value is 0 that means "auto". Arguments: max_width (int): Width of the menu. """ self._max_width = max_width def setLength(self, length): """ Set maximum height of the menu. Default value is 10 items. Arguments: length (int): Number of items to which menu height should be resized. """ self._length = length def setComment(self, comment): """ Set format of comment label. In the format template "%d" is automatically replaced by number of currently selected items. By default, format label is "%d". Arguments: comment (str): Comment label. """ self._comment = comment self._updateComment() font_metrics = self._label.fontMetrics() width_cancel = font_metrics.width(translate("UndoAction", "Cancel")) width_selected = font_metrics.width(comment + "0" * 3) self._label.setMinimumWidth(max(width_cancel, width_selected)) def sizeHint(self): """ Get size hint for the menu. Returns: QSize: Widget's size hint. """ hint = QMenu.sizeHint(self) if self._max_width > 0: hint.setWidth(self._max_width) if self._length > 0: height = self._length * (self._list.fontMetrics().height() + 2) height = height + self._label.sizeHint().height() hint.setHeight(height) return hint def minimumSizeHint(self): """ Get minimal size hint for the combo box. Returns: QSize: Widget's minimum size hint. """ return self.sizeHint() def setVisible(self, visible): """ Called when list widget is shown/hidden. Arguments: visible (bool): True if widget is being shown, False otherwise. """ if visible: self._list.setFocus() self._list.scrollToItem(self._list.item(0), QListWidget.PositionAtTop) self._setSelected(0) QMenu.setVisible(self, visible) def keyPressEvent(self, event): """ Handle key press event. Arguments: event (QKeyEvent): Key press event. """ if event.type() == QEvent.KeyRelease: return event.accept() nb_selected = self._selected() nb_lines = self._length if self._length > 0 else 10 # pragma pylint: disable=too-many-branches if event.key() == Qt.Key_Up: self._setSelected(max(1, nb_selected - 1)) elif event.key() == Qt.Key_Down: self._setSelected(max(1, nb_selected + 1)) elif event.key() == Qt.Key_PageUp: self._setSelected(max(1, nb_selected - nb_lines)) elif event.key() == Qt.Key_PageDown: self._setSelected(max(1, nb_selected + nb_lines)) elif event.key() == Qt.Key_Home: self._setSelected(1) elif event.key() == Qt.Key_End: self._setSelected(self._list.count()) elif event.key() == Qt.Key_Return: self._accept() elif event.key() == Qt.Key_Escape: self.hide() def eventFilter(self, obj, event): """ Filter events if this object has been installed as an event filter for the watched object. Arguments: obj (QObject): Watched object. event (QEvent): Event being processed. Returns: bool: True if event should be filtered out (i.e. if further processing should be stopped); False otherwise. """ res = True if obj == self._list: if event.type() == QEvent.Leave: self._setSelected(0) res = False else: if event.type() == QEvent.MouseMove: if not self._list.viewport().rect().contains(event.pos()): self._setSelected(0) elif self._list.itemAt(event.pos()): row = self._list.row(self._list.itemAt(event.pos())) + 1 self._setSelected(row) elif event.type() == QEvent.MouseButtonRelease: self._accept() elif event.type() in [ QEvent.MouseButtonPress, QEvent.MouseButtonDblClick ]: pass else: res = False if res: return True else: return QMenu.eventFilter(self, obj, event) def _accept(self): """ Validate user's choice. Emits `triggered(int)` signal. """ nb_selected = self._selected() self.hide() if nb_selected > 0: self.triggered.emit(nb_selected) def _setSelected(self, count): """ Set selection. Arguments: count (int): Number of selected items. """ index = min(count, self._list.count()) selection = QItemSelection() selection_model = self._list.selectionModel() selection.select(selection_model.model().index(0, 0), selection_model.model().index(index - 1, 0)) selection_model.select(selection, QItemSelectionModel.ClearAndSelect) self._list.scrollToItem(self._list.item(index - 1)) self._list.clearFocus() self._updateComment() def _selected(self): """ Get number of selected items. Returns: int: Number of selected items. """ return len(self._list.selectedItems()) def _updateComment(self): """Update comment label.""" comment = translate("UndoAction", "Cancel") nb_selected = self._selected() if nb_selected > 0: comment = self._comment try: comment = comment % nb_selected except TypeError: pass self._label.setText(comment)
class EventsQWidget(QWidget): """ Class who create QWidget for events """ def __init__(self): super(EventsQWidget, self).__init__() self.setObjectName('events') # Fields self.events_list = QListWidget() self.timer = QTimer() def initialize(self): """ Intialize QWidget """ self.timer.setInterval(30000) self.timer.start() self.timer.timeout.connect(self.send_datamanager_events) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.events_list.setDragDropMode(QAbstractItemView.DragOnly) self.events_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.events_list.setDropIndicatorShown(True) self.events_list.doubleClicked.connect(self.remove_event) self.events_list.setWordWrap(True) self.events_list.setIconSize(QSize(16, 16)) self.add_event('OK', _('Welcome %s, you are connected to Alignak Backend') % data_manager.database['user'].name, timer=True) layout.addWidget(self.events_list) def send_datamanager_events(self): """ Add events stored in DataManager """ events = data_manager.get_events() if events: for event in events: self.add_event(event['event_type'], event['message'], timer=False, host=event['host']) def add_event(self, event_type, msg, timer=False, host=None): """ Add event to events list :param event_type: the type of event: OK, DOWN, ACK, ... :type event_type: str :param msg: message of event :type msg: str :param timer: timer to hide event at end of time :type timer: bool :param host: data of a host to set ``Qt.UserRole`` :type host: None | str """ if not self.event_exist(msg): logger.debug('Add Event: msg: %s, timer: %s, host: %s', msg, timer, host) event = EventItem() event.initialize(event_type, msg, timer=timer, host=host) self.events_list.insertItem(0, event) if timer: event_duration = int( settings.get_config('Alignak-app', 'notification_duration')) * 1000 QTimer.singleShot(event_duration, lambda: self.remove_timer_event(event)) else: logger.debug('Event with msg: %s already exist.', msg) def event_exist(self, msg): """ Check if event already displayed, move it to top and update tooltip. Only for EventItem who have a ``Qt.UserRole`` :param msg: message of event :type msg: str :return: if message exist or not in events QWidgetList :rtype: bool """ for i in range(0, self.events_list.count()): if self.events_list.item(i).data(Qt.DisplayRole) == msg: item = self.events_list.takeItem(i) msg_to_send = '%s. (Send at %s)' % (msg, get_current_time()) item.setToolTip(msg_to_send) self.events_list.insertItem(0, item) return True return False def remove_timer_event(self, event): """ Remove EventItem with timer :param event: EventItem with timer :type event: EventItem """ logger.debug('Remove Timer Event: %s', event.text()) self.events_list.takeItem(self.events_list.row(event)) def remove_event(self, item=None): """ Remove item when user double click on an item :param item: item to remove, else remove the current row :type item: EventItem """ if isinstance(item, EventItem): row = self.events_list.row(item) self.events_list.takeItem(row) else: item = self.events_list.takeItem(self.events_list.currentRow()) logger.debug('Remove Event: %s', item.text())
def __init__(self, gui, initial_panel=None): QDialog.__init__(self, gui) self.l = l = QGridLayout(self) self.setLayout(l) self.setWindowTitle(_('Preferences for Edit Book')) self.setWindowIcon(QIcon(I('config.png'))) self.stacks = QStackedWidget(self) l.addWidget(self.stacks, 0, 1, 1, 1) self.categories_list = cl = QListWidget(self) cl.currentRowChanged.connect(self.stacks.setCurrentIndex) cl.clearPropertyFlags() cl.setViewMode(cl.IconMode) cl.setFlow(cl.TopToBottom) cl.setMovement(cl.Static) cl.setWrapping(False) cl.setSpacing(15) cl.setWordWrap(True) l.addWidget(cl, 0, 0, 1, 1) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.rdb = b = bb.addButton(_('Restore all defaults'), bb.ResetRole) b.setToolTip(_('Restore defaults for all preferences')) b.clicked.connect(self.restore_all_defaults) self.rcdb = b = bb.addButton(_('Restore current defaults'), bb.ResetRole) b.setToolTip(_('Restore defaults for currently displayed preferences')) b.clicked.connect(self.restore_current_defaults) l.addWidget(bb, 1, 0, 1, 2) self.resize(800, 600) geom = tprefs.get('preferences_geom', None) if geom is not None: self.restoreGeometry(geom) self.keyboard_panel = ShortcutConfig(self) self.keyboard_panel.initialize(gui.keyboard) self.editor_panel = EditorSettings(self) self.integration_panel = IntegrationSettings(self) self.main_window_panel = MainWindowSettings(self) self.preview_panel = PreviewSettings(self) self.toolbars_panel = ToolbarSettings(self) for name, icon, panel in [ (_('Main window'), 'page.png', 'main_window'), (_('Editor settings'), 'modified.png', 'editor'), (_('Preview settings'), 'viewer.png', 'preview'), (_('Keyboard shortcuts'), 'keyboard-prefs.png', 'keyboard'), (_('Toolbars'), 'wizard.png', 'toolbars'), (_('Integration with calibre'), 'lt.png', 'integration'), ]: i = QListWidgetItem(QIcon(I(icon)), name, cl) cl.addItem(i) self.stacks.addWidget(getattr(self, panel + '_panel')) cl.setCurrentRow(0) cl.item(0).setSelected(True) w, h = cl.sizeHintForColumn(0), 0 for i in xrange(cl.count()): h = max(h, cl.sizeHintForRow(i)) cl.item(i).setSizeHint(QSize(w, h)) cl.setMaximumWidth(cl.sizeHintForColumn(0) + 35) cl.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
class SpyQWidget(QWidget): """ Class who create QWidget for spied hosts """ def __init__(self): super(SpyQWidget, self).__init__() self.host_services_lbl = QLabel(_('You are not spying on any hosts for now...')) self.spy_list_widget = SpyQListWidget() self.host_list_widget = QListWidget() self.spy_timer = QTimer() def initialize(self): """ Intialize Spy QWidget """ layout = QGridLayout() self.setLayout(layout) spy_icon = QLabel() spy_pixmap = QPixmap(settings.get_image('spy')) spy_icon.setPixmap(spy_pixmap) spy_icon.setScaledContents(True) spy_icon.setFixedSize(20, 20) layout.addWidget(spy_icon, 0, 0, 1, 1) layout.setAlignment(spy_icon, Qt.AlignRight) spy_title = QLabel(_('Spy Hosts')) spy_title.setObjectName('title') spy_title.setMinimumHeight(40) layout.addWidget(spy_title, 0, 1, 1, 1) hint_lbl = QLabel('Click to refresh, double-click to stop spying') hint_lbl.setObjectName('subtitle') layout.addWidget(hint_lbl, 1, 0, 1, 1) layout.setAlignment(hint_lbl, Qt.AlignCenter) self.host_services_lbl.setObjectName('subtitle') layout.addWidget(self.host_services_lbl, 1, 1, 1, 1) layout.setAlignment(self.host_services_lbl, Qt.AlignCenter) self.spy_list_widget.setDragDropMode(QAbstractItemView.DragDrop) self.spy_list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.spy_list_widget.doubleClicked.connect(self.remove_event) self.spy_list_widget.setAcceptDrops(True) self.spy_list_widget.setWordWrap(True) self.spy_list_widget.insertItem(0, self.get_hint_item()) self.spy_list_widget.item_dropped.connect(get_events_widget().remove_event) self.spy_list_widget.clicked.connect( lambda: self.manage_host_events(self.spy_list_widget.currentRow()) ) layout.addWidget(self.spy_list_widget, 2, 0, 1, 1) self.host_list_widget.setObjectName('spy') # self.host_list_widget.setMinimumWidth(500) layout.addWidget(self.host_list_widget, 2, 1, 1, 1) spy_interval = int(settings.get_config('Alignak-app', 'spy_interval')) * 1000 self.spy_timer.setInterval(spy_interval) self.spy_timer.start() self.spy_timer.timeout.connect(self.send_spy_events) @staticmethod def get_hint_item(): """ Return an EventItem with a hint text :return: event item with hint text :rtype: EventItem """ drop_hint_item = EventItem() drop_hint_item.setText(_('Drop host-related events here to spy on it...')) drop_hint_item.setIcon(QIcon(settings.get_image('spy'))) drop_hint_item.setFlags(Qt.ItemIsDropEnabled) return drop_hint_item def send_spy_events(self): """ Send event messages for all hosts who are spied """ if self.spy_list_widget.spied_hosts: for host_id in self.spy_list_widget.spied_hosts: host = data_manager.get_item('host', host_id) get_events_widget().add_event( EventItem.get_event_type(host.data), _('Host %s, current state: %s') % ( host.get_display_name(), host.data['ls_state']), host=host.item_id ) def manage_host_events(self, row): """ Manage spy events for a host, defined by current row of "spy_list_widget" :param row: current row of "spy_list_widget" :type row: int """ # Clear QListWidget self.host_list_widget.clear() # Get Host and its services if row < 0: item = None else: item = self.spy_list_widget.item(row) if item: host = data_manager.get_item('host', item.host) if _('(new !)') in item.data(Qt.DisplayRole): item.setData(Qt.DisplayRole, item.data(Qt.DisplayRole).replace(_('(new !)'), '')) item.setToolTip(item.toolTip().replace(_('(new !)'), '')) self.host_services_lbl.setText(_('Problems found for %s:') % host.get_display_name()) services = data_manager.get_host_services(host.item_id) if services: problems = False for service in services: if data_manager.is_problem('service', service.data): problems = True svc_state = _('Service %s is %s') % ( service.get_display_name(), service.data['ls_state'] ) event = EventItem() event.initialize( service.data['ls_state'], svc_state, host=host.item_id ) tooltip = 'Output: %s (%s)' % ( service.data['ls_output'], get_date_fromtimestamp(service.data['ls_last_check']) ) event.setToolTip(tooltip) self.host_list_widget.insertItem(0, event) if not problems: event = EventItem() event.initialize( host.data['ls_state'], _('%s is %s. Services of host seems managed.') % ( host.get_display_name(), host.data['ls_state']), host=host.item_id ) self.host_list_widget.insertItem(0, event) else: no_service_event = EventItem() no_service_event.initialize( host.data['ls_state'], _('%s is %s. No services.') % (host.get_display_name(), host.data['ls_state']) ) self.host_list_widget.insertItem(0, no_service_event) def remove_event(self): """ Remove item when user double click on an item, update parent tab text """ item = self.spy_list_widget.currentItem() self.spy_list_widget.spied_hosts.remove(item.data(Qt.UserRole)) self.spy_list_widget.takeItem(self.spy_list_widget.currentRow()) if not self.spy_list_widget.spied_hosts: self.host_list_widget.clear() self.spy_list_widget.insertItem(0, self.get_hint_item()) self.spy_list_widget.initialized = False self.host_services_lbl.setText(_('You are not spying on any hosts for now...')) if not self.spy_list_widget.selectedItems(): self.manage_host_events(self.spy_list_widget.currentRow()) self.update_parent_spytab() def update_parent_spytab(self): # pragma: no cover - not testable """ Update the parent spy tab text """ if self.parent(): if self.spy_list_widget.spied_hosts: self.parent().parent().setTabText( self.parent().parent().indexOf(self), _('Spied Hosts (%d)') % self.spy_list_widget.count() ) else: # Remove hint item from count self.parent().parent().setTabText( self.parent().parent().indexOf(self), _('Spied Hosts (%d)') % (self.spy_list_widget.count() - 1) )
class SavedSearchEditor(Dialog): def __init__(self, parent, initial_search=None): self.initial_search = initial_search Dialog.__init__( self, _('Manage Saved searches'), 'manage-saved-searches', parent) def setup_ui(self): from calibre.gui2.ui import get_gui db = get_gui().current_db self.l = l = QVBoxLayout(self) b = self.bb.addButton(_('&Add search'), QDialogButtonBox.ButtonRole.ActionRole) b.setIcon(QIcon(I('plus.png'))) b.clicked.connect(self.add_search) b = self.bb.addButton(_('&Remove search'), QDialogButtonBox.ButtonRole.ActionRole) b.setIcon(QIcon(I('minus.png'))) b.clicked.connect(self.del_search) b = self.bb.addButton(_('&Edit search'), QDialogButtonBox.ButtonRole.ActionRole) b.setIcon(QIcon(I('modified.png'))) b.clicked.connect(self.edit_search) self.slist = QListWidget(self) self.slist.setStyleSheet('QListView::item { padding: 3px }') self.slist.activated.connect(self.edit_search) self.slist.setAlternatingRowColors(True) self.searches = {name: db.saved_search_lookup(name) for name in db.saved_search_names()} self.populate_search_list() if self.initial_search is not None and self.initial_search in self.searches: self.select_search(self.initial_search) elif self.searches: self.slist.setCurrentRow(0) self.slist.currentItemChanged.connect(self.current_index_changed) l.addWidget(self.slist) self.desc = la = QLabel('\xa0') la.setWordWrap(True) l.addWidget(la) l.addWidget(self.bb) self.current_index_changed(self.slist.currentItem()) self.setMinimumHeight(500) self.setMinimumWidth(600) @property def current_search_name(self): i = self.slist.currentItem() if i is not None: ans = i.text() if ans in self.searches: return ans def keyPressEvent(self, ev): if ev.key() == Qt.Key.Key_Delete: self.del_search() return return Dialog.keyPressEvent(self, ev) def populate_search_list(self): self.slist.clear() for name in sorted(self.searches.keys(), key=sort_key): self.slist.addItem(name) def add_search(self): d = AddSavedSearch(parent=self, commit_changes=False, validate=self.validate_add) if d.exec_() != QDialog.DialogCode.Accepted: return name, expression = d.accepted_data self.searches[name] = expression self.populate_search_list() self.select_search(name) def del_search(self): n = self.current_search_name if n is not None: if not confirm( '<p>' + _( 'The current saved search will be ' '<b>permanently deleted</b>. Are you sure?') + '</p>', 'saved_search_editor_delete', self): return self.slist.takeItem(self.slist.currentRow()) del self.searches[n] def edit_search(self): n = self.current_search_name if not n: return d = AddSavedSearch(parent=self, commit_changes=False, label=_('Edit the name and/or expression below.'), validate=self.validate_edit) d.setWindowTitle(_('Edit saved search')) d.sname.setText(n) d.search.setPlainText(self.searches[n]) if d.exec_() != QDialog.DialogCode.Accepted: return name, expression = d.accepted_data self.slist.currentItem().setText(name) del self.searches[n] self.searches[name] = expression self.current_index_changed(self.slist.currentItem()) def duplicate_msg(self, name): return _('A saved search with the name {} already exists. Choose another name').format(name) def validate_edit(self, name, expression): q = self.current_search_name if icu_lower(name) in {icu_lower(n) for n in self.searches if n != q}: return self.duplicate_msg(name) def validate_add(self, name, expression): if icu_lower(name) in {icu_lower(n) for n in self.searches}: return self.duplicate_msg(name) def select_search(self, name): items = self.slist.findItems(name, Qt.MatchFlag.MatchFixedString | Qt.MatchFlag.MatchCaseSensitive) if items: self.slist.setCurrentItem(items[0]) def current_index_changed(self, item): n = self.current_search_name if n: t = self.searches[n] else: t = '' self.desc.setText('<p><b>{}</b>: '.format(_('Search expression')) + prepare_string_for_xml(t)) def accept(self): commit_searches(self.searches) Dialog.accept(self)
def keyPressEvent(self, event): if event.key() == Qt.Key_Delete: self.delete_format.emit() else: return QListWidget.keyPressEvent(self, event)
class PluginWidget(QWidget): TITLE = _('CSV/XML options') HELP = _('Options specific to') + ' CSV/XML ' + _('output') sync_enabled = False formats = {'csv', 'xml'} handles_scrolling = True def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout(self) self.la = la = QLabel(_('Fields to include in output:')) la.setWordWrap(True) l.addWidget(la) self.db_fields = QListWidget(self) l.addWidget(self.db_fields) self.la2 = la = QLabel(_('Drag and drop to re-arrange fields')) l.addWidget(la) self.db_fields.setDragEnabled(True) self.db_fields.setDragDropMode( QAbstractItemView.DragDropMode.InternalMove) self.db_fields.setDefaultDropAction( Qt.DropAction.CopyAction if ismacos else Qt.DropAction.MoveAction) self.db_fields.setAlternatingRowColors(True) self.db_fields.setObjectName("db_fields") def initialize(self, catalog_name, db): self.name = catalog_name from calibre.library.catalogs import FIELDS db = get_gui().current_db self.all_fields = {x for x in FIELDS if x != 'all'} | set(db.custom_field_keys()) sort_order, fields = get_saved_field_data(self.name, self.all_fields) fm = db.field_metadata def name(x): if x == 'isbn': return 'ISBN' if x == 'library_name': return _('Library name') if x.endswith('_index'): return name(x[:-len('_index')]) + ' ' + _('Number') return fm[x].get('name') or x def key(x): return (sort_order.get(x, 10000), name(x)) self.db_fields.clear() for x in sorted(self.all_fields, key=key): QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.ItemDataRole.UserRole, x) if x.startswith('#') and fm[x]['datatype'] == 'series': x += '_index' QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData( Qt.ItemDataRole.UserRole, x) # Restore the activated fields from last use for x in range(self.db_fields.count()): item = self.db_fields.item(x) item.setCheckState(Qt.CheckState.Checked if unicode_type( item.data(Qt.ItemDataRole.UserRole)) in fields else Qt.CheckState.Unchecked) def options(self): # Save the currently activated fields fields, all_fields = [], [] for x in range(self.db_fields.count()): item = self.db_fields.item(x) all_fields.append(unicode_type(item.data( Qt.ItemDataRole.UserRole))) if item.checkState() == Qt.CheckState.Checked: fields.append(unicode_type(item.data( Qt.ItemDataRole.UserRole))) set_saved_field_data(self.name, fields, {x: i for i, x in enumerate(all_fields)}) # Return a dictionary with current options for this widget if len(fields): return {'fields': fields} else: return {'fields': ['all']}
def setup_ui(self): self.vl = vl = QVBoxLayout(self) self.stack = l = QStackedLayout() self.pi = pi = ProgressIndicator(self, 256) vl.addLayout(l), vl.addWidget(self.bb) self.restore_defs_button = b = self.bb.addButton( _('Restore &default icons'), self.bb.ActionRole) b.clicked.connect(self.restore_defaults) b.setIcon(QIcon(I('view-refresh.png'))) self.c = c = QWidget(self) self.c.v = v = QVBoxLayout(self.c) v.addStretch(), v.addWidget(pi, 0, Qt.AlignCenter) self.wait_msg = m = QLabel(self) v.addWidget(m, 0, Qt.AlignCenter), v.addStretch() f = m.font() f.setBold(True), f.setPointSize(28), m.setFont(f) self.start_spinner() l.addWidget(c) self.w = w = QWidget(self) l.addWidget(w) w.l = l = QGridLayout(w) def add_row(x, y=None): if isinstance(x, type('')): x = QLabel(x) row = l.rowCount() if y is None: if isinstance(x, QLabel): x.setWordWrap(True) l.addWidget(x, row, 0, 1, 2) else: if isinstance(x, QLabel): x.setBuddy(y) l.addWidget(x, row, 0), l.addWidget(y, row, 1) add_row( _('Choose an icon theme below. You will need to restart' ' calibre to see the new icons.')) add_row( _('Current icon theme:') + '\xa0<b>' + (self.current_theme or 'None')) self.sort_by = sb = QComboBox(self) add_row(_('&Sort by:'), sb) sb.addItems([ _('Number of icons'), _('Popularity'), _('Name'), ]) sb.setEditable(False), sb.setCurrentIndex( gprefs.get('choose_icon_theme_sort_by', 1)) sb.currentIndexChanged[int].connect(self.re_sort) sb.currentIndexChanged[int].connect( lambda: gprefs.set('choose_icon_theme_sort_by', sb.currentIndex())) self.theme_list = tl = QListWidget(self) tl.setVerticalScrollMode(tl.ScrollPerPixel) self.delegate = Delegate(tl) tl.setItemDelegate(self.delegate) tl.itemDoubleClicked.connect(self.accept) add_row(tl) t = Thread(name='GetIconThemes', target=self.get_themes) t.daemon = True t.start()
def order_widget(self, name, prefs=None): prefs = prefs or tprefs widget = QListWidget(self) widget.addItems(prefs.defaults[name]) widget.setDragEnabled(True) widget.setDragDropMode(widget.InternalMove) widget.viewport().setAcceptDrops(True) widget.setDropIndicatorShown(True) widget.indexesMoved.connect(self.emit_changed) widget.setDefaultDropAction(Qt.MoveAction) widget.setMovement(widget.Snap) widget.setSpacing(5) widget.defaults = prefs.defaults[name] def getter(w): return list(map(unicode, (w.item(i).text() for i in xrange(w.count())))) def setter(w, val): order_map = {x:i for i, x in enumerate(val)} items = list(w.defaults) limit = len(items) items.sort(key=lambda x:order_map.get(x, limit)) w.clear() for x in items: i = QListWidgetItem(w) i.setText(x) i.setFlags(i.flags() | Qt.ItemIsDragEnabled) return self(name, widget=widget, getter=getter, setter=setter, prefs=prefs)
class ChooseFormatDialog(QDialog): 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) self.formats.currentRowChanged.connect( self.update_open_with_button) 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 if show_open_with: self.populate_open_with() self.update_open_with_button() def populate_open_with(self): from calibre.gui2.open_with import populate_menu, edit_programs menu = self.own menu.clear() fmt = self._formats[self.formats.currentRow()] populate_menu(menu, self.open_with, fmt) if len(menu.actions()) == 0: menu.addAction( _('Open %s with...') % fmt.upper(), self.choose_open_with) else: menu.addSeparator() menu.addAction( _('Add other application for %s files...') % fmt.upper(), self.choose_open_with) menu.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, self)) def update_open_with_button(self): fmt = self._formats[self.formats.currentRow()] self.owb.setText(_('Open %s With...') % fmt) def open_with(self, entry): self.open_with_format = (self._formats[self.formats.currentRow()], entry) self.accept() def choose_open_with(self): from calibre.gui2.open_with import choose_program fmt = self._formats[self.formats.currentRow()] entry = choose_program(fmt, self) if entry is not None: self.open_with(entry) def book_converted(self, book_id, fmt): fmt = fmt.upper() if fmt not in self._formats: self._formats.append(fmt) self.formats.addItem( QListWidgetItem( file_icon_provider().icon_from_ext(fmt.lower()), fmt.upper())) def activated_slot(self, *args): self.accept() def format(self): return self._format def accept(self): self._format = self._formats[self.formats.currentRow()] return QDialog.accept(self)
class ConfigWidget(QWidget): plugin = None def __init__(self, plugin): QWidget.__init__(self) self.plugin = plugin self.layout = QVBoxLayout() self.setLayout(self.layout) self.engine_location_label = QLabel('ElasticSearch engine location:') self.layout.addWidget(self.engine_location_label) self.elasticsearch_url_textbox = QLineEdit(self) self.elasticsearch_url_textbox.setText(prefs['elasticsearch_url']) self.layout.addWidget(self.elasticsearch_url_textbox) self.engine_location_label.setBuddy(self.elasticsearch_url_textbox) self.layout.addSpacing(10) self.pdftotext_path_label = QLabel('Path to pdftotext tool:') self.layout.addWidget(self.pdftotext_path_label) self.pdftotext_path_textbox = QLineEdit(self) self.pdftotext_path_textbox.setText(prefs['pdftotext_path']) self.layout.addWidget(self.pdftotext_path_textbox) self.pdftotext_path_label.setBuddy(self.pdftotext_path_textbox) self.layout.addSpacing(10) self.concurrency_label = QLabel( 'Number of parallel processes for text extraction:') self.layout.addWidget(self.concurrency_label) self.concurrency_textbox = QLineEdit(self) self.concurrency_textbox.setText(str(prefs['concurrency'])) self.layout.addWidget(self.concurrency_textbox) self.concurrency_label.setBuddy(self.concurrency_textbox) self.layout.addSpacing(10) self.formats_label = QLabel('Index book formats:') self.layout.addWidget(self.formats_label) file_formats = prefs['file_formats'].split(',') self.formats_list = QListWidget(self) for fmt in SUPPORTED_FORMATS: item = QListWidgetItem(fmt) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked if fmt in file_formats else Qt.Unchecked) self.formats_list.addItem(item) self.layout.addWidget(self.formats_list) self.formats_label.setBuddy(self.formats_list) self.layout.addSpacing(10) self.autoindex_checkbox = QCheckBox( "Automatically index new books on search", self) self.autoindex_checkbox.setCheckState( Qt.Checked if prefs['autoindex'] else Qt.Unchecked) self.layout.addWidget(self.autoindex_checkbox) self.layout.addSpacing(10) self.privacy_label = QLabel('Privacy:') self.layout.addWidget(self.privacy_label) self.clear_search_history_button = QPushButton('Clear search &history', self) self.clear_search_history_button.clicked.connect(self.on_clear_history) self.layout.addWidget(self.clear_search_history_button) self.clear_search_index_buttin = QPushButton('Clear search &index', self) self.clear_search_index_buttin.clicked.connect(self.on_clear_index) self.layout.addWidget(self.clear_search_index_buttin) def save_settings(self): prefs['elasticsearch_url'] = self.elasticsearch_url_textbox.text() prefs['pdftotext_path'] = self.pdftotext_path_textbox.text() try: prefs['concurrency'] = int(self.concurrency_textbox.text()) except Exception: pass file_formats = [] for i in range(len(SUPPORTED_FORMATS)): if self.formats_list.item(i).checkState() == Qt.Checked: file_formats.append(self.formats_list.item(i).text()) prefs['file_formats'] = ','.join(file_formats) prefs['autoindex'] = True if self.autoindex_checkbox.checkState( ) == Qt.Checked else False def on_clear_history(self): from calibre.gui2 import info_dialog if 'search_lru' in prefs: del prefs['search_lru'] if self.plugin.search_dialog: self.plugin.search_dialog.clear_lru() info_dialog(self, TITLE, 'History cleared', show=True) def on_clear_index(self): from calibre.gui2 import question_dialog, error_dialog if question_dialog( self, TITLE, 'You are about to clear all fulltext search index. Rebuilding it might take a while. Are you sure?', default_yes=False): elastic_search_client = Elasticsearch([prefs['elasticsearch_url']], timeout=20.0) if not elastic_search_client.ping(): error_dialog( self, TITLE, 'Could not connect to ElasticSearch cluster. Please make sure that it\'s running.', show=True) return elastic_search_client.indices.delete(index='library', ignore=[400, 404]) prefs[self.plugin.gui.current_db.new_api.library_id] = { 'index_state': {} }
class PluginWidget(QWidget): TITLE = _("CSV/XML Options") HELP = _("Options specific to") + " CSV/XML " + _("output") sync_enabled = False formats = set(["csv", "xml"]) def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout(self) self.la = la = QLabel(_("Fields to include in output:")) la.setWordWrap(True) l.addWidget(la) self.db_fields = QListWidget(self) l.addWidget(self.db_fields) self.la2 = la = QLabel(_("Drag and drop to re-arrange fields")) l.addWidget(la) self.db_fields.setDragEnabled(True) self.db_fields.setDragDropMode(QListWidget.InternalMove) self.db_fields.setDefaultDropAction(Qt.MoveAction) self.db_fields.setAlternatingRowColors(True) self.db_fields.setObjectName("db_fields") def initialize(self, catalog_name, db): self.name = catalog_name from calibre.library.catalogs import FIELDS db = get_gui().current_db self.all_fields = {x for x in FIELDS if x != "all"} | set(db.custom_field_keys()) sort_order = gprefs.get(self.name + "_db_fields_sort_order", {}) fm = db.field_metadata def name(x): if x == "isbn": return "ISBN" if x == "library_name": return _("Library Name") if x.endswith("_index"): return name(x[: -len("_index")]) + " " + _("Number") return fm[x].get("name") or x def key(x): return (sort_order.get(x, 10000), name(x)) self.db_fields.clear() for x in sorted(self.all_fields, key=key): QListWidgetItem(name(x) + " (%s)" % x, self.db_fields).setData(Qt.UserRole, x) if x.startswith("#") and fm[x]["datatype"] == "series": x += "_index" QListWidgetItem(name(x) + " (%s)" % x, self.db_fields).setData(Qt.UserRole, x) # Restore the activated fields from last use fields = frozenset(gprefs.get(self.name + "_db_fields", self.all_fields)) for x in range(self.db_fields.count()): item = self.db_fields.item(x) item.setCheckState(Qt.Checked if unicode(item.data(Qt.UserRole)) in fields else Qt.Unchecked) def options(self): # Save the currently activated fields fields, all_fields = [], [] for x in xrange(self.db_fields.count()): item = self.db_fields.item(x) all_fields.append(unicode(item.data(Qt.UserRole))) if item.checkState() == Qt.Checked: fields.append(unicode(item.data(Qt.UserRole))) gprefs.set(self.name + "_db_fields", fields) gprefs.set(self.name + "_db_fields_sort_order", {x: i for i, x in enumerate(all_fields)}) # Return a dictionary with current options for this widget if len(fields): return {"fields": fields} else: return {"fields": ["all"]}
def keyPressEvent(self, ev): if ev.key() == Qt.Key_Delete: self.delete_selected() ev.accept() return return QListWidget.keyPressEvent(self, ev)
def __init__(self, parent): QWidget.__init__(self, parent) self.l = l = QFormLayout(self) l.setFieldGrowthPolicy(l.ExpandingFieldsGrow) self.hm = hm = QLabel(_( 'Create a basic news recipe, by adding RSS feeds to it.\n' 'For some news sources, you will have to use the "Switch to advanced mode" ' 'button below to further customize the fetch process.')) hm.setWordWrap(True) l.addRow(hm) self.title = t = QLineEdit(self) l.addRow(_('Recipe &title:'), t) t.setStyleSheet('QLineEdit { font-weight: bold }') self.oldest_article = o = QSpinBox(self) o.setSuffix(' ' + _('day(s)')) o.setToolTip(_("The oldest article to download")) o.setMinimum(1), o.setMaximum(36500) l.addRow(_('&Oldest article:'), o) self.max_articles = m = QSpinBox(self) m.setMinimum(5), m.setMaximum(100) m.setToolTip(_("Maximum number of articles to download per feed.")) l.addRow(_("&Max. number of articles per feed:"), m) self.fg = fg = QGroupBox(self) fg.setTitle(_("Feeds in recipe")) self.feeds = f = QListWidget(self) fg.h = QHBoxLayout(fg) fg.h.addWidget(f) fg.l = QVBoxLayout() self.up_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))) b.setToolTip(_('Move selected feed up')) fg.l.addWidget(b) b.clicked.connect(self.move_up) self.remove_button = b = QToolButton(self) b.setIcon(QIcon(I('list_remove.png'))) b.setToolTip(_('Remove selected feed')) fg.l.addWidget(b) b.clicked.connect(self.remove_feed) self.down_button = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))) b.setToolTip(_('Move selected feed down')) fg.l.addWidget(b) b.clicked.connect(self.move_down) fg.h.addLayout(fg.l) l.addRow(fg) self.afg = afg = QGroupBox(self) afg.setTitle(_('Add feed to recipe')) afg.l = QFormLayout(afg) afg.l.setFieldGrowthPolicy(l.ExpandingFieldsGrow) self.feed_title = ft = QLineEdit(self) afg.l.addRow(_('&Feed title:'), ft) self.feed_url = fu = QLineEdit(self) afg.l.addRow(_('Feed &URL:'), fu) self.afb = b = QPushButton(QIcon(I('plus.png')), _('&Add feed'), self) b.setToolTip(_('Add this feed to the recipe')) b.clicked.connect(self.add_feed) afg.l.addRow(b) l.addRow(afg)
class ManageKeysDialog(QDialog): def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext=u""): QDialog.__init__(self, parent) self.parent = parent self.key_type_name = key_type_name self.plugin_keys = plugin_keys self.create_key = create_key self.keyfile_ext = keyfile_ext self.json_file = (keyfile_ext == u"k4i") self.setWindowTitle("{0} {1}: Manage {2}s".format( PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name)) # Start Qt Gui dialog layout layout = QVBoxLayout(self) self.setLayout(layout) keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self) layout.addWidget(keys_group_box) keys_group_box_layout = QHBoxLayout() keys_group_box.setLayout(keys_group_box_layout) self.listy = QListWidget(self) self.listy.setToolTip( u"{0}s that will be used to decrypt ebooks".format( self.key_type_name)) self.listy.setSelectionMode(QAbstractItemView.SingleSelection) self.populate_list() keys_group_box_layout.addWidget(self.listy) button_layout = QVBoxLayout() keys_group_box_layout.addLayout(button_layout) self._add_key_button = QtGui.QToolButton(self) self._add_key_button.setIcon(QIcon(I('plus.png'))) self._add_key_button.setToolTip(u"Create new {0}".format( self.key_type_name)) self._add_key_button.clicked.connect(self.add_key) button_layout.addWidget(self._add_key_button) self._delete_key_button = QtGui.QToolButton(self) self._delete_key_button.setToolTip(_(u"Delete highlighted key")) self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) self._delete_key_button.clicked.connect(self.delete_key) button_layout.addWidget(self._delete_key_button) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) layout.addSpacing(5) migrate_layout = QHBoxLayout() layout.addLayout(migrate_layout) migrate_layout.addStretch() self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) migrate_layout.addWidget(self.button_box) self.resize(self.sizeHint()) def populate_list(self): if type(self.plugin_keys) == dict: for key in self.plugin_keys.keys(): self.listy.addItem(QListWidgetItem(key)) else: for key in self.plugin_keys: self.listy.addItem(QListWidgetItem(key)) def add_key(self): d = self.create_key(self) d.exec_() if d.result() != d.Accepted: # New key generation cancelled. return new_key_value = d.key_value if new_key_value in self.plugin_keys: info_dialog( None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name), u"This {0} is already in the list of {0}s has not been added.". format(self.key_type_name), show=True) return self.plugin_keys.append(d.key_value) self.listy.clear() self.populate_list() def delete_key(self): if not self.listy.currentItem(): return keyname = unicode(self.listy.currentItem().text()) if not question_dialog( self, "{0} {1}: Confirm Delete".format(PLUGIN_NAME, PLUGIN_VERSION), u"Do you really want to delete the {1} <strong>{0}</strong>?". format(keyname, self.key_type_name), show_copy_button=False, default_yes=False): return self.plugin_keys.remove(keyname) self.listy.clear() self.populate_list()
class ManageKeysDialog(QDialog): def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext = u"", wineprefix = None): QDialog.__init__(self,parent) self.parent = parent self.key_type_name = key_type_name self.plugin_keys = plugin_keys self.create_key = create_key self.keyfile_ext = keyfile_ext self.import_key = (keyfile_ext != u"") self.binary_file = (keyfile_ext == "der") self.json_file = (keyfile_ext == "k4i") self.android_file = (keyfile_ext == "k4a") self.wineprefix = wineprefix self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name)) # Start Qt Gui dialog layout 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/">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) keys_group_box = QGroupBox(_("{0}s".format(self.key_type_name)), self) layout.addWidget(keys_group_box) keys_group_box_layout = QHBoxLayout() keys_group_box.setLayout(keys_group_box_layout) self.listy = QListWidget(self) self.listy.setToolTip("{0}s that will be used to decrypt ebooks".format(self.key_type_name)) self.listy.setSelectionMode(QAbstractItemView.SingleSelection) self.populate_list() keys_group_box_layout.addWidget(self.listy) button_layout = QVBoxLayout() keys_group_box_layout.addLayout(button_layout) self._add_key_button = QtGui.QToolButton(self) self._add_key_button.setIcon(QIcon(I('plus.png'))) self._add_key_button.setToolTip("Create new {0}".format(self.key_type_name)) self._add_key_button.clicked.connect(self.add_key) button_layout.addWidget(self._add_key_button) self._delete_key_button = QtGui.QToolButton(self) self._delete_key_button.setToolTip(_("Delete highlighted key")) self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) self._delete_key_button.clicked.connect(self.delete_key) button_layout.addWidget(self._delete_key_button) if type(self.plugin_keys) == dict and self.import_key: self._rename_key_button = QtGui.QToolButton(self) self._rename_key_button.setToolTip(_("Rename highlighted key")) self._rename_key_button.setIcon(QIcon(I('edit-select-all.png'))) self._rename_key_button.clicked.connect(self.rename_key) button_layout.addWidget(self._rename_key_button) self.export_key_button = QtGui.QToolButton(self) self.export_key_button.setToolTip("Save highlighted key to a .{0} file".format(self.keyfile_ext)) self.export_key_button.setIcon(QIcon(I('save.png'))) self.export_key_button.clicked.connect(self.export_key) button_layout.addWidget(self.export_key_button) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) if self.wineprefix is not None: layout.addSpacing(5) wineprefix_layout = QHBoxLayout() layout.addLayout(wineprefix_layout) wineprefix_layout.setAlignment(Qt.AlignCenter) self.wp_label = QLabel("WINEPREFIX:") wineprefix_layout.addWidget(self.wp_label) self.wp_lineedit = QLineEdit(self) wineprefix_layout.addWidget(self.wp_lineedit) self.wp_label.setBuddy(self.wp_lineedit) self.wp_lineedit.setText(self.wineprefix) layout.addSpacing(5) migrate_layout = QHBoxLayout() layout.addLayout(migrate_layout) if self.import_key: migrate_layout.setAlignment(Qt.AlignJustify) self.migrate_btn = QPushButton("Import Existing Keyfiles", self) self.migrate_btn.setToolTip("Import *.{0} files (created using other tools).".format(self.keyfile_ext)) self.migrate_btn.clicked.connect(self.migrate_wrapper) migrate_layout.addWidget(self.migrate_btn) migrate_layout.addStretch() self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) migrate_layout.addWidget(self.button_box) self.resize(self.sizeHint()) def getwineprefix(self): if self.wineprefix is not None: return self.wp_lineedit.text().strip() return u"" def populate_list(self): if type(self.plugin_keys) == dict: for key in self.plugin_keys.keys(): self.listy.addItem(QListWidgetItem(key)) else: for key in self.plugin_keys: self.listy.addItem(QListWidgetItem(key)) def add_key(self): d = self.create_key(self) d.exec_() if d.result() != d.Accepted: # New key generation cancelled. return new_key_value = d.key_value if type(self.plugin_keys) == dict: if new_key_value in self.plugin_keys.values(): old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0] info_dialog(None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name), "The new {1} is the same as the existing {1} named <strong>{0}</strong> and has not been added.".format(old_key_name,self.key_type_name), show=True) return self.plugin_keys[d.key_name] = new_key_value else: if new_key_value in self.plugin_keys: info_dialog(None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name), "This {0} is already in the list of {0}s has not been added.".format(self.key_type_name), show=True) return self.plugin_keys.append(d.key_value) self.listy.clear() self.populate_list() def rename_key(self): if not self.listy.currentItem(): errmsg = "No {0} selected to rename. Highlight a keyfile first.".format(self.key_type_name) r = error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), _(errmsg), show=True, show_copy_button=False) return d = RenameKeyDialog(self) d.exec_() if d.result() != d.Accepted: # rename cancelled or moot. return keyname = self.listy.currentItem().text() if not question_dialog(self, "{0} {1}: Confirm Rename".format(PLUGIN_NAME, PLUGIN_VERSION), "Do you really want to rename the {2} named <strong>{0}</strong> to <strong>{1}</strong>?".format(keyname,d.key_name,self.key_type_name), show_copy_button=False, default_yes=False): return self.plugin_keys[d.key_name] = self.plugin_keys[keyname] del self.plugin_keys[keyname] self.listy.clear() self.populate_list() def delete_key(self): if not self.listy.currentItem(): return keyname = self.listy.currentItem().text() if not question_dialog(self, "{0} {1}: Confirm Delete".format(PLUGIN_NAME, PLUGIN_VERSION), "Do you really want to delete the {1} <strong>{0}</strong>?".format(keyname, self.key_type_name), show_copy_button=False, default_yes=False): return if type(self.plugin_keys) == dict: del self.plugin_keys[keyname] else: self.plugin_keys.remove(keyname) self.listy.clear() self.populate_list() 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. help_file_name = "{0}_{1}_Help.htm".format(PLUGIN_NAME, self.key_type_name) file_path = os.path.join(config_dir, "plugins", "DeDRM", "help", help_file_name) with open(file_path,'w') as f: f.write(self.parent.load_resource(help_file_name)) return file_path url = 'file:///' + get_help_file_resource() open_url(QUrl(url)) def migrate_files(self): unique_dlg_name = PLUGIN_NAME + "import {0} keys".format(self.key_type_name).replace(' ', '_') #takes care of automatically remembering last directory caption = "Select {0} files to import".format(self.key_type_name) filters = [("{0} files".format(self.key_type_name), [self.keyfile_ext])] files = choose_files(self, unique_dlg_name, caption, filters, all_files=False) counter = 0 skipped = 0 if files: for filename in files: fpath = os.path.join(config_dir, filename) filename = os.path.basename(filename) new_key_name = os.path.splitext(os.path.basename(filename))[0] with open(fpath,'rb') as keyfile: new_key_value = keyfile.read() if self.binary_file: new_key_value = new_key_value.hex() elif self.json_file: new_key_value = json.loads(new_key_value) elif self.android_file: # convert to list of the keys in the string new_key_value = new_key_value.splitlines() match = False for key in self.plugin_keys.keys(): if uStrCmp(new_key_name, key, True): skipped += 1 msg = "A key with the name <strong>{0}</strong> already exists!\nSkipping key file <strong>{1}</strong>.\nRename the existing key and import again".format(new_key_name,filename) inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), _(msg), show_copy_button=False, show=True) match = True break if not match: if new_key_value in self.plugin_keys.values(): old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0] skipped += 1 info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), "The key in file {0} is the same as the existing key <strong>{1}</strong> and has been skipped.".format(filename,old_key_name), show_copy_button=False, show=True) else: counter += 1 self.plugin_keys[new_key_name] = new_key_value msg = u"" if counter+skipped > 1: if counter > 0: msg += "Imported <strong>{0:d}</strong> key {1}. ".format(counter, "file" if counter == 1 else "files") if skipped > 0: msg += "Skipped <strong>{0:d}</strong> key {1}.".format(skipped, "file" if counter == 1 else "files") inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), _(msg), show_copy_button=False, show=True) return counter > 0 def migrate_wrapper(self): if self.migrate_files(): self.listy.clear() self.populate_list() def export_key(self): if not self.listy.currentItem(): errmsg = "No keyfile selected to export. Highlight a keyfile first." r = error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), _(errmsg), show=True, show_copy_button=False) return keyname = self.listy.currentItem().text() unique_dlg_name = PLUGIN_NAME + "export {0} keys".format(self.key_type_name).replace(' ', '_') #takes care of automatically remembering last directory caption = "Save {0} File as...".format(self.key_type_name) filters = [("{0} Files".format(self.key_type_name), ["{0}".format(self.keyfile_ext)])] defaultname = "{0}.{1}".format(keyname, self.keyfile_ext) filename = choose_save_file(self, unique_dlg_name, caption, filters, all_files=False, initial_filename=defaultname) if filename: with file(filename, 'wb') as fname: if self.binary_file: fname.write(self.plugin_keys[keyname].decode('hex')) elif self.json_file: fname.write(json.dumps(self.plugin_keys[keyname])) elif self.android_file: for key in self.plugin_keys[keyname]: fname.write(key) fname.write("\n") else: fname.write(self.plugin_keys[keyname])
def __init__(self, parent=None, initial=None): QDialog.__init__(self, parent) self.setWindowTitle(_('Choose a texture')) self.l = l = QVBoxLayout() self.setLayout(l) self.tdir = texture_dir() self.images = il = QListWidget(self) il.itemDoubleClicked.connect(self.accept, type=Qt.QueuedConnection) il.setIconSize(QSize(256, 256)) il.setViewMode(il.IconMode) il.setFlow(il.LeftToRight) il.setSpacing(20) il.setSelectionMode(il.SingleSelection) il.itemSelectionChanged.connect(self.update_remove_state) l.addWidget(il) self.ad = ad = QLabel( _('The builtin textures come from <a href="http://subtlepatterns.com">subtlepatterns.com</a>.' )) ad.setOpenExternalLinks(True) ad.setWordWrap(True) l.addWidget(ad) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) b = self.add_button = bb.addButton(_('Add texture'), bb.ActionRole) b.setIcon(QIcon(I('plus.png'))) b.clicked.connect(self.add_texture) b = self.remove_button = bb.addButton(_('Remove texture'), bb.ActionRole) b.setIcon(QIcon(I('minus.png'))) b.clicked.connect(self.remove_texture) l.addWidget(bb) images = [{ 'fname': ':' + os.path.basename(x), 'path': x, 'name': ' '.join( map(string.capitalize, os.path.splitext(os.path.basename(x))[0].split('_'))) } for x in glob.glob(I('textures/*.png'))] + [ { 'fname': os.path.basename(x), 'path': x, 'name': os.path.splitext(os.path.basename(x))[0], } for x in glob.glob(os.path.join(self.tdir, '*')) if x.rpartition('.')[-1].lower() in {'jpeg', 'png', 'jpg'} ] images.sort(key=lambda x: sort_key(x['name'])) map(self.create_item, images) self.update_remove_state() if initial: existing = { unicode(i.data(Qt.UserRole) or ''): i for i in (self.images.item(c) for c in xrange(self.images.count())) } item = existing.get(initial, None) if item is not None: item.setSelected(True) QTimer.singleShot(100, partial(il.scrollToItem, item)) self.resize(QSize(950, 650))
def setup_ui(self): self.setWindowIcon(QIcon(I('modified.png'))) self.l = l = QVBoxLayout(self) self.stack = s = QStackedLayout() l.addLayout(s), l.addWidget(self.bb) self.listc = c = QWidget(self) s.addWidget(c) c.l = l = QVBoxLayout(c) c.h = h = QHBoxLayout() l.addLayout(h) self.search_bar = sb = QLineEdit(self) sb.setPlaceholderText(_('Search for a snippet')) h.addWidget(sb) self.next_button = b = QPushButton(_('&Next')) b.clicked.connect(self.find_next) h.addWidget(b) c.h2 = h = QHBoxLayout() l.addLayout(h) self.snip_list = sl = QListWidget(self) sl.doubleClicked.connect(self.edit_snippet) h.addWidget(sl) c.l2 = l = QVBoxLayout() h.addLayout(l) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('plus.png'))), b.setText( _('&Add snippet')), b.setToolButtonStyle( Qt.ToolButtonTextUnderIcon) b.clicked.connect(self.add_snippet) l.addWidget(b) self.edit_button = b = QToolButton(self) b.setIcon(QIcon(I('modified.png'))), b.setText( _('&Edit snippet')), b.setToolButtonStyle( Qt.ToolButtonTextUnderIcon) b.clicked.connect(self.edit_snippet) l.addWidget(b) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('minus.png'))), b.setText( _('&Remove snippet')), b.setToolButtonStyle( Qt.ToolButtonTextUnderIcon) b.clicked.connect(self.remove_snippet) l.addWidget(b) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('config.png'))), b.setText( _('Change &built-in')), b.setToolButtonStyle( Qt.ToolButtonTextUnderIcon) b.clicked.connect(self.change_builtin) l.addWidget(b) for i, snip in enumerate( sorted(user_snippets.get('snippets', []), key=itemgetter('trigger'))): item = self.snip_to_item(snip) if i == 0: self.snip_list.setCurrentItem(item) self.edit_snip = es = EditSnippet(self) self.stack.addWidget(es)
def __init__(self): super(SpyQWidget, self).__init__() self.host_services_lbl = QLabel(_('You are not spying on any hosts for now...')) self.spy_list_widget = SpyQListWidget() self.host_list_widget = QListWidget() self.spy_timer = QTimer()
def order_widget(self, name, prefs=None): prefs = prefs or tprefs widget = QListWidget(self) widget.addItems(prefs.defaults[name]) widget.setDragEnabled(True) widget.setDragDropMode(widget.InternalMove) widget.viewport().setAcceptDrops(True) widget.setDropIndicatorShown(True) widget.indexesMoved.connect(self.emit_changed) widget.setDefaultDropAction(Qt.MoveAction) widget.setMovement(widget.Snap) widget.setSpacing(5) widget.defaults = prefs.defaults[name] def getter(w): return list( map(unicode_type, (w.item(i).text() for i in range(w.count())))) def setter(w, val): order_map = {x: i for i, x in enumerate(val)} items = list(w.defaults) limit = len(items) items.sort(key=lambda x: order_map.get(x, limit)) w.clear() for x in items: i = QListWidgetItem(w) i.setText(x) i.setFlags(i.flags() | Qt.ItemIsDragEnabled) return self(name, widget=widget, getter=getter, setter=setter, prefs=prefs)
class CalibreBookBrainzPluginDialog(QDialog): def __init__(self, gui, icon, do_user_config): QDialog.__init__(self, gui) self.gui = gui self.do_user_config = do_user_config self.db = gui.current_db self.l = QVBoxLayout() self.setLayout(self.l) self.header = QLabel(prefs['searchinbookbrainz']) self.l.addWidget(self.header) self.img = QLabel() pixmap = QPixmap("images/BBt.svg") self.img.setPixmap(pixmap) self.l.addWidget(self.img) # QCol = QColor() # QCol.setRed(220) # QCol.setGreen(255) # QCol.setBlue(240) self.setWindowTitle('Calibre Book Brainz Integration') self.setWindowIcon(icon) self.search_space = QLineEdit() self.selected_button = QPushButton('Use title from selected book', self) self.selected_button.clicked.connect(self.exporttitlefromselected) self.l.addWidget(self.selected_button) self.search_space = QLineEdit() self.l.addWidget(self.search_space) self.listWidget = QListWidget() self.l.addWidget(self.listWidget) self.searchExecutionButton = QPushButton('Search', self) self.searchExecutionButton.clicked.connect(self.search) self.l.addWidget(self.searchExecutionButton) self.aboutButton = QPushButton('About', self) self.aboutButton.clicked.connect(self.about) self.l.addWidget(self.aboutButton) self.resize(400, 600) self.search_space.setFocus() def exporttitlefromselected(self): rows = self.gui.current_view().selectionModel().selectedRows() if len(rows) == 0: self.search_space.setText("") else: mi = self.gui.library_view.model().db.get_metadata(rows[0].row()) self.search_space.setText(mi.title) def search(self): text = self.search_space.text() print(text) self.listWidget.clear() self.listWidget.setFocus() try: url = "https://bookbrainz.org/ws/search/?q=\"" + text + "\"&mode=\"search\"" hits = request_get(url)['hits'] except: return numQueries = len(hits) act = 0 for i in range(numQueries): enttype = hits[i]['_source']['_type'] if not enttype in ['Publication', 'Work', 'Edition']: continue print(hits[i]) item = QListWidgetItem("%i. %s BBID : %i" % ((act + 1), hits[i]['_source']['default_alias']['name'], 1)) Qcol = QColor() if i % 2 == 0: Qcol.setRed(240) Qcol.setGreen(255) Qcol.setBlue(255) else: Qcol.setRed(220) Qcol.setGreen(255) Qcol.setBlue(240) item.setBackground(QBrush(Qcol)) self.listWidget.addItem(item) act += 1 self.listWidget.setFocus() self.searchExecutionButton.setFocus() def about(self): text = get_resources('about.txt') QMessageBox.about(self, 'About the Calibre Book Brainz Plugin', text.decode('utf-8')) def config(self): self.do_user_config(parent=self) # Apply the changes self.label.setText(prefs['hello_world_msg'])
def __init__(self, parent=None): QListWidget.__init__(self, parent) self.setSelectionMode(self.ExtendedSelection)
class PluginWidget(QWidget): TITLE = _('CSV/XML options') HELP = _('Options specific to')+' CSV/XML '+_('output') sync_enabled = False formats = {'csv', 'xml'} handles_scrolling = True def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout(self) self.la = la = QLabel(_('Fields to include in output:')) la.setWordWrap(True) l.addWidget(la) self.db_fields = QListWidget(self) l.addWidget(self.db_fields) self.la2 = la = QLabel(_('Drag and drop to re-arrange fields')) l.addWidget(la) self.db_fields.setDragEnabled(True) self.db_fields.setDragDropMode(QListWidget.InternalMove) self.db_fields.setDefaultDropAction(Qt.MoveAction) self.db_fields.setAlternatingRowColors(True) self.db_fields.setObjectName("db_fields") def initialize(self, catalog_name, db): self.name = catalog_name from calibre.library.catalogs import FIELDS db = get_gui().current_db self.all_fields = {x for x in FIELDS if x != 'all'} | set(db.custom_field_keys()) sort_order, fields = get_saved_field_data(self.name, self.all_fields) fm = db.field_metadata def name(x): if x == 'isbn': return 'ISBN' if x == 'library_name': return _('Library name') if x.endswith('_index'): return name(x[:-len('_index')]) + ' ' + _('Number') return fm[x].get('name') or x def key(x): return (sort_order.get(x, 10000), name(x)) self.db_fields.clear() for x in sorted(self.all_fields, key=key): QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.UserRole, x) if x.startswith('#') and fm[x]['datatype'] == 'series': x += '_index' QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.UserRole, x) # Restore the activated fields from last use for x in range(self.db_fields.count()): item = self.db_fields.item(x) item.setCheckState(Qt.Checked if unicode_type(item.data(Qt.UserRole)) in fields else Qt.Unchecked) def options(self): # Save the currently activated fields fields, all_fields = [], [] for x in range(self.db_fields.count()): item = self.db_fields.item(x) all_fields.append(unicode_type(item.data(Qt.UserRole))) if item.checkState() == Qt.Checked: fields.append(unicode_type(item.data(Qt.UserRole))) set_saved_field_data(self.name, fields, {x:i for i, x in enumerate(all_fields)}) # Return a dictionary with current options for this widget if len(fields): return {'fields':fields} else: return {'fields':['all']}
def __init__(self, mi=None, prefs=None, parent=None, for_global_prefs=False): QWidget.__init__(self, parent) self.ignore_changed = False self.for_global_prefs = for_global_prefs self.l = l = QHBoxLayout(self) l.setContentsMargins(0, 0, 0, 0) self.setLayout(l) self.settings_tabs = st = QTabWidget(self) l.addWidget(st) self.preview_label = la = Preview(self) l.addWidget(la) if prefs is None: prefs = cprefs self.original_prefs = prefs self.mi = mi or self.default_mi() self.colors_page = cp = QWidget(st) st.addTab(cp, _('&Colors')) cp.l = l = QGridLayout() cp.setLayout(l) if for_global_prefs: msg = _('When generating covers, a color scheme for the cover is chosen at random from the' ' color schemes below. You can prevent an individual scheme from being selected by' ' unchecking it. The preview on the right shows the currently selected color scheme.') else: msg = _('Choose a color scheme to be used for this generated cover.') + '<p>' + _( 'In normal cover generation, the color scheme is chosen at random from the list of color schemes below. You' ' can prevent an individual color scheme from being chosen by unchecking it here.') cp.la = la = QLabel('<p>' + msg) la.setWordWrap(True) l.addWidget(la, 0, 0, 1, -1) self.colors_list = cl = QListWidget(cp) l.addWidget(cl, 1, 0, 1, -1) self.colors_map = OrderedDict() self.ncs = ncs = QPushButton(QIcon(I('plus.png')), _('&New color scheme'), cp) ncs.clicked.connect(self.create_color_scheme) l.addWidget(ncs) self.ecs = ecs = QPushButton(QIcon(I('format-fill-color.png')), _('&Edit color scheme'), cp) ecs.clicked.connect(self.edit_color_scheme) l.addWidget(ecs, l.rowCount()-1, 1) self.rcs = rcs = QPushButton(QIcon(I('minus.png')), _('&Remove color scheme'), cp) rcs.clicked.connect(self.remove_color_scheme) l.addWidget(rcs, l.rowCount()-1, 2) self.styles_page = sp = QWidget(st) st.addTab(sp, _('&Styles')) sp.l = l = QVBoxLayout() sp.setLayout(l) if for_global_prefs: msg = _('When generating covers, a style for the cover is chosen at random from the' ' styles below. You can prevent an individual style from being selected by' ' unchecking it. The preview on the right shows the currently selected style.') else: msg = _('Choose a style to be used for this generated cover.') + '<p>' + _( 'In normal cover generation, the style is chosen at random from the list of styles below. You' ' can prevent an individual style from being chosen by unchecking it here.') sp.la = la = QLabel('<p>' + msg) la.setWordWrap(True) l.addWidget(la) self.styles_list = sl = QListWidget(sp) l.addWidget(sl) self.style_map = OrderedDict() self.font_page = fp = QWidget(st) st.addTab(fp, _('&Fonts and sizes')) fp.l = l = QFormLayout() fp.setLayout(l) fp.f = [] def add_hline(): f = QFrame() fp.f.append(f) f.setFrameShape(f.HLine) l.addRow(f) for x, label, size_label in ( ('title', _('&Title font family:'), _('&Title font size:')), ('subtitle', _('&Subtitle font family'), _('&Subtitle font size:')), ('footer', _('&Footer font family'), _('&Footer font size')), ): attr = '%s_font_family' % x ff = FontFamilyChooser(fp) setattr(self, attr, ff) l.addRow(label, ff) ff.family_changed.connect(self.emit_changed) attr = '%s_font_size' % x fs = QSpinBox(fp) setattr(self, attr, fs) fs.setMinimum(8), fs.setMaximum(200), fs.setSuffix(' px') fs.setValue(prefs[attr]) fs.valueChanged.connect(self.emit_changed) l.addRow(size_label, fs) add_hline() self.changed_timer = t = QTimer(self) t.setSingleShot(True), t.setInterval(500), t.timeout.connect(self.emit_changed) def create_sz(label): ans = QSpinBox(self) ans.setSuffix(' px'), ans.setMinimum(100), ans.setMaximum(10000) l.addRow(label, ans) ans.valueChanged.connect(self.changed_timer.start) return ans self.cover_width = create_sz(_('Cover &width:')) self.cover_height = create_sz(_('Cover &height:')) fp.cla = la = QLabel(_( 'Note that the preview to the side is of fixed aspect ratio, so changing the cover' ' width above will not have any effect. If you change the height, you should also change the width nevertheless' ' as it will be used in actual cover generation.')) la.setWordWrap(True) l.addRow(la) self.templates_page = tp = QWidget(st) st.addTab(tp, _('&Text')) tp.l = l = QVBoxLayout() tp.setLayout(l) tp.la = la = QLabel(_( 'The text on the generated cover is taken from the metadata of the book.' ' This is controlled via templates. You can use the <b>, <i> and <br> tags' ' in the templates for bold, italic and line breaks, respectively. The' ' default templates use the title, series and authors. You can change them to use' ' whatever metadata you like.')) la.setWordWrap(True), la.setTextFormat(Qt.PlainText) l.addWidget(la) 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) connect_lambda(b.clicked, self, lambda self: 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) create_template_widget(_('The title template'), 'title', _('Change the &title template')) create_template_widget(_('The sub-title template'), 'subtitle', _('Change the &sub-title template')) create_template_widget(_('The footer template'), 'footer', _('Change the &footer template')) l.addStretch(2) self.apply_prefs(prefs) self.changed.connect(self.update_preview) self.styles_list.itemSelectionChanged.connect(self.update_preview) self.colors_list.itemSelectionChanged.connect(self.update_preview) self.update_preview()
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)
class PrefsViewerDialog(SizePersistedDialog): def __init__(self, gui, namespace): SizePersistedDialog.__init__(self, gui, 'Prefs Viewer dialog') self.setWindowTitle('Preferences for: ' + namespace) self.db = gui.current_db self.namespace = namespace self._init_controls() self.resize_dialog() self._populate_settings() if self.keys_list.count(): self.keys_list.setCurrentRow(0) def _init_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(True) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok) button_box.accepted.connect(self.accept) button_box.setCenterButtons(True) layout.addWidget(button_box) def _populate_settings(self): self.keys_list.clear() ns_prefix = 'namespaced:%s:' % self.namespace keys = sorted([ k[len(ns_prefix):] for k in six.iterkeys(self.db.prefs) if k.startswith(ns_prefix) ]) for key in keys: self.keys_list.addItem(key) self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0)) self.keys_list.currentRowChanged[int].connect( self._current_row_changed) def _current_row_changed(self, new_row): if new_row < 0: self.value_text.clear() return key = unicode(self.keys_list.currentItem().text()) val = self.db.prefs.get_namespaced(self.namespace, key, '') self.value_text.setPlainText(self.db.prefs.to_raw(val))
class PrefsViewerDialog(SizePersistedDialog): def __init__(self, gui, namespace): SizePersistedDialog.__init__(self, gui, _('Prefs Viewer dialog')) self.setWindowTitle(_('Preferences for: ')+namespace) self.gui = gui self.db = gui.current_db self.namespace = namespace self._init_controls() self.resize_dialog() self._populate_settings() if self.keys_list.count(): self.keys_list.setCurrentRow(0) def _init_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(True) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok) button_box.accepted.connect(self.accept) self.clear_button = button_box.addButton(_('Clear'), QDialogButtonBox.ResetRole) self.clear_button.setIcon(get_icon('trash.png')) self.clear_button.setToolTip(_('Clear all settings for this plugin')) self.clear_button.clicked.connect(self._clear_settings) if DEBUG: self.edit_button = button_box.addButton(_('Edit'), QDialogButtonBox.ResetRole) self.edit_button.setIcon(get_icon('edit_input.png')) self.edit_button.setToolTip(_('Edit settings.')) self.edit_button.clicked.connect(self._edit_settings) self.save_button = button_box.addButton(_('Save'), QDialogButtonBox.ResetRole) self.save_button.setIcon(get_icon('save.png')) self.save_button.setToolTip(_('Save setting for this plugin')) self.save_button.clicked.connect(self._save_settings) self.save_button.setEnabled(False) layout.addWidget(button_box) def _populate_settings(self): self.keys_list.clear() ns_prefix = self._get_ns_prefix() keys = sorted([k[len(ns_prefix):] for k in self.db.prefs.iterkeys() if k.startswith(ns_prefix)]) for key in keys: self.keys_list.addItem(key) self.keys_list.setMinimumWidth(self.keys_list.sizeHintForColumn(0)) self.keys_list.currentRowChanged[int].connect(self._current_row_changed) def _current_row_changed(self, new_row): if new_row < 0: self.value_text.clear() return key = unicode(self.keys_list.currentItem().text()) val = self.db.prefs.get_namespaced(self.namespace, key, '') self.value_text.setPlainText(self.db.prefs.to_raw(val)) def _get_ns_prefix(self): return 'namespaced:%s:'% self.namespace def _edit_settings(self): from calibre.gui2.dialogs.confirm_delete import confirm message = '<p>' + _('Are you sure you want to edit settings in this library for this plugin?') + '</p>' \ + '<p>' + _('The FanFicFare team does not support hand edited configurations.') + '</p>' if confirm(message, self.namespace+'_edit_settings', self): self.save_button.setEnabled(True) self.edit_button.setEnabled(False) self.value_text.setReadOnly(False) def _save_settings(self): from calibre.gui2.dialogs.confirm_delete import confirm message = '<p>' + _('Are you sure you want to save this setting in this library for this plugin?') + '</p>' \ + '<p>' + _('Any settings in other libraries or stored in a JSON file in your calibre plugins folder will not be touched.') + '</p>' \ + '<p>' + _('You must restart calibre afterwards.') + '</p>' if not confirm(message, self.namespace+'_save_settings', self): return ns_prefix = self._get_ns_prefix() key = unicode(self.keys_list.currentItem().text()) self.db.prefs.set_namespaced(self.namespace, key, self.db.prefs.raw_to_object(self.value_text.toPlainText())) d = info_dialog(self, 'Settings saved', '<p>' + _('All settings for this plugin in this library have been saved.') + '</p>' \ + '<p>' + _('Please restart calibre now.') + '</p>', show_copy_button=False) b = d.bb.addButton(_('Restart calibre now'), d.bb.AcceptRole) b.setIcon(QIcon(I('lt.png'))) d.do_restart = False def rf(): d.do_restart = True b.clicked.connect(rf) d.set_details('') d.exec_() b.clicked.disconnect() self.close() if d.do_restart: self.gui.quit(restart=True) def _clear_settings(self): from calibre.gui2.dialogs.confirm_delete import confirm message = '<p>' + _('Are you sure you want to clear your settings in this library for this plugin?') + '</p>' \ + '<p>' + _('Any settings in other libraries or stored in a JSON file in your calibre plugins folder will not be touched.') + '</p>' \ + '<p>' + _('You must restart calibre afterwards.') + '</p>' if not confirm(message, self.namespace+'_clear_settings', self): return ns_prefix = self._get_ns_prefix() keys = [k for k in self.db.prefs.iterkeys() if k.startswith(ns_prefix)] for k in keys: del self.db.prefs[k] self._populate_settings() d = info_dialog(self, 'Settings deleted', '<p>' + _('All settings for this plugin in this library have been cleared.') + '</p>' \ + '<p>' + _('Please restart calibre now.') + '</p>', show_copy_button=False) b = d.bb.addButton(_('Restart calibre now'), d.bb.AcceptRole) b.setIcon(QIcon(I('lt.png'))) d.do_restart = False def rf(): d.do_restart = True b.clicked.connect(rf) d.set_details('') d.exec_() b.clicked.disconnect() self.close() if d.do_restart: self.gui.quit(restart=True)
class EventsQWidget(QWidget): """ Class who create QWidget for events """ def __init__(self): super(EventsQWidget, self).__init__() self.setObjectName('events') # Fields self.events_list = QListWidget() self.timer = QTimer() def initialize(self): """ Intialize QWidget """ self.timer.setInterval(30000) self.timer.start() self.timer.timeout.connect(self.send_datamanager_events) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.events_list.setDragDropMode(QAbstractItemView.DragOnly) self.events_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.events_list.setDropIndicatorShown(True) self.events_list.doubleClicked.connect(self.remove_event) self.events_list.setWordWrap(True) self.events_list.setIconSize(QSize(16, 16)) self.add_event( 'OK', _('Welcome %s, you are connected to Alignak Backend') % data_manager.database['user'].name, timer=True ) layout.addWidget(self.events_list) def send_datamanager_events(self): """ Add events stored in DataManager """ events = data_manager.get_events() if events: for event in events: self.add_event( event['event_type'], event['message'], timer=False, host=event['host'] ) def add_event(self, event_type, msg, timer=False, host=None): """ Add event to events list :param event_type: the type of event: OK, DOWN, ACK, ... :type event_type: str :param msg: message of event :type msg: str :param timer: timer to hide event at end of time :type timer: bool :param host: data of a host to set ``Qt.UserRole`` :type host: None | str """ if not self.event_exist(msg): logger.debug( 'Add Event: msg: %s, timer: %s, host: %s', msg, timer, host ) event = EventItem() event.initialize(event_type, msg, timer=timer, host=host) self.events_list.insertItem(0, event) if timer: event_duration = int( settings.get_config('Alignak-app', 'notification_duration') ) * 1000 QTimer.singleShot( event_duration, lambda: self.remove_timer_event(event) ) else: logger.debug( 'Event with msg: %s already exist.', msg ) def event_exist(self, msg): """ Check if event already displayed, move it to top and update tooltip. Only for EventItem who have a ``Qt.UserRole`` :param msg: message of event :type msg: str :return: if message exist or not in events QWidgetList :rtype: bool """ for i in range(0, self.events_list.count()): if self.events_list.item(i).data(Qt.DisplayRole) == msg: item = self.events_list.takeItem(i) msg_to_send = '%s. (Send at %s)' % (msg, get_current_time()) item.setToolTip(msg_to_send) self.events_list.insertItem(0, item) return True return False def remove_timer_event(self, event): """ Remove EventItem with timer :param event: EventItem with timer :type event: EventItem """ logger.debug('Remove Timer Event: %s', event.text()) self.events_list.takeItem(self.events_list.row(event)) def remove_event(self, item=None): """ Remove item when user double click on an item :param item: item to remove, else remove the current row :type item: EventItem """ if isinstance(item, EventItem): row = self.events_list.row(item) self.events_list.takeItem(row) else: item = self.events_list.takeItem(self.events_list.currentRow()) logger.debug('Remove Event: %s', item.text())
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QGridLayout(self) def add_row(*args): r = l.rowCount() if len(args) == 1: l.addWidget(args[0], r, 0, 1, 2) else: la = QLabel(args[0]) l.addWidget(la, r, 0, Qt.AlignRight), l.addWidget(args[1], r, 1) la.setBuddy(args[1]) self.heading = la = QLabel('<h2>\xa0') add_row(la) self.helpl = la = QLabel( _('For help with snippets, see the <a href="%s">User Manual</a>') % localize_user_manual_link( 'https://manual.calibre-ebook.com/snippets.html')) la.setOpenExternalLinks(True) add_row(la) self.name = n = QLineEdit(self) n.setPlaceholderText(_('The name of this snippet')) add_row(_('&Name:'), n) self.trig = t = QLineEdit(self) t.setPlaceholderText(_('The text used to trigger this snippet')) add_row(_('Tri&gger:'), t) self.template = t = QPlainTextEdit(self) la.setBuddy(t) add_row(_('&Template:'), t) self.types = t = QListWidget(self) t.setFlow(t.LeftToRight) t.setWrapping(True), t.setResizeMode(t.Adjust), t.setSpacing(5) fm = t.fontMetrics() t.setMaximumHeight(2 * (fm.ascent() + fm.descent()) + 25) add_row(_('&File types:'), t) t.setToolTip(_('Which file types this snippet should be active in')) self.frame = f = QFrame(self) f.setFrameShape(f.HLine) add_row(f) self.test = d = SnippetTextEdit('', self) d.snippet_manager.snip_func = self.snip_func d.setToolTip(_('You can test your snippet here')) d.setMaximumHeight(t.maximumHeight() + 15) add_row(_('T&est:'), d) i = QListWidgetItem(_('All'), t) i.setData(Qt.UserRole, '*') i.setCheckState(Qt.Checked) i.setFlags(i.flags() | Qt.ItemIsUserCheckable) for ftype in sorted(all_text_syntaxes): i = QListWidgetItem(ftype, t) i.setData(Qt.UserRole, ftype) i.setCheckState(Qt.Checked) i.setFlags(i.flags() | Qt.ItemIsUserCheckable) self.creating_snippet = False
def __init__(self, plugin): QWidget.__init__(self) self.plugin = plugin self.layout = QVBoxLayout() self.setLayout(self.layout) self.engine_location_label = QLabel('ElasticSearch engine location:') self.layout.addWidget(self.engine_location_label) self.elasticsearch_url_textbox = QLineEdit(self) self.elasticsearch_url_textbox.setText(prefs['elasticsearch_url']) self.layout.addWidget(self.elasticsearch_url_textbox) self.engine_location_label.setBuddy(self.elasticsearch_url_textbox) self.layout.addSpacing(10) self.pdftotext_path_label = QLabel('Path to pdftotext tool:') self.layout.addWidget(self.pdftotext_path_label) self.pdftotext_path_textbox = QLineEdit(self) self.pdftotext_path_textbox.setText(prefs['pdftotext_path']) self.layout.addWidget(self.pdftotext_path_textbox) self.pdftotext_path_label.setBuddy(self.pdftotext_path_textbox) self.layout.addSpacing(10) self.concurrency_label = QLabel( 'Number of parallel processes for text extraction:') self.layout.addWidget(self.concurrency_label) self.concurrency_textbox = QLineEdit(self) self.concurrency_textbox.setText(str(prefs['concurrency'])) self.layout.addWidget(self.concurrency_textbox) self.concurrency_label.setBuddy(self.concurrency_textbox) self.layout.addSpacing(10) self.formats_label = QLabel('Index book formats:') self.layout.addWidget(self.formats_label) file_formats = prefs['file_formats'].split(',') self.formats_list = QListWidget(self) for fmt in SUPPORTED_FORMATS: item = QListWidgetItem(fmt) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked if fmt in file_formats else Qt.Unchecked) self.formats_list.addItem(item) self.layout.addWidget(self.formats_list) self.formats_label.setBuddy(self.formats_list) self.layout.addSpacing(10) self.autoindex_checkbox = QCheckBox( "Automatically index new books on search", self) self.autoindex_checkbox.setCheckState( Qt.Checked if prefs['autoindex'] else Qt.Unchecked) self.layout.addWidget(self.autoindex_checkbox) self.layout.addSpacing(10) self.privacy_label = QLabel('Privacy:') self.layout.addWidget(self.privacy_label) self.clear_search_history_button = QPushButton('Clear search &history', self) self.clear_search_history_button.clicked.connect(self.on_clear_history) self.layout.addWidget(self.clear_search_history_button) self.clear_search_index_buttin = QPushButton('Clear search &index', self) self.clear_search_index_buttin.clicked.connect(self.on_clear_index) self.layout.addWidget(self.clear_search_index_buttin)