From eb9607772c8dbe662396567fa2bd40fc2c8e0bff Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 24 Nov 2015 18:17:44 +0100 Subject: [PATCH] Change "add your own columns" to display more info about the columns. --- src/calibre/gui2/preferences/columns.py | 143 ++++++++++++++---- src/calibre/gui2/preferences/columns.ui | 2 +- .../gui2/preferences/create_custom_column.py | 21 +-- 3 files changed, 122 insertions(+), 44 deletions(-) diff --git a/src/calibre/gui2/preferences/columns.py b/src/calibre/gui2/preferences/columns.py index 6060f3aa89..b52925ab45 100644 --- a/src/calibre/gui2/preferences/columns.py +++ b/src/calibre/gui2/preferences/columns.py @@ -7,8 +7,9 @@ __docformat__ = 'restructuredtext en' import copy, sys -from PyQt5.Qt import Qt, QListWidgetItem, QIcon +from PyQt5.Qt import Qt, QTableWidgetItem, QIcon, QHeaderView, QTimer +from calibre.gui2 import gprefs from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.columns_ui import Ui_Form from calibre.gui2.preferences.create_custom_column import CreateCustomColumn @@ -43,6 +44,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.changed_signal.emit() def commit(self): + widths = [] + for i in range(0, self.opt_columns.columnCount()): + widths.append(self.opt_columns.columnWidth(i)) + gprefs.set('custcol-prefs-table-geometry', widths) rr = ConfigWidgetBase.commit(self) return self.apply_custom_column_changes() or rr @@ -57,39 +62,105 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def init_columns(self, defaults=False): # Set up columns self.opt_columns.blockSignals(True) - model = self.gui.library_view.model() + self.model = model = self.gui.library_view.model() colmap = list(model.column_map) state = self.columns_state(defaults) - hidden_cols = state['hidden_columns'] + self.hidden_cols = state['hidden_columns'] positions = state['column_positions'] colmap.sort(cmp=lambda x,y: cmp(positions[x], positions[y])) self.opt_columns.clear() - for col in colmap: - item = QListWidgetItem(model.headers[col], self.opt_columns) - item.setData(Qt.UserRole, (col)) - if col.startswith('#'): - item.setData(Qt.DecorationRole, (QIcon(I('column.png')))) - flags = Qt.ItemIsEnabled|Qt.ItemIsSelectable - if col != 'ondevice': - flags |= Qt.ItemIsUserCheckable - item.setFlags(flags) - if col != 'ondevice': - item.setCheckState(Qt.Unchecked if col in hidden_cols else - Qt.Checked) + + 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.blockSignals(False) + def restore_geometry(self): + geom = gprefs.get('custcol-prefs-table-geometry', None) + if geom is not None and len(geom) == self.opt_columns.columnCount(): + try: + for i in range(0, self.opt_columns.columnCount()): + self.opt_columns.setColumnWidth(i, geom[i]) + except: + self.set_default_geometry() + else: + self.set_default_geometry() + + def set_default_geometry(self): + self.opt_columns.resizeColumnsToContents() + self.opt_columns.resizeRowsToContents() + + def setup_row(self, field_metadata, row, col): + item = QTableWidgetItem(col) + self.opt_columns.setItem(row, 1, item) + + if col.startswith('#'): + fm = self.custcols[col] + else: + fm = field_metadata[col] + dt = fm['datatype'] + if fm['is_multiple']: + dt = '*' + dt + item = QTableWidgetItem(self.column_desc[dt]) + self.opt_columns.setItem(row, 2, item) + + desc = fm['display'].get('description', "") + item = QTableWidgetItem(desc) + self.opt_columns.setItem(row, 3, item) + + item = QTableWidgetItem(fm['name']) + item.setData(Qt.UserRole, (col)) + self.opt_columns.setItem(row, 0, item) + + if col.startswith('#'): + item.setData(Qt.DecorationRole, (QIcon(I('column.png')))) + flags = Qt.ItemIsEnabled|Qt.ItemIsSelectable + if col != 'ondevice': + flags |= Qt.ItemIsUserCheckable + item.setFlags(flags) + if col != 'ondevice': + item.setCheckState(Qt.Unchecked if col in self.hidden_cols else + Qt.Checked) + def up_column(self): idx = self.opt_columns.currentRow() if idx > 0: - self.opt_columns.insertItem(idx-1, self.opt_columns.takeItem(idx)) - self.opt_columns.setCurrentRow(idx-1) + for i in range(0, self.opt_columns.columnCount()): + lower = self.opt_columns.takeItem(idx-1, i) + upper = self.opt_columns.takeItem(idx, i) + self.opt_columns.setItem(idx, i, lower) + self.opt_columns.setItem(idx-1, i, upper) + self.opt_columns.setCurrentCell(idx-1, 0) self.changed_signal.emit() def down_column(self): idx = self.opt_columns.currentRow() - if idx < self.opt_columns.count()-1: - self.opt_columns.insertItem(idx+1, self.opt_columns.takeItem(idx)) - self.opt_columns.setCurrentRow(idx+1) + if idx < self.opt_columns.rowCount()-1: + for i in range(0, self.opt_columns.columnCount()): + lower = self.opt_columns.takeItem(idx, i) + upper = self.opt_columns.takeItem(idx+1, i) + self.opt_columns.setItem(idx+1, i, lower) + self.opt_columns.setItem(idx, i, upper) + self.opt_columns.setCurrentCell(idx+1, 0) self.changed_signal.emit() def del_custcol(self): @@ -97,7 +168,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if idx < 0: return error_dialog(self, '', _('You must select a column to delete it'), show=True) - col = unicode(self.opt_columns.item(idx).data(Qt.UserRole) or '') + col = unicode(self.opt_columns.item(idx, 0).data(Qt.UserRole) or '') if col not in self.custcols: return error_dialog(self, '', _('The selected column is not a custom column'), show=True) @@ -105,8 +176,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): _('Do you really want to delete column %s and all its data?') % self.custcols[col]['name'], show_copy_button=False): return - self.opt_columns.item(idx).setCheckState(False) - self.opt_columns.takeItem(idx) + self.opt_columns.removeRow(idx) if self.custcols[col]['colnum'] is None: del self.custcols[col] # A newly-added column was deleted else: @@ -115,25 +185,38 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def add_custcol(self): model = self.gui.library_view.model() - CreateCustomColumn(self, False, model.orig_headers, ALL_COLUMNS) + CreateCustomColumn(self, None, None, model.orig_headers, ALL_COLUMNS) + if self.cc_column_key is None: + return + row = self.opt_columns.rowCount() + self.opt_columns.setRowCount(row + 1) + self.setup_row(self.field_metadata, row, self.cc_column_key) self.changed_signal.emit() def edit_custcol(self): model = self.gui.library_view.model() - CreateCustomColumn(self, True, model.orig_headers, ALL_COLUMNS) + row = self.opt_columns.currentRow() + try: + key = unicode(self.opt_columns.item(row, 0).data(Qt.UserRole)) + except: + key = '' + CreateCustomColumn(self, row, key, model.orig_headers, ALL_COLUMNS) + if self.cc_column_key is None: + return + self.setup_row(self.field_metadata, row, self.cc_column_key) self.changed_signal.emit() def apply_custom_column_changes(self): model = self.gui.library_view.model() db = model.db - config_cols = [unicode(self.opt_columns.item(i).data(Qt.UserRole) or '')\ - for i in range(self.opt_columns.count())] + config_cols = [unicode(self.opt_columns.item(i, 0).data(Qt.UserRole) or '')\ + for i in range(self.opt_columns.rowCount())] if not config_cols: config_cols = ['title'] removed_cols = set(model.column_map) - set(config_cols) - hidden_cols = set([unicode(self.opt_columns.item(i).data(Qt.UserRole) or '')\ - for i in range(self.opt_columns.count()) \ - if self.opt_columns.item(i).checkState()==Qt.Unchecked]) + hidden_cols = set([unicode(self.opt_columns.item(i, 0).data(Qt.UserRole) or '')\ + for i in range(self.opt_columns.rowCount()) \ + if self.opt_columns.item(i, 0).checkState()==Qt.Unchecked]) hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols hidden_cols = list(hidden_cols.intersection(set(model.column_map))) if 'ondevice' in hidden_cols: diff --git a/src/calibre/gui2/preferences/columns.ui b/src/calibre/gui2/preferences/columns.ui index 423d5dd106..0b1caf10be 100644 --- a/src/calibre/gui2/preferences/columns.ui +++ b/src/calibre/gui2/preferences/columns.ui @@ -25,7 +25,7 @@ - + true diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index 225116ad18..2c0fe64fe9 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -6,7 +6,7 @@ __copyright__ = '2010, Kovid Goyal ' import re from functools import partial -from PyQt5.Qt import QDialog, Qt, QListWidgetItem, QColor, QIcon +from PyQt5.Qt import QDialog, Qt, QListWidgetItem, QColor, QIcon, QTableWidgetItem from calibre.gui2.preferences.create_custom_column_ui import Ui_QCreateCustomColumn from calibre.gui2 import error_dialog @@ -48,7 +48,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): 'text':_('Column built from other columns, behaves like tags'), 'is_multiple':True}, } - def __init__(self, parent, editing, standard_colheads, standard_colnames): + def __init__(self, parent, current_row, current_key, standard_colheads, standard_colnames): QDialog.__init__(self, parent) Ui_QCreateCustomColumn.__init__(self) self.setupUi(self) @@ -77,7 +77,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.composite_sort_by.addItem(sort_by) self.parent = parent - self.editing_col = editing + self.parent.cc_column_key = None + self.editing_col = current_row is not None self.standard_colheads = standard_colheads self.standard_colnames = standard_colnames self.column_type_box.setMaxVisibleItems(len(self.column_types)) @@ -96,12 +97,12 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.setWindowTitle(_('Edit a custom column')) self.heading_label.setText(_('Edit a custom column')) self.shortcuts.setVisible(False) - idx = parent.opt_columns.currentRow() + idx = current_row if idx < 0: self.simple_error(_('No column selected'), _('No column has been selected')) return - col = unicode(parent.opt_columns.item(idx).data(Qt.UserRole) or '') + col = current_key if col not in parent.custcols: self.simple_error('', _('Selected column is not a user-defined column')) return @@ -325,20 +326,14 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): 'colnum':None, 'is_multiple':is_multiple, } - item = QListWidgetItem(col_heading, self.parent.opt_columns) - item.setData(Qt.UserRole, (key)) - item.setData(Qt.DecorationRole, (QIcon(I('column.png')))) - item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable) - item.setCheckState(Qt.Checked) + self.parent.cc_column_key = key else: - idx = self.parent.opt_columns.currentRow() - item = self.parent.opt_columns.item(idx) - item.setText(col_heading) self.parent.custcols[self.orig_column_name]['label'] = col self.parent.custcols[self.orig_column_name]['name'] = col_heading self.parent.custcols[self.orig_column_name]['display'].update(display_dict) self.parent.custcols[self.orig_column_name]['*edited'] = True self.parent.custcols[self.orig_column_name]['*must_restart'] = True + self.parent.cc_column_key = key QDialog.accept(self) def reject(self):