diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py
index ceb6751238..5dc3f25dfb 100644
--- a/src/calibre/ebooks/metadata/book/base.py
+++ b/src/calibre/ebooks/metadata/book/base.py
@@ -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
diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py
index 50c411aaa4..6990a76b21 100644
--- a/src/calibre/gui2/library/delegates.py
+++ b/src/calibre/gui2/library/delegates.py
@@ -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): # {{{
diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py
index 86c5871193..554b104c34 100644
--- a/src/calibre/gui2/library/models.py
+++ b/src/calibre/gui2/library/models.py
@@ -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':
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index 1cfb04921d..f59473851f 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -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':
diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py
index 3a245580dd..f3fe8f03a3 100644
--- a/src/calibre/gui2/preferences/create_custom_column.py
+++ b/src/calibre/gui2/preferences/create_custom_column.py
@@ -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()
diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui
index 2bdadd4b9d..02daae988f 100644
--- a/src/calibre/gui2/preferences/create_custom_column.ui
+++ b/src/calibre/gui2/preferences/create_custom_column.ui
@@ -171,6 +171,20 @@ Everything else will show nothing.
+ -
+
+
+
+ 0
+ 0
+
+
+
+ <p>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
+
+
+
+
-
@@ -181,6 +195,19 @@ Everything else will show nothing.
+ -
+
+
+ <p>Example: ${0:,.2f} gives floating point number prefixed by a dollar sign, 2 digits after the decimal point, with thousands separated by commas
+
+
+ <p>Default: Not formatted. For format language details see <a href="http://docs.python.org/library/string.html#format-string-syntax">the python documentation</a>
+
+
+ true
+
+
+
-
@@ -193,6 +220,16 @@ Everything else will show nothing.
+ -
+
+
+ Format for &numbers
+
+
+ number_format_box
+
+
+
-