Preferenes->Add your own columns: Show more information about existing columns

Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
Kovid Goyal 2015-11-24 22:52:29 +05:30
commit b99d56acc7
3 changed files with 122 additions and 44 deletions

View File

@ -7,8 +7,9 @@ __docformat__ = 'restructuredtext en'
import copy, sys 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 import ConfigWidgetBase, test_widget
from calibre.gui2.preferences.columns_ui import Ui_Form from calibre.gui2.preferences.columns_ui import Ui_Form
from calibre.gui2.preferences.create_custom_column import CreateCustomColumn from calibre.gui2.preferences.create_custom_column import CreateCustomColumn
@ -43,6 +44,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.changed_signal.emit() self.changed_signal.emit()
def commit(self): 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) rr = ConfigWidgetBase.commit(self)
return self.apply_custom_column_changes() or rr return self.apply_custom_column_changes() or rr
@ -57,39 +62,105 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
def init_columns(self, defaults=False): def init_columns(self, defaults=False):
# Set up columns # Set up columns
self.opt_columns.blockSignals(True) self.opt_columns.blockSignals(True)
model = self.gui.library_view.model() self.model = model = self.gui.library_view.model()
colmap = list(model.column_map) colmap = list(model.column_map)
state = self.columns_state(defaults) state = self.columns_state(defaults)
hidden_cols = state['hidden_columns'] self.hidden_cols = state['hidden_columns']
positions = state['column_positions'] positions = state['column_positions']
colmap.sort(cmp=lambda x,y: cmp(positions[x], positions[y])) colmap.sort(cmp=lambda x,y: cmp(positions[x], positions[y]))
self.opt_columns.clear() self.opt_columns.clear()
for col in colmap:
item = QListWidgetItem(model.headers[col], self.opt_columns) db = model.db
item.setData(Qt.UserRole, (col)) self.field_metadata = db.field_metadata
if col.startswith('#'):
item.setData(Qt.DecorationRole, (QIcon(I('column.png')))) self.opt_columns.setColumnCount(4)
flags = Qt.ItemIsEnabled|Qt.ItemIsSelectable item = QTableWidgetItem(_('Column Header'))
if col != 'ondevice': self.opt_columns.setHorizontalHeaderItem(0, item)
flags |= Qt.ItemIsUserCheckable item = QTableWidgetItem(_('Lookup name'))
item.setFlags(flags) self.opt_columns.setHorizontalHeaderItem(1, item)
if col != 'ondevice': item = QTableWidgetItem(_('Type'))
item.setCheckState(Qt.Unchecked if col in hidden_cols else self.opt_columns.setHorizontalHeaderItem(2, item)
Qt.Checked) 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) 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): def up_column(self):
idx = self.opt_columns.currentRow() idx = self.opt_columns.currentRow()
if idx > 0: if idx > 0:
self.opt_columns.insertItem(idx-1, self.opt_columns.takeItem(idx)) for i in range(0, self.opt_columns.columnCount()):
self.opt_columns.setCurrentRow(idx-1) 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() self.changed_signal.emit()
def down_column(self): def down_column(self):
idx = self.opt_columns.currentRow() idx = self.opt_columns.currentRow()
if idx < self.opt_columns.count()-1: if idx < self.opt_columns.rowCount()-1:
self.opt_columns.insertItem(idx+1, self.opt_columns.takeItem(idx)) for i in range(0, self.opt_columns.columnCount()):
self.opt_columns.setCurrentRow(idx+1) 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() self.changed_signal.emit()
def del_custcol(self): def del_custcol(self):
@ -97,7 +168,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
if idx < 0: if idx < 0:
return error_dialog(self, '', _('You must select a column to delete it'), return error_dialog(self, '', _('You must select a column to delete it'),
show=True) 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: if col not in self.custcols:
return error_dialog(self, '', return error_dialog(self, '',
_('The selected column is not a custom column'), show=True) _('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?') % _('Do you really want to delete column %s and all its data?') %
self.custcols[col]['name'], show_copy_button=False): self.custcols[col]['name'], show_copy_button=False):
return return
self.opt_columns.item(idx).setCheckState(False) self.opt_columns.removeRow(idx)
self.opt_columns.takeItem(idx)
if self.custcols[col]['colnum'] is None: if self.custcols[col]['colnum'] is None:
del self.custcols[col] # A newly-added column was deleted del self.custcols[col] # A newly-added column was deleted
else: else:
@ -115,25 +185,38 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
def add_custcol(self): def add_custcol(self):
model = self.gui.library_view.model() 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() self.changed_signal.emit()
def edit_custcol(self): def edit_custcol(self):
model = self.gui.library_view.model() 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() self.changed_signal.emit()
def apply_custom_column_changes(self): def apply_custom_column_changes(self):
model = self.gui.library_view.model() model = self.gui.library_view.model()
db = model.db db = model.db
config_cols = [unicode(self.opt_columns.item(i).data(Qt.UserRole) or '')\ config_cols = [unicode(self.opt_columns.item(i, 0).data(Qt.UserRole) or '')\
for i in range(self.opt_columns.count())] for i in range(self.opt_columns.rowCount())]
if not config_cols: if not config_cols:
config_cols = ['title'] config_cols = ['title']
removed_cols = set(model.column_map) - set(config_cols) removed_cols = set(model.column_map) - set(config_cols)
hidden_cols = set([unicode(self.opt_columns.item(i).data(Qt.UserRole) or '')\ hidden_cols = set([unicode(self.opt_columns.item(i, 0).data(Qt.UserRole) or '')\
for i in range(self.opt_columns.count()) \ for i in range(self.opt_columns.rowCount()) \
if self.opt_columns.item(i).checkState()==Qt.Unchecked]) if self.opt_columns.item(i, 0).checkState()==Qt.Unchecked])
hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols
hidden_cols = list(hidden_cols.intersection(set(model.column_map))) hidden_cols = list(hidden_cols.intersection(set(model.column_map)))
if 'ondevice' in hidden_cols: if 'ondevice' in hidden_cols:

