From 2d4f602282b2133c90ea0d4a61ca531d8c730f4e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 09:22:01 -0600 Subject: [PATCH 01/17] ... --- src/calibre/gui2/preferences/__init__.py | 2 +- src/calibre/gui2/preferences/behavior.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index 54eb2f713c..b482429504 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -21,7 +21,7 @@ class ConfigWidgetInterface(object): ''' This class defines the interface that all widgets displayed in the Preferences dialog must implement. See :class:`ConfigWidgetBase` for - a base class that implements this interface and defines various conveninece + a base class that implements this interface and defines various convenience methods as well. ''' diff --git a/src/calibre/gui2/preferences/behavior.py b/src/calibre/gui2/preferences/behavior.py index d64af343f2..b376d067bc 100644 --- a/src/calibre/gui2/preferences/behavior.py +++ b/src/calibre/gui2/preferences/behavior.py @@ -43,6 +43,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('overwrite_author_title_metadata', config) r('get_social_metadata', config) + if test_eight_code: + self.opt_overwrite_author_title_metadata.setVisible(False) + self.opt_get_social_metadata.setVisible(False) r('new_version_notification', config) r('upload_news_to_device', config) r('delete_news_from_library_on_upload', config) From 573c5f2910ee310d9c63c0edece3b2f553b0887c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 10:14:42 -0600 Subject: [PATCH 02/17] ... --- src/calibre/ebooks/metadata/sources/amazon.py | 2 +- .../gui2/preferences/metadata_sources.py | 11 ++ .../gui2/preferences/metadata_sources.ui | 117 ++++++++++++++++++ src/calibre/utils/config.py | 2 - 4 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 src/calibre/gui2/preferences/metadata_sources.py create mode 100644 src/calibre/gui2/preferences/metadata_sources.ui diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index 5262ee0d1d..3ffb95f2fb 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -279,7 +279,7 @@ class Worker(Thread): # Get details {{{ class Amazon(Source): - name = 'Amazon Web' + name = 'Amazon.com' description = _('Downloads metadata from Amazon') capabilities = frozenset(['identify', 'cover']) diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py new file mode 100644 index 0000000000..cc6da1e995 --- /dev/null +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2011, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + + diff --git a/src/calibre/gui2/preferences/metadata_sources.ui b/src/calibre/gui2/preferences/metadata_sources.ui new file mode 100644 index 0000000000..9cb5943dfe --- /dev/null +++ b/src/calibre/gui2/preferences/metadata_sources.ui @@ -0,0 +1,117 @@ + + + StackedWidget + + + + 0 + 0 + 766 + 447 + + + + StackedWidget + + + + + + + Metadata sources + + + + + + <p>Disable any metadata sources you do not want by unchecking them. You can also set the cover priority. Covers from sources that have a higher (smaller) priority will be preferred when bulk downloading metadata. +<p>Double click on a metadata source to customize it. + + + true + + + + + + + + + + + + + Downloaded metadata fields + + + + + + If you uncheck any fields, metadata for those fields will not be downloaded + + + + + + + + + + Convert all downloaded comments to plain &text + + + + + + + Max. number of &tags to download: + + + opt_max_tags + + + + + + + + + + Max. &time to wait after first match is found: + + + opt_wait_after_first_identify_result + + + + + + + secs + + + + + + + Max. time to wait after &cover is found: + + + opt_wait_after_first_cover_result + + + + + + + secs + + + + + + + + + + diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index 7f2c75a272..66316d051b 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -785,8 +785,6 @@ def write_tweaks(raw): tweaks = read_tweaks() test_eight_code = tweaks.get('test_eight_code', False) -# test_eight_code notes -# Change Amazon plugin name to just Amazon def migrate(): if hasattr(os, 'geteuid') and os.geteuid() == 0: From fb8fc927cf498b0b3cd2710fbdb0a7c6e50d2a06 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 10:25:43 -0600 Subject: [PATCH 03/17] Fix publisher combobox not being cleared before initializing --- src/calibre/gui2/metadata/basic_widgets.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index 537736d3d0..2925f623df 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -988,13 +988,13 @@ class PublisherEdit(MultiCompleteComboBox): # {{{ all_publishers.sort(key=lambda x : sort_key(x[1])) self.update_items_cache([x[1] for x in all_publishers]) publisher_id = db.publisher_id(id_, index_is_id=True) - idx, c = None, 0 - for i in all_publishers: - id, name = i - if id == publisher_id: - idx = c + idx = None + self.clear() + for i, x in enumerate(all_publishers): + id_, name = x + if id_ == publisher_id: + idx = i self.addItem(name) - c += 1 self.setEditText('') if idx is not None: From 0c755dedf1fbccf16d3dfd6acaddc511eed9a2ec Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 10:27:20 -0600 Subject: [PATCH 04/17] ... --- src/calibre/gui2/metadata/basic_widgets.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index 2925f623df..b2ee79c9c0 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -172,6 +172,7 @@ class AuthorsEdit(MultiCompleteComboBox): self.books_to_refresh = set([]) all_authors = db.all_authors() all_authors.sort(key=lambda x : sort_key(x[1])) + self.clear() for i in all_authors: id, name = i name = [name.strip().replace('|', ',') for n in name.split(',')] @@ -326,6 +327,7 @@ class SeriesEdit(MultiCompleteComboBox): self.update_items_cache([x[1] for x in all_series]) series_id = db.series_id(id_, index_is_id=True) idx, c = None, 0 + self.clear() for i in all_series: id, name = i if id == series_id: From 624bb54a4956f668f0318da6f87802dd97f7fc33 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 10:42:43 -0600 Subject: [PATCH 05/17] Amazon plugin: Use latin1 rather than utf-8 as URL encoding --- src/calibre/customize/builtins.py | 14 ++ src/calibre/ebooks/metadata/sources/amazon.py | 4 +- .../gui2/preferences/metadata_sources.py | 9 + .../gui2/preferences/metadata_sources.ui | 193 +++++++++--------- 4 files changed, 126 insertions(+), 94 deletions(-) diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 298799daa5..52e7e91497 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1038,6 +1038,17 @@ class Server(PreferencesPlugin): 'give you access to your calibre library from anywhere, ' 'on any device, over the internet') +class MetadataSources(PreferencesPlugin): + name = 'Metadata download' + icon = I('metadata.png') + gui_name = _('Metadata download') + category = 'Sharing' + gui_category = _('Sharing') + category_order = 4 + name_order = 3 + config_widget = 'calibre.gui2.preferences.metadata_sources' + description = _('Control how calibre downloads ebook metadata from the net') + class Plugins(PreferencesPlugin): name = 'Plugins' icon = I('plugins.png') @@ -1076,6 +1087,9 @@ plugins += [LookAndFeel, Behavior, Columns, Toolbar, Search, InputOptions, CommonOptions, OutputOptions, Adding, Saving, Sending, Plugboard, Email, Server, Plugins, Tweaks, Misc, TemplateFunctions] +if test_eight_code: + plugins.append(MetadataSources) + #}}} diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index 3ffb95f2fb..a102a550b5 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -341,9 +341,9 @@ class Amazon(Source): # Insufficient metadata to make an identify query return None - utf8q = dict([(x.encode('utf-8'), y.encode('utf-8')) for x, y in + latin1q = dict([(x.encode('latin1'), y.encode('latin1')) for x, y in q.iteritems()]) - url = 'http://www.amazon.%s/s/?'%domain + urlencode(utf8q) + url = 'http://www.amazon.%s/s/?'%domain + urlencode(latin1q) return url # }}} diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index cc6da1e995..3a10bdce3e 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -7,5 +7,14 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' +from calibre.gui2.preferences import ConfigWidgetBase, test_widget +from calibre.gui2.preferences.metadata_sources_ui import Ui_Form +class ConfigWidget(ConfigWidgetBase, Ui_Form): + pass + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Interface', 'Behavior') diff --git a/src/calibre/gui2/preferences/metadata_sources.ui b/src/calibre/gui2/preferences/metadata_sources.ui index 9cb5943dfe..b8aabdd4fe 100644 --- a/src/calibre/gui2/preferences/metadata_sources.ui +++ b/src/calibre/gui2/preferences/metadata_sources.ui @@ -1,116 +1,125 @@ - StackedWidget - + Form + 0 0 - 766 - 447 + 781 + 300 - StackedWidget + Form - - - - - - Metadata sources - - - - - - <p>Disable any metadata sources you do not want by unchecking them. You can also set the cover priority. Covers from sources that have a higher (smaller) priority will be preferred when bulk downloading metadata. + + + 0 + + + + + + + + + Metadata sources + + + + + + <p>Disable any metadata sources you do not want by unchecking them. You can also set the cover priority. Covers from sources that have a higher (smaller) priority will be preferred when bulk downloading metadata. <p>Double click on a metadata source to customize it. + + + true + + + + + + + + + + + + + Downloaded metadata fields - - true + + + + + If you uncheck any fields, metadata for those fields will not be downloaded + + + + + + + + + + Convert all downloaded comments to plain &text - - + + + + Max. number of &tags to download: + + + opt_max_tags + + - - - - - - - Downloaded metadata fields - - - - - - If you uncheck any fields, metadata for those fields will not be downloaded + + + + + + + Max. &time to wait after first match is found: + + + opt_wait_after_first_identify_result + + + + + + + secs + + + + + + + Max. time to wait after &cover is found: + + + opt_wait_after_first_cover_result + + + + + + + secs - - - - - Convert all downloaded comments to plain &text - - - - - - - Max. number of &tags to download: - - - opt_max_tags - - - - - - - - - - Max. &time to wait after first match is found: - - - opt_wait_after_first_identify_result - - - - - - - secs - - - - - - - Max. time to wait after &cover is found: - - - opt_wait_after_first_cover_result - - - - - - - secs - - - - - - + + + + From 5556a1604c9ffb17b353a58269f27e4d02f39cda Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 12:11:07 -0600 Subject: [PATCH 06/17] ... --- src/calibre/customize/ui.py | 11 ++ src/calibre/ebooks/metadata/sources/amazon.py | 3 +- .../gui2/preferences/metadata_sources.py | 147 +++++++++++++++++- .../gui2/preferences/metadata_sources.ui | 32 +++- 4 files changed, 184 insertions(+), 9 deletions(-) diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index b8abbf9b03..e8011e9ad8 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -75,6 +75,17 @@ def enable_plugin(plugin_or_name): ep.add(x) config['enabled_plugins'] = ep +def restore_plugin_state_to_default(plugin_or_name): + x = getattr(plugin_or_name, 'name', plugin_or_name) + dp = config['disabled_plugins'] + if x in dp: + dp.remove(x) + config['disabled_plugins'] = dp + ep = config['enabled_plugins'] + if x in ep: + ep.remove(x) + config['enabled_plugins'] = ep + default_disabled_plugins = set([ 'Douban Books', 'Douban.com covers', 'Nicebooks', 'Nicebooks covers', 'Kent District Library' diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index a102a550b5..2ad5bfbacc 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -341,7 +341,8 @@ class Amazon(Source): # Insufficient metadata to make an identify query return None - latin1q = dict([(x.encode('latin1'), y.encode('latin1')) for x, y in + latin1q = dict([(x.encode('latin1', 'ignore'), y.encode('latin1', + 'ignore')) for x, y in q.iteritems()]) url = 'http://www.amazon.%s/s/?'%domain + urlencode(latin1q) return url diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index 3a10bdce3e..a912e6f956 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -7,14 +7,157 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' +from operator import attrgetter + +from PyQt4.Qt import (QAbstractTableModel, Qt) + from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.metadata_sources_ui import Ui_Form +from calibre.ebooks.metadata.sources.base import msprefs +from calibre.customize.ui import (all_metadata_plugins, is_disabled, + enable_plugin, disable_plugin, restore_plugin_state_to_default) +from calibre.gui2 import NONE + +class SourcesModel(QAbstractTableModel): # {{{ + + def __init__(self, parent=None): + QAbstractTableModel.__init__(self, parent) + + self.plugins = [] + self.enabled_overrides = {} + self.cover_overrides = {} + + def initialize(self): + self.plugins = list(all_metadata_plugins()) + self.plugins.sort(key=attrgetter('name')) + self.enabled_overrides = {} + self.cover_overrides = {} + self.reset() + + def rowCount(self, parent=None): + return len(self.plugins) + + def columnCount(self, parent=None): + return 2 + + def headerData(self, section, orientation, role): + if orientation == Qt.Horizontal and role == Qt.DisplayRole: + if section == 0: + return _('Source') + if section == 1: + return _('Cover priority') + return NONE + + def data(self, index, role): + try: + plugin = self.plugins[index.row()] + except: + return NONE + col = index.column() + + if role == Qt.DisplayRole: + if col == 0: + return plugin.name + elif col == 1: + orig = msprefs['cover_priorities'].get(plugin.name, 1) + return self.cover_overrides.get(plugin, orig) + elif role == Qt.CheckStateRole and col == 0: + orig = Qt.Unchecked if is_disabled(plugin) else Qt.Checked + return self.enabled_overrides.get(plugin, orig) + + return NONE + + def setData(self, index, val, role): + try: + plugin = self.plugins[index.row()] + except: + return False + col = index.column() + ret = False + if col == 0 and role == Qt.CheckStateRole: + val, ok = val.toInt() + if ok: + self.enabled_overrides[plugin] = val + ret = True + if col == 1 and role == Qt.EditRole: + val, ok = val.toInt() + if ok: + self.cover_overrides[plugin] = val + ret = True + if ret: + self.dataChanged.emit(index, index) + return ret + + + def flags(self, index): + col = index.column() + ans = QAbstractTableModel.flags(self, index) + if col == 0: + return ans | Qt.ItemIsUserCheckable + return Qt.ItemIsEditable | ans + + def commit(self): + for plugin, val in self.enabled_overrides.iteritems(): + if val == Qt.Checked: + enable_plugin(plugin) + elif val == Qt.Unchecked: + disable_plugin(plugin) + + if self.cover_overrides: + cp = msprefs['cover_priorities'] + for plugin, val in self.cover_overrides.iteritems(): + if val == 1: + cp.pop(plugin.name, None) + else: + cp[plugin.name] = val + msprefs['cover_priorities'] = cp + + self.enabled_overrides = {} + self.cover_overrides = {} + + def restore_defaults(self): + del msprefs['cover_priorities'] + self.enabled_overrides = {} + self.cover_overrides = {} + for plugin in self.plugins: + restore_plugin_state_to_default(plugin) + self.reset() + +# }}} class ConfigWidget(ConfigWidgetBase, Ui_Form): - pass + + def genesis(self, gui): + r = self.register + r('txt_comments', msprefs) + r('max_tags', msprefs) + r('wait_after_first_identify_result', msprefs) + r('wait_after_first_cover_result', msprefs) + + self.configure_plugin_button.clicked.connect(self.configure_plugin) + self.sources_model = SourcesModel(self) + self.sources_view.setModel(self.sources_model) + self.sources_model.dataChanged.connect(self.changed_signal) + + def configure_plugin(self): + pass + + def initialize(self): + ConfigWidgetBase.initialize(self) + self.sources_model.initialize() + self.sources_view.resizeColumnsToContents() + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + self.sources_model.restore_defaults() + self.changed_signal.emit() + + def commit(self): + self.sources_model.commit() + return ConfigWidgetBase.commit(self) if __name__ == '__main__': from PyQt4.Qt import QApplication app = QApplication([]) - test_widget('Interface', 'Behavior') + test_widget('Sharing', 'Metadata download') diff --git a/src/calibre/gui2/preferences/metadata_sources.ui b/src/calibre/gui2/preferences/metadata_sources.ui index b8aabdd4fe..68ac6352cf 100644 --- a/src/calibre/gui2/preferences/metadata_sources.ui +++ b/src/calibre/gui2/preferences/metadata_sources.ui @@ -30,8 +30,8 @@ - <p>Disable any metadata sources you do not want by unchecking them. You can also set the cover priority. Covers from sources that have a higher (smaller) priority will be preferred when bulk downloading metadata. -<p>Double click on a metadata source to customize it. + Disable any metadata sources you do not want by unchecking them. You can also set the cover priority. Covers from sources that have a higher (smaller) priority will be preferred when bulk downloading metadata. + true @@ -39,7 +39,25 @@ - + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + + + + Configure selected source + + + + :/images/plugins.png:/images/plugins.png + + @@ -51,7 +69,7 @@ - + If you uncheck any fields, metadata for those fields will not be downloaded @@ -100,7 +118,7 @@ - Max. time to wait after &cover is found: + Max. time to wait after first &cover is found: opt_wait_after_first_cover_result @@ -121,6 +139,8 @@ - + + + From e35860a2b2ca314c6540c5600309bea97006709c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 13:58:05 -0600 Subject: [PATCH 07/17] Fix #756807 (unhandled exception when creating catalogs in EPUB or MOBI format) --- src/calibre/gui2/catalog/catalog_epub_mobi.py | 5 +++- .../gui2/preferences/metadata_sources.py | 29 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index d5149569be..8af72e51c0 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -193,7 +193,10 @@ class PluginWidget(QWidget,Ui_Form): opts_dict['header_note_source_field'] = self.header_note_source_field_name # Append the output profile - opts_dict['output_profile'] = [load_defaults('page_setup')['output_profile']] + try: + opts_dict['output_profile'] = [load_defaults('page_setup')['output_profile']] + except: + opts_dict['output_profile'] = ['default'] if False: print "opts_dict" for opt in sorted(opts_dict.keys()): diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index a912e6f956..66fd35e038 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' from operator import attrgetter -from PyQt4.Qt import (QAbstractTableModel, Qt) +from PyQt4.Qt import (QAbstractTableModel, Qt, QAbstractListModel) from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.metadata_sources_ui import Ui_Form @@ -125,6 +125,29 @@ class SourcesModel(QAbstractTableModel): # {{{ # }}} +class FieldsModel(QAbstractListModel): # {{{ + + def __init__(self, parent=None): + QAbstractTableModel.__init__(self, parent) + + self.fields = [] + + def rowCount(self, parent=None): + return len(self.fields) + + def initialize(self): + fields = set() + for p in all_metadata_plugins(): + fields |= p.touched_fields + self.fields = [] + for x in fields: + if not x.startswith('identifiers:'): + self.fields.append(x) + self.reset() + + +# }}} + class ConfigWidget(ConfigWidgetBase, Ui_Form): def genesis(self, gui): @@ -139,6 +162,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.sources_view.setModel(self.sources_model) self.sources_model.dataChanged.connect(self.changed_signal) + self.fields_model = FieldsModel(self) + self.fields_view.setModel(self.fields_model) + self.fields_model.dataChanged.connect(self.changed_signal) + def configure_plugin(self): pass From 0e8f01a545d3de85e852d47155e5f22d9d0a5f9d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 15:43:48 -0600 Subject: [PATCH 08/17] Fix #756736 (Tweaks not translated) --- setup/pygettext.py | 6 +- setup/translations.py | 38 +- src/calibre/ebooks/fb2/output.py | 32 +- src/calibre/gui2/preferences/tweaks.py | 11 +- src/calibre/translations/calibre.pot | 1010 ++++++++++++++++-------- 5 files changed, 751 insertions(+), 346 deletions(-) diff --git a/setup/pygettext.py b/setup/pygettext.py index bc171396f4..322758871d 100644 --- a/setup/pygettext.py +++ b/setup/pygettext.py @@ -170,8 +170,8 @@ from setup import __appname__, __version__ as version # there. pot_header = '''\ # Translation template file.. -# Copyright (C) 2007 Kovid Goyal -# Kovid Goyal , 2007. +# Copyright (C) %(year)s Kovid Goyal +# Kovid Goyal , %(year)s. # msgid "" msgstr "" @@ -185,7 +185,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\\n" "Generated-By: pygettext.py %%(version)s\\n" -'''%dict(appname=__appname__, version=version) +'''%dict(appname=__appname__, version=version, year=time.strftime('%Y')) def usage(code, msg=''): diff --git a/setup/translations.py b/setup/translations.py index 7f81abf8f5..1f026555ec 100644 --- a/setup/translations.py +++ b/setup/translations.py @@ -26,6 +26,38 @@ class POT(Command): ans.append(os.path.abspath(os.path.join(root, name))) return ans + def get_tweaks_docs(self): + path = self.a(self.j(self.SRC, '..', 'resources', 'default_tweaks.py')) + with open(path, 'rb') as f: + raw = f.read().decode('utf-8') + msgs = [] + lines = list(raw.splitlines()) + for i, line in enumerate(lines): + if line.startswith('#:'): + msgs.append((i, line[2:].strip())) + j = i + block = [] + while True: + j += 1 + line = lines[j] + if not line.startswith('#'): + break + block.append(line[1:].strip()) + if block: + msgs.append((i+1, '\n'.join(block))) + + ans = [] + for lineno, msg in msgs: + ans.append('#: %s:%d'%(path, lineno)) + slash = unichr(92) + msg = msg.replace(slash, slash*2).replace('"', r'\"').replace('\n', + r'\n').replace('\r', r'\r').replace('\t', r'\t') + ans.append('msgid "%s"'%msg) + ans.append('msgstr ""') + ans.append('') + + return '\n'.join(ans) + def run(self, opts): files = self.source_files() @@ -35,10 +67,10 @@ class POT(Command): atexit.register(shutil.rmtree, tempdir) pygettext(buf, ['-k', '__', '-p', tempdir]+files) src = buf.getvalue() + src += '\n\n' + self.get_tweaks_docs() pot = os.path.join(self.PATH, __appname__+'.pot') - f = open(pot, 'wb') - f.write(src) - f.close() + with open(pot, 'wb') as f: + f.write(src) self.info('Translations template:', os.path.abspath(pot)) return pot diff --git a/src/calibre/ebooks/fb2/output.py b/src/calibre/ebooks/fb2/output.py index bccc665d35..54bb4550d5 100644 --- a/src/calibre/ebooks/fb2/output.py +++ b/src/calibre/ebooks/fb2/output.py @@ -28,7 +28,7 @@ class FB2Output(OutputFormatPlugin): 'sf_horror', # Horror & mystic 'sf_humor', # Humor 'sf_fantasy', # Fantasy - 'sf', # Science Fiction + 'sf', # Science Fiction # Detectives & Thrillers 'det_classic', # Classical detectives 'det_police', # Police Stories @@ -41,20 +41,20 @@ class FB2Output(OutputFormatPlugin): 'det_maniac', # Maniacs 'det_hard', # Hard#boiled 'thriller', # Thrillers - 'detective', # Detectives + 'detective', # Detectives # Prose 'prose_classic', # Classics prose 'prose_history', # Historical prose 'prose_contemporary', # Contemporary prose 'prose_counter', # Counterculture 'prose_rus_classic', # Russial classics prose - 'prose_su_classics', # Soviet classics prose + 'prose_su_classics', # Soviet classics prose # Romance 'love_contemporary', # Contemporary Romance 'love_history', # Historical Romance 'love_detective', # Detective Romance 'love_short', # Short Romance - 'love_erotica', # Erotica + 'love_erotica', # Erotica # Adventure 'adv_western', # Western 'adv_history', # History @@ -62,7 +62,7 @@ class FB2Output(OutputFormatPlugin): 'adv_maritime', # Maritime Fiction 'adv_geo', # Travel & geography 'adv_animal', # Nature & animals - 'adventure', # Other + 'adventure', # Other # Children's 'child_tale', # Fairy Tales 'child_verse', # Verses @@ -71,17 +71,17 @@ class FB2Output(OutputFormatPlugin): 'child_det', # Detectives & Thrillers 'child_adv', # Adventures 'child_education', # Educational - 'children', # Other + 'children', # Other # Poetry & Dramaturgy 'poetry', # Poetry - 'dramaturgy', # Dramaturgy + 'dramaturgy', # Dramaturgy # Antique literature 'antique_ant', # Antique 'antique_european', # European 'antique_russian', # Old russian 'antique_east', # Old east 'antique_myths', # Myths. Legends. Epos - 'antique', # Other + 'antique', # Other # Scientific#educational 'sci_history', # History 'sci_psychology', # Psychology @@ -98,7 +98,7 @@ class FB2Output(OutputFormatPlugin): 'sci_chem', # Chemistry 'sci_biology', # Biology 'sci_tech', # Technical - 'science', # Other + 'science', # Other # Computers & Internet 'comp_www', # Internet 'comp_programming', # Programming @@ -106,29 +106,29 @@ class FB2Output(OutputFormatPlugin): 'comp_soft', # Software 'comp_db', # Databases 'comp_osnet', # OS & Networking - 'computers', # Other + 'computers', # Other # Reference 'ref_encyc', # Encyclopedias 'ref_dict', # Dictionaries 'ref_ref', # Reference 'ref_guide', # Guidebooks - 'reference', # Other + 'reference', # Other # Nonfiction 'nonf_biography', # Biography & Memoirs 'nonf_publicism', # Publicism 'nonf_criticism', # Criticism 'design', # Art & design - 'nonfiction', # Other + 'nonfiction', # Other # Religion & Inspiration 'religion_rel', # Religion 'religion_esoterics', # Esoterics 'religion_self', # Self#improvement - 'religion', # Other + 'religion', # Other # Humor 'humor_anecdote', # Anecdote (funny stories) 'humor_prose', # Prose 'humor_verse', # Verses - 'humor', # Other + 'humor', # Other # Home & Family 'home_cooking', # Cooking 'home_pets', # Pets @@ -155,14 +155,14 @@ class FB2Output(OutputFormatPlugin): OptionRecommendation(name='fb2_genre', recommended_value='antique', level=OptionRecommendation.LOW, choices=FB2_GENRES, - help=_('Genre for the book. Choices: %s\n\n See: ' % FB2_GENRES) + 'http://www.fictionbook.org/index.php/Eng:FictionBook_2.1_genres ' \ + help=(_('Genre for the book. Choices: %s\n\n See: ') % FB2_GENRES) + 'http://www.fictionbook.org/index.php/Eng:FictionBook_2.1_genres ' \ + _('for a complete list with descriptions.')), ]) def convert(self, oeb_book, output_path, input_plugin, opts, log): from calibre.ebooks.oeb.transforms.jacket import linearize_jacket from calibre.ebooks.oeb.transforms.rasterize import SVGRasterizer, Unavailable - + try: rasterizer = SVGRasterizer() rasterizer(oeb_book, opts) diff --git a/src/calibre/gui2/preferences/tweaks.py b/src/calibre/gui2/preferences/tweaks.py index 9d0097ac35..a1756bf1ba 100644 --- a/src/calibre/gui2/preferences/tweaks.py +++ b/src/calibre/gui2/preferences/tweaks.py @@ -14,9 +14,9 @@ from calibre.utils.config import read_raw_tweaks, write_tweaks from calibre.gui2.widgets import PythonHighlighter from calibre import isbytestring -from PyQt4.Qt import QAbstractListModel, Qt, QStyledItemDelegate, QStyle, \ - QStyleOptionViewItem, QFont, QDialogButtonBox, QDialog, \ - QVBoxLayout, QPlainTextEdit, QLabel +from PyQt4.Qt import (QAbstractListModel, Qt, QStyledItemDelegate, QStyle, + QStyleOptionViewItem, QFont, QDialogButtonBox, QDialog, + QVBoxLayout, QPlainTextEdit, QLabel) class Delegate(QStyledItemDelegate): # {{{ def __init__(self, view): @@ -35,8 +35,9 @@ class Delegate(QStyledItemDelegate): # {{{ class Tweak(object): # {{{ def __init__(self, name, doc, var_names, defaults, custom): - self.name = name - self.doc = doc.strip() + translate = __builtins__['_'] + self.name = translate(name) + self.doc = translate(doc.strip()) self.var_names = var_names self.default_values = {} for x in var_names: diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 274068acf8..16e4a37a13 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -1,12 +1,12 @@ # Translation template file.. -# Copyright (C) 2007 Kovid Goyal -# Kovid Goyal , 2007. +# Copyright (C) 2011 Kovid Goyal +# Kovid Goyal , 2011. # msgid "" msgstr "" "Project-Id-Version: calibre 0.7.54\n" -"POT-Creation-Date: 2011-04-08 10:54+MDT\n" -"PO-Revision-Date: 2011-04-08 10:54+MDT\n" +"POT-Creation-Date: 2011-04-10 15:36+MDT\n" +"PO-Revision-Date: 2011-04-10 15:36+MDT\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -73,7 +73,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:46 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/google.py:81 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:161 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:359 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:360 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/txt.py:18 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:43 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:69 @@ -117,8 +117,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:102 #: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:313 #: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:315 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:311 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:318 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:343 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:155 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:368 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:371 @@ -141,25 +141,25 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/email.py:252 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:429 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:448 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1013 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1187 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1016 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1190 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:72 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:169 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:188 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:112 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:86 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:160 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:199 #: /home/kovid/work/calibre/src/calibre/library/cli.py:216 #: /home/kovid/work/calibre/src/calibre/library/database.py:914 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:495 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:503 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:514 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1777 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1901 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2890 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2892 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3025 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:500 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:508 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:519 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1782 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1906 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2895 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2897 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3030 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:233 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:156 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:159 @@ -182,8 +182,8 @@ msgid "Customize" msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:156 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:42 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:47 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:46 msgid "Cannot configure" msgstr "" @@ -209,7 +209,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:557 #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:22 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:195 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:285 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:307 @@ -407,9 +407,9 @@ msgid "Template Functions" msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1010 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1046 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1058 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1057 #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1069 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1080 msgid "Advanced" msgstr "" @@ -423,6 +423,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1021 #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1033 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1046 msgid "Sharing" msgstr "" @@ -439,27 +440,36 @@ msgid "Setup the calibre Content Server which will give you access to your calib msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1044 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:57 +msgid "Metadata download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1050 +msgid "Control how calibre downloads ebook metadata from the net" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1055 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:268 msgid "Plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1050 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1061 msgid "Add/remove/customize various bits of calibre functionality" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1056 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1067 msgid "Tweaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1062 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1073 msgid "Fine tune how calibre behaves in various contexts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1067 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1078 msgid "Miscellaneous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1073 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1084 msgid "Miscellaneous advanced configuration" msgstr "" @@ -632,11 +642,11 @@ msgstr "" msgid "Enabled plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:476 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:490 msgid "Initialization of plugin %s failed with traceback:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:509 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:523 msgid "" " %prog options\n" "\n" @@ -644,27 +654,27 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:515 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:529 msgid "Add a plugin by specifying the path to the zip file containing it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:517 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:531 msgid "Remove a custom plugin by name. Has no effect on builtin plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:519 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:533 msgid "Customize plugin. Specify name of plugin and customization string separated by a comma." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:521 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:535 msgid "List all installed plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:523 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:537 msgid "Enable the named plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:525 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:539 msgid "Disable the named plugin" msgstr "" @@ -770,9 +780,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:945 #: /home/kovid/work/calibre/src/calibre/gui2/actions/fetch_news.py:73 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:445 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:294 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:307 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2754 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:299 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:312 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2759 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:159 msgid "News" msgstr "" @@ -780,8 +790,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2651 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:65 #: /home/kovid/work/calibre/src/calibre/library/catalog.py:634 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2716 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2734 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2721 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2739 msgid "Catalog" msgstr "" @@ -1889,6 +1899,13 @@ msgstr "" msgid "Specify the sectionization of elements. A value of \"nothing\" turns the book into a single section. A value of \"files\" turns each file into a separate section; use this if your device is having trouble. A value of \"Table of Contents\" turns the entries in the Table of Contents into titles and creates sections; if it fails, adjust the \"Structure Detection\" and/or \"Table of Contents\" settings (turn on \"Force use of auto-generated Table of Contents)." msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/output.py:158 +msgid "" +"Genre for the book. Choices: %s\n" +"\n" +" See: " +msgstr "" + #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/output.py:159 msgid "for a complete list with descriptions." msgstr "" @@ -2248,8 +2265,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:64 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:426 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1018 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1021 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:331 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:574 msgid "Title" @@ -2259,7 +2276,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:61 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:66 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:431 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1022 msgid "Author(s)" msgstr "" @@ -2280,7 +2297,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:129 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:94 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:388 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1206 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1209 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:211 msgid "Comments" msgstr "" @@ -2291,7 +2308,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:72 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1202 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1205 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:65 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:171 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:761 @@ -2304,7 +2321,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:73 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:393 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1211 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1214 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:65 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:114 msgid "Series" @@ -2315,7 +2332,7 @@ msgid "Language" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:688 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1194 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1197 msgid "Timestamp" msgstr "" @@ -2323,7 +2340,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:69 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:271 msgid "Published" msgstr "" @@ -2443,10 +2460,6 @@ msgstr "" msgid "Downloads metadata from Douban.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:57 -msgid "Metadata download" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:144 msgid "ratings" msgstr "" @@ -2688,7 +2701,7 @@ msgstr "" msgid "UK" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/amazon.py:380 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/amazon.py:389 msgid "Amazon timed out. Try again later." msgstr "" @@ -2812,7 +2825,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/cover.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:176 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:220 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:722 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:723 msgid "Book %s of %s" msgstr "" @@ -3071,7 +3084,7 @@ msgstr "" msgid "Preserve the aspect ratio of the cover, instead of stretching it to fill the full first page of the generated pdf." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftohtml.py:55 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftohtml.py:57 msgid "Could not find pdftohtml, check it is in your PATH" msgstr "" @@ -3196,138 +3209,138 @@ msgstr "" msgid "Do not remove image references within the document. This is only useful when paired with a txt-output-formatting option that is not none because links are always removed with plain text output." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:97 msgid "Send file to storage card instead of main memory by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:99 msgid "Confirm before deleting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:101 msgid "Main window geometry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:78 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:103 msgid "Notify when a new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:105 msgid "Use Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:107 msgid "Sort tags list by name, popularity, or rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:109 msgid "Match tags by any or all." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:111 msgid "Number of covers to show in the cover browsing mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:113 msgid "Defaults for conversion to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:115 msgid "Options for the LRF ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:118 msgid "Formats that are viewed using the internal viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:120 msgid "Columns to be displayed in the book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:121 msgid "Automatically launch content server on application startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:122 msgid "Oldest news kept in database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:123 msgid "Show system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:125 msgid "Upload downloaded news to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:102 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127 msgid "Delete books from library after uploading to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:129 msgid "Show the cover flow in a separate window instead of in the main calibre window" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:131 msgid "Disable notifications from the system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:133 msgid "Default action to perform when send to device button is clicked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 msgid "Start searching as you type. If this is disabled then search will only take place when the Enter or Return key is pressed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:141 msgid "When searching, show all books with search results highlighted instead of showing only the matches. You can use the N or F3 keys to go to the next match." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:159 msgid "Maximum number of waiting worker processes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:161 msgid "Download social metadata (tags/rating/etc.)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:163 msgid "Overwrite author and title with new metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:165 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:101 msgid "Automatically download the cover, if available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:167 msgid "Limit max simultaneous jobs to number of CPUs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:169 msgid "The layout of the user interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:171 msgid "Show the average rating per item indication in the tag browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:148 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:173 msgid "Disable UI animations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:178 msgid "tag browser categories not to display" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:448 msgid "Choose Files" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:308 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:532 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:534 msgid "Books" msgstr "" @@ -3503,17 +3516,17 @@ msgstr "" msgid "Fetch annotations (experimental)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:56 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:241 msgid "Use library only" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:242 msgid "User annotations generated from main library only" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/actions/catalog.py:30 #: /home/kovid/work/calibre/src/calibre/gui2/actions/convert.py:87 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:127 @@ -3525,31 +3538,31 @@ msgstr "" msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:66 msgid "No books selected to fetch annotations from" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:91 msgid "Merging user annotations into database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:119 msgid "%s
Last Page Read: %d (%d%%)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:125 msgid "%s
Last Page Read: Location %d (%d%%)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:144 msgid "Location %d • %s
%s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:153 msgid "Page %d • %s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:158 msgid "Location %d • %s
" msgstr "" @@ -3579,7 +3592,7 @@ msgid "Select destination for %s.%s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:81 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:57 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:170 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:125 msgid "%d books" @@ -3632,36 +3645,36 @@ msgstr "" msgid "Restore database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:220 msgid "Rename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:221 msgid "Choose a new name for the library %s. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:222 msgid "Note that the actual library folder will be renamed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:229 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:199 msgid "Already exists" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:230 msgid "The folder %s already exists. Delete it first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:236 msgid "Rename failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:237 msgid "Failed to rename the library at %s. The most common cause for this is if one of the files in the library is open in another program." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:248 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:53 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:78 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:368 @@ -3673,31 +3686,31 @@ msgstr "" msgid "Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:250 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:249 msgid "All files from %s will be permanently deleted. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:269 msgid "none" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:270 msgid "Backup status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:271 msgid "Book metadata files remaining to be written: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:277 msgid "Backup metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:278 msgid "Metadata will be backed up while calibre is running, at the rate of approximately 1 book every three seconds." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:310 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:106 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:111 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:286 @@ -3705,11 +3718,11 @@ msgstr "" msgid "Success" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:311 msgid "Found no errors in your calibre library database. Do you want calibre to check if the files in your library match the information in the database?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:316 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:150 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:692 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:972 @@ -3720,39 +3733,39 @@ msgstr "" msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:318 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:317 msgid "Database integrity check failed, click Show details for details." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:322 msgid "No problems found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:323 msgid "The files in your library match the information in the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:332 msgid "No library found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:333 msgid "No existing calibre library was found at %s. It will be removed from the list of known libraries." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:400 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:405 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:404 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:101 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:789 msgid "Not allowed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:400 msgid "You cannot change libraries while using the environment variable CALIBRE_OVERRIDE_DATABASE_PATH." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:405 msgid "You cannot change libraries while jobs are running." msgstr "" @@ -3977,16 +3990,16 @@ msgstr "" msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:141 msgid "Connect/share" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:178 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:79 msgid "Stopping" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:179 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:80 msgid "Stopping server, this could take upto a minute, please wait..." msgstr "" @@ -4178,20 +4191,20 @@ msgstr "" msgid "Ctrl+P" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:24 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:23 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:206 msgid "Run welcome wizard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:28 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:27 msgid "Restart in debug mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:43 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:42 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:47 msgid "Cannot configure before calibre is restarted." msgstr "" @@ -4556,8 +4569,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:277 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:279 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:148 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:177 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:89 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:91 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:93 @@ -4601,7 +4614,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:160 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:383 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1192 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1195 msgid "Path" msgstr "" @@ -4620,8 +4633,8 @@ msgid "Formats" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:29 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1022 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1195 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1025 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1198 msgid "Collections" msgstr "" @@ -4634,8 +4647,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:375 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:381 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:387 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1201 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1205 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1204 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1208 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:78 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:83 @@ -4735,12 +4748,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:40 #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:64 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:154 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/conversion_ui.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:81 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:92 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard_ui.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:86 @@ -5103,9 +5117,9 @@ msgid "Style the selected text block" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:34 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:36 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:168 msgid "Normal" msgstr "" @@ -5630,38 +5644,38 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:180 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:171 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:662 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:666 msgid "Choose cover for " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:187 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:178 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:670 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:674 msgid "Cannot read" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:188 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:179 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:671 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:675 msgid "You do not have permission to read the file: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:196 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:203 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:187 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:679 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:683 msgid "Error reading file" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:197 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:188 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:680 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:684 msgid "

