def __init__(self, sort_key): QTableWidgetItem.__init__(self) self.initial_value = '' self.current_value = '' self.is_deleted = False self.is_placeholder = False self.sort_key = sort_key
def init_columns(self, defaults=False): # Set up columns self.opt_columns.blockSignals(True) self.model = model = self.gui.library_view.model() colmap = list(model.column_map) state = self.columns_state(defaults) self.hidden_cols = state['hidden_columns'] positions = state['column_positions'] colmap.sort(key=lambda x: positions[x]) self.opt_columns.clear() db = model.db self.field_metadata = db.field_metadata self.opt_columns.setColumnCount(4) item = QTableWidgetItem(_('Column header')) self.opt_columns.setHorizontalHeaderItem(0, item) item = QTableWidgetItem(_('Lookup name')) self.opt_columns.setHorizontalHeaderItem(1, item) item = QTableWidgetItem(_('Type')) self.opt_columns.setHorizontalHeaderItem(2, item) item = QTableWidgetItem(_('Description')) self.opt_columns.setHorizontalHeaderItem(3, item) self.opt_columns.setRowCount(len(colmap)) self.column_desc = dict(map(lambda x:(CreateCustomColumn.column_types[x]['datatype'], CreateCustomColumn.column_types[x]['text']), CreateCustomColumn.column_types)) for row, col in enumerate(colmap): self.setup_row(self.field_metadata, row, col) self.restore_geometry() self.opt_columns.cellDoubleClicked.connect(self.row_double_clicked) self.opt_columns.blockSignals(False)
def setup_ui(self): self.l = l = QVBoxLayout(self) self.la = la = QLabel( _('Create rules to convert identifiers into links.')) la.setWordWrap(True) l.addWidget(la) items = [] for k, lx in iteritems(msprefs['id_link_rules']): for n, t in lx: items.append((k, n, t)) items.sort(key=lambda x: sort_key(x[1])) self.table = t = QTableWidget(len(items), 3, self) t.setHorizontalHeaderLabels([_('Key'), _('Name'), _('Template')]) for r, (key, val, template) in enumerate(items): t.setItem(r, 0, QTableWidgetItem(key)) t.setItem(r, 1, QTableWidgetItem(val)) t.setItem(r, 2, QTableWidgetItem(template)) l.addWidget(t) t.horizontalHeader().setSectionResizeMode(2, t.horizontalHeader().Stretch) self.cb = b = QPushButton(QIcon(I('plus.png')), _('&Add rule'), self) connect_lambda(b.clicked, self, lambda self: self.edit_rule()) self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole) self.rb = b = QPushButton(QIcon(I('minus.png')), _('&Remove rule'), self) connect_lambda(b.clicked, self, lambda self: self.remove_rule()) self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole) self.eb = b = QPushButton(QIcon(I('modified.png')), _('&Edit rule'), self) connect_lambda(b.clicked, self, lambda self: self.edit_rule(self.table.currentRow())) self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole) l.addWidget(self.bb)
def __init__(self, getter=None): self.val = '' self.sort = None self.sort_idx = 0 self.getter = getter self.resolved = False QTableWidgetItem.__init__(self, '') self.setFlags(Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable)
def __init__(self, parent, get_option, get_help, db=None, book_id=None): # Dummy attributes to fool the Widget() option handler code. We handle # everything in our *handler methods. for i in range(1, 4): x = 'sr%d_' % i for y in ('search', 'replace'): z = x + y setattr(self, 'opt_' + z, z) self.opt_search_replace = 'search_replace' Widget.__init__(self, parent, OPTIONS['pipe']['search_and_replace']) self.db, self.book_id = db, book_id self.sr_search.set_msg(_('&Search regular expression:')) self.sr_search.set_book_id(book_id) self.sr_search.set_db(db) self.sr_search.doc_update.connect(self.update_doc) proto = QTableWidgetItem() proto.setFlags( Qt.ItemFlags(Qt.ItemFlag.ItemIsSelectable + Qt.ItemFlag.ItemIsEnabled)) self.search_replace.setItemPrototype(proto) self.search_replace.setColumnCount(2) self.search_replace.setColumnWidth(0, 320) self.search_replace.setColumnWidth(1, 320) self.search_replace.setHorizontalHeaderLabels( [_('Search regular expression'), _('Replacement text')]) self.sr_add.clicked.connect(self.sr_add_clicked) self.sr_change.clicked.connect(self.sr_change_clicked) self.sr_remove.clicked.connect(self.sr_remove_clicked) self.sr_load.clicked.connect(self.sr_load_clicked) self.sr_save.clicked.connect(self.sr_save_clicked) self.sr_up.clicked.connect(self.sr_up_clicked) self.sr_down.clicked.connect(self.sr_down_clicked) self.search_replace.currentCellChanged.connect( self.sr_currentCellChanged) self.initialize_options(get_option, get_help, db, book_id) try: self.rh_label.setText( self.rh_label.text() % localize_user_manual_link( 'https://manual.calibre-ebook.com/regexp.html')) except TypeError: pass # link already localized
def data(self, role): if role == Qt.ItemDataRole.DisplayRole: if self.is_deleted: return '' return self.current_value elif role == Qt.ItemDataRole.EditRole: return self.current_value else: return QTableWidgetItem.data(self, role)
def move_row(self, row, direction): t = self.table.item(row, 0).text() c = self.table.cellWidget(row, 1).currentIndex() self.table.removeRow(row) row += direction self.table.insertRow(row) self.table.setItem(row, 0, QTableWidgetItem(t)) self.make_color_combobox(row, c) self.table.setCurrentCell(row, 0)
def __init__(self, parent, items): QDialog.__init__(self, parent) Ui_DeleteMatchingFromDeviceDialog.__init__(self) self.setupUi(self) self.explanation.setText('<p>' + _('All checked books will be ' '<b>permanently deleted</b> from your ' 'device. Please verify the list.') + '</p>') self.buttonBox.accepted.connect(self.accepted) self.buttonBox.rejected.connect(self.rejected) self.table.cellClicked.connect(self.cell_clicked) self.table.setSelectionMode( QAbstractItemView.SelectionMode.NoSelection) self.table.setColumnCount(7) self.table.setHorizontalHeaderLabels([ '', _('Location'), _('Title'), _('Author'), _('Date'), _('Format'), _('Path') ]) rows = 0 for card in items: rows += len(items[card][1]) self.table.setRowCount(rows) row = 0 for card in items: (model, books) = items[card] for (id, book) in books: item = QTableWidgetItem() item.setFlags(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsEnabled) item.setCheckState(Qt.CheckState.Checked) item.setData(Qt.ItemDataRole.UserRole, (model, id, book.path)) self.table.setItem(row, 0, item) self.table.setItem(row, 1, tableItem(card)) self.table.setItem(row, 2, titleTableItem(book.title)) self.table.setItem(row, 3, authorTableItem(book)) self.table.setItem(row, 4, dateTableItem(book.datetime)) self.table.setItem( row, 5, centeredTableItem(book.path.rpartition('.')[2])) self.table.setItem(row, 6, tableItem(book.path)) row += 1 self.table.setCurrentCell(0, 1) self.table.resizeColumnsToContents() self.table.setSortingEnabled(True) self.table.sortByColumn(2, Qt.SortOrder.AscendingOrder) self.table.setCurrentCell(0, 1)
def add_columns_to_widget(self): ''' Get the list of columns from the preferences. Clear the current table and add the current column set ''' self.column_order = [x[0] for x in get_qv_field_list(self.fm) if x[1]] self.books_table.clear() self.books_table.setRowCount(0) self.books_table.setColumnCount(len(self.column_order)) for idx, col in enumerate(self.column_order): t = QTableWidgetItem(self.fm[col]['name']) self.books_table.setHorizontalHeaderItem(idx, t)
def ins_button_clicked(self): row = self.table.currentRow() if row < 0: error_dialog(self, _('Select a cell'), _('Select a cell before clicking the button'), show=True) return self.table.insertRow(row) self.table.setItem(row, 0, QTableWidgetItem()) c = QComboBox(self) c.addItem('') c.addItems(QColor.colorNames()) self.table.setCellWidget(row, 1, c)
def edit_rule(self, r=-1): key = name = template = '' if r > -1: key, name, template = map(lambda c: self.table.item(r, c).text(), range(3)) d = IdLinksRuleEdit(key, name, template, self) if d.exec_() == QDialog.DialogCode.Accepted: if r < 0: self.table.setRowCount(self.table.rowCount() + 1) r = self.table.rowCount() - 1 rule = d.rule for c in range(3): self.table.setItem(r, c, QTableWidgetItem(rule[c])) self.table.scrollToItem(self.table.item(r, 0))
def __init__(self, parent, db, key): QDialog.__init__(self, parent) self.setWindowTitle(_('Edit permissible values for {0}').format(key)) self.db = db l = QGridLayout() bbox = QVBoxLayout() bbox.addStretch(10) self.del_button = QToolButton() self.del_button.setIcon(QIcon(I('trash.png'))) self.del_button.setToolTip(_('Remove the currently selected value')) self.ins_button = QToolButton() self.ins_button.setIcon(QIcon(I('plus.png'))) self.ins_button.setToolTip(_('Add a new permissible value')) self.move_up_button = QToolButton() self.move_up_button.setIcon(QIcon(I('arrow-up.png'))) self.move_down_button = QToolButton() self.move_down_button.setIcon(QIcon(I('arrow-down.png'))) bbox.addWidget(self.del_button) bbox.addStretch(1) bbox.addWidget(self.ins_button) bbox.addStretch(1) bbox.addWidget(self.move_up_button) bbox.addStretch(1) bbox.addWidget(self.move_down_button) bbox.addStretch(10) l.addItem(bbox, 0, 0) self.del_button.clicked.connect(self.del_line) self.all_colors = {unicode_type(s) for s in list(QColor.colorNames())} tl = QVBoxLayout() l.addItem(tl, 0, 1) self.table = t = QTableWidget(parent) t.setColumnCount(2) t.setRowCount(1) t.setHorizontalHeaderLabels([_('Value'), _('Color')]) t.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) tl.addWidget(t) self.fm = fm = db.field_metadata[key] permitted_values = fm.get('display', {}).get('enum_values', '') colors = fm.get('display', {}).get('enum_colors', '') t.setRowCount(len(permitted_values)) for i, v in enumerate(permitted_values): t.setItem(i, 0, QTableWidgetItem(v)) c = self.make_color_combobox(i, -1) if colors: c.setCurrentIndex(c.findText(colors[i])) else: c.setCurrentIndex(0) t.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeMode.Stretch) self.setLayout(l) self.bb = bb = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addWidget(bb, 1, 0, 1, 2) self.ins_button.clicked.connect(self.ins_button_clicked) self.move_down_button.clicked.connect(self.move_down_clicked) self.move_up_button.clicked.connect(self.move_up_clicked) geom = gprefs.get('enum-values-edit-geometry') if geom is not None: QApplication.instance().safe_restore_geometry(self, geom)
def __init__(self, gui, view, id_, row_index): QDialog.__init__(self, gui, flags=Qt.WindowType.Window) Ui_MatchBooks.__init__(self) self.setupUi(self) self.isClosed = False self.books_table_column_widths = None try: self.books_table_column_widths = \ gprefs.get('match_books_dialog_books_table_widths', None) geom = gprefs.get('match_books_dialog_geometry', None) if geom: QApplication.instance().safe_restore_geometry( self, QByteArray(geom)) except: pass self.search_text.initialize('match_books_dialog') # Remove the help button from the window title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags() & (~Qt.WindowType.WindowContextHelpButtonHint)) self.setWindowIcon(icon) self.device_db = view.model().db self.library_db = gui.library_view.model().db self.view = view self.gui = gui self.current_device_book_id = id_ self.current_device_book_index = row_index self.current_library_book_id = None # Set up the books table columns self.books_table.setSelectionBehavior( QAbstractItemView.SelectionBehavior.SelectRows) self.books_table.setSelectionMode( QAbstractItemView.SelectionMode.SingleSelection) self.books_table.setColumnCount(3) t = QTableWidgetItem(_('Title')) self.books_table.setHorizontalHeaderItem(0, t) t = QTableWidgetItem(_('Authors')) self.books_table.setHorizontalHeaderItem(1, t) t = QTableWidgetItem(ngettext("Series", 'Series', 1)) self.books_table.setHorizontalHeaderItem(2, t) self.books_table_header_height = self.books_table.height() self.books_table.cellDoubleClicked.connect(self.book_doubleclicked) self.books_table.cellClicked.connect(self.book_clicked) self.books_table.sortByColumn(0, Qt.SortOrder.AscendingOrder) # get the standard table row height. Do this here because calling # resizeRowsToContents can word wrap long cell contents, creating # double-high rows self.books_table.setRowCount(1) self.books_table.setItem(0, 0, TableItem('A', '')) self.books_table.resizeRowsToContents() self.books_table_row_height = self.books_table.rowHeight(0) self.books_table.setRowCount(0) self.search_button.clicked.connect(self.do_search) self.search_button.setDefault(False) self.search_text.lineEdit().returnPressed.connect(self.return_pressed) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.ignore_next_key = False search_text = self.device_db[self.current_device_book_id].title search_text = search_text.replace('(', '\\(').replace(')', '\\)') self.search_text.setText(search_text)
def __init__(self, val, sort, idx=0): self.sort = sort self.sort_idx = idx QTableWidgetItem.__init__(self, val) self.setFlags(Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable)
def __init__(self, text): QTableWidgetItem.__init__(self, text) self.setFlags(Qt.ItemFlag.ItemIsEnabled) self.sort = text.lower()
def __init__(self, count): QTableWidgetItem.__init__(self, str(count)) self._count = count
def __init__(self, count): QTableWidgetItem.__init__(self, unicode_type(count)) self._count = count
def setData(self, role, data): if role == Qt.ItemDataRole.EditRole: self.current_value = data QTableWidgetItem.setData(self, role, data)
def __init__(self, txt): QTableWidgetItem.__init__(self, txt) self.sort_key = sort_key(str(txt))
def setText(self, txt): self.sort_key = sort_key(unicode_type(txt)) QTableWidgetItem.setText(self, txt)
def __init__(self, txt): QTableWidgetItem.__init__(self, txt) self.sort_key = sort_key(unicode_type(txt))
def setText(self, txt): self.sort_key = sort_key(str(txt)) QTableWidgetItem.setText(self, txt)
def setText(self, txt): self.is_placeholder = False self.current_value = txt QTableWidgetItem.setText(self, txt)
def setup_row(self, field_metadata, row, col, oldkey=None): flags = Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable item = QTableWidgetItem(col) item.setFlags(flags) self.opt_columns.setItem(row, 1, item) if col.startswith('#'): fm = self.custcols[oldkey if oldkey is not None else col] else: fm = field_metadata[col] if col == 'title': coltype = _('Text') elif col == 'ondevice': coltype = _('Yes/No with text') else: dt = fm['datatype'] if fm['is_multiple']: if col == 'authors' or fm.get('display', {}).get('is_names', False): coltype = _('Ampersand separated text, shown in the Tag browser') else: coltype = self.column_desc['*' + dt] else: coltype = self.column_desc[dt] coltype_info = (coltype if oldkey is None else ' ' + _('(lookup name was {}) {}'.format(oldkey, coltype))) item = QTableWidgetItem(coltype_info) item.setFlags(flags) self.opt_columns.setItem(row, 2, item) desc = fm['display'].get('description', "") item = QTableWidgetItem(desc) item.setFlags(flags) self.opt_columns.setItem(row, 3, item) item = QTableWidgetItem(fm['name']) item.setData(Qt.ItemDataRole.UserRole, (col)) item.setFlags(flags) self.opt_columns.setItem(row, 0, item) if col.startswith('#'): item.setData(Qt.ItemDataRole.DecorationRole, (QIcon(I('column.png')))) if col != 'ondevice': flags |= Qt.ItemFlag.ItemIsUserCheckable item.setFlags(flags) if col != 'ondevice': item.setCheckState(Qt.CheckState.Unchecked if col in self.hidden_cols else Qt.CheckState.Checked)
def data(self, role): self.get_data() if role == Qt.DisplayRole: return self.val return QTableWidgetItem.data(self, role)
def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter): data = self.get_book_ids(self.apply_vl_checkbox.isChecked()) self.all_tags = {} filter_text = icu_lower(str(self.filter_box.text())) for k, v, count in data: if not filter_text or self.string_contains(filter_text, icu_lower(v)): self.all_tags[v] = { 'key': k, 'count': count, 'cur_name': v, 'is_deleted': k in self.to_delete } self.original_names[k] = v if self.is_enumerated: self.edit_delegate.set_completion_data(self.enum_permitted_values) else: self.edit_delegate.set_completion_data( self.original_names.values()) self.ordered_tags = sorted(self.all_tags.keys(), key=self.sorter) if tags is None: tags = self.ordered_tags select_item = None self.table.blockSignals(True) self.table.clear() self.table.setColumnCount(3) self.name_col = QTableWidgetItem(self.category_name) self.table.setHorizontalHeaderItem(0, self.name_col) self.count_col = QTableWidgetItem(_('Count')) self.table.setHorizontalHeaderItem(1, self.count_col) self.was_col = QTableWidgetItem(_('Was')) self.table.setHorizontalHeaderItem(2, self.was_col) self.table.setRowCount(len(tags)) for row, tag in enumerate(tags): item = NameTableWidgetItem(self.sorter) item.set_is_deleted(self.all_tags[tag]['is_deleted']) _id = self.all_tags[tag]['key'] item.setData(Qt.ItemDataRole.UserRole, _id) item.set_initial_text(tag) if _id in self.to_rename: item.setText(self.to_rename[_id]) else: item.setText(tag) if self.is_enumerated and str( item.text()) not in self.enum_permitted_values: item.setBackground(QColor('#FF2400')) item.setToolTip( '<p>' + _("This is not one of this column's permitted values ({0})" ).format(', '.join(self.enum_permitted_values)) + '</p>') item.setFlags(item.flags() | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable) self.table.setItem(row, 0, item) if select_item is None: if ttm_is_first_letter: if primary_startswith(tag, tag_to_match): select_item = item elif tag == tag_to_match: select_item = item item = CountTableWidgetItem(self.all_tags[tag]['count']) # only the name column can be selected item.setFlags( item.flags() & ~(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable)) self.table.setItem(row, 1, item) item = QTableWidgetItem() item.setFlags( item.flags() & ~(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable)) if _id in self.to_rename or _id in self.to_delete: item.setData(Qt.ItemDataRole.DisplayRole, tag) self.table.setItem(row, 2, item) if self.last_sorted_by == 'name': self.table.sortByColumn(0, self.name_order) elif self.last_sorted_by == 'count': self.table.sortByColumn(1, self.count_order) else: self.table.sortByColumn(2, self.was_order) if select_item is not None: self.table.setCurrentItem(select_item) self.table.setFocus(Qt.FocusReason.OtherFocusReason) self.start_find_pos = select_item.row() else: self.table.setCurrentCell(0, 0) self.search_box.setFocus() self.start_find_pos = -1 self.table.blockSignals(False)