tags within the book to '
- 'determine pages.'),
- _('Custom column name to retrieve page counts from') +
- ':::' +
- _('If you have a custom column in your library that you use to '
- 'store the page count of books, you can have calibre use that '
- 'information, instead of calculating a page count. Specify the '
- 'name of the custom column here, for example, #pages. '),
+ _('Send page number information when sending books') + ':::' + _(
+ 'The Kindle 3 and newer versions can use page number information'
+ ' in MOBI files. With this option, calibre will calculate and send'
+ ' this information to the Kindle when uploading MOBI files by'
+ ' USB. Note that the page numbers do not correspond to any paper'
+ ' book.'),
+ _('Page count calculation method') + ':::' + '' + _(
+ 'There are multiple ways to generate the page number information.'
+ ' If a page count is given then the book will be divided into that many pages.'
+ ' Otherwise the number of pages will be approximated using one of the following'
+ ' methods.
'
+ ' - fast: 2300 characters of uncompressed text per page.\n\n'
+ '
- accurate: Based on the number of chapters, paragraphs, and visible lines in the book.'
+ ' This method is designed to simulate an average paperback book where there are 32 lines per'
+ ' page and a maximum of 70 characters per line.\n\n'
+ '
- pagebreak: The "pagebreak" method uses the presense of tags within'
+ ' the book to determine pages.
'
+ 'Methods other than "fast" are going to be much slower.'
+ ' Further, if "pagebreak" fails to determine a page count accurate will be used, and if '
+ ' "accurate" fails fast will be used.'),
+ _('Custom column name to retrieve page counts from') + ':::' + _(
+ 'If you have a custom column in your library that you use to'
+ ' store the page count of books, you can have calibre use that'
+ ' information, instead of calculating a page count. Specify the'
+ ' name of the custom column here, for example, #pages.'),
]
EXTRA_CUSTOMIZATION_DEFAULT = [
True,
- False,
- 'accurate',
+ 'fast',
'',
]
OPT_APNX = 0
- OPT_APNX_ACCURATE = 1
- OPT_APNX_ACCURATE_METHOD = 2
- OPT_APNX_CUST_COL = 3
+ OPT_APNX_METHOD = 1
+ OPT_APNX_CUST_COL = 2
+ EXTRA_CUSTOMIZATION_CHOICES = {OPT_APNX_METHOD:{'fast', 'accurate', 'pagebreak'}}
+
# x330 on the PaperWhite
THUMBNAIL_HEIGHT = 330
# x262 on the Touch. Doesn't choke on x330, though.
+ @classmethod
+ def migrate_extra_customization(cls, vals):
+ if isinstance(vals[cls.OPT_APNX_METHOD], bool):
+ # Previously this option used to be a bool
+ vals[cls.OPT_APNX_METHOD] = 'accurate' if vals[cls.OPT_APNX_METHOD] else 'fast'
+ return vals
+
def formats_to_scan_for(self):
ans = USBMS.formats_to_scan_for(self) | {'azw3'}
return ans
@@ -408,7 +413,8 @@ class KINDLE2(KINDLE):
if not coverdata or not coverdata[2]:
return
thumb_dir = os.path.join(self._main_prefix, 'system', 'thumbnails')
- if not os.path.exists(thumb_dir): return
+ if not os.path.exists(thumb_dir):
+ return
from calibre.ebooks.mobi.reader.headers import MetadataHeader
with lopen(filepath, 'rb') as f:
@@ -451,12 +457,8 @@ class KINDLE2(KINDLE):
apnx_path = '%s.apnx' % os.path.join(path, filename)
apnx_builder = APNXBuilder()
try:
- method = None
- if opts.extra_customization[self.OPT_APNX_ACCURATE]:
- method = opts.extra_customization[self.OPT_APNX_ACCURATE_METHOD]
- apnx_builder.write_apnx(filepath, apnx_path,
- method=method,
- page_count=custom_page_count)
+ method = opts.extra_customization[self.OPT_APNX_METHOD]
+ apnx_builder.write_apnx(filepath, apnx_path, method=method, page_count=custom_page_count)
except:
print 'Failed to generate APNX'
import traceback
diff --git a/src/calibre/devices/usbms/deviceconfig.py b/src/calibre/devices/usbms/deviceconfig.py
index b2eadd7461..2a750ba559 100644
--- a/src/calibre/devices/usbms/deviceconfig.py
+++ b/src/calibre/devices/usbms/deviceconfig.py
@@ -27,9 +27,13 @@ class DeviceConfig(object):
#: EXTRA_CUSTOMIZATION_MESSAGE you *must* set this as well.
EXTRA_CUSTOMIZATION_DEFAULT = None
+ #: A dictionary providing choices for options that should be displayed as a
+ #: combo box to the user. The dictionary maps extra #: customization indexes
+ #: to a set of choices.
+ EXTRA_CUSTOMIZATION_CHOICES = None
+
SUPPORTS_SUB_DIRS = False
- SUPPORTS_SUB_DIRS_FOR_SCAN = False # This setting is used when scanning for
- # books when SUPPORTS_SUB_DIRS is False
+ SUPPORTS_SUB_DIRS_FOR_SCAN = False # This setting is used when scanning for books when SUPPORTS_SUB_DIRS is False
SUPPORTS_SUB_DIRS_DEFAULT = True
MUST_READ_METADATA = False
@@ -41,7 +45,6 @@ class DeviceConfig(object):
#: If True the user can add new formats to the driver
USER_CAN_ADD_NEW_FORMATS = True
-
@classmethod
def _default_save_template(cls):
from calibre.library.save_to_disk import config
@@ -81,7 +84,7 @@ class DeviceConfig(object):
from calibre.gui2.device_drivers.configwidget import ConfigWidget
cw = ConfigWidget(cls.settings(), cls.FORMATS, cls.SUPPORTS_SUB_DIRS,
cls.MUST_READ_METADATA, cls.SUPPORTS_USE_AUTHOR_SORT,
- cls.EXTRA_CUSTOMIZATION_MESSAGE, cls)
+ cls.EXTRA_CUSTOMIZATION_MESSAGE, cls, extra_customization_choices=cls.EXTRA_CUSTOMIZATION_CHOICES)
return cw
@classmethod
@@ -103,6 +106,8 @@ class DeviceConfig(object):
continue
if hasattr(config_widget.opt_extra_customization[i], 'isChecked'):
ec.append(config_widget.opt_extra_customization[i].isChecked())
+ elif hasattr(config_widget.opt_extra_customization[i], 'currentText'):
+ ec.append(unicode(config_widget.opt_extra_customization[i].currentText()).strip())
else:
ec.append(unicode(config_widget.opt_extra_customization[i].text()).strip())
else:
@@ -113,6 +118,10 @@ class DeviceConfig(object):
st = unicode(config_widget.opt_save_template.text())
proxy['save_template'] = st
+ @classmethod
+ def migrate_extra_customization(cls, vals):
+ return vals
+
@classmethod
def settings(cls):
opts = cls._config().parse()
@@ -121,9 +130,7 @@ class DeviceConfig(object):
opts.extra_customization = []
if not isinstance(opts.extra_customization, list):
opts.extra_customization = [opts.extra_customization]
- for i,d in enumerate(cls.EXTRA_CUSTOMIZATION_DEFAULT):
- if i >= len(opts.extra_customization):
- opts.extra_customization.append(d)
+ opts.extra_customization = cls.migrate_extra_customization(opts.extra_customization)
return opts
@classmethod
diff --git a/src/calibre/gui2/device_drivers/configwidget.py b/src/calibre/gui2/device_drivers/configwidget.py
index 17c97b7ba0..512415a81d 100644
--- a/src/calibre/gui2/device_drivers/configwidget.py
+++ b/src/calibre/gui2/device_drivers/configwidget.py
@@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
import textwrap
from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QVariant, QLabel,
- QLineEdit, QCheckBox)
+ QLineEdit, QCheckBox, QComboBox)
from calibre.gui2 import error_dialog, question_dialog
from calibre.gui2.device_drivers.configwidget_ui import Ui_ConfigWidget
@@ -18,7 +18,7 @@ class ConfigWidget(QWidget, Ui_ConfigWidget):
def __init__(self, settings, all_formats, supports_subdirs,
must_read_metadata, supports_use_author_sort,
- extra_customization_message, device):
+ extra_customization_message, device, extra_customization_choices=None):
QWidget.__init__(self)
Ui_ConfigWidget.__init__(self)
@@ -62,6 +62,7 @@ class ConfigWidget(QWidget, Ui_ConfigWidget):
else:
self.opt_use_author_sort.hide()
if extra_customization_message:
+ extra_customization_choices = extra_customization_choices or {}
def parse_msg(m):
msg, _, tt = m.partition(':::') if m else ('', '', '')
return msg.strip(), textwrap.fill(tt.strip(), 100)
@@ -84,6 +85,14 @@ class ConfigWidget(QWidget, Ui_ConfigWidget):
self.opt_extra_customization.append(QCheckBox(label_text))
self.opt_extra_customization[-1].setToolTip(tt)
self.opt_extra_customization[i].setChecked(bool(settings.extra_customization[i]))
+ elif i in extra_customization_choices:
+ cb = QComboBox(self)
+ self.opt_extra_customization.append(cb)
+ l = QLabel(label_text)
+ l.setToolTip(tt), cb.setToolTip(tt), l.setBuddy(cb), cb.setToolTip(tt)
+ for li in sorted(extra_customization_choices[i]):
+ self.opt_extra_customization[i].addItem(li)
+ cb.setCurrentIndex(max(0, cb.findText(settings.extra_customization[i])))
else:
self.opt_extra_customization.append(QLineEdit(self))
l = QLabel(label_text)
@@ -111,7 +120,6 @@ class ConfigWidget(QWidget, Ui_ConfigWidget):
self.extra_layout.addWidget(self.opt_extra_customization, 1, 0)
self.opt_save_template.setText(settings.save_template)
-
def up_column(self):
idx = self.columns.currentRow()
if idx > 0:
@@ -125,7 +133,8 @@ class ConfigWidget(QWidget, Ui_ConfigWidget):
self.columns.setCurrentRow(idx+1)
def format_map(self):
- formats = [unicode(self.columns.item(i).data(Qt.UserRole).toString()) for i in range(self.columns.count()) if self.columns.item(i).checkState()==Qt.Checked]
+ formats = [unicode(self.columns.item(i).data(Qt.UserRole).toString())
+ for i in range(self.columns.count()) if self.columns.item(i).checkState()==Qt.Checked]
return formats
def use_subdirs(self):
@@ -156,7 +165,7 @@ class ConfigWidget(QWidget, Ui_ConfigWidget):
return True
except Exception as err:
error_dialog(self, _('Invalid template'),
- ''+_('The template %s is invalid:')%tmpl + \
+ '
'+_('The template %s is invalid:')%tmpl +
'
'+unicode(err), show=True)
return False