There was an error reading from file:
" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:204 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:196 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:690 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:694 msgid " is not a valid picture" msgstr "" @@ -5729,7 +5743,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:544 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:433 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:214 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:296 msgid "&Series:" msgstr "" @@ -5739,7 +5753,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:546 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:434 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:435 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:294 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:295 msgid "List of known series. You can add new series." msgstr "" @@ -5753,6 +5767,7 @@ msgid "MOBI Output" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output.py:44 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:72 msgid "Default" msgstr "" @@ -6336,7 +6351,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:215 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:248 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:252 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1028 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1031 msgid "Undefined" msgstr "" @@ -6839,7 +6854,7 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_device_ui.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1191 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1194 msgid "Format" msgstr "" @@ -7031,7 +7046,7 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:68 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1020 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1023 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:32 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:71 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:241 @@ -7399,7 +7414,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:530 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:424 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:805 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:806 msgid "&Rating:" msgstr "" @@ -7407,7 +7422,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:532 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:425 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:426 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:806 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:807 msgid "Rating of this book. 0-5 stars" msgstr "" @@ -7428,7 +7443,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:539 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:431 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:432 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:147 msgid "Open Tag Editor" msgstr "" @@ -7481,7 +7496,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:558 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:440 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1012 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1015 msgid "&Date:" msgstr "" @@ -7554,14 +7569,14 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:581 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:465 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:419 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:549 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:440 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:591 msgid "&Basic metadata" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:582 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:466 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:447 msgid "&Custom metadata" msgstr "" @@ -7721,42 +7736,43 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:122 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:128 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:266 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:275 msgid "Could not read cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:269 msgid "Could not read cover from %s format" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:276 msgid "The cover in the %s format is invalid" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:158 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:765 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:766 msgid "Cover size: %dx%d pixels" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:195 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:693 msgid "Not a valid picture" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:214 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:716 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:717 msgid "Specify title and author" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:215 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:718 msgid "You must specify a title and author before generating a cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:902 msgid "Downloading cover..." msgstr "" @@ -7794,44 +7810,44 @@ msgid "The cover is not a valid picture" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:307 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:530 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:532 msgid "Choose formats for " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:338 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:562 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:564 msgid "No permission" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:339 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:565 msgid "You do not have permission to read the following files:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:366 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:367 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:593 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:594 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:595 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:596 msgid "No format selected" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:378 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:605 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:607 msgid "Could not read metadata" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:379 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:606 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:608 msgid "Could not read metadata from %s format" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:453 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:232 msgid " The green color indicates that the current author sort matches the current author" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:456 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:235 msgid " The red color indicates that the current author sort does not match the current author. No action is required if this is what you want." msgstr "" @@ -7846,7 +7862,7 @@ msgid " The red color warns that the current title sort does not match the curre msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:472 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:53 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:106 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:221 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:384 @@ -7855,14 +7871,14 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:475 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:484 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:374 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:379 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:400 msgid "Save changes and edit the metadata of %s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:481 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:48 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:820 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:107 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:211 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:401 @@ -7871,22 +7887,22 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:690 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:695 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:951 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:954 msgid "This ISBN number is valid" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:698 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:954 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:957 msgid "This ISBN number is invalid" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:783 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:881 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:883 msgid "Tags changed" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:784 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:882 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:884 msgid "You have changed the tags. In order to use the tags editor, you must either discard or apply these changes. Apply changes?" msgstr "" @@ -7915,12 +7931,12 @@ msgid "You must specify at least one of ISBN, Title, Authors or Publisher" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:961 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:321 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:342 msgid "Permission denied" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:962 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:322 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:343 msgid "Could not open %s. Is it being used by another program?" msgstr "" @@ -7933,19 +7949,19 @@ msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:94 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:95 msgid "" "Automatically create the title sort entry based on the current title entry.\n" "Using this button to create title sort will change title sort from red to green." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:413 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:117 msgid "Swap the author and title" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:415 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:106 msgid "" "Automatically create the author sort entry based on the current author entry.\n" "Using this button to create author sort will change author sort from red to green." @@ -7965,14 +7981,14 @@ msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:422 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:218 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.\n" "If the box is colored green, then text matches the individual author's sort strings. If it is colored red, then the authors and this text do not match." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:436 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:124 msgid "Remove unused series (Series that have no books)" msgstr "" @@ -7985,17 +8001,16 @@ msgid "dd MMM yyyy" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:442 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1063 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1066 msgid "Publishe&d:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:445 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:161 msgid "&Fetch metadata from server" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:448 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:623 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:627 msgid "&Browse" msgstr "" @@ -8004,7 +8019,7 @@ msgid "Remove border (if any) from cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:450 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:625 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:629 msgid "T&rim" msgstr "" @@ -8013,12 +8028,12 @@ msgid "Reset cover to default" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:452 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:627 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:631 msgid "&Remove" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:453 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:633 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:637 msgid "Download co&ver" msgstr "" @@ -8027,7 +8042,7 @@ msgid "Generate a default cover based on the title and author" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:455 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:634 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:638 msgid "&Generate cover" msgstr "" @@ -8044,7 +8059,7 @@ msgid "Remove the selected formats for this book from the database." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:461 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:448 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:450 msgid "Set the cover for the book from the selected format" msgstr "" @@ -8053,7 +8068,7 @@ msgid "Update metadata from the metadata in the selected format" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:464 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:608 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:652 msgid "&Comments" msgstr "" @@ -8469,7 +8484,7 @@ msgid "&Author:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:215 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:846 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:847 msgid "Ta&gs:" msgstr "" @@ -8932,7 +8947,8 @@ msgid "Downloading %s from %s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dnd.py:84 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:368 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:458 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:712 msgid "Download failed" msgstr "" @@ -9211,7 +9227,7 @@ msgid "Show books in the main memory of the device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:67 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1009 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1014 msgid "Card A" msgstr "" @@ -9220,7 +9236,7 @@ msgid "Show books in storage card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:69 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1011 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1016 msgid "Card B" msgstr "" @@ -9276,6 +9292,10 @@ msgstr "" msgid "Delete current saved search" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:263 +msgid "Donate" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:354 msgid "Y" msgstr "" @@ -9298,34 +9318,34 @@ msgstr "" msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:761 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1311 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:764 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1314 #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:796 msgid "The lookup/search name is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:767 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1313 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:770 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1316 msgid "This book's UUID is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1017 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1020 msgid "In Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1021 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1024 msgid "Size" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1211 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1214 msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1291 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1294 msgid "Marked for deletion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1294 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1297 msgid "Double click to edit me

" msgstr "" @@ -9398,7 +9418,7 @@ msgid "No matches for the search phrase %s were found." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:160 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:377 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:467 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:503 msgid "No matches found" msgstr "" @@ -9584,57 +9604,57 @@ msgstr "" msgid "Title &sort:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:223 msgid "Author s&ort:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:352 msgid "&Number:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:431 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:433 msgid "" "Last modified: %s\n" "\n" "Double click to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:735 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:736 msgid "Invalid cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:736 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:737 msgid "Could not change cover as the image is invalid." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:763 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:764 msgid "This book has no cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:813 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:814 msgid "stars" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:847 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:848 msgid "Tags categorize the book. This is particularly useful while searching.

They can be any wordsor phrases, separated by commas." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:905 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:907 msgid "I&ds:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:906 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:908 msgid "" "Edit the identifiers for this book. For example: \n" "\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:961 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:964 msgid "&Publisher:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1031 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1034 msgid "Clear date" msgstr "" @@ -9667,7 +9687,7 @@ msgid "%s %s for: %s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:291 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:175 msgid "Done" msgstr "" @@ -9680,64 +9700,118 @@ msgstr "" msgid "Details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:73 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:227 msgid "Edit Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:466 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:627 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:163 +msgid "&Download metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:487 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:671 msgid "Change cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:535 msgid "Co&mments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:574 msgid "&Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:579 msgid "&Cover and formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:596 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:640 msgid "C&ustom metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 msgid "Has cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 msgid "Has summary" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:185 +msgid "" +"The has cover indication is not fully\n" +"reliable. Sometimes results marked as not\n" +"having a cover will find a cover in the download\n" +"cover stage, and vice versa." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:254 +msgid "See at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:389 msgid "calibre is downloading metadata from: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:321 -msgid "Downloading" +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:411 +msgid "Please wait" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:440 msgid "Query: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:369 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:459 msgid "Failed to download metadata. Click Show Details to see details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:378 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:468 msgid "Failed to find any books that match your search. Try making the search less specific. For example, use only the author's last name and a single distinctive word from the title.

