Allow the user to specify formatting for number type custom columns

This commit is contained in:
Kovid Goyal 2011-05-28 10:17:10 -06:00
commit d1efa068cd
6 changed files with 89 additions and 13 deletions

View File

@ -628,6 +628,12 @@ class Metadata(object):
res = _('Yes') if res else _('No')
elif datatype == 'rating':
res = res/2.0
elif datatype in ['int', 'float']:
try:
fmt = cmeta['display'].get('number_format', None)
res = fmt.format(res)
except:
pass
return (name, unicode(res), orig_res, cmeta)
# convert top-level ids into their value

View File

@ -249,6 +249,23 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
# }}}
class CcTextDelegate(QStyledItemDelegate): # {{{
'''
Delegate for text data.
'''
def createEditor(self, parent, option, index):
m = index.model()
col = m.column_map[index.column()]
editor = MultiCompleteLineEdit(parent)
editor.set_separator(None)
complete_items = sorted(list(m.db.all_custom(label=m.db.field_metadata.key_to_label(col))),
key=sort_key)
editor.update_items_cache(complete_items)
return editor
# }}}
class CcNumberDelegate(QStyledItemDelegate): # {{{
'''
Delegate for text/int/float data.
'''
@ -256,25 +273,23 @@ class CcTextDelegate(QStyledItemDelegate): # {{{
def createEditor(self, parent, option, index):
m = index.model()
col = m.column_map[index.column()]
typ = m.custom_columns[col]['datatype']
if typ == 'int':
if m.custom_columns[col]['datatype'] == 'int':
editor = QSpinBox(parent)
editor.setRange(-100, 100000000)
editor.setSpecialValueText(_('Undefined'))
editor.setSingleStep(1)
elif typ == 'float':
else:
editor = QDoubleSpinBox(parent)
editor.setSpecialValueText(_('Undefined'))
editor.setRange(-100., 100000000)
editor.setDecimals(2)
else:
editor = MultiCompleteLineEdit(parent)
editor.set_separator(None)
complete_items = sorted(list(m.db.all_custom(label=m.db.field_metadata.key_to_label(col))),
key=sort_key)
editor.update_items_cache(complete_items)
return editor
def setEditorData(self, editor, index):
m = index.model()
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
editor.setValue(val)
# }}}
class CcEnumDelegate(QStyledItemDelegate): # {{{

View File

@ -623,7 +623,12 @@ class BooksModel(QAbstractTableModel): # {{{
return None
return QVariant(text)
def number_type(r, idx=-1):
def number_type(r, idx=-1, fmt=None):
if fmt is not None:
try:
return QVariant(fmt.format(self.db.data[r][idx]))
except:
pass
return QVariant(self.db.data[r][idx])
self.dc = {
@ -674,7 +679,8 @@ class BooksModel(QAbstractTableModel): # {{{
bool_cols_are_tristate=
self.db.prefs.get('bools_are_tristate'))
elif datatype in ('int', 'float'):
self.dc[col] = functools.partial(number_type, idx=idx)
fmt = self.custom_columns[col]['display'].get('number_format', None)
self.dc[col] = functools.partial(number_type, idx=idx, fmt=fmt)
elif datatype == 'datetime':
self.dc[col] = functools.partial(datetime_type, idx=idx)
elif datatype == 'bool':

View File

@ -15,7 +15,7 @@ from PyQt4.Qt import QTableView, Qt, QAbstractItemView, QMenu, pyqtSignal, \
from calibre.gui2.library.delegates import RatingDelegate, PubDateDelegate, \
TextDelegate, DateDelegate, CompleteDelegate, CcTextDelegate, \
CcBoolDelegate, CcCommentsDelegate, CcDateDelegate, CcTemplateDelegate, \
CcEnumDelegate
CcEnumDelegate, CcNumberDelegate
from calibre.gui2.library.models import BooksModel, DeviceBooksModel
from calibre.utils.config import tweaks, prefs
from calibre.gui2 import error_dialog, gprefs
@ -89,6 +89,7 @@ class BooksView(QTableView): # {{{
self.cc_bool_delegate = CcBoolDelegate(self)
self.cc_comments_delegate = CcCommentsDelegate(self)
self.cc_template_delegate = CcTemplateDelegate(self)
self.cc_number_delegate = CcNumberDelegate(self)
self.display_parent = parent
self._model = modelcls(self)
self.setModel(self._model)
@ -501,8 +502,10 @@ class BooksView(QTableView): # {{{
self.tags_delegate)
else:
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate)
elif cc['datatype'] in ('series', 'int', 'float'):
elif cc['datatype'] == 'series':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate)
elif cc['datatype'] in ('int', 'float'):
self.setItemDelegateForColumn(cm.index(colhead), self.cc_number_delegate)
elif cc['datatype'] == 'bool':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_bool_delegate)
elif cc['datatype'] == 'rating':

View File

@ -127,6 +127,9 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
elif ct == 'enumeration':
self.enum_box.setText(','.join(c['display'].get('enum_values', [])))
self.enum_colors.setText(','.join(c['display'].get('enum_colors', [])))
elif ct in ['int', 'float']:
if c['display'].get('number_format', None):
self.number_format_box.setText(c['display'].get('number_format', ''))
self.datatype_changed()
if ct in ['text', 'composite', 'enumeration']:
self.use_decorations.setChecked(c['display'].get('use_decorations', False))
@ -171,6 +174,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
col_type = None
for x in ('box', 'default_label', 'label'):
getattr(self, 'date_format_'+x).setVisible(col_type == 'datetime')
getattr(self, 'number_format_'+x).setVisible(col_type in ['int', 'float'])
for x in ('box', 'default_label', 'label', 'sort_by', 'sort_by_label',
'make_category'):
getattr(self, 'composite_'+x).setVisible(col_type in ['composite', '*composite'])
@ -267,6 +271,11 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
display_dict = {'enum_values': l, 'enum_colors': c}
elif col_type == 'text' and is_multiple:
display_dict = {'is_names': self.is_names.isChecked()}
elif col_type in ['int', 'float']:
if unicode(self.number_format_box.text()).strip():
display_dict = {'number_format':unicode(self.number_format_box.text()).strip()}
else:
display_dict = {'number_format': None}
if col_type in ['text', 'composite', 'enumeration'] and not is_multiple:
display_dict['use_decorations'] = self.use_decorations.checkState()

View File

@ -171,6 +171,20 @@ Everything else will show nothing.</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="number_format_box">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;p&gt;Use 0 (a zero) for the field name. Example: {0:0>5.2f} gives a 5-digit floating point number, 2 digits after the decimal point, with leading zeros
</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="date_format_default_label">
<property name="toolTip">
@ -181,6 +195,19 @@ Everything else will show nothing.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="number_format_default_label">
<property name="toolTip">
<string>&lt;p&gt;Example: ${0:,.2f} gives floating point number prefixed by a dollar sign, 2 digits after the decimal point, with thousands separated by commas</string>
</property>
<property name="text">
<string>&lt;p&gt;Default: Not formatted. For format language details see &lt;a href="http://docs.python.org/library/string.html#format-string-syntax"&gt;the python documentation&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
@ -193,6 +220,16 @@ Everything else will show nothing.</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="number_format_label">
<property name="text">
<string>Format for &amp;numbers</string>
</property>
<property name="buddy">
<cstring>number_format_box</cstring>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="composite_label">
<property name="text">