View File

@ -25,7 +25,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QListWidget" name="opt_columns"> <widget class="QTableWidget" name="opt_columns">
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>true</bool> <bool>true</bool>
</property> </property>

View File

@ -6,7 +6,7 @@ __copyright__ = '2010, Kovid Goyal <kovid at kovidgoyal.net>'
import re import re
from functools import partial 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.preferences.create_custom_column_ui import Ui_QCreateCustomColumn
from calibre.gui2 import error_dialog 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}, '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) QDialog.__init__(self, parent)
Ui_QCreateCustomColumn.__init__(self) Ui_QCreateCustomColumn.__init__(self)
self.setupUi(self) self.setupUi(self)
@ -77,7 +77,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
self.composite_sort_by.addItem(sort_by) self.composite_sort_by.addItem(sort_by)
self.parent = parent 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_colheads = standard_colheads
self.standard_colnames = standard_colnames self.standard_colnames = standard_colnames
self.column_type_box.setMaxVisibleItems(len(self.column_types)) 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.setWindowTitle(_('Edit a custom column'))
self.heading_label.setText(_('Edit a custom column')) self.heading_label.setText(_('Edit a custom column'))
self.shortcuts.setVisible(False) self.shortcuts.setVisible(False)
idx = parent.opt_columns.currentRow() idx = current_row
if idx < 0: if idx < 0:
self.simple_error(_('No column selected'), self.simple_error(_('No column selected'),
_('No column has been selected')) _('No column has been selected'))
return return
col = unicode(parent.opt_columns.item(idx).data(Qt.UserRole) or '') col = current_key
if col not in parent.custcols: if col not in parent.custcols:
self.simple_error('', _('Selected column is not a user-defined column')) self.simple_error('', _('Selected column is not a user-defined column'))
return return
@ -325,20 +326,14 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
'colnum':None, 'colnum':None,
'is_multiple':is_multiple, 'is_multiple':is_multiple,
} }
item = QListWidgetItem(col_heading, self.parent.opt_columns) self.parent.cc_column_key = key
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)
else: 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]['label'] = col
self.parent.custcols[self.orig_column_name]['name'] = col_heading 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]['display'].update(display_dict)
self.parent.custcols[self.orig_column_name]['*edited'] = True self.parent.custcols[self.orig_column_name]['*edited'] = True
self.parent.custcols[self.orig_column_name]['*must_restart'] = True self.parent.custcols[self.orig_column_name]['*must_restart'] = True
self.parent.cc_column_key = key
QDialog.accept(self) QDialog.accept(self)
def reject(self): def reject(self):