To see the full log, click Show Details." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:407 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:534 +msgid "Current cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:537 +msgid "Searching..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:683 +msgid "Downloading covers for %s, please wait..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:713 +msgid "Failed to download any covers, click \"Show details\" for details." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:719 +msgid "Could not find any covers for %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:721 +msgid "Found %d covers of %s. Pick the one you like best." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:766 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:205 +msgid "Copy to clipboard" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:773 +msgid "Download log" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:809 msgid "Downloading metadata..." msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:827 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:918 +msgid "View log" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/preferences/__init__.py:36 msgid "Restore settings to default values. You have to click Apply to actually save the default settings." msgstr "" @@ -9809,85 +9883,107 @@ msgstr "" msgid "&Configure metadata from file name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:34 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:36 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:170 msgid "Low" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:34 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:169 msgid "High" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:36 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:37 msgid "Very low" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:72 +msgid "Compact Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:176 msgid "Confirmation dialogs have all been reset" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:155 msgid "&Overwrite author and title by default when fetching metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:156 msgid "Download &social metadata (tags/ratings/etc.) by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:157 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:158 +msgid "Yes/No columns have three values (Requires restart)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:159 +msgid "" +"If checked, Yes/No custom columns values can be Yes, No, or Unknown.\n" +"If not checked, the values can be Yes or No." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:161 msgid "Automatically send downloaded &news to ebook reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:162 msgid "&Delete news from library when it is automatically sent to reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:136 -msgid "Default network &timeout:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:137 -msgid "Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:138 -msgid " seconds" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:142 -msgid "Job &priority:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:163 msgid "Preferred &output format:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:164 +msgid "Default network &timeout:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:165 +msgid "Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:166 +msgid " seconds" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:167 +msgid "Job &priority:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:171 msgid "Restriction to apply when the current library is opened:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:172 msgid "Apply this restriction on calibre startup if the current library is being used. Also applied when switching to this library. Note that this setting is per library. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:146 -msgid "Reset all disabled &confirmation dialogs" +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:173 +msgid "Edit metadata (single) layout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:174 +msgid "Choose a different layout for the Edit Metadata dialog. The compact metadata layout favors editing custom metadata over changing covers and formats." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:175 msgid "Preferred &input format order:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:178 msgid "Use internal &viewer for:" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:179 +msgid "Reset all disabled &confirmation dialogs" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns.py:96 msgid "You must select a column to delete it" msgstr "" @@ -10490,6 +10586,69 @@ msgstr "" msgid "Restart needed" msgstr "" +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:46 +msgid "Source" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:48 +msgid "Cover priority" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:93 +msgid "Metadata sources" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:94 +msgid "" +"Disable any metadata sources you do not want by unchecking them. You can also set the cover priority. Covers from sources that have a higher (smaller) priority will be preferred when bulk downloading metadata.\n" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:96 +msgid "Configure selected source" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:97 +msgid "Downloaded metadata fields" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:98 +msgid "If you uncheck any fields, metadata for those fields will not be downloaded" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:99 +msgid "Convert all downloaded comments to plain &text" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:100 +msgid "Max. number of &tags to download:" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:101 +msgid "Max. &time to wait after first match is found:" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:102 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:199 +msgid " secs" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:103 +msgid "Max. time to wait after first &cover is found:" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:42 msgid "Failed to install command line tools." msgstr "" @@ -11125,47 +11284,55 @@ msgstr "" msgid "Switch between library and device views" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:41 msgid "Separator" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:58 msgid "Choose library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:219 msgid "The main toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:211 -msgid "The optional second toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:220 msgid "The main toolbar when a device is connected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:221 +msgid "The optional second toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:222 +msgid "The menubar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:223 +msgid "The menubar when a device is connected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:224 msgid "The context menu for the books in the calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:226 msgid "The context menu for the books on the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:260 msgid "Cannot add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:250 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:261 msgid "Cannot add the actions %s to this location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:279 msgid "Cannot remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:280 msgid "Cannot remove the actions %s from this location" msgstr "" @@ -11438,7 +11605,7 @@ msgid "Changing the metadata for that many books can take a while. Are you sure? msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1152 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:413 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:418 msgid "Searches" msgstr "" @@ -11606,12 +11773,12 @@ msgstr "" msgid "The following books have already been converted to %s format. Do you wish to reconvert them?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:188 -msgid "&Restore" +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:156 +msgid "&Donate to support calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:190 -msgid "&Donate to support calibre" +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:189 +msgid "&Restore" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/ui.py:194 @@ -11807,10 +11974,6 @@ msgstr "" msgid "disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:199 -msgid " secs" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:200 msgid "Mouse &wheel flips pages" msgstr "" @@ -12133,10 +12296,6 @@ msgstr "" msgid "Find next occurrence" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:205 -msgid "Copy to clipboard" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:207 msgid "Reference Mode" msgstr "" @@ -13258,23 +13417,23 @@ msgstr "" msgid "The label must contain only lower case letters, digits and underscores, and start with a letter" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:66 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:65 msgid "%sAverage rating is %3.1f" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1007 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1012 msgid "Main" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3051 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3056 msgid "

