This commit is contained in:
Kovid Goyal 2021-12-24 20:57:27 +05:30
commit c36036f05f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 106 additions and 31 deletions

View File

@ -14,7 +14,7 @@ from calibre.gui2 import gprefs, Application
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
from calibre.gui2 import error_dialog, question_dialog, ALL_COLUMNS from calibre.gui2 import error_dialog, question_dialog
class ConfigWidget(ConfigWidgetBase, Ui_Form): class ConfigWidget(ConfigWidgetBase, Ui_Form):
@ -210,7 +210,7 @@ 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, None, None, model.orig_headers, ALL_COLUMNS) CreateCustomColumn(self.gui, self, None, model.orig_headers)
if self.cc_column_key is None: if self.cc_column_key is None:
return return
row = self.opt_columns.rowCount() row = self.opt_columns.rowCount()
@ -225,7 +225,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
key = str(self.opt_columns.item(row, 0).data(Qt.ItemDataRole.UserRole)) key = str(self.opt_columns.item(row, 0).data(Qt.ItemDataRole.UserRole))
except: except:
key = '' key = ''
CreateCustomColumn(self, row, key, model.orig_headers, ALL_COLUMNS) CreateCustomColumn(self.gui, self, key, model.orig_headers)
if self.cc_column_key is None: if self.cc_column_key is None:
return return
self.setup_row(self.field_metadata, row, self.cc_column_key, self.setup_row(self.field_metadata, row, self.cc_column_key,

View File

@ -7,7 +7,8 @@ __copyright__ = '2010, Kovid Goyal <kovid at kovidgoyal.net>'
'''Dialog to create a new custom column''' '''Dialog to create a new custom column'''
import re import copy, re
from enum import Enum
from functools import partial from functools import partial
from qt.core import ( from qt.core import (
@ -91,8 +92,9 @@ class CreateCustomColumn(QDialog):
))) )))
column_types_map = {k['datatype']:idx for idx, k in iteritems(column_types)} column_types_map = {k['datatype']:idx for idx, k in iteritems(column_types)}
def __init__(self, parent, current_row, current_key, standard_colheads, standard_colnames): def __init__(self, gui, caller, current_key, standard_colheads, freeze_key=False):
QDialog.__init__(self, parent) QDialog.__init__(self, gui)
self.gui = gui
self.setup_ui() self.setup_ui()
self.setWindowTitle(_('Create a custom column')) self.setWindowTitle(_('Create a custom column'))
self.heading_label.setText('<b>' + _('Create a custom column')) self.heading_label.setText('<b>' + _('Create a custom column'))
@ -106,11 +108,10 @@ class CreateCustomColumn(QDialog):
for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]: for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]:
self.composite_sort_by.addItem(sort_by) self.composite_sort_by.addItem(sort_by)
self.parent = parent self.caller = caller
self.parent.cc_column_key = None self.caller.cc_column_key = None
self.editing_col = current_row is not None self.editing_col = current_key is not None
self.standard_colheads = standard_colheads self.standard_colheads = standard_colheads
self.standard_colnames = standard_colnames
self.column_type_box.setMaxVisibleItems(len(self.column_types)) self.column_type_box.setMaxVisibleItems(len(self.column_types))
for t in self.column_types: for t in self.column_types:
self.column_type_box.addItem(self.column_types[t]['text']) self.column_type_box.addItem(self.column_types[t]['text'])
@ -124,17 +125,15 @@ class CreateCustomColumn(QDialog):
self.setWindowTitle(_('Edit custom column')) self.setWindowTitle(_('Edit custom column'))
self.heading_label.setText('<b>' + _('Edit custom column')) self.heading_label.setText('<b>' + _('Edit custom column'))
self.shortcuts.setVisible(False) self.shortcuts.setVisible(False)
idx = current_row
if idx < 0:
self.simple_error(_('No column selected'), _('No column has been selected'))
return
col = current_key col = current_key
if col not in parent.custcols: if col not in caller.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
c = parent.custcols[col] c = caller.custcols[col]
self.column_name_box.setText(c['label']) self.column_name_box.setText(c['label'])
if freeze_key:
self.column_name_box.setEnabled(False)
self.column_heading_box.setText(c['name']) self.column_heading_box.setText(c['name'])
self.column_heading_box.setFocus() self.column_heading_box.setFocus()
ct = c['datatype'] ct = c['datatype']
@ -511,21 +510,21 @@ class CreateCustomColumn(QDialog):
if not col_heading: if not col_heading:
return self.simple_error('', _('No column heading was provided')) return self.simple_error('', _('No column heading was provided'))
db = self.parent.gui.library_view.model().db db = self.gui.library_view.model().db
key = db.field_metadata.custom_field_prefix+col key = db.field_metadata.custom_field_prefix+col
bad_col = False bad_col = False
if key in self.parent.custcols: if key in self.caller.custcols:
if not self.editing_col or \ if not self.editing_col or \
self.parent.custcols[key]['colnum'] != self.orig_column_number: self.caller.custcols[key]['colnum'] != self.orig_column_number:
bad_col = True bad_col = True
if bad_col: if bad_col:
return self.simple_error('', _('The lookup name %s is already used')%col) return self.simple_error('', _('The lookup name %s is already used')%col)
bad_head = False bad_head = False
for t in self.parent.custcols: for t in self.caller.custcols:
if self.parent.custcols[t]['name'] == col_heading: if self.caller.custcols[t]['name'] == col_heading:
if not self.editing_col or \ if not self.editing_col or \
self.parent.custcols[t]['colnum'] != self.orig_column_number: self.caller.custcols[t]['colnum'] != self.orig_column_number:
bad_head = True bad_head = True
for t in self.standard_colheads: for t in self.standard_colheads:
if self.standard_colheads[t] == col_heading: if self.standard_colheads[t] == col_heading:
@ -647,7 +646,7 @@ class CreateCustomColumn(QDialog):
display_dict['description'] = self.description_box.text().strip() display_dict['description'] = self.description_box.text().strip()
if not self.editing_col: if not self.editing_col:
self.parent.custcols[key] = { self.caller.custcols[key] = {
'label':col, 'label':col,
'name':col_heading, 'name':col_heading,
'datatype':col_type, 'datatype':col_type,
@ -656,17 +655,93 @@ class CreateCustomColumn(QDialog):
'colnum':None, 'colnum':None,
'is_multiple':is_multiple, 'is_multiple':is_multiple,
} }
self.parent.cc_column_key = key self.caller.cc_column_key = key
else: else:
self.parent.custcols[self.orig_column_name]['label'] = col cc = self.caller.custcols[self.orig_column_name]
self.parent.custcols[self.orig_column_name]['name'] = col_heading cc['label'] = col
cc['name'] = col_heading
# Remove any previous default value # Remove any previous default value
self.parent.custcols[self.orig_column_name]['display'].pop('default_value', None) cc['display'].pop('default_value', None)
self.parent.custcols[self.orig_column_name]['display'].update(display_dict) cc['display'].update(display_dict)
self.parent.custcols[self.orig_column_name]['*edited'] = True cc['*edited'] = True
self.parent.custcols[self.orig_column_name]['*must_restart'] = True cc['*must_restart'] = True
self.parent.cc_column_key = key self.caller.cc_column_key = key
QDialog.accept(self) QDialog.accept(self)
def reject(self): def reject(self):
QDialog.reject(self) QDialog.reject(self)
class CreateNewCustomColumn(object):
class Result(Enum):
COLUMN_ADDED = 0
CANCELED = 1
INVALID_KEY = 2
DUPLICATE_KEY = 3
INVALID_TYPE = 4
INVALID_IS_MULTIPLE = 5
'''
Open a dialog to create a new custom column with given lookup_name,
column_heading, datatype, and is_multiple. The lookup name must begin with
a '#' and must not already exist. The datatype must be valid and is_multiple
must be valid for that datatype. The user cannot change the datatype.
Set freeze_key to False if you want to allow the user choose a different
lookup name. The proposed lookup name still must not exist, and the user
will not be allowed to choose the lookup name of an existing column.
The parameter 'gui' is the main calibre gui (calibre.gui2.ui.get_gui())
The method returns a tuple (Result.enum_value, message). If tuple[0] is
Result.COLUMN_ADDED then the message is the lookup name including the '#',
otherwise it is a potentially localized error message. You or the user must
restart calibre for the column to be actually added.
Usage:
from calibre.gui2.preferences.create_custom_column import CreateNewCustomColumn
result = CreateNewCustomColumn().create_new_custom_column(....)
if result[0] == CreateNewCustomColumn.Result.COLUMN_ADDED:
'''
def create_new_custom_column(self, gui, lookup_name, column_heading,
datatype, is_multiple, freeze_key=True):
db = gui.library_view.model().db
self.custcols = copy.deepcopy(db.field_metadata.custom_field_metadata())
if not lookup_name.startswith('#'):
return (self.Result.INVALID_KEY, _("The lookup name must begin with a '#'"))
if lookup_name in self.custcols:
return(self.Result.DUPLICATE_KEY, _("The custom column %s already exists") % lookup_name)
if datatype not in CreateCustomColumn.column_types_map:
return(self.Result.INVALID_TYPE,
_("The custom column type %s doesn't exist") % datatype)
if is_multiple and '*' + datatype not in CreateCustomColumn.column_types_map:
return(self.Result.INVALID_IS_MULTIPLE,
_("You cannot specify is_multiple for the datatype %s") % datatype)
if not column_heading:
column_heading = lookup_name
self.key = lookup_name
self.custcols[lookup_name] = {
'label': lookup_name,
'name': column_heading,
'datatype': datatype,
'display': {},
'normalized': None,
'colnum': None,
'is_multiple': is_multiple,
}
dialog = CreateCustomColumn(gui, self, lookup_name, gui.library_view.model().orig_headers,
freeze_key=freeze_key)
print(dialog.accepted, dialog.result())
if dialog.result() == QDialog.DialogCode.Accepted and self.cc_column_key != None:
cc = self.custcols[lookup_name]
db.create_custom_column(
label=cc['label'],
name=cc['name'],
datatype=cc['datatype'],
is_multiple=cc['is_multiple'],
display=cc['display'])
gui.must_restart_before_config = True
return ((self.Result.COLUMN_ADDED, self.cc_column_key))
return (self.Result.CANCELED, _('Canceled'))