Migrating old database to ebook library in %s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3080 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3085 msgid "Copying %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3097 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3102 msgid "Compacting database" msgstr "" @@ -14329,3 +14488,216 @@ msgstr "" msgid "Do not download CSS stylesheets." msgstr "" + + +#: /home/kovid/work/calibre/resources/default_tweaks.py:12 +msgid "Auto increment series index" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:13 +msgid "The algorithm used to assign a new book in an existing series a series number.\nNew series numbers assigned using this tweak are always integer values, except\nif a constant non-integer is specified.\nPossible values are:\nnext - First available integer larger than the largest existing number\nfirst_free - First available integer larger than 0\nnext_free - First available integer larger than the smallest existing number\nlast_free - First available integer smaller than the largest existing number\nReturn largest existing + 1 if no free number is found\nconst - Assign the number 1 always\na number - Assign that number always. The number is not in quotes. Note that\n0.0 can be used here.\nExamples:\nseries_index_auto_increment = 'next'\nseries_index_auto_increment = 'next_free'\nseries_index_auto_increment = 16.5" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:31 +msgid "Add separator after completing an author name" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:32 +msgid "Should the completion separator be append\nto the end of the completed text to\nautomatically begin a new completion operation\nfor authors.\nCan be either True or False" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:40 +msgid "Author sort name algorithm" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:41 +msgid "The algorithm used to copy author to author_sort\nPossible values are:\ninvert: use \"fn ln\" -> \"ln, fn\" (the default algorithm)\ncopy : copy author to author_sort without modification\ncomma : use 'copy' if there is a ',' in the name, otherwise use 'invert'\nnocomma : \"fn ln\" -> \"ln fn\" (without the comma)\nWhen this tweak is changed, the author_sort values stored with each author\nmust be recomputed by right-clicking on an author in the left-hand tags pane,\nselecting 'manage authors', and pressing 'Recalculate all author sort values'." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:52 +msgid "Use author sort in Tag Browser" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:53 +msgid "Set which author field to display in the tags pane (the list of authors,\nseries, publishers etc on the left hand side). The choices are author and\nauthor_sort. This tweak affects only what is displayed under the authors\ncategory in the tags pane and content server. Please note that if you set this\nto author_sort, it is very possible to see duplicate names in the list because\nalthough it is guaranteed that author names are unique, there is no such\nguarantee for author_sort values. Showing duplicates won't break anything, but\nit could lead to some confusion. When using 'author_sort', the tooltip will\nshow the author's name.\nExamples:\ncategories_use_field_for_author_name = 'author'\ncategories_use_field_for_author_name = 'author_sort'" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:67 +msgid "Control partitioning of Tag Browser" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:68 +msgid "When partitioning the tags browser, the format of the subcategory label is\ncontrolled by a template: categories_collapsed_name_template if sorting by\nname, categories_collapsed_rating_template if sorting by average rating, and\ncategories_collapsed_popularity_template if sorting by popularity. There are\ntwo variables available to the template: first and last. The variable 'first'\nis the initial item in the subcategory, and the variable 'last' is the final\nitem in the subcategory. Both variables are 'objects'; they each have multiple\nvalues that are obtained by using a suffix. For example, first.name for an\nauthor category will be the name of the author. The sub-values available are:\nname: the printable name of the item\ncount: the number of books that references this item\navg_rating: the average rating of all the books referencing this item\nsort: the sort value. For authors, this is the author_sort for that author\ncategory: the category (e.g., authors, series) that the item is in.\nNote that the \"r'\" in front of the { is necessary if there are backslashes\n(\\ characters) in the template. It doesn't hurt anything to leave it there\neven if there aren't any backslashes." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:90 +msgid "Specify columns to sort the booklist by on startup" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:91 +msgid "Provide a set of columns to be sorted on when calibre starts\nThe argument is None if saved sort history is to be used\notherwise it is a list of column,order pairs. Column is the\nlookup/search name, found using the tooltip for the column\nOrder is 0 for ascending, 1 for descending\nFor example, set it to [('authors',0),('title',0)] to sort by\ntitle within authors." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:100 +msgid "Control how dates are displayed" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:101 +msgid "Format to be used for publication date and the timestamp (date).\nA string controlling how the publication date is displayed in the GUI\nd the day as number without a leading zero (1 to 31)\ndd the day as number with a leading zero (01 to 31)\nddd the abbreviated localized day name (e.g. 'Mon' to 'Sun').\ndddd the long localized day name (e.g. 'Monday' to 'Qt::Sunday').\nM the month as number without a leading zero (1-12)\nMM the month as number with a leading zero (01-12)\nMMM the abbreviated localized month name (e.g. 'Jan' to 'Dec').\nMMMM the long localized month name (e.g. 'January' to 'December').\nyy the year as two digit number (00-99)\nyyyy the year as four digit number\nFor example, given the date of 9 Jan 2010, the following formats show\nMMM yyyy ==> Jan 2010 yyyy ==> 2010 dd MMM yyyy ==> 09 Jan 2010\nMM/yyyy ==> 01/2010 d/M/yy ==> 9/1/10 yy ==> 10\npublication default if not set: MMM yyyy\ntimestamp default if not set: dd MMM yyyy" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:121 +msgid "Control sorting of titles and series in the library display" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:122 +msgid "Control title and series sorting in the library view. If set to\n'library_order', the title sort field will be used instead of the title.\nUnless you have manually edited the title sort field, leading articles such as\nThe and A will be ignored. If set to 'strictly_alphabetic', the titles will be\nsorted as-is (sort by title instead of title sort). For example, with\nlibrary_order, The Client will sort under 'C'. With strictly_alphabetic, the\nbook will sort under 'T'.\nThis flag affects Calibre's library display. It has no effect on devices. In\naddition, titles for books added before changing the flag will retain their\norder until the title is edited. Double-clicking on a title and hitting return\nwithout changing anything is sufficient to change the sort." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:135 +msgid "Control formatting of title and series when used in templates" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:136 +msgid "Control how title and series names are formatted when saving to disk/sending\nto device. The behavior depends on the field being processed. If processing\ntitle, then if this tweak is set to 'library_order', the title will be\nreplaced with title_sort. If it is set to 'strictly_alphabetic', then the\ntitle will not be changed. If processing series, then if set to\n'library_order', articles such as 'The' and 'An' will be moved to the end. If\nset to 'strictly_alphabetic', the series will be sent without change.\nFor example, if the tweak is set to library_order, \"The Lord of the Rings\"\nwill become \"Lord of the Rings, The\". If the tweak is set to\nstrictly_alphabetic, it would remain \"The Lord of the Rings\"." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:148 +msgid "Set the list of words considered to be \"articles\" for sort strings" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:149 +msgid "Set the list of words that are to be considered 'articles' when computing the\ntitle sort strings. The list is a regular expression, with the articles\nseparated by 'or' bars. Comparisons are case insensitive, and that cannot be\nchanged. Changes to this tweak won't have an effect until the book is modified\nin some way. If you enter an invalid pattern, it is silently ignored.\nTo disable use the expression: '^$'\nDefault: '^(A|The|An)\\s+'" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:158 +msgid "Specify a folder calibre should connect to at startup" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:159 +msgid "Specify a folder that calibre should connect to at startup using\nconnect_to_folder. This must be a full path to the folder. If the folder does\nnot exist when calibre starts, it is ignored. If there are '\\' characters in\nthe path (such as in Windows paths), you must double them.\nExamples:\nauto_connect_to_folder = 'C:\\\\Users\\\\someone\\\\Desktop\\\\testlib'\nauto_connect_to_folder = '/home/dropbox/My Dropbox/someone/library'" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:168 +msgid "Specify renaming rules for SONY collections" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:169 +msgid "Specify renaming rules for sony collections. This tweak is only applicable if\nmetadata management is set to automatic. Collections on Sonys are named\ndepending upon whether the field is standard or custom. A collection derived\nfrom a standard field is named for the value in that field. For example, if\nthe standard 'series' column contains the value 'Darkover', then the\ncollection name is 'Darkover'. A collection derived from a custom field will\nhave the name of the field added to the value. For example, if a custom series\ncolumn named 'My Series' contains the name 'Darkover', then the collection\nwill by default be named 'Darkover (My Series)'. For purposes of this\ndocumentation, 'Darkover' is called the value and 'My Series' is called the\ncategory. If two books have fields that generate the same collection name,\nthen both books will be in that collection.\nThis set of tweaks lets you specify for a standard or custom field how\nthe collections are to be named. You can use it to add a description to a\nstandard field, for example 'Foo (Tag)' instead of the 'Foo'. You can also use\nit to force multiple fields to end up in the same collection. For example, you\ncould force the values in 'series', '#my_series_1', and '#my_series_2' to\nappear in collections named 'some_value (Series)', thereby merging all of the\nfields into one set of collections.\nThere are two related tweaks. The first determines the category name to use\nfor a metadata field. The second is a template, used to determines how the\nvalue and category are combined to create the collection name.\nThe syntax of the first tweak, sony_collection_renaming_rules, is:\n{'field_lookup_name':'category_name_to_use', 'lookup_name':'name', ...}\nThe second tweak, sony_collection_name_template, is a template. It uses the\nsame template language as plugboards and save templates. This tweak controls\nhow the value and category are combined together to make the collection name.\nThe only two fields available are {category} and {value}. The {value} field is\nnever empty. The {category} field can be empty. The default is to put the\nvalue first, then the category enclosed in parentheses, it is isn't empty:\n'{value} {category:|(|)}'\nExamples: The first three examples assume that the second tweak\nhas not been changed.\n1: I want three series columns to be merged into one set of collections. The\ncolumn lookup names are 'series', '#series_1' and '#series_2'. I want nothing\nin the parenthesis. The value to use in the tweak value would be:\nsony_collection_renaming_rules={'series':'', '#series_1':'', '#series_2':''}\n2: I want the word '(Series)' to appear on collections made from series, and\nthe word '(Tag)' to appear on collections made from tags. Use:\nsony_collection_renaming_rules={'series':'Series', 'tags':'Tag'}\n3: I want 'series' and '#myseries' to be merged, and for the collection name\nto have '(Series)' appended. The renaming rule is:\nsony_collection_renaming_rules={'series':'Series', '#myseries':'Series'}\n4: Same as example 2, but instead of having the category name in parentheses\nand appended to the value, I want it prepended and separated by a colon, such\nas in Series: Darkover. I must change the template used to format the category name\nThe resulting two tweaks are:\nsony_collection_renaming_rules={'series':'Series', 'tags':'Tag'}\nsony_collection_name_template='{category:||: }{value}'" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:221 +msgid "Specify how SONY collections are sorted" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:222 +msgid "Specify how sony collections are sorted. This tweak is only applicable if\nmetadata management is set to automatic. You can indicate which metadata is to\nbe used to sort on a collection-by-collection basis. The format of the tweak\nis a list of metadata fields from which collections are made, followed by the\nname of the metadata field containing the sort value.\nExample: The following indicates that collections built from pubdate and tags\nare to be sorted by the value in the custom column '#mydate', that collections\nbuilt from 'series' are to be sorted by 'series_index', and that all other\ncollections are to be sorted by title. If a collection metadata field is not\nnamed, then if it is a series- based collection it is sorted by series order,\notherwise it is sorted by title order.\n[(['pubdate', 'tags'],'#mydate'), (['series'],'series_index'), (['*'], 'title')]\nNote that the bracketing and parentheses are required. The syntax is\n[ ( [list of fields], sort field ) , ( [ list of fields ] , sort field ) ]\nDefault: empty (no rules), so no collection attributes are named." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:240 +msgid "Control how tags are applied when copying books to another library" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:241 +msgid "Set this to True to ensure that tags in 'Tags to add when adding\na book' are added when copying books to another library" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:246 +msgid "Set the maximum number of tags to show per book in the content server" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:250 +msgid "Set custom metadata fields that the content server will or will not display." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:251 +msgid "content_server_will_display is a list of custom fields to be displayed.\ncontent_server_wont_display is a list of custom fields not to be displayed.\nwont_display has priority over will_display.\nThe special value '*' means all custom fields. The value [] means no entries.\nDefaults:\ncontent_server_will_display = ['*']\ncontent_server_wont_display = []\nExamples:\nTo display only the custom fields #mytags and #genre:\ncontent_server_will_display = ['#mytags', '#genre']\ncontent_server_wont_display = []\nTo display all fields except #mycomments:\ncontent_server_will_display = ['*']\ncontent_server_wont_display['#mycomments']" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:268 +msgid "Set custom metadata fields that the book details panel will or will not display." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:269 +msgid "book_details_will_display is a list of custom fields to be displayed.\nbook_details_wont_display is a list of custom fields not to be displayed.\nwont_display has priority over will_display.\nThe special value '*' means all custom fields. The value [] means no entries.\nDefaults:\nbook_details_will_display = ['*']\nbook_details_wont_display = []\nExamples:\nTo display only the custom fields #mytags and #genre:\nbook_details_will_display = ['#mytags', '#genre']\nbook_details_wont_display = []\nTo display all fields except #mycomments:\nbook_details_will_display = ['*']\nbook_details_wont_display['#mycomments']\nAs above, this tweak affects only display of custom fields. The standard\nfields are not affected" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:288 +msgid "Set the maximum number of sort 'levels'" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:289 +msgid "Set the maximum number of sort 'levels' that calibre will use to resort the\nlibrary after certain operations such as searches or device insertion. Each\nsort level adds a performance penalty. If the database is large (thousands of\nbooks) the penalty might be noticeable. If you are not concerned about multi-\nlevel sorts, and if you are seeing a slowdown, reduce the value of this tweak." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:296 +msgid "Specify which font to use when generating a default cover" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:297 +msgid "Absolute path to .ttf font files to use as the fonts for the title, author\nand footer when generating a default cover. Useful if the default font (Liberation\nSerif) does not contain glyphs for the language of the books in your library." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:303 +msgid "Control behavior of double clicks on the book list" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:304 +msgid "Behavior of doubleclick on the books list. Choices: open_viewer, do_nothing,\nedit_cell, edit_metadata. Selecting edit_metadata has the side effect of\ndisabling editing a field using a single click.\nDefault: open_viewer.\nExample: doubleclick_on_library_view = 'do_nothing'" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:312 +msgid "Language to use when sorting." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:313 +msgid "Setting this tweak will force sorting to use the\ncollating order for the specified language. This might be useful if you run\ncalibre in English but want sorting to work in the language where you live.\nSet the tweak to the desired ISO 639-1 language code, in lower case.\nYou can find the list of supported locales at\nhttp://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/nls/rbagsicusortsequencetables.htm\nDefault: locale_for_sorting = '' -- use the language calibre displays in\nExample: locale_for_sorting = 'fr' -- sort using French rules.\nExample: locale_for_sorting = 'nb' -- sort using Norwegian rules." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:324 +msgid "Number of columns for custom metadata in the edit metadata dialog" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:325 +msgid "Set whether to use one or two columns for custom metadata when editing\nmetadata one book at a time. If True, then the fields are laid out using two\ncolumns. If False, one column is used." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:330 +msgid "The number of seconds to wait before sending emails" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:331 +msgid "The number of seconds to wait before sending emails when using a\npublic email server like gmail or hotmail. Default is: 5 minutes\nSetting it to lower may cause the server's SPAM controls to kick in,\nmaking email sending fail. Changes will take effect only after a restart of\ncalibre." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:338 +msgid "Remove the bright yellow lines at the edges of the book list" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:339 +msgid "Control whether the bright yellow lines at the edges of book list are drawn\nwhen a section of the user interface is hidden. Changes will take effect\nafter a restart of calibre." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:344 +msgid "The maximum width and height for covers saved in the calibre library" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:345 +msgid "All covers in the calibre library will be resized, preserving aspect ratio,\nto fit within this size. This is to prevent slowdowns caused by extremely\nlarge covers" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:350 +msgid "Where to send downloaded news" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:351 +msgid "When automatically sending downloaded news to a connected device, calibre\nwill by default send it to the main memory. By changing this tweak, you can\ncontrol where it is sent. Valid values are \"main\", \"carda\", \"cardb\". Note\nthat if there isn't enough free space available on the location you choose,\nthe files will be sent to the location with the most free space." +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:358 +msgid "What interfaces should the content server listen on" +msgstr "" + +#: /home/kovid/work/calibre/resources/default_tweaks.py:359 +msgid "By default, the calibre content server listens on '0.0.0.0' which means that it\naccepts IPv4 connections on all interfaces. You can change this to, for\nexample, '127.0.0.1' to only listen for connections from the local machine, or\nto '::' to listen to all incoming IPv6 and IPv4 connections (this may not\nwork on all operating systems)" +msgstr "" From 9c8456b275de6a53ccff106f6bf37e3d0d71d49d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 15:47:13 -0600 Subject: [PATCH 09/17] Fix a regression in 0.7.54 that broke reading covers/metadata from cbz files. Fixes #756892 (no cover when adding CBZ) --- src/calibre/customize/builtins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 52e7e91497..8f6c597ee5 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -173,7 +173,7 @@ class ComicMetadataReader(MetadataReaderPlugin): stream.seek(pos) if id_ == b'Rar': ftype = 'cbr' - elif id.startswith(b'PK'): + elif id_.startswith(b'PK'): ftype = 'cbz' if ftype == 'cbr': from calibre.libunrar import extract_first_alphabetically as extract_first From ecf79847f989a73732e7a52dfefee5db6a3c8bdb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 15:50:13 -0600 Subject: [PATCH 10/17] Support for Motorola Xoom with Android 3.0. Fixes #756888 (Calibre does not recognize my Android (3.0) device) --- src/calibre/devices/android/driver.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/calibre/devices/android/driver.py b/src/calibre/devices/android/driver.py index 7702a7caf0..a63ce8c581 100644 --- a/src/calibre/devices/android/driver.py +++ b/src/calibre/devices/android/driver.py @@ -37,7 +37,7 @@ class ANDROID(USBMS): 0x22b8 : { 0x41d9 : [0x216], 0x2d61 : [0x100], 0x2d67 : [0x100], 0x41db : [0x216], 0x4285 : [0x216], 0x42a3 : [0x216], 0x4286 : [0x216], 0x42b3 : [0x216], 0x42b4 : [0x216], - 0x7086 : [0x0226], + 0x7086 : [0x0226], 0x70a8: [0x9999], }, # Sony Ericsson @@ -96,7 +96,8 @@ class ANDROID(USBMS): VENDOR_NAME = ['HTC', 'MOTOROLA', 'GOOGLE_', 'ANDROID', 'ACER', 'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE', 'ARCHOS', - 'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA'] + 'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA', + 'GENERIC-'] WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE', '__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897', 'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', @@ -104,7 +105,7 @@ class ANDROID(USBMS): 'SGH-T849', '_MB300', 'A70S', 'S_ANDROID', 'A101IT', 'A70H', 'IDEOS_TABLET', 'MYTOUCH_4G', 'UMS_COMPOSITE', 'SCH-I800_CARD', '7', 'A956', 'A955', 'A43', 'ANDROID_PLATFORM', 'TEGRA_2', - 'MB860'] + 'MB860', 'MULTI-CARD'] WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD', 'A70S', 'A101IT', '7'] From e5da008e24bb90d257767098dac84ebfdf0a1558 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 17:12:24 -0600 Subject: [PATCH 11/17] Add button to edit metadata single to configure metadata downloading --- src/calibre/ebooks/metadata/sources/amazon.py | 3 +- src/calibre/gui2/metadata/single.py | 17 ++++- src/calibre/gui2/preferences/__init__.py | 52 ++++++++----- .../gui2/preferences/metadata_sources.py | 73 +++++++++++++++++-- .../gui2/preferences/metadata_sources.ui | 3 + 5 files changed, 121 insertions(+), 27 deletions(-) diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index 2ad5bfbacc..24df68e51d 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -284,7 +284,8 @@ class Amazon(Source): capabilities = frozenset(['identify', 'cover']) touched_fields = frozenset(['title', 'authors', 'identifier:amazon', - 'identifier:isbn', 'rating', 'comments', 'publisher', 'pubdate']) + 'identifier:isbn', 'rating', 'comments', 'publisher', 'pubdate', + 'language']) has_html_comments = True supports_gzip_transfer_encoding = True diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 175af291f1..7c9dd00734 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -166,6 +166,11 @@ class MetadataSingleDialogBase(ResizableDialog): font.setBold(True) self.fetch_metadata_button.setFont(font) + self.config_metadata_button = QToolButton(self) + self.config_metadata_button.setIcon(QIcon(I('config.png'))) + self.config_metadata_button.clicked.connect(self.configure_metadata) + self.config_metadata_button.setToolTip( + _('Change how calibre downloads metadata')) # }}} @@ -315,6 +320,12 @@ class MetadataSingleDialogBase(ResizableDialog): if d.cover_pixmap is not None: self.cover.current_val = pixmap_to_data(d.cover_pixmap) + def configure_metadata(self): + from calibre.gui2.preferences import show_config_widget + gui = self.parent() + show_config_widget('Sharing', 'Metadata download', parent=self, + gui=gui, never_shutdown=True) + def download_cover(self, *args): from calibre.gui2.metadata.single_download import CoverFetch d = CoverFetch(self.cover.pixmap(), self) @@ -451,7 +462,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{ sto = QWidget.setTabOrder sto(self.button_box, self.fetch_metadata_button) - sto(self.fetch_metadata_button, self.title) + sto(self.fetch_metadata_button, self.config_metadata_button) + sto(self.config_metadata_button, self.title) def create_row(row, one, two, three, col=1, icon='forward.png'): ql = BuddyLabel(one) @@ -530,7 +542,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{ self.tabs[0].spc_two = QSpacerItem(10, 10, QSizePolicy.Expanding, QSizePolicy.Expanding) l.addItem(self.tabs[0].spc_two, 8, 0, 1, 3) - l.addWidget(self.fetch_metadata_button, 9, 0, 1, 3) + l.addWidget(self.fetch_metadata_button, 9, 0, 1, 2) + l.addWidget(self.config_metadata_button, 9, 2, 1, 1) self.tabs[0].gb2 = gb = QGroupBox(_('Co&mments'), self) gb.l = l = QVBoxLayout() diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index b482429504..1669e24059 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -7,8 +7,9 @@ __docformat__ = 'restructuredtext en' import textwrap -from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \ - QLineEdit, QComboBox, QVariant, Qt +from PyQt4.Qt import (QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, + QLineEdit, QComboBox, QVariant, Qt, QIcon, QDialog, QVBoxLayout, + QDialogButtonBox) from calibre.customize.ui import preferences_plugins from calibre.utils.config import ConfigProxy @@ -284,7 +285,14 @@ def get_plugin(category, name): 'No Preferences Plugin with category: %s and name: %s found' % (category, name)) -# Testing {{{ +class ConfigDialog(QDialog): + def set_widget(self, w): self.w = w + def accept(self): + try: + self.restart_required = self.w.commit() + except AbortCommit: + return + QDialog.accept(self) def init_gui(): from calibre.gui2.ui import Main @@ -298,21 +306,24 @@ def init_gui(): gui.initialize(db.library_path, db, None, actions, show_gui=False) return gui -def test_widget(category, name, gui=None): - from PyQt4.Qt import QDialog, QVBoxLayout, QDialogButtonBox - class Dialog(QDialog): - def set_widget(self, w): self.w = w - def accept(self): - try: - self.restart_required = self.w.commit() - except AbortCommit: - return - QDialog.accept(self) +def show_config_widget(category, name, gui=None, show_restart_msg=False, + parent=None, never_shutdown=False): + ''' + Show the preferences plugin identified by category and name + :param gui: gui instance, if None a hidden gui is created + :param show_restart_msg: If True and the preferences plugin indicates a + restart is required, show a message box telling the user to restart + :param parent: The parent of the displayed dialog + + :return: True iff a restart is required for the changes made by the user to + take effect + ''' pl = get_plugin(category, name) - d = Dialog() + d = ConfigDialog(parent) d.resize(750, 550) - d.setWindowTitle(category + " - " + name) + d.setWindowTitle(_('Configure ') + name) + d.setWindowIcon(QIcon(I('config.png'))) bb = QDialogButtonBox(d) bb.setStandardButtons(bb.Apply|bb.Cancel|bb.RestoreDefaults) bb.accepted.connect(d.accept) @@ -335,11 +346,18 @@ def test_widget(category, name, gui=None): w.genesis(gui) w.initialize() d.exec_() - if getattr(d, 'restart_required', False): + rr = getattr(d, 'restart_required', False) + if show_restart_msg and rr: from calibre.gui2 import warning_dialog warning_dialog(gui, 'Restart required', 'Restart required', show=True) - if mygui: + if mygui and not never_shutdown: gui.shutdown() + return rr + +# Testing {{{ + +def test_widget(category, name, gui=None): + show_config_widget(category, name, gui=gui, show_restart_msg=True) def test_all(): from PyQt4.Qt import QApplication diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index 66fd35e038..8324684bc8 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -15,7 +15,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.metadata_sources_ui import Ui_Form from calibre.ebooks.metadata.sources.base import msprefs from calibre.customize.ui import (all_metadata_plugins, is_disabled, - enable_plugin, disable_plugin, restore_plugin_state_to_default) + enable_plugin, disable_plugin, default_disabled_plugins) from calibre.gui2 import NONE class SourcesModel(QAbstractTableModel): # {{{ @@ -116,11 +116,11 @@ class SourcesModel(QAbstractTableModel): # {{{ self.cover_overrides = {} def restore_defaults(self): - del msprefs['cover_priorities'] - self.enabled_overrides = {} - self.cover_overrides = {} - for plugin in self.plugins: - restore_plugin_state_to_default(plugin) + self.enabled_overrides = dict([(p, (Qt.Unchecked if p.name in + default_disabled_plugins else Qt.Checked)) for p in self.plugins]) + self.cover_overrides = dict([(p, + msprefs.defaults['cover_priorities'].get(p.name, 1)) + for p in self.plugins]) self.reset() # }}} @@ -131,6 +131,18 @@ class FieldsModel(QAbstractListModel): # {{{ QAbstractTableModel.__init__(self, parent) self.fields = [] + self.descs = { + 'authors': _('Authors'), + 'comments': _('Comments'), + 'pubdate': _('Published date'), + 'publisher': _('Publisher'), + 'rating' : _('Rating'), + 'tags' : _('Tags'), + 'title': _('Title'), + 'series': _('Series'), + 'language': _('Language'), + } + self.overrides = {} def rowCount(self, parent=None): return len(self.fields) @@ -141,10 +153,54 @@ class FieldsModel(QAbstractListModel): # {{{ fields |= p.touched_fields self.fields = [] for x in fields: - if not x.startswith('identifiers:'): + if not x.startswith('identifier:') and x not in ('series_index',): self.fields.append(x) + self.fields.sort(key=lambda x:self.descs.get(x, x)) self.reset() + def state(self, field, defaults=False): + src = msprefs.defaults if defaults else msprefs + return (Qt.Unchecked if field in src['ignore_fields'] + else Qt.Checked) + + def data(self, index, role): + try: + field = self.fields[index.row()] + except: + return None + if role == Qt.DisplayRole: + return self.descs.get(field, field) + if role == Qt.CheckStateRole: + return self.overrides.get(field, self.state(field)) + return NONE + + def flags(self, index): + ans = QAbstractTableModel.flags(self, index) + return ans | Qt.ItemIsUserCheckable + + def restore_defaults(self): + self.overrides = dict([(f, self.state(f, True)) for f in self.fields]) + self.reset() + + def setData(self, index, val, role): + try: + field = self.fields[index.row()] + except: + return False + ret = False + if role == Qt.CheckStateRole: + val, ok = val.toInt() + if ok: + self.overrides[field] = val + ret = True + if ret: + self.dataChanged.emit(index, index) + return ret + + def commit(self): + val = [k for k, v in self.overrides.iteritems() if v == Qt.Unchecked] + msprefs['ignore_fields'] = val + # }}} @@ -173,14 +229,17 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): ConfigWidgetBase.initialize(self) self.sources_model.initialize() self.sources_view.resizeColumnsToContents() + self.fields_model.initialize() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) self.sources_model.restore_defaults() + self.fields_model.restore_defaults() self.changed_signal.emit() def commit(self): self.sources_model.commit() + self.fields_model.commit() return ConfigWidgetBase.commit(self) if __name__ == '__main__': diff --git a/src/calibre/gui2/preferences/metadata_sources.ui b/src/calibre/gui2/preferences/metadata_sources.ui index 68ac6352cf..546120f628 100644 --- a/src/calibre/gui2/preferences/metadata_sources.ui +++ b/src/calibre/gui2/preferences/metadata_sources.ui @@ -73,6 +73,9 @@ If you uncheck any fields, metadata for those fields will not be downloaded + + QAbstractItemView::NoSelection + From 9084f0be4529b1cfe88cc46ae845a4c365ccc69d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 17:23:12 -0600 Subject: [PATCH 12/17] For kiwidude --- src/calibre/gui2/ui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 8b2beedfd4..4a9d76418c 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -449,12 +449,12 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ self.library_view.model().count_changed() prefs['library_path'] = self.library_path db = self.library_view.model().db - for action in self.iactions.values(): - action.library_changed(db) self.set_window_title() self.apply_named_search_restriction('') # reset restriction to null self.saved_searches_changed() # reload the search restrictions combo box self.apply_named_search_restriction(db.prefs['gui_restriction']) + for action in self.iactions.values(): + action.library_changed(db) if olddb is not None: try: if call_close: From 385986fe4b0f284e50e19436b5a13612a1267fdb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 17:28:38 -0600 Subject: [PATCH 13/17] ... --- src/calibre/ebooks/metadata/sources/identify.py | 3 --- src/calibre/gui2/metadata/single.py | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index cd658a0daf..fad810c26e 100644 --- a/src/calibre/ebooks/metadata/sources/identify.py +++ b/src/calibre/ebooks/metadata/sources/identify.py @@ -357,11 +357,8 @@ def identify(log, abort, # {{{ if r.plugin.has_html_comments and r.comments: r.comments = html2text(r.comments) - dummy = Metadata(_('Unknown')) max_tags = msprefs['max_tags'] for r in results: - for f in msprefs['ignore_fields']: - setattr(r, f, getattr(dummy, f)) r.tags = r.tags[:max_tags] return results diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 7c9dd00734..4ce76d8cc8 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -24,6 +24,7 @@ from calibre.gui2.metadata.basic_widgets import (TitleEdit, AuthorsEdit, from calibre.gui2.metadata.single_download import FullFetch from calibre.gui2.custom_column_widgets import populate_metadata_page from calibre.utils.config import tweaks +from calibre.ebooks.metadata.book.base import Metadata class MetadataSingleDialogBase(ResizableDialog): @@ -314,7 +315,11 @@ class MetadataSingleDialogBase(ResizableDialog): ret = d.start(title=self.title.current_val, authors=self.authors.current_val, identifiers=self.identifiers.current_val) if ret == d.Accepted: + from calibre.ebooks.metadata.sources.base import msprefs mi = d.book + dummy = Metadata(_('Unknown')) + for f in msprefs['ignore_fields']: + setattr(mi, f, getattr(dummy, f)) if mi is not None: self.update_from_mi(mi) if d.cover_pixmap is not None: From f628964592de086e984f6793e9b9cc84e35f7263 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 21:15:20 -0600 Subject: [PATCH 14/17] ... --- src/calibre/ebooks/metadata/sources/base.py | 36 +++++++++- .../ebooks/metadata/sources/openlibrary.py | 2 +- .../gui2/preferences/metadata_sources.py | 69 +++++++++++++++++-- 3 files changed, 99 insertions(+), 8 deletions(-) diff --git a/src/calibre/ebooks/metadata/sources/base.py b/src/calibre/ebooks/metadata/sources/base.py index 67a80d5785..5089d8951b 100644 --- a/src/calibre/ebooks/metadata/sources/base.py +++ b/src/calibre/ebooks/metadata/sources/base.py @@ -131,7 +131,22 @@ def fixcase(x): x = titlecase(x) return x +class Option(object): + __slots__ = ['type', 'default', 'label', 'desc', 'name', 'choices'] + def __init__(self, name, type_, default, label, desc, choices=None): + ''' + :param name: The name of this option. Must be a valid python identifier + :param type_: The type of this option, one of ('number', 'string', + 'bool', 'choices') + :param default: The default value for this option + :param label: A short (few words) description of this option + :param desc: A longer description of this option + :param choices: A list of possible values, used only if type='choices' + ''' + self.name, self.type, self.default, self.label, self.desc = (name, + type_, default, label, desc) + self.choices = choices class Source(Plugin): @@ -158,10 +173,14 @@ class Source(Plugin): supports_gzip_transfer_encoding = False #: Cached cover URLs can sometimes be unreliable (i.e. the download could - #: fail or the returned image could be bogus. If that is the case set this to - #: False + #: fail or the returned image could be bogus. If that is often the case + #: with this source set to False cached_cover_url_is_reliable = True + #: A list of :class:`Option` objects. They will be used to automatically + #: construct the configuration widget for this plugin + options = () + def __init__(self, *args, **kwargs): Plugin.__init__(self, *args, **kwargs) @@ -170,6 +189,9 @@ class Source(Plugin): self.cache_lock = threading.RLock() self._config_obj = None self._browser = None + self.prefs.defaults['ignore_fields'] = [] + for opt in self.options: + self.prefs.defaults[opt.name] = opt.default # Configuration {{{ @@ -180,6 +202,16 @@ class Source(Plugin): ''' return True + def is_customizable(self): + return True + + def config_widget(self): + from calibre.gui2.metadata.config import ConfigWidget + return ConfigWidget(self) + + def save_settings(self, config_widget): + config_widget.commit() + @property def prefs(self): if self._config_obj is None: diff --git a/src/calibre/ebooks/metadata/sources/openlibrary.py b/src/calibre/ebooks/metadata/sources/openlibrary.py index 19b8747265..4645d2a18a 100644 --- a/src/calibre/ebooks/metadata/sources/openlibrary.py +++ b/src/calibre/ebooks/metadata/sources/openlibrary.py @@ -12,7 +12,7 @@ from calibre.ebooks.metadata.sources.base import Source class OpenLibrary(Source): name = 'Open Library' - description = _('Downloads metadata from The Open Library') + description = _('Downloads covers from The Open Library') capabilities = frozenset(['cover']) diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index 8324684bc8..4500a03b30 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -9,14 +9,15 @@ __docformat__ = 'restructuredtext en' from operator import attrgetter -from PyQt4.Qt import (QAbstractTableModel, Qt, QAbstractListModel) +from PyQt4.Qt import (QAbstractTableModel, Qt, QAbstractListModel, QWidget, + pyqtSignal, QVBoxLayout, QDialogButtonBox, QFrame, QLabel) from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.metadata_sources_ui import Ui_Form from calibre.ebooks.metadata.sources.base import msprefs from calibre.customize.ui import (all_metadata_plugins, is_disabled, enable_plugin, disable_plugin, default_disabled_plugins) -from calibre.gui2 import NONE +from calibre.gui2 import NONE, error_dialog class SourcesModel(QAbstractTableModel): # {{{ @@ -64,7 +65,8 @@ class SourcesModel(QAbstractTableModel): # {{{ elif role == Qt.CheckStateRole and col == 0: orig = Qt.Unchecked if is_disabled(plugin) else Qt.Checked return self.enabled_overrides.get(plugin, orig) - + elif role == Qt.UserRole: + return plugin return NONE def setData(self, index, val, role): @@ -127,6 +129,7 @@ class SourcesModel(QAbstractTableModel): # {{{ class FieldsModel(QAbstractListModel): # {{{ + def __init__(self, parent=None): QAbstractTableModel.__init__(self, parent) @@ -143,6 +146,7 @@ class FieldsModel(QAbstractListModel): # {{{ 'language': _('Language'), } self.overrides = {} + self.exclude = frozenset(['series_index']) def rowCount(self, parent=None): return len(self.fields) @@ -153,7 +157,7 @@ class FieldsModel(QAbstractListModel): # {{{ fields |= p.touched_fields self.fields = [] for x in fields: - if not x.startswith('identifier:') and x not in ('series_index',): + if not x.startswith('identifier:') and x not in self.exclude: self.fields.append(x) self.fields.sort(key=lambda x:self.descs.get(x, x)) self.reset() @@ -204,6 +208,41 @@ class FieldsModel(QAbstractListModel): # {{{ # }}} +class PluginConfig(QWidget): # {{{ + + finished = pyqtSignal() + + def __init__(self, plugin, parent): + QWidget.__init__(self, parent) + + self.plugin = plugin + + self.l = l = QVBoxLayout() + self.setLayout(l) + self.c = c = QLabel(_('Configure %s
%s') % (plugin.name, + plugin.description)) + c.setAlignment(Qt.AlignHCenter) + l.addWidget(c) + + self.config_widget = plugin.config_widget() + self.l.addWidget(self.config_widget) + + self.bb = QDialogButtonBox( + QDialogButtonBox.Save|QDialogButtonBox.Cancel, + parent=self) + self.bb.accepted.connect(self.finished) + self.bb.rejected.connect(self.finished) + self.bb.accepted.connect(self.commit) + l.addWidget(self.bb) + + self.f = QFrame(self) + self.f.setFrameShape(QFrame.HLine) + l.addWidget(self.f) + + def commit(self): + self.plugin.save_settings(self.config_widget) +# }}} + class ConfigWidget(ConfigWidgetBase, Ui_Form): def genesis(self, gui): @@ -223,7 +262,27 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.fields_model.dataChanged.connect(self.changed_signal) def configure_plugin(self): - pass + for index in self.sources_view.selectionModel().selectedRows(): + plugin = self.sources_model.data(index, Qt.UserRole) + if plugin is not NONE: + return self.do_config(plugin) + error_dialog(self, _('No source selected'), + _('No source selected, cannot configure.'), show=True) + + def do_config(self, plugin): + self.pc = PluginConfig(plugin, self) + self.stack.insertWidget(1, self.pc) + self.stack.setCurrentIndex(1) + self.pc.finished.connect(self.pc_finished) + + def pc_finished(self): + try: + self.pc.finished.diconnect() + except: + pass + self.stack.setCurrentIndex(0) + self.stack.removeWidget(self.pc) + self.pc = None def initialize(self): ConfigWidgetBase.initialize(self) From 5289f7edc81cba424321def02bd32685c610c4cd Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 21:21:33 -0600 Subject: [PATCH 15/17] ... --- src/calibre/gui2/metadata/config.py | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/calibre/gui2/metadata/config.py diff --git a/src/calibre/gui2/metadata/config.py b/src/calibre/gui2/metadata/config.py new file mode 100644 index 0000000000..83d51c2e28 --- /dev/null +++ b/src/calibre/gui2/metadata/config.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2011, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + +from PyQt4.Qt import (QWidget, QGridLayout, QGroupBox, QListView, Qt) +from calibre.gui2.preferences.metadata_sources import FieldsModel as FM + +class FieldsModel(FM): # {{{ + + def __init__(self, plugin): + FM.__init__(self) + self.plugin = plugin + self.exclude = frozenset(['title', 'authors']) | self.exclude + self.prefs = self.plugin.prefs + + def initialize(self): + fields = self.plugin.touched_fields + self.fields = [] + for x in fields: + if not x.startswith('identifier:') and x not in self.exclude: + self.fields.append(x) + self.fields.sort(key=lambda x:self.descs.get(x, x)) + self.reset() + + def state(self, field, defaults=False): + src = self.prefs.defaults if defaults else self.prefs + return (Qt.Unchecked if field in src['ignore_fields'] + else Qt.Checked) + + def restore_defaults(self): + self.overrides = dict([(f, self.state(f, True)) for f in self.fields]) + self.reset() + + def commit(self): + val = [k for k, v in self.overrides.iteritems() if v == Qt.Unchecked] + self.prefs['ignore_fields'] = val + +# }}} + +class ConfigWidget(QWidget): + + def __init__(self, plugin): + QWidget.__init__(self) + self.plugin = plugin + + self.l = l = QGridLayout() + self.setLayout(l) + + self.gb = QGroupBox(_('Downloaded metadata fields'), self) + l.addWidget(self.gb, 0, 0) + self.gb.l = QGridLayout() + self.gb.setLayout(self.gb.l) + self.fields_view = v = QListView(self) + self.gb.l.addWidget(v, 0, 0) + v.setFlow(v.LeftToRight) + v.setWrapping(True) + v.setResizeMode(v.Adjust) + self.fields_model = FieldsModel(self.plugin) + self.fields_model.initialize() + v.setModel(self.fields_model) + + def commit(self): + self.fields_model.commit() + From b9b5ea7e6254ef5751cec07001b21f0a0f3ffdaf Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 21:46:02 -0600 Subject: [PATCH 16/17] Configuration for metadata download sources completed --- src/calibre/gui2/metadata/config.py | 56 +++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/metadata/config.py b/src/calibre/gui2/metadata/config.py index 83d51c2e28..68c935061d 100644 --- a/src/calibre/gui2/metadata/config.py +++ b/src/calibre/gui2/metadata/config.py @@ -7,8 +7,11 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import textwrap + +from PyQt4.Qt import (QWidget, QGridLayout, QGroupBox, QListView, Qt, QSpinBox, + QDoubleSpinBox, QCheckBox, QLineEdit, QComboBox, QLabel) -from PyQt4.Qt import (QWidget, QGridLayout, QGroupBox, QListView, Qt) from calibre.gui2.preferences.metadata_sources import FieldsModel as FM class FieldsModel(FM): # {{{ @@ -53,7 +56,7 @@ class ConfigWidget(QWidget): self.setLayout(l) self.gb = QGroupBox(_('Downloaded metadata fields'), self) - l.addWidget(self.gb, 0, 0) + l.addWidget(self.gb, 0, 0, 1, 2) self.gb.l = QGridLayout() self.gb.setLayout(self.gb.l) self.fields_view = v = QListView(self) @@ -65,6 +68,55 @@ class ConfigWidget(QWidget): self.fields_model.initialize() v.setModel(self.fields_model) + self.memory = [] + self.widgets = [] + for opt in plugin.options: + self.create_widgets(opt) + + def create_widgets(self, opt): + val = self.plugin.prefs[opt.name] + if opt.type == 'number': + c = QSpinBox if isinstance(opt.default, int) else QDoubleSpinBox + widget = c(self) + widget.setValue(val) + elif opt.type == 'string': + widget = QLineEdit(self) + widget.setText(val) + elif opt.type == 'bool': + widget = QCheckBox(opt.label, self) + widget.setChecked(bool(val)) + elif opt.type == 'choices': + widget = QComboBox(self) + for x in opt.choices: + widget.addItem(x) + idx = opt.choices.index(val) + widget.setCurrentIndex(idx) + widget.opt = opt + widget.setToolTip(textwrap.fill(opt.desc)) + self.widgets.append(widget) + r = self.l.rowCount() + if opt.type == 'bool': + self.l.addWidget(widget, r, 0, 1, self.l.columnCount()) + else: + l = QLabel(opt.label) + l.setToolTip(widget.toolTip()) + self.memory.append(l) + l.setBuddy(widget) + self.l.addWidget(l, r, 0, 1, 1) + self.l.addWidget(widget, r, 1, 1, 1) + + def commit(self): self.fields_model.commit() + for w in self.widgets: + if isinstance(w, (QSpinBox, QDoubleSpinBox)): + val = w.value() + elif isinstance(w, QLineEdit): + val = unicode(w.text()) + elif isinstance(w, QCheckBox): + val = w.isChecked() + elif isinstance(w, QComboBox): + val = unicode(w.currentText()) + self.plugin.prefs[w.opt.name] = val + From 4c3256457febe6fa805d7834e8a25b3954ee30bc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 22:38:31 -0600 Subject: [PATCH 17/17] ... --- src/calibre/manual/faq.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index f8b257fd75..44e3665131 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -65,6 +65,22 @@ There are two aspects to this problem: 2. When adding HTML files to |app|, you may need to tell |app| what encoding the files are in. To do this go to :guilabel:`Preferences->Advanced->Plugins->File Type plugins` and customize the HTML2Zip plugin, telling it what encoding your HTML files are in. Now when you add HTML files to |app| they will be correctly processed. HTML files from different sources often have different encodings, so you may have to change this setting repeatedly. A common encoding for many files from the web is ``cp1252`` and I would suggest you try that first. Note that when converting HTML files, leave the input encoding setting mentioned above blank. This is because the HTML2ZIP plugin automatically converts the HTML files to a standard encoding (utf-8). 3. Embedding fonts: If you are generating an LRF file to read on your SONY Reader, you are limited by the fact that the Reader only supports a few non-English characters in the fonts it comes pre-loaded with. You can work around this problem by embedding a unicode-aware font that supports the character set your file uses into the LRF file. You should embed atleast a serif and a sans-serif font. Be aware that embedding fonts significantly slows down page-turn speed on the reader. +What's the deal with Table of Contents in MOBI files? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The first thing to realize is that most ebooks have two tables of contents. One is the traditional Table of Contents, like the TOC you find in paper books. This Table of Contents is part of the main document flow and can be styled however you like. This TOC is called the *content TOC*. + +Then there is the *metadata TOC*. A metadata TOC is a TOC that is not part of the book text and is typically accessed by some special button on a reader. For example, in the calibre viewer, you use the Show Table of Contents button to see this TOC. This TOC cannot be styled by the book creator. How it is represented is up to the viewer program. + +In the MOBI format, the situation is a little confused. This is because the MOBI format, alone amongst mainstream ebook formats, *does not* have decent support for a metadata TOC. A MOBI book simulates the presence of a metadata TOC by putting an *extra* content TOC at the end of the book. When you click Goto Table of Contents on your Kindle, it is to this extra content TOC that the Kindle takes you. + +Now it might well seem to you that the MOBI book has two identical TOCs. Remember that one is semantically a content TOC and the other is a metadata TOC, even though both might have exactly the same entries and look the same. One can be accessed directly from the Kindle's menus, the other cannot. + +When converting to MOBI, calibre detects the *metadata TOC* in the input document and generates an end-of-file TOC in the output MOBI file. You can turn this off by an option in the MOBI Output settings. You cannot control where this generated TOC will go. Remember this TOC is semantically a *metadata TOC*, in any format other than MOBI it *cannot not be part of the text*. The fact that it is part of the text in MOBI is an accident caused by the limitations of MOBI. If you want a TOC at a particular location in your document text, create one by hand. + +If you have a hand edited TOC in the input document, you can use the TOC detection options in calibre to automatically generate the metadata TOC from it. See the conversion section of the User Manual for more details on how to use these options. + +Finally, I encourage you to ditch the content TOC and only have a metadata TOC in your ebooks. Metadata TOCs will give the people reading your ebooks a much superior navigation experience (except on the Kindle, where they are essentially the same as a content TOC). How do I use some of the advanced features of the conversion tools? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~