diff --git a/Changelog.yaml b/Changelog.yaml index 24ec402a49..49daddfeb0 100644 --- a/Changelog.yaml +++ b/Changelog.yaml @@ -19,6 +19,60 @@ # new recipes: # - title: +- version: 0.7.57 + date: 2011-04-22 + + new features: + - title: "Launch worker processes on demand instead of keeping a pool of them in memory. Reduces memory footprint." + + - title: "Use the visual formatting of the Table of Contents to try to automatically create a multi-level TOC when converting/viewing MOBI files." + tickets: [763681] + + - title: "Add a new function booksize() to the template language to get the value of the size column in calibre." + + - title: "Add support for using metadata plugboards with the content server (only with the epub format)" + + - title: "Change default algorithm for automatically computing author sort to be more intelligent and handle the case when the author name has a comma in it" + + - title: "Show cover size in the tooltips of the book details panel and book details popup window" + + bug fixes: + - title: "Dragging and dropping a cover onto the book details panel did not change the cover size" + tickets: [768332] + + - title: "Fix non-escaped '|' when searching for commas in authors using REGEXP_MATCH" + + - title: "Fix ratings in templates being multiplied by 2" + + - title: "Fix adding a comma to custom series values when using completion." + tickets: [763788] + + - title: "CHM Input: Another workaround for a Microsoft mess." + tickets: [763336] + + - title: "Fix job count in the spinner not always being updated when a job completes" + + - title: "Changing case only of a title does not update title sort" + tickets: [768904] + + improved recipes: + - ecuisine.ro, egirl.ro and tabu.ro + - Daily Telegraph + - Handelsblatt + - Il Sole 24 Ore + - Newsweek + - Arcamax + + new recipes: + - title: BabyOnline.ro + author: Silviu Cotoara + + - title: "The Journal.ie" + author: Phil Burns + + - title: "Der Spiegel" + author: Nikolas Mangold + - version: 0.7.56 date: 2011-04-17 diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 86dd1ada3b..bab753dc18 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -4,7 +4,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = u'calibre' -numeric_version = (0, 7, 56) +numeric_version = (0, 7, 57) __version__ = u'.'.join(map(unicode, numeric_version)) __author__ = u"Kovid Goyal " diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index b427f19952..bc9070852b 100644 --- a/src/calibre/ebooks/metadata/sources/identify.py +++ b/src/calibre/ebooks/metadata/sources/identify.py @@ -42,6 +42,10 @@ class Worker(Thread): self.log.exception('Plugin', self.plugin.name, 'failed') self.plugin.dl_time_spent = time.time() - start + @property + def name(self): + return self.plugin.name + def is_worker_alive(workers): for w in workers: if w.is_alive(): @@ -348,7 +352,11 @@ def identify(log, abort, # {{{ if (first_result_at is not None and time.time() - first_result_at > wait_time): - log('Not waiting any longer for more results') + log.warn('Not waiting any longer for more results. Still running' + ' sources:') + for worker in workers: + if worker.is_alive(): + log.debug('\t' + worker.name) abort.set() break diff --git a/src/calibre/ebooks/metadata/sources/overdrive.py b/src/calibre/ebooks/metadata/sources/overdrive.py index ef07800a77..e975d41ea6 100755 --- a/src/calibre/ebooks/metadata/sources/overdrive.py +++ b/src/calibre/ebooks/metadata/sources/overdrive.py @@ -204,8 +204,8 @@ class OverDrive(Source): else: initial_q = ' '.join(author_tokens) xref_q = '+'.join(title_tokens) - log.error('Initial query is %s'%initial_q) - log.error('Cross reference query is %s'%xref_q) + #log.error('Initial query is %s'%initial_q) + #log.error('Cross reference query is %s'%xref_q) q_xref = q+'SearchResults.svc/GetResults?iDisplayLength=50&sSearch='+xref_q query = '{"szKeyword":"'+initial_q+'"}' diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index 9d4d3891ca..bd1e85d8e8 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -8,14 +8,15 @@ __docformat__ = 'restructuredtext en' import os from functools import partial -from PyQt4.Qt import Qt, QMenu, QModelIndex +from PyQt4.Qt import Qt, QMenu, QModelIndex, QTimer -from calibre.gui2 import error_dialog, config, Dispatcher +from calibre.gui2 import error_dialog, config, Dispatcher, question_dialog from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.tag_list_editor import TagListEditor from calibre.gui2.actions import InterfaceAction +from calibre.ebooks.metadata import authors_to_string from calibre.utils.icu import sort_key from calibre.utils.config import test_eight_code @@ -78,6 +79,7 @@ class EditMetadataAction(InterfaceAction): self.qaction.setEnabled(enabled) self.action_merge.setEnabled(enabled) + # Download metadata {{{ def download_metadata(self, ids=None): if ids is None: rows = self.gui.library_view.selectionModel().selectedRows() @@ -88,14 +90,73 @@ class EditMetadataAction(InterfaceAction): ids = [db.id(row.row()) for row in rows] from calibre.gui2.metadata.bulk_download2 import start_download start_download(self.gui, ids, - Dispatcher(self.bulk_metadata_downloaded)) + Dispatcher(self.metadata_downloaded)) - def bulk_metadata_downloaded(self, job): + def metadata_downloaded(self, job): if job.failed: self.gui.job_exception(job, dialog_title=_('Failed to download metadata')) return - from calibre.gui2.metadata.bulk_download2 import proceed - proceed(self.gui, job) + from calibre.gui2.metadata.bulk_download2 import get_job_details + id_map, failed_ids, failed_covers, all_failed, det_msg = \ + get_job_details(job) + if all_failed: + return error_dialog(self.gui, _('Download failed'), + _('Failed to download metadata or covers for any of the %d' + ' book(s).') % len(id_map), det_msg=det_msg, show=True) + + self.gui.status_bar.show_message(_('Metadata download completed'), 3000) + + msg = '

' + _('Finished downloading metadata for %d book(s). ' + 'Proceed with updating the metadata in your library?')%len(id_map) + + show_copy_button = False + if failed_ids or failed_covers: + show_copy_button = True + msg += '

'+_('Could not download metadata and/or covers for %d of the books. Click' + ' "Show details" to see which books.')%len(failed_ids) + + payload = (id_map, failed_ids, failed_covers) + from calibre.gui2.dialogs.message_box import ProceedNotification + p = ProceedNotification(payload, job.html_details, + _('Download log'), _('Download complete'), msg, + det_msg=det_msg, show_copy_button=show_copy_button, + parent=self.gui) + p.proceed.connect(self.apply_downloaded_metadata) + p.show() + + def apply_downloaded_metadata(self, payload): + id_map, failed_ids, failed_covers = payload + id_map = dict([(k, v) for k, v in id_map.iteritems() if k not in + failed_ids]) + if not id_map: + return + + modified = set() + db = self.gui.current_db + + for i, mi in id_map.iteritems(): + lm = db.metadata_last_modified(i, index_is_id=True) + if lm > mi.last_modified: + title = db.title(i, index_is_id=True) + authors = db.authors(i, index_is_id=True) + if authors: + authors = [x.replace('|', ',') for x in authors.split(',')] + title += ' - ' + authors_to_string(authors) + modified.add(title) + + if modified: + from calibre.utils.icu import lower + + modified = sorted(modified, key=lower) + if not question_dialog(self.gui, _('Some books changed'), '

'+ + _('The metadata for some books in your library has' + ' changed since you started the download. If you' + ' proceed, some of those changes may be overwritten. ' + 'Click "Show details" to see the list of changed books. ' + 'Do you want to proceed?'), det_msg='\n'.join(modified)): + return + + self.apply_metadata_changes(id_map) def download_metadata_old(self, checked, covers=True, set_metadata=True, set_social_metadata=None): @@ -140,6 +201,7 @@ class EditMetadataAction(InterfaceAction): x.updated, cr) if self.gui.cover_flow: self.gui.cover_flow.dataChanged() + # }}} def edit_metadata(self, checked, bulk=None): ''' @@ -466,4 +528,89 @@ class EditMetadataAction(InterfaceAction): self.gui.upload_collections(model.db, view=view, oncard=oncard) view.reset() + # Apply bulk metadata changes {{{ + def apply_metadata_changes(self, id_map, title=None, msg=''): + ''' + Apply the metadata changes in id_map to the database synchronously + id_map must be a mapping of ids to Metadata objects. Set any fields you + do not want updated in the Metadata object to null. An easy way to do + that is to create a metadata object as Metadata(_('Unknown')) and then + only set the fields you want changed on this object. + ''' + if title is None: + title = _('Applying changed metadata') + self.apply_id_map = list(id_map.iteritems()) + self.apply_current_idx = 0 + self.apply_failures = [] + self.applied_ids = [] + self.apply_pd = None + if len(self.apply_id_map) > 1: + from calibre.gui2.dialogs.progress import ProgressDialog + self.apply_pd = ProgressDialog(title, msg, min=0, + max=len(self.apply_id_map)-1, parent=self.gui, + cancelable=False) + self.apply_pd.setModal(True) + self.apply_pd.show() + self.do_one_apply() + + + def do_one_apply(self): + if self.apply_current_idx >= len(self.apply_id_map): + return self.finalize_apply() + + i, mi = self.apply_id_map[self.apply_current_idx] + db = self.gui.current_db + try: + set_title = not mi.is_null('title') + set_authors = not mi.is_null('authors') + db.set_metadata(i, mi, commit=False, set_title=set_title, + set_authors=set_authors, notify=False) + self.applied_ids.append(i) + except: + import traceback + self.apply_failures.append((i, traceback.format_exc())) + + try: + if mi.cover: + os.remove(mi.cover) + except: + pass + + self.apply_current_idx += 1 + if self.apply_pd is not None: + self.apply_pd.value += 1 + QTimer.singleShot(50, self.do_one_apply) + + def finalize_apply(self): + db = self.gui.current_db + db.commit() + + if self.apply_pd is not None: + self.apply_pd.hide() + + if self.apply_failures: + msg = [] + for i, tb in self.apply_failures: + title = db.title(i, index_is_id=True) + authors = db.authors(i, index_is_id=True) + if authors: + authors = [x.replace('|', ',') for x in authors.split(',')] + title += ' - ' + authors_to_string(authors) + msg.append(title+'\n\n'+tb+'\n'+('*'*80)) + + error_dialog(self.gui, _('Some failures'), + _('Failed to apply updated metadata for some books' + ' in your library. Click "Show Details" to see ' + 'details.'), det_msg='\n\n'.join(msg), show=True) + if self.applied_ids: + cr = self.gui.library_view.currentIndex().row() + self.gui.library_view.model().refresh_ids( + self.applied_ids, cr) + if self.gui.cover_flow: + self.gui.cover_flow.dataChanged() + + self.apply_id_map = [] + self.apply_pd = None + + # }}} diff --git a/src/calibre/gui2/actions/store.py b/src/calibre/gui2/actions/store.py index b87d1818ea..90f2cac3cd 100644 --- a/src/calibre/gui2/actions/store.py +++ b/src/calibre/gui2/actions/store.py @@ -33,7 +33,7 @@ class StoreAction(InterfaceAction): def search(self): self.show_disclaimer() - from calibre.gui2.store.search import SearchDialog + from calibre.gui2.store.search.search import SearchDialog sd = SearchDialog(self.gui.istores, self.gui) sd.exec_() diff --git a/src/calibre/gui2/dialogs/message_box.py b/src/calibre/gui2/dialogs/message_box.py index 945d50de4e..6034618458 100644 --- a/src/calibre/gui2/dialogs/message_box.py +++ b/src/calibre/gui2/dialogs/message_box.py @@ -6,13 +6,13 @@ __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' -from PyQt4.Qt import QDialog, QIcon, QApplication, QSize, QKeySequence, \ - QAction, Qt +from PyQt4.Qt import (QDialog, QIcon, QApplication, QSize, QKeySequence, + QAction, Qt, pyqtSignal, QTextBrowser, QDialogButtonBox, QVBoxLayout) from calibre.constants import __version__ from calibre.gui2.dialogs.message_box_ui import Ui_Dialog -class MessageBox(QDialog, Ui_Dialog): +class MessageBox(QDialog, Ui_Dialog): # {{{ ERROR = 0 WARNING = 1 @@ -111,6 +111,81 @@ class MessageBox(QDialog, Ui_Dialog): self.det_msg_toggle.setVisible(bool(msg)) self.det_msg.setVisible(False) self.do_resize() +# }}} + +class ViewLog(QDialog): # {{{ + + def __init__(self, title, html, parent=None): + QDialog.__init__(self, parent) + self.l = l = QVBoxLayout() + self.setLayout(l) + + self.tb = QTextBrowser(self) + self.tb.setHtml('

%s
' % html) + l.addWidget(self.tb) + + self.bb = QDialogButtonBox(QDialogButtonBox.Ok) + self.bb.accepted.connect(self.accept) + self.bb.rejected.connect(self.reject) + self.copy_button = self.bb.addButton(_('Copy to clipboard'), + self.bb.ActionRole) + self.copy_button.setIcon(QIcon(I('edit-copy.png'))) + self.copy_button.clicked.connect(self.copy_to_clipboard) + l.addWidget(self.bb) + self.setModal(False) + self.resize(QSize(700, 500)) + self.setWindowTitle(title) + self.setWindowIcon(QIcon(I('debug.png'))) + self.show() + + def copy_to_clipboard(self): + txt = self.tb.toPlainText() + QApplication.clipboard().setText(txt) +# }}} + +class ProceedNotification(MessageBox): # {{{ + + proceed = pyqtSignal(object) + + def __init__(self, payload, html_log, log_viewer_title, title, msg, det_msg='', show_copy_button=False, parent=None): + ''' + A non modal popup that notifies the user that a background task has + been completed. If they user clicks yes, the proceed signal is emitted + with payload as its argument. + + :param payload: Arbitrary object, emitted in the proceed signal + :param html_log: An HTML or plain text log + :param log_viewer_title: The title for the log viewer window + :param title: The title fo rthis popup + :param msg: The msg to display + :param det_msg: Detailed message + ''' + MessageBox.__init__(self, MessageBox.QUESTION, title, msg, + det_msg=det_msg, show_copy_button=show_copy_button, + parent=parent) + self.payload = payload + self.html_log = html_log + self.log_viewer_title = log_viewer_title + self.finished.connect(self.do_proceed) + + self.vlb = self.bb.addButton(_('View log'), self.bb.ActionRole) + self.vlb.setIcon(QIcon(I('debug.png'))) + self.vlb.clicked.connect(self.show_log) + self.det_msg_toggle.setVisible(bool(det_msg)) + self.setModal(False) + + def show_log(self): + self.log_viewer = ViewLog(self.log_viewer_title, self.html_log, + parent=self) + + def do_proceed(self, result): + if result == self.Accepted: + self.proceed.emit(self.payload) + try: + self.proceed.disconnect() + except: + pass +# }}} if __name__ == '__main__': app = QApplication([]) diff --git a/src/calibre/gui2/jobs.py b/src/calibre/gui2/jobs.py index 34eef4406a..51c54843a4 100644 --- a/src/calibre/gui2/jobs.py +++ b/src/calibre/gui2/jobs.py @@ -169,11 +169,11 @@ class JobManager(QAbstractTableModel): # {{{ job.update() if orig_state != job.run_state: needs_reset = True + if job.is_finished: + self.job_done.emit(len(self.unfinished_jobs())) if needs_reset: self.jobs.sort() self.reset() - if job.is_finished: - self.job_done.emit(len(self.unfinished_jobs())) else: for job in jobs: idx = self.jobs.index(job) diff --git a/src/calibre/gui2/metadata/bulk_download2.py b/src/calibre/gui2/metadata/bulk_download2.py index 017635c6fb..2a307fc902 100644 --- a/src/calibre/gui2/metadata/bulk_download2.py +++ b/src/calibre/gui2/metadata/bulk_download2.py @@ -7,19 +7,14 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os from functools import partial from itertools import izip +from threading import Event -from PyQt4.Qt import (QIcon, QDialog, QVBoxLayout, QTextBrowser, QSize, - QDialogButtonBox, QApplication, QTimer, QLabel, QProgressBar, - QGridLayout, QPixmap, Qt) +from PyQt4.Qt import (QIcon, QDialog, + QDialogButtonBox, QLabel, QGridLayout, QPixmap, Qt) -from calibre.gui2.dialogs.message_box import MessageBox from calibre.gui2.threaded_jobs import ThreadedJob -from calibre.utils.icu import lower -from calibre.ebooks.metadata import authors_to_string -from calibre.gui2 import question_dialog, error_dialog from calibre.ebooks.metadata.sources.identify import identify, msprefs from calibre.ebooks.metadata.sources.covers import download_cover from calibre.ebooks.metadata.book.base import Metadata @@ -107,178 +102,7 @@ def start_download(gui, ids, callback): gui.status_bar.show_message(_('Metadata download started'), 3000) # }}} -class ViewLog(QDialog): # {{{ - - def __init__(self, html, parent=None): - QDialog.__init__(self, parent) - self.l = l = QVBoxLayout() - self.setLayout(l) - - self.tb = QTextBrowser(self) - self.tb.setHtml('
%s
' % html) - l.addWidget(self.tb) - - self.bb = QDialogButtonBox(QDialogButtonBox.Ok) - self.bb.accepted.connect(self.accept) - self.bb.rejected.connect(self.reject) - self.copy_button = self.bb.addButton(_('Copy to clipboard'), - self.bb.ActionRole) - self.copy_button.setIcon(QIcon(I('edit-copy.png'))) - self.copy_button.clicked.connect(self.copy_to_clipboard) - l.addWidget(self.bb) - self.setModal(False) - self.resize(QSize(700, 500)) - self.setWindowTitle(_('Download log')) - self.setWindowIcon(QIcon(I('debug.png'))) - self.show() - - def copy_to_clipboard(self): - txt = self.tb.toPlainText() - QApplication.clipboard().setText(txt) - -_vl = None -def view_log(job, parent): - global _vl - _vl = ViewLog(job.html_details, parent) - -# }}} - -# Apply downloaded metadata {{{ -class ApplyDialog(QDialog): - - def __init__(self, gui): - QDialog.__init__(self, gui) - - self.l = l = QVBoxLayout() - self.setLayout(l) - l.addWidget(QLabel(_('Applying downloaded metadata to your library'))) - - self.pb = QProgressBar(self) - l.addWidget(self.pb) - - self.bb = QDialogButtonBox(QDialogButtonBox.Cancel) - self.bb.rejected.connect(self.reject) - l.addWidget(self.bb) - - self.gui = gui - self.timer = QTimer(self) - self.timer.timeout.connect(self.do_one) - - def start(self, id_map): - self.id_map = list(id_map.iteritems()) - self.current_idx = 0 - self.failures = [] - self.ids = [] - self.canceled = False - self.pb.setMinimum(0) - self.pb.setMaximum(len(id_map)) - self.timer.start(50) - - def do_one(self): - if self.canceled: - return - if self.current_idx >= len(self.id_map): - self.timer.stop() - self.finalize() - return - - i, mi = self.id_map[self.current_idx] - db = self.gui.current_db - try: - set_title = not mi.is_null('title') - set_authors = not mi.is_null('authors') - db.set_metadata(i, mi, commit=False, set_title=set_title, - set_authors=set_authors) - self.ids.append(i) - except: - import traceback - self.failures.append((i, traceback.format_exc())) - - try: - if mi.cover: - os.remove(mi.cover) - except: - pass - - self.pb.setValue(self.pb.value()+1) - self.current_idx += 1 - - def reject(self): - self.canceled = True - self.timer.stop() - QDialog.reject(self) - - def finalize(self): - if self.canceled: - return - if self.failures: - msg = [] - db = self.gui.current_db - for i, tb in self.failures: - title = db.title(i, index_is_id=True) - authors = db.authors(i, index_is_id=True) - if authors: - authors = [x.replace('|', ',') for x in authors.split(',')] - title += ' - ' + authors_to_string(authors) - msg.append(title+'\n\n'+tb+'\n'+('*'*80)) - - parent = self if self.isVisible() else self.parent() - error_dialog(parent, _('Some failures'), - _('Failed to apply updated metadata for some books' - ' in your library. Click "Show Details" to see ' - 'details.'), det_msg='\n\n'.join(msg), show=True) - if self.ids: - cr = self.gui.library_view.currentIndex().row() - self.gui.library_view.model().refresh_ids( - self.ids, cr) - if self.gui.cover_flow: - self.gui.cover_flow.dataChanged() - self.accept() - -_amd = None -def apply_metadata(job, gui, q, result): - global _amd - q.vlb.clicked.disconnect() - q.finished.disconnect() - if result != q.Accepted: - return - id_map, failed_ids, failed_covers, title_map, all_failed = job.result - id_map = dict([(k, v) for k, v in id_map.iteritems() if k not in - failed_ids]) - if not id_map: - return - - modified = set() - db = gui.current_db - - for i, mi in id_map.iteritems(): - lm = db.metadata_last_modified(i, index_is_id=True) - if lm > mi.last_modified: - title = db.title(i, index_is_id=True) - authors = db.authors(i, index_is_id=True) - if authors: - authors = [x.replace('|', ',') for x in authors.split(',')] - title += ' - ' + authors_to_string(authors) - modified.add(title) - - if modified: - modified = sorted(modified, key=lower) - if not question_dialog(gui, _('Some books changed'), '

'+ - _('The metadata for some books in your library has' - ' changed since you started the download. If you' - ' proceed, some of those changes may be overwritten. ' - 'Click "Show details" to see the list of changed books. ' - 'Do you want to proceed?'), det_msg='\n'.join(modified)): - return - - if _amd is None: - _amd = ApplyDialog(gui) - _amd.start(id_map) - if len(id_map) > 3: - _amd.exec_() - -def proceed(gui, job): - gui.status_bar.show_message(_('Metadata download completed'), 3000) +def get_job_details(job): id_map, failed_ids, failed_covers, title_map, all_failed = job.result det_msg = [] for i in failed_ids | failed_covers: @@ -289,31 +113,7 @@ def proceed(gui, job): title += (' ' + _('(Failed cover)')) det_msg.append(title) det_msg = '\n'.join(det_msg) - - if all_failed: - q = error_dialog(gui, _('Download failed'), - _('Failed to download metadata or covers for any of the %d' - ' book(s).') % len(id_map), det_msg=det_msg) - else: - fmsg = '' - if failed_ids or failed_covers: - fmsg = '

'+_('Could not download metadata and/or covers for %d of the books. Click' - ' "Show details" to see which books.')%len(failed_ids) - msg = '

' + _('Finished downloading metadata for %d book(s). ' - 'Proceed with updating the metadata in your library?')%len(id_map) - q = MessageBox(MessageBox.QUESTION, _('Download complete'), - msg + fmsg, det_msg=det_msg, show_copy_button=bool(failed_ids), - parent=gui) - q.finished.connect(partial(apply_metadata, job, gui, q)) - - q.vlb = q.bb.addButton(_('View log'), q.bb.ActionRole) - q.vlb.setIcon(QIcon(I('debug.png'))) - q.vlb.clicked.connect(partial(view_log, job, q)) - q.det_msg_toggle.setVisible(bool(failed_ids | failed_covers)) - q.setModal(False) - q.show() - -# }}} + return id_map, failed_ids, failed_covers, all_failed, det_msg def merge_result(oldmi, newmi): dummy = Metadata(_('Unknown')) @@ -345,6 +145,10 @@ def download(ids, db, do_identify, covers, ans = {} count = 0 all_failed = True + ''' + # Test apply dialog + all_failed = do_identify = covers = False + ''' for i, mi in izip(ids, metadata): if abort.is_set(): log.error('Aborting...') @@ -354,7 +158,7 @@ def download(ids, db, do_identify, covers, if do_identify: results = [] try: - results = identify(log, abort, title=title, authors=authors, + results = identify(log, Event(), title=title, authors=authors, identifiers=identifiers) except: pass diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py index a3ac777115..06ea8cf76a 100644 --- a/src/calibre/gui2/metadata/single_download.py +++ b/src/calibre/gui2/metadata/single_download.py @@ -15,10 +15,10 @@ from operator import attrgetter from Queue import Queue, Empty from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt, - QStyle, QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox, + QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox, QStackedWidget, QWidget, QTableView, QGridLayout, QFontInfo, QPalette, QTimer, pyqtSignal, QAbstractTableModel, QVariant, QSize, QListView, - QPixmap, QAbstractListModel, QColor, QRect, QTextBrowser) + QPixmap, QAbstractListModel, QColor, QRect, QTextBrowser, QModelIndex) from PyQt4.QtWebKit import QWebView from calibre.customize.ui import metadata_plugins @@ -52,12 +52,9 @@ class RichTextDelegate(QStyledItemDelegate): # {{{ return ans def paint(self, painter, option, index): + QStyledItemDelegate.paint(self, painter, option, QModelIndex()) painter.save() painter.setClipRect(QRectF(option.rect)) - if hasattr(QStyle, 'CE_ItemViewItem'): - QApplication.style().drawControl(QStyle.CE_ItemViewItem, option, painter) - elif option.state & QStyle.State_Selected: - painter.fillRect(option.rect, option.palette.highlight()) painter.translate(option.rect.topLeft()) self.to_doc(index).drawContents(painter) painter.restore() @@ -116,14 +113,17 @@ class CoverDelegate(QStyledItemDelegate): # {{{ def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, index) - # Ensure the cover is rendered over any selection rect style = QApplication.style() - style.drawItemPixmap(painter, option.rect, Qt.AlignTop|Qt.AlignHCenter, - QPixmap(index.data(Qt.DecorationRole))) - if self.timer.isActive() and index.data(Qt.UserRole).toBool(): + waiting = self.timer.isActive() and index.data(Qt.UserRole).toBool() + if waiting: rect = QRect(0, 0, self.spinner_width, self.spinner_width) rect.moveCenter(option.rect.center()) self.draw_spinner(painter, rect) + else: + # Ensure the cover is rendered over any selection rect + style.drawItemPixmap(painter, option.rect, Qt.AlignTop|Qt.AlignHCenter, + QPixmap(index.data(Qt.DecorationRole))) + # }}} class ResultsModel(QAbstractTableModel): # {{{ @@ -949,7 +949,7 @@ class CoverFetch(QDialog): # {{{ # }}} if __name__ == '__main__': - #DEBUG_DIALOG = True + DEBUG_DIALOG = True app = QApplication([]) d = FullFetch() d.start(title='great gatsby', authors=['fitzgerald']) diff --git a/src/calibre/gui2/store/__init__.py b/src/calibre/gui2/store/__init__.py index 43909e9d8b..16e9f5689d 100644 --- a/src/calibre/gui2/store/__init__.py +++ b/src/calibre/gui2/store/__init__.py @@ -46,9 +46,12 @@ class StorePlugin(object): # {{{ ''' def __init__(self, gui, name): + from calibre.gui2 import JSONConfig + self.gui = gui self.name = name self.base_plugin = None + self.config = JSONConfig('store/stores/' + self.name) def open(self, gui, parent=None, detail_item=None, external=False): ''' diff --git a/src/calibre/gui2/store/basic_config.py b/src/calibre/gui2/store/basic_config.py index 88ee197146..5e59b63694 100644 --- a/src/calibre/gui2/store/basic_config.py +++ b/src/calibre/gui2/store/basic_config.py @@ -8,14 +8,8 @@ __docformat__ = 'restructuredtext en' from PyQt4.Qt import QWidget -from calibre.gui2 import gprefs from calibre.gui2.store.basic_config_widget_ui import Ui_Form -def save_settings(config_widget): - gprefs[config_widget.store.name + '_open_external'] = config_widget.open_external.isChecked() - tags = unicode(config_widget.tags.text()) - gprefs[config_widget.store.name + '_tags'] = tags - class BasicStoreConfigWidget(QWidget, Ui_Form): def __init__(self, store): @@ -27,10 +21,10 @@ class BasicStoreConfigWidget(QWidget, Ui_Form): self.load_setings() def load_setings(self): - settings = self.store.get_settings() + config = self.store.config - self.open_external.setChecked(settings.get(self.store.name + '_open_external')) - self.tags.setText(settings.get(self.store.name + '_tags', '')) + self.open_external.setChecked(config.get('open_external', False)) + self.tags.setText(config.get('tags', '')) class BasicStoreConfig(object): @@ -41,12 +35,6 @@ class BasicStoreConfig(object): return BasicStoreConfigWidget(self) def save_settings(self, config_widget): - save_settings(config_widget) - - def get_settings(self): - settings = {} - - settings[self.name + '_open_external'] = gprefs.get(self.name + '_open_external', False) - settings[self.name + '_tags'] = gprefs.get(self.name + '_tags', self.name + ', store, download') - - return settings + self.config['open_external'] = config_widget.open_external.isChecked() + tags = unicode(config_widget.tags.text()) + self.config['tags'] = tags diff --git a/src/calibre/gui2/store/bewrite_plugin.py b/src/calibre/gui2/store/bewrite_plugin.py index 8cc4a2745f..80f3b2d54e 100644 --- a/src/calibre/gui2/store/bewrite_plugin.py +++ b/src/calibre/gui2/store/bewrite_plugin.py @@ -23,10 +23,9 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class BeWriteStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://www.bewrite.net/mm5/merchant.mvc?Screen=SFNT' - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): if detail_item: url = url + detail_item open_url(QUrl(url_slash_cleaner(url))) @@ -36,7 +35,7 @@ class BeWriteStore(BasicStoreConfig, StorePlugin): detail_url = url + detail_item d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/bn_plugin.py b/src/calibre/gui2/store/bn_plugin.py index 8b1cfa03f0..f26a60c89d 100644 --- a/src/calibre/gui2/store/bn_plugin.py +++ b/src/calibre/gui2/store/bn_plugin.py @@ -25,8 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class BNStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() - pub_id = '21000000000352219' # Use Kovid's affiliate id 30% of the time. if random.randint(1, 10) in (1, 2, 3): @@ -40,12 +38,12 @@ class BNStore(BasicStoreConfig, StorePlugin): isbn = mo.group('isbn') detail_item = 'http://gan.doubleclick.net/gan_click?lid=41000000012871747&pid=' + isbn + '&adurl=' + detail_item + '&pubid=' + pub_id - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_item if detail_item else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_item) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/diesel_ebooks_plugin.py b/src/calibre/gui2/store/diesel_ebooks_plugin.py index b33bad15f9..a21d6943d7 100644 --- a/src/calibre/gui2/store/diesel_ebooks_plugin.py +++ b/src/calibre/gui2/store/diesel_ebooks_plugin.py @@ -24,7 +24,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class DieselEbooksStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://www.diesel-ebooks.com/' aff_id = '?aid=2049' @@ -37,12 +36,12 @@ class DieselEbooksStore(BasicStoreConfig, StorePlugin): detail_url = url + detail_item + aff_id url = url + aff_id - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/ebooks_com_plugin.py b/src/calibre/gui2/store/ebooks_com_plugin.py index 1597cc89ca..85176c10d7 100644 --- a/src/calibre/gui2/store/ebooks_com_plugin.py +++ b/src/calibre/gui2/store/ebooks_com_plugin.py @@ -25,8 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class EbookscomStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() - m_url = 'http://www.dpbolvw.net/' h_click = 'click-4879827-10364500' d_click = 'click-4879827-10281551' @@ -40,12 +38,12 @@ class EbookscomStore(BasicStoreConfig, StorePlugin): if detail_item: detail_url = m_url + d_click + detail_item - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/eharlequin_plugin.py b/src/calibre/gui2/store/eharlequin_plugin.py index 4f54508c80..daa67e801c 100644 --- a/src/calibre/gui2/store/eharlequin_plugin.py +++ b/src/calibre/gui2/store/eharlequin_plugin.py @@ -25,8 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class EHarlequinStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() - m_url = 'http://www.dpbolvw.net/' h_click = 'click-4879827-534091' d_click = 'click-4879827-10375439' @@ -40,12 +38,12 @@ class EHarlequinStore(BasicStoreConfig, StorePlugin): if detail_item: detail_url = m_url + d_click + detail_item - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/feedbooks_plugin.py b/src/calibre/gui2/store/feedbooks_plugin.py index e56964b339..9b1f7f6574 100644 --- a/src/calibre/gui2/store/feedbooks_plugin.py +++ b/src/calibre/gui2/store/feedbooks_plugin.py @@ -23,11 +23,10 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class FeedbooksStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://m.feedbooks.com/' ext_url = 'http://feedbooks.com/' - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): if detail_item: ext_url = ext_url + detail_item open_url(QUrl(url_slash_cleaner(ext_url))) @@ -37,7 +36,7 @@ class FeedbooksStore(BasicStoreConfig, StorePlugin): detail_url = url + detail_item d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/gutenberg_plugin.py b/src/calibre/gui2/store/gutenberg_plugin.py index 04fe4da0fb..d820a44f8d 100644 --- a/src/calibre/gui2/store/gutenberg_plugin.py +++ b/src/calibre/gui2/store/gutenberg_plugin.py @@ -23,11 +23,10 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class GutenbergStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://m.gutenberg.org/' ext_url = 'http://gutenberg.org/' - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): if detail_item: ext_url = ext_url + detail_item open_url(QUrl(url_slash_cleaner(ext_url))) @@ -37,7 +36,7 @@ class GutenbergStore(BasicStoreConfig, StorePlugin): detail_url = url + detail_item d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/kobo_plugin.py b/src/calibre/gui2/store/kobo_plugin.py index 421348d210..9ec0e4b786 100644 --- a/src/calibre/gui2/store/kobo_plugin.py +++ b/src/calibre/gui2/store/kobo_plugin.py @@ -24,8 +24,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class KoboStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() - m_url = 'http://www.dpbolvw.net/' h_click = 'click-4879827-10762497' d_click = 'click-4879827-10772898' @@ -39,12 +37,12 @@ class KoboStore(BasicStoreConfig, StorePlugin): if detail_item: detail_url = m_url + d_click + detail_item - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/manybooks_plugin.py b/src/calibre/gui2/store/manybooks_plugin.py index 57eb42c13e..1ae9d47d01 100644 --- a/src/calibre/gui2/store/manybooks_plugin.py +++ b/src/calibre/gui2/store/manybooks_plugin.py @@ -24,19 +24,18 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class ManyBooksStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://manybooks.net/' detail_url = None if detail_item: detail_url = url + detail_item - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/mobileread_plugin.py b/src/calibre/gui2/store/mobileread_plugin.py index 72813982dc..25125d38c0 100644 --- a/src/calibre/gui2/store/mobileread_plugin.py +++ b/src/calibre/gui2/store/mobileread_plugin.py @@ -18,7 +18,7 @@ from PyQt4.Qt import Qt, QUrl, QDialog, QAbstractItemModel, QModelIndex, QVarian pyqtSignal from calibre import browser -from calibre.gui2 import open_url, NONE, JSONConfig +from calibre.gui2 import open_url, NONE from calibre.gui2.store import StorePlugin from calibre.gui2.store.basic_config import BasicStoreConfig from calibre.gui2.store.mobileread_store_dialog_ui import Ui_Dialog @@ -29,20 +29,18 @@ from calibre.utils.icu import sort_key class MobileReadStore(BasicStoreConfig, StorePlugin): def genesis(self): - self.config = JSONConfig('store/store/' + self.name) self.rlock = RLock() def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://www.mobileread.com/' - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(detail_item if detail_item else url)) else: if detail_item: d = WebStoreDialog(self.gui, url, parent, detail_item) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() else: d = MobeReadStoreDialog(self, parent) diff --git a/src/calibre/gui2/store/open_library_plugin.py b/src/calibre/gui2/store/open_library_plugin.py index 0e2fa4b14f..93b9c02dcf 100644 --- a/src/calibre/gui2/store/open_library_plugin.py +++ b/src/calibre/gui2/store/open_library_plugin.py @@ -23,10 +23,9 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class OpenLibraryStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://openlibrary.org/' - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): if detail_item: url = url + detail_item open_url(QUrl(url_slash_cleaner(url))) @@ -36,7 +35,7 @@ class OpenLibraryStore(BasicStoreConfig, StorePlugin): detail_url = url + detail_item d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/gui2/store/search.py b/src/calibre/gui2/store/search.py deleted file mode 100644 index 69c3bd2f06..0000000000 --- a/src/calibre/gui2/store/search.py +++ /dev/null @@ -1,726 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import (unicode_literals, division, absolute_import, print_function) - -__license__ = 'GPL 3' -__copyright__ = '2011, John Schember ' -__docformat__ = 'restructuredtext en' - -import re -import time -import traceback -from contextlib import closing -from operator import attrgetter -from random import shuffle -from threading import Thread -from Queue import Queue - -from PyQt4.Qt import (Qt, QAbstractItemModel, QDialog, QTimer, QVariant, - QModelIndex, QPixmap, QSize, QCheckBox, QVBoxLayout) - -from calibre import browser -from calibre.gui2 import NONE, JSONConfig -from calibre.gui2.progress_indicator import ProgressIndicator -from calibre.gui2.store.search_ui import Ui_Dialog -from calibre.gui2.store.search_result import SearchResult -from calibre.library.caches import _match, CONTAINS_MATCH, EQUALS_MATCH, \ - REGEXP_MATCH -from calibre.utils.icu import sort_key -from calibre.utils.magick.draw import thumbnail -from calibre.utils.search_query_parser import SearchQueryParser - -HANG_TIME = 75000 # milliseconds seconds -TIMEOUT = 75 # seconds -SEARCH_THREAD_TOTAL = 4 -COVER_DOWNLOAD_THREAD_TOTAL = 2 - -def comparable_price(text): - if len(text) < 3 or text[-3] not in ('.', ','): - text += '00' - text = re.sub(r'\D', '', text) - text = text.rjust(6, '0') - return text - - -class SearchDialog(QDialog, Ui_Dialog): - - def __init__(self, istores, *args): - QDialog.__init__(self, *args) - self.setupUi(self) - - self.config = JSONConfig('store/search') - - # We keep a cache of store plugins and reference them by name. - self.store_plugins = istores - self.search_pool = SearchThreadPool(SearchThread, SEARCH_THREAD_TOTAL) - # Check for results and hung threads. - self.checker = QTimer() - self.hang_check = 0 - - self.model = Matches() - self.results_view.setModel(self.model) - - # Add check boxes for each store so the user - # can disable searching specific stores on a - # per search basis. - stores_group_layout = QVBoxLayout() - self.stores_group.setLayout(stores_group_layout) - for x in self.store_plugins: - cbox = QCheckBox(x) - cbox.setChecked(True) - stores_group_layout.addWidget(cbox) - setattr(self, 'store_check_' + x, cbox) - stores_group_layout.addStretch() - - # Create and add the progress indicator - self.pi = ProgressIndicator(self, 24) - self.bottom_layout.insertWidget(0, self.pi) - - self.search.clicked.connect(self.do_search) - self.checker.timeout.connect(self.get_results) - self.results_view.activated.connect(self.open_store) - self.select_all_stores.clicked.connect(self.stores_select_all) - self.select_invert_stores.clicked.connect(self.stores_select_invert) - self.select_none_stores.clicked.connect(self.stores_select_none) - self.finished.connect(self.dialog_closed) - - self.restore_state() - - def resize_columns(self): - total = 600 - # Cover - self.results_view.setColumnWidth(0, 85) - total = total - 85 - # Title - self.results_view.setColumnWidth(1,int(total*.35)) - # Author - self.results_view.setColumnWidth(2,int(total*.35)) - # Price - self.results_view.setColumnWidth(3, int(total*.5)) - # DRM - self.results_view.setColumnWidth(4, int(total*.5)) - # Store - self.results_view.setColumnWidth(5, int(total*.15)) - # Formats - self.results_view.setColumnWidth(6, int(total*.5)) - - def do_search(self, checked=False): - # Stop all running threads. - self.checker.stop() - self.search_pool.abort() - # Clear the visible results. - self.results_view.model().clear_results() - - # Don't start a search if there is nothing to search for. - query = unicode(self.search_edit.text()) - if not query.strip(): - return - # Give the query to the results model so it can do - # futher filtering. - self.results_view.model().set_query(query) - - # Plugins are in alphebetic order. Randomize the - # order of plugin names. This way plugins closer - # to a don't have an unfair advantage over - # plugins further from a. - store_names = self.store_plugins.keys() - if not store_names: - return - # Remove all of our internal filtering logic from the query. - query = self.clean_query(query) - shuffle(store_names) - # Add plugins that the user has checked to the search pool's work queue. - for n in store_names: - if getattr(self, 'store_check_' + n).isChecked(): - self.search_pool.add_task(query, n, self.store_plugins[n], TIMEOUT) - if self.search_pool.has_tasks(): - self.hang_check = 0 - self.checker.start(100) - self.search_pool.start_threads() - self.pi.startAnimation() - - def clean_query(self, query): - query = query.lower() - # Remove control modifiers. - query = query.replace('\\', '') - query = query.replace('!', '') - query = query.replace('=', '') - query = query.replace('~', '') - query = query.replace('>', '') - query = query.replace('<', '') - # Remove the prefix. - for loc in ( 'all', 'author', 'authors', 'title'): - query = re.sub(r'%s:"?(?P[^\s"]+)"?' % loc, '\g', query) - # Remove the prefix and search text. - for loc in ('cover', 'drm', 'format', 'formats', 'price', 'store'): - query = re.sub(r'%s:"[^"]"' % loc, '', query) - query = re.sub(r'%s:[^\s]*' % loc, '', query) - # Remove logic. - query = re.sub(r'(^|\s)(and|not|or)(\s|$)', ' ', query) - # Remove excess whitespace. - query = re.sub(r'\s{2,}', ' ', query) - query = query.strip() - return query - - def save_state(self): - self.config['store_search_geometry'] = bytearray(self.saveGeometry()) - self.config['store_search_store_splitter_state'] = bytearray(self.store_splitter.saveState()) - self.config['store_search_results_view_column_width'] = [self.results_view.columnWidth(i) for i in range(self.model.columnCount())] - - store_check = {} - for n in self.store_plugins: - store_check[n] = getattr(self, 'store_check_' + n).isChecked() - self.config['store_search_store_checked'] = store_check - - def restore_state(self): - geometry = self.config.get('store_search_geometry', None) - if geometry: - self.restoreGeometry(geometry) - - splitter_state = self.config.get('store_search_store_splitter_state', None) - if splitter_state: - self.store_splitter.restoreState(splitter_state) - - results_cwidth = self.config.get('store_search_results_view_column_width', None) - if results_cwidth: - for i, x in enumerate(results_cwidth): - if i >= self.model.columnCount(): - break - self.results_view.setColumnWidth(i, x) - else: - self.resize_columns() - - store_check = self.config.get('store_search_store_checked', None) - if store_check: - for n in store_check: - if hasattr(self, 'store_check_' + n): - getattr(self, 'store_check_' + n).setChecked(store_check[n]) - - def get_results(self): - # We only want the search plugins to run - # a maximum set amount of time before giving up. - self.hang_check += 1 - if self.hang_check >= HANG_TIME: - self.search_pool.abort() - self.checker.stop() - self.pi.stopAnimation() - else: - # Stop the checker if not threads are running. - if not self.search_pool.threads_running() and not self.search_pool.has_tasks(): - self.checker.stop() - self.pi.stopAnimation() - - while self.search_pool.has_results(): - res, store_plugin = self.search_pool.get_result() - if res: - self.results_view.model().add_result(res, store_plugin) - - def open_store(self, index): - result = self.results_view.model().get_result(index) - self.store_plugins[result.store_name].open(self, result.detail_item) - - def get_store_checks(self): - ''' - Returns a list of QCheckBox's for each store. - ''' - checks = [] - for x in self.store_plugins: - check = getattr(self, 'store_check_' + x, None) - if check: - checks.append(check) - return checks - - def stores_select_all(self): - for check in self.get_store_checks(): - check.setChecked(True) - - def stores_select_invert(self): - for check in self.get_store_checks(): - check.setChecked(not check.isChecked()) - - def stores_select_none(self): - for check in self.get_store_checks(): - check.setChecked(False) - - def dialog_closed(self, result): - self.model.closing() - self.search_pool.abort() - self.save_state() - - -class GenericDownloadThreadPool(object): - ''' - add_task must be implemented in a subclass. - ''' - - def __init__(self, thread_type, thread_count): - self.thread_type = thread_type - self.thread_count = thread_count - - self.tasks = Queue() - self.results = Queue() - self.threads = [] - - def add_task(self): - raise NotImplementedError() - - def start_threads(self): - for i in range(self.thread_count): - t = self.thread_type(self.tasks, self.results) - self.threads.append(t) - t.start() - - def abort(self): - self.tasks = Queue() - self.results = Queue() - for t in self.threads: - t.abort() - self.threads = [] - - def has_tasks(self): - return not self.tasks.empty() - - def get_result(self): - return self.results.get() - - def get_result_no_wait(self): - return self.results.get_nowait() - - def result_count(self): - return len(self.results) - - def has_results(self): - return not self.results.empty() - - def threads_running(self): - for t in self.threads: - if t.is_alive(): - return True - return False - - -class SearchThreadPool(GenericDownloadThreadPool): - ''' - Threads will run until there is no work or - abort is called. Create and start new threads - using start_threads(). Reset by calling abort(). - - Example: - sp = SearchThreadPool(SearchThread, 3) - add tasks using add_task(...) - sp.start_threads() - all threads have finished. - sp.abort() - add tasks using add_task(...) - sp.start_threads() - ''' - - def add_task(self, query, store_name, store_plugin, timeout): - self.tasks.put((query, store_name, store_plugin, timeout)) - - -class SearchThread(Thread): - - def __init__(self, tasks, results): - Thread.__init__(self) - self.daemon = True - self.tasks = tasks - self.results = results - self._run = True - - def abort(self): - self._run = False - - def run(self): - while self._run and not self.tasks.empty(): - try: - query, store_name, store_plugin, timeout = self.tasks.get() - for res in store_plugin.search(query, timeout=timeout): - if not self._run: - return - res.store_name = store_name - self.results.put((res, store_plugin)) - self.tasks.task_done() - except: - traceback.print_exc() - - -class CoverThreadPool(GenericDownloadThreadPool): - ''' - Once started all threads run until abort is called. - ''' - - def add_task(self, search_result, update_callback, timeout=5): - self.tasks.put((search_result, update_callback, timeout)) - - -class CoverThread(Thread): - - def __init__(self, tasks, results): - Thread.__init__(self) - self.daemon = True - self.tasks = tasks - self.results = results - self._run = True - - self.br = browser() - - def abort(self): - self._run = False - - def run(self): - while self._run: - try: - time.sleep(.1) - while not self.tasks.empty(): - if not self._run: - break - result, callback, timeout = self.tasks.get() - if result and result.cover_url: - with closing(self.br.open(result.cover_url, timeout=timeout)) as f: - result.cover_data = f.read() - result.cover_data = thumbnail(result.cover_data, 64, 64)[2] - callback() - self.tasks.task_done() - except: - continue - - -class DetailsThreadPool(GenericDownloadThreadPool): - ''' - Once started all threads run until abort is called. - ''' - - def add_task(self, search_result, store_plugin, update_callback, timeout=10): - self.tasks.put((search_result, store_plugin, update_callback, timeout)) - - -class DetailsThread(Thread): - - def __init__(self, tasks, results): - Thread.__init__(self) - self.daemon = True - self.tasks = tasks - self.results = results - self._run = True - - def abort(self): - self._run = False - - def run(self): - while self._run: - try: - time.sleep(.1) - while not self.tasks.empty(): - if not self._run: - break - result, store_plugin, callback, timeout = self.tasks.get() - if result: - store_plugin.get_details(result, timeout) - callback(result) - self.tasks.task_done() - except: - continue - -class Matches(QAbstractItemModel): - - HEADERS = [_('Cover'), _('Title'), _('Author(s)'), _('Price'), _('DRM'), _('Store'), _('Formats')] - - def __init__(self): - QAbstractItemModel.__init__(self) - - self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64, - Qt.SmoothTransformation) - self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64, - Qt.SmoothTransformation) - self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_question.png')).scaledToHeight(64, - Qt.SmoothTransformation) - - # All matches. Used to determine the order to display - # self.matches because the SearchFilter returns - # matches unordered. - self.all_matches = [] - # Only the showing matches. - self.matches = [] - self.query = '' - self.search_filter = SearchFilter() - self.cover_pool = CoverThreadPool(CoverThread, 2) - self.cover_pool.start_threads() - self.details_pool = DetailsThreadPool(DetailsThread, 4) - self.details_pool.start_threads() - - def closing(self): - self.cover_pool.abort() - self.details_pool.abort() - - def clear_results(self): - self.all_matches = [] - self.matches = [] - self.all_matches = [] - self.search_filter.clear_search_results() - self.query = '' - self.cover_pool.abort() - self.cover_pool.start_threads() - self.details_pool.abort() - self.details_pool.start_threads() - self.reset() - - def add_result(self, result, store_plugin): - if result not in self.all_matches: - self.layoutAboutToBeChanged.emit() - self.all_matches.append(result) - self.search_filter.add_search_result(result) - if result.cover_url: - result.cover_queued = True - self.cover_pool.add_task(result, self.filter_results) - else: - result.cover_queued = False - self.details_pool.add_task(result, store_plugin, self.got_result_details) - self.filter_results() - self.layoutChanged.emit() - - def get_result(self, index): - row = index.row() - if row < len(self.matches): - return self.matches[row] - else: - return None - - def filter_results(self): - self.layoutAboutToBeChanged.emit() - if self.query: - self.matches = list(self.search_filter.parse(self.query)) - else: - self.matches = list(self.search_filter.universal_set()) - self.reorder_matches() - self.layoutChanged.emit() - - def got_result_details(self, result): - if not result.cover_queued and result.cover_url: - result.cover_queued = True - self.cover_pool.add_task(result, self.filter_results) - if result in self.matches: - row = self.matches.index(result) - self.dataChanged.emit(self.index(row, 0), self.index(row, self.columnCount() - 1)) - if result.drm not in (SearchResult.DRM_LOCKED, SearchResult.DRM_UNLOCKED, SearchResult.DRM_UNKNOWN): - result.drm = SearchResult.DRM_UNKNOWN - self.filter_results() - - def set_query(self, query): - self.query = query - - def index(self, row, column, parent=QModelIndex()): - return self.createIndex(row, column) - - def parent(self, index): - if not index.isValid() or index.internalId() == 0: - return QModelIndex() - return self.createIndex(0, 0) - - def rowCount(self, *args): - return len(self.matches) - - def columnCount(self, *args): - return len(self.HEADERS) - - def headerData(self, section, orientation, role): - if role != Qt.DisplayRole: - return NONE - text = '' - if orientation == Qt.Horizontal: - if section < len(self.HEADERS): - text = self.HEADERS[section] - return QVariant(text) - else: - return QVariant(section+1) - - def data(self, index, role): - row, col = index.row(), index.column() - result = self.matches[row] - if role == Qt.DisplayRole: - if col == 1: - return QVariant(result.title) - elif col == 2: - return QVariant(result.author) - elif col == 3: - return QVariant(result.price) - elif col == 5: - return QVariant(result.store_name) - elif col == 6: - return QVariant(result.formats) - return NONE - elif role == Qt.DecorationRole: - if col == 0 and result.cover_data: - p = QPixmap() - p.loadFromData(result.cover_data) - return QVariant(p) - if col == 4: - if result.drm == SearchResult.DRM_LOCKED: - return QVariant(self.DRM_LOCKED_ICON) - elif result.drm == SearchResult.DRM_UNLOCKED: - return QVariant(self.DRM_UNLOCKED_ICON) - elif result.drm == SearchResult.DRM_UNKNOWN: - return QVariant(self.DRM_UNKNOWN_ICON) - elif role == Qt.ToolTipRole: - if col == 1: - return QVariant('

%s

' % result.title) - elif col == 2: - return QVariant('

%s

' % result.author) - elif col == 3: - return QVariant('

' + _('Detected price as: %s. Check with the store before making a purchase to verify this price is correct. This price often does not include promotions the store may be running.') % result.price + '

') - elif col == 4: - if result.drm == SearchResult.DRM_LOCKED: - return QVariant('

' + _('This book as been detected as having DRM restrictions. This book may not work with your reader and you will have limitations placed upon you as to what you can do with this book. Check with the store before making any purchases to ensure you can actually read this book.') + '

') - elif result.drm == SearchResult.DRM_UNLOCKED: - return QVariant('

' + _('This book has been detected as being DRM Free. You should be able to use this book on any device provided it is in a format calibre supports for conversion. However, before making a purchase double check the DRM status with the store. The store may not be disclosing the use of DRM.') + '

') - else: - return QVariant('

' + _('The DRM status of this book could not be determined. There is a very high likelihood that this book is actually DRM restricted.') + '

') - elif col == 5: - return QVariant('

%s

' % result.store_name) - elif col == 6: - return QVariant('

%s

' % result.formats) - elif role == Qt.SizeHintRole: - return QSize(64, 64) - return NONE - - def data_as_text(self, result, col): - text = '' - if col == 1: - text = result.title - elif col == 2: - text = result.author - elif col == 3: - text = comparable_price(result.price) - elif col == 4: - if result.drm == SearchResult.DRM_UNLOCKED: - text = 'a' - elif result.drm == SearchResult.DRM_LOCKED: - text = 'b' - else: - text = 'c' - elif col == 5: - text = result.store_name - elif col == 6: - text = ', '.join(sorted(result.formats.split(','))) - return text - - def sort(self, col, order, reset=True): - if not self.matches: - return - descending = order == Qt.DescendingOrder - self.all_matches.sort(None, - lambda x: sort_key(unicode(self.data_as_text(x, col))), - descending) - self.reorder_matches() - if reset: - self.reset() - - def reorder_matches(self): - self.matches = sorted(self.matches, key=lambda x: self.all_matches.index(x)) - - -class SearchFilter(SearchQueryParser): - - USABLE_LOCATIONS = [ - 'all', - 'author', - 'authors', - 'cover', - 'drm', - 'format', - 'formats', - 'price', - 'title', - 'store', - ] - - def __init__(self): - SearchQueryParser.__init__(self, locations=self.USABLE_LOCATIONS) - self.srs = set([]) - - def add_search_result(self, search_result): - self.srs.add(search_result) - - def clear_search_results(self): - self.srs = set([]) - - def universal_set(self): - return self.srs - - def get_matches(self, location, query): - location = location.lower().strip() - if location == 'authors': - location = 'author' - elif location == 'formats': - location = 'format' - - matchkind = CONTAINS_MATCH - if len(query) > 1: - if query.startswith('\\'): - query = query[1:] - elif query.startswith('='): - matchkind = EQUALS_MATCH - query = query[1:] - elif query.startswith('~'): - matchkind = REGEXP_MATCH - query = query[1:] - if matchkind != REGEXP_MATCH: ### leave case in regexps because it can be significant e.g. \S \W \D - query = query.lower() - - if location not in self.USABLE_LOCATIONS: - return set([]) - matches = set([]) - all_locs = set(self.USABLE_LOCATIONS) - set(['all']) - locations = all_locs if location == 'all' else [location] - q = { - 'author': lambda x: x.author.lower(), - 'cover': attrgetter('cover_url'), - 'drm': attrgetter('drm'), - 'format': attrgetter('formats'), - 'price': lambda x: comparable_price(x.price), - 'store': lambda x: x.store_name.lower(), - 'title': lambda x: x.title.lower(), - } - for x in ('author', 'format'): - q[x+'s'] = q[x] - for sr in self.srs: - for locvalue in locations: - accessor = q[locvalue] - if query == 'true': - if locvalue == 'drm': - if accessor(sr) == SearchResult.DRM_LOCKED: - matches.add(sr) - else: - if accessor(sr) is not None: - matches.add(sr) - continue - if query == 'false': - if locvalue == 'drm': - if accessor(sr) == SearchResult.DRM_UNLOCKED: - matches.add(sr) - else: - if accessor(sr) is None: - matches.add(sr) - continue - # this is bool, so can't match below - if locvalue == 'drm': - continue - try: - ### Can't separate authors because comma is used for name sep and author sep - ### Exact match might not get what you want. For that reason, turn author - ### exactmatch searches into contains searches. - if locvalue == 'author' and matchkind == EQUALS_MATCH: - m = CONTAINS_MATCH - else: - m = matchkind - - if locvalue == 'format': - vals = accessor(sr).split(',') - else: - vals = [accessor(sr)] - if _match(query, vals, m): - matches.add(sr) - break - except ValueError: # Unicode errors - traceback.print_exc() - return matches diff --git a/src/calibre/gui2/store/search/__init__.py b/src/calibre/gui2/store/search/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/calibre/gui2/store/search/download_thread.py b/src/calibre/gui2/store/search/download_thread.py new file mode 100644 index 0000000000..a6f92011f6 --- /dev/null +++ b/src/calibre/gui2/store/search/download_thread.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +import time +import traceback +from contextlib import closing +from threading import Thread +from Queue import Queue + +from calibre import browser +from calibre.utils.magick.draw import thumbnail + +class GenericDownloadThreadPool(object): + ''' + add_task must be implemented in a subclass. + ''' + + def __init__(self, thread_type, thread_count): + self.thread_type = thread_type + self.thread_count = thread_count + + self.tasks = Queue() + self.results = Queue() + self.threads = [] + + def add_task(self): + raise NotImplementedError() + + def start_threads(self): + for i in range(self.thread_count): + t = self.thread_type(self.tasks, self.results) + self.threads.append(t) + t.start() + + def abort(self): + self.tasks = Queue() + self.results = Queue() + for t in self.threads: + t.abort() + self.threads = [] + + def has_tasks(self): + return not self.tasks.empty() + + def get_result(self): + return self.results.get() + + def get_result_no_wait(self): + return self.results.get_nowait() + + def result_count(self): + return len(self.results) + + def has_results(self): + return not self.results.empty() + + def threads_running(self): + for t in self.threads: + if t.is_alive(): + return True + return False + + +class SearchThreadPool(GenericDownloadThreadPool): + ''' + Threads will run until there is no work or + abort is called. Create and start new threads + using start_threads(). Reset by calling abort(). + + Example: + sp = SearchThreadPool(SearchThread, 3) + add tasks using add_task(...) + sp.start_threads() + all threads have finished. + sp.abort() + add tasks using add_task(...) + sp.start_threads() + ''' + + def add_task(self, query, store_name, store_plugin, timeout): + self.tasks.put((query, store_name, store_plugin, timeout)) + + +class SearchThread(Thread): + + def __init__(self, tasks, results): + Thread.__init__(self) + self.daemon = True + self.tasks = tasks + self.results = results + self._run = True + + def abort(self): + self._run = False + + def run(self): + while self._run and not self.tasks.empty(): + try: + query, store_name, store_plugin, timeout = self.tasks.get() + for res in store_plugin.search(query, timeout=timeout): + if not self._run: + return + res.store_name = store_name + self.results.put((res, store_plugin)) + self.tasks.task_done() + except: + traceback.print_exc() + + +class CoverThreadPool(GenericDownloadThreadPool): + ''' + Once started all threads run until abort is called. + ''' + + def add_task(self, search_result, update_callback, timeout=5): + self.tasks.put((search_result, update_callback, timeout)) + + +class CoverThread(Thread): + + def __init__(self, tasks, results): + Thread.__init__(self) + self.daemon = True + self.tasks = tasks + self.results = results + self._run = True + + self.br = browser() + + def abort(self): + self._run = False + + def run(self): + while self._run: + try: + time.sleep(.1) + while not self.tasks.empty(): + if not self._run: + break + result, callback, timeout = self.tasks.get() + if result and result.cover_url: + with closing(self.br.open(result.cover_url, timeout=timeout)) as f: + result.cover_data = f.read() + result.cover_data = thumbnail(result.cover_data, 64, 64)[2] + callback() + self.tasks.task_done() + except: + continue + + +class DetailsThreadPool(GenericDownloadThreadPool): + ''' + Once started all threads run until abort is called. + ''' + + def add_task(self, search_result, store_plugin, update_callback, timeout=10): + self.tasks.put((search_result, store_plugin, update_callback, timeout)) + + +class DetailsThread(Thread): + + def __init__(self, tasks, results): + Thread.__init__(self) + self.daemon = True + self.tasks = tasks + self.results = results + self._run = True + + def abort(self): + self._run = False + + def run(self): + while self._run: + try: + time.sleep(.1) + while not self.tasks.empty(): + if not self._run: + break + result, store_plugin, callback, timeout = self.tasks.get() + if result: + store_plugin.get_details(result, timeout) + callback(result) + self.tasks.task_done() + except: + continue diff --git a/src/calibre/gui2/store/search/models.py b/src/calibre/gui2/store/search/models.py new file mode 100644 index 0000000000..73b7bcc90a --- /dev/null +++ b/src/calibre/gui2/store/search/models.py @@ -0,0 +1,337 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +import re +from operator import attrgetter + +from PyQt4.Qt import (Qt, QAbstractItemModel, QVariant, QPixmap, QModelIndex, QSize) + +from calibre.gui2 import NONE +from calibre.gui2.store.search_result import SearchResult +from calibre.gui2.store.search.download_thread import DetailsThreadPool, \ + DetailsThread, CoverThreadPool, CoverThread +from calibre.library.caches import _match, CONTAINS_MATCH, EQUALS_MATCH, \ + REGEXP_MATCH +from calibre.utils.icu import sort_key +from calibre.utils.search_query_parser import SearchQueryParser + +def comparable_price(text): + if len(text) < 3 or text[-3] not in ('.', ','): + text += '00' + text = re.sub(r'\D', '', text) + text = text.rjust(6, '0') + return text + + +class Matches(QAbstractItemModel): + + HEADERS = [_('Cover'), _('Title'), _('Price'), _('DRM'), _('Store')] + HTML_COLS = (1, 4) + + def __init__(self): + QAbstractItemModel.__init__(self) + + self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64, + Qt.SmoothTransformation) + self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64, + Qt.SmoothTransformation) + self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_question.png')).scaledToHeight(64, + Qt.SmoothTransformation) + + # All matches. Used to determine the order to display + # self.matches because the SearchFilter returns + # matches unordered. + self.all_matches = [] + # Only the showing matches. + self.matches = [] + self.query = '' + self.search_filter = SearchFilter() + self.cover_pool = CoverThreadPool(CoverThread, 2) + self.cover_pool.start_threads() + self.details_pool = DetailsThreadPool(DetailsThread, 4) + self.details_pool.start_threads() + + self.sort_col = 2 + self.sort_order = Qt.AscendingOrder + + def closing(self): + self.cover_pool.abort() + self.details_pool.abort() + + def clear_results(self): + self.all_matches = [] + self.matches = [] + self.all_matches = [] + self.search_filter.clear_search_results() + self.query = '' + self.cover_pool.abort() + self.cover_pool.start_threads() + self.details_pool.abort() + self.details_pool.start_threads() + self.reset() + + def add_result(self, result, store_plugin): + if result not in self.all_matches: + self.layoutAboutToBeChanged.emit() + self.all_matches.append(result) + self.search_filter.add_search_result(result) + if result.cover_url: + result.cover_queued = True + self.cover_pool.add_task(result, self.filter_results) + else: + result.cover_queued = False + self.details_pool.add_task(result, store_plugin, self.got_result_details) + self.filter_results() + self.layoutChanged.emit() + + def get_result(self, index): + row = index.row() + if row < len(self.matches): + return self.matches[row] + else: + return None + + def has_results(self): + return len(self.matches) > 0 + + def filter_results(self): + self.layoutAboutToBeChanged.emit() + if self.query: + self.matches = list(self.search_filter.parse(self.query)) + else: + self.matches = list(self.search_filter.universal_set()) + self.sort(self.sort_col, self.sort_order, False) + self.layoutChanged.emit() + + def got_result_details(self, result): + if not result.cover_queued and result.cover_url: + result.cover_queued = True + self.cover_pool.add_task(result, self.filter_results) + if result in self.matches: + row = self.matches.index(result) + self.dataChanged.emit(self.index(row, 0), self.index(row, self.columnCount() - 1)) + if result.drm not in (SearchResult.DRM_LOCKED, SearchResult.DRM_UNLOCKED, SearchResult.DRM_UNKNOWN): + result.drm = SearchResult.DRM_UNKNOWN + self.filter_results() + + def set_query(self, query): + self.query = query + + def index(self, row, column, parent=QModelIndex()): + return self.createIndex(row, column) + + def parent(self, index): + if not index.isValid() or index.internalId() == 0: + return QModelIndex() + return self.createIndex(0, 0) + + def rowCount(self, *args): + return len(self.matches) + + def columnCount(self, *args): + return len(self.HEADERS) + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return NONE + text = '' + if orientation == Qt.Horizontal: + if section < len(self.HEADERS): + text = self.HEADERS[section] + return QVariant(text) + else: + return QVariant(section+1) + + def data(self, index, role): + row, col = index.row(), index.column() + result = self.matches[row] + if role == Qt.DisplayRole: + if col == 1: + t = result.title if result.title else _('Unknown') + a = result.author if result.author else '' + return QVariant('%s
%s' % (t, a)) + elif col == 2: + return QVariant(result.price) + elif col == 4: + return QVariant('%s
%s' % (result.store_name, result.formats)) + return NONE + elif role == Qt.DecorationRole: + if col == 0 and result.cover_data: + p = QPixmap() + p.loadFromData(result.cover_data) + return QVariant(p) + if col == 3: + if result.drm == SearchResult.DRM_LOCKED: + return QVariant(self.DRM_LOCKED_ICON) + elif result.drm == SearchResult.DRM_UNLOCKED: + return QVariant(self.DRM_UNLOCKED_ICON) + elif result.drm == SearchResult.DRM_UNKNOWN: + return QVariant(self.DRM_UNKNOWN_ICON) + elif role == Qt.ToolTipRole: + if col == 1: + return QVariant('

%s

' % result.title) + elif col == 2: + return QVariant('

' + _('Detected price as: %s. Check with the store before making a purchase to verify this price is correct. This price often does not include promotions the store may be running.') % result.price + '

') + elif col == 3: + if result.drm == SearchResult.DRM_LOCKED: + return QVariant('

' + _('This book as been detected as having DRM restrictions. This book may not work with your reader and you will have limitations placed upon you as to what you can do with this book. Check with the store before making any purchases to ensure you can actually read this book.') + '

') + elif result.drm == SearchResult.DRM_UNLOCKED: + return QVariant('

' + _('This book has been detected as being DRM Free. You should be able to use this book on any device provided it is in a format calibre supports for conversion. However, before making a purchase double check the DRM status with the store. The store may not be disclosing the use of DRM.') + '

') + else: + return QVariant('

' + _('The DRM status of this book could not be determined. There is a very high likelihood that this book is actually DRM restricted.') + '

') + elif col == 4: + return QVariant('

%s

' % result.formats) + elif role == Qt.SizeHintRole: + return QSize(64, 64) + return NONE + + def data_as_text(self, result, col): + text = '' + if col == 1: + text = result.title + elif col == 2: + text = comparable_price(result.price) + elif col == 3: + if result.drm == SearchResult.DRM_UNLOCKED: + text = 'a' + if result.drm == SearchResult.DRM_LOCKED: + text = 'b' + else: + text = 'c' + elif col == 4: + text = result.store_name + return text + + def sort(self, col, order, reset=True): + self.sort_col = col + self.sort_order = order + if not self.matches: + return + descending = order == Qt.DescendingOrder + self.all_matches.sort(None, + lambda x: sort_key(unicode(self.data_as_text(x, col))), + descending) + self.reorder_matches() + if reset: + self.reset() + + def reorder_matches(self): + def keygen(x): + try: + return self.all_matches.index(x) + except: + return 100000 + self.matches = sorted(self.matches, key=keygen) + + +class SearchFilter(SearchQueryParser): + + USABLE_LOCATIONS = [ + 'all', + 'author', + 'authors', + 'cover', + 'drm', + 'format', + 'formats', + 'price', + 'title', + 'store', + ] + + def __init__(self): + SearchQueryParser.__init__(self, locations=self.USABLE_LOCATIONS) + self.srs = set([]) + + def add_search_result(self, search_result): + self.srs.add(search_result) + + def clear_search_results(self): + self.srs = set([]) + + def universal_set(self): + return self.srs + + def get_matches(self, location, query): + location = location.lower().strip() + if location == 'authors': + location = 'author' + elif location == 'formats': + location = 'format' + + matchkind = CONTAINS_MATCH + if len(query) > 1: + if query.startswith('\\'): + query = query[1:] + elif query.startswith('='): + matchkind = EQUALS_MATCH + query = query[1:] + elif query.startswith('~'): + matchkind = REGEXP_MATCH + query = query[1:] + if matchkind != REGEXP_MATCH: ### leave case in regexps because it can be significant e.g. \S \W \D + query = query.lower() + + if location not in self.USABLE_LOCATIONS: + return set([]) + matches = set([]) + all_locs = set(self.USABLE_LOCATIONS) - set(['all']) + locations = all_locs if location == 'all' else [location] + q = { + 'author': lambda x: x.author.lower(), + 'cover': attrgetter('cover_url'), + 'drm': attrgetter('drm'), + 'format': attrgetter('formats'), + 'price': lambda x: comparable_price(x.price), + 'store': lambda x: x.store_name.lower(), + 'title': lambda x: x.title.lower(), + } + for x in ('author', 'format'): + q[x+'s'] = q[x] + for sr in self.srs: + for locvalue in locations: + accessor = q[locvalue] + if query == 'true': + if locvalue == 'drm': + if accessor(sr) == SearchResult.DRM_LOCKED: + matches.add(sr) + else: + if accessor(sr) is not None: + matches.add(sr) + continue + if query == 'false': + if locvalue == 'drm': + if accessor(sr) == SearchResult.DRM_UNLOCKED: + matches.add(sr) + else: + if accessor(sr) is None: + matches.add(sr) + continue + # this is bool, so can't match below + if locvalue == 'drm': + continue + try: + ### Can't separate authors because comma is used for name sep and author sep + ### Exact match might not get what you want. For that reason, turn author + ### exactmatch searches into contains searches. + if locvalue == 'author' and matchkind == EQUALS_MATCH: + m = CONTAINS_MATCH + else: + m = matchkind + + if locvalue == 'format': + vals = accessor(sr).split(',') + else: + vals = [accessor(sr)] + if _match(query, vals, m): + matches.add(sr) + break + except ValueError: # Unicode errors + import traceback + traceback.print_exc() + return matches diff --git a/src/calibre/gui2/store/search/results_view.py b/src/calibre/gui2/store/search/results_view.py new file mode 100644 index 0000000000..91c067006e --- /dev/null +++ b/src/calibre/gui2/store/search/results_view.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import (QTreeView) + +from calibre.gui2.metadata.single_download import RichTextDelegate +from calibre.gui2.store.search.models import Matches + +class ResultsView(QTreeView): + + def __init__(self, *args): + QTreeView.__init__(self,*args) + + self._model = Matches() + self.setModel(self._model) + + self.rt_delegate = RichTextDelegate(self) + + for i in self._model.HTML_COLS: + self.setItemDelegateForColumn(i, self.rt_delegate) + diff --git a/src/calibre/gui2/store/search/search.py b/src/calibre/gui2/store/search/search.py new file mode 100644 index 0000000000..5c4b1cee00 --- /dev/null +++ b/src/calibre/gui2/store/search/search.py @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +import re +from random import shuffle + +from PyQt4.Qt import (Qt, QDialog, QTimer, QCheckBox, QVBoxLayout) + +from calibre.gui2 import JSONConfig, info_dialog +from calibre.gui2.progress_indicator import ProgressIndicator +from calibre.gui2.store.search.download_thread import SearchThreadPool, SearchThread +from calibre.gui2.store.search.search_ui import Ui_Dialog + +HANG_TIME = 75000 # milliseconds seconds +TIMEOUT = 75 # seconds +SEARCH_THREAD_TOTAL = 4 +COVER_DOWNLOAD_THREAD_TOTAL = 2 + +class SearchDialog(QDialog, Ui_Dialog): + + def __init__(self, istores, *args): + QDialog.__init__(self, *args) + self.setupUi(self) + + self.config = JSONConfig('store/search') + + # We keep a cache of store plugins and reference them by name. + self.store_plugins = istores + self.search_pool = SearchThreadPool(SearchThread, SEARCH_THREAD_TOTAL) + # Check for results and hung threads. + self.checker = QTimer() + self.hang_check = 0 + + # Add check boxes for each store so the user + # can disable searching specific stores on a + # per search basis. + stores_group_layout = QVBoxLayout() + self.stores_group.setLayout(stores_group_layout) + for x in self.store_plugins: + cbox = QCheckBox(x) + cbox.setChecked(True) + stores_group_layout.addWidget(cbox) + setattr(self, 'store_check_' + x, cbox) + stores_group_layout.addStretch() + + # Create and add the progress indicator + self.pi = ProgressIndicator(self, 24) + self.top_layout.addWidget(self.pi) + + self.search.clicked.connect(self.do_search) + self.checker.timeout.connect(self.get_results) + self.results_view.activated.connect(self.open_store) + self.select_all_stores.clicked.connect(self.stores_select_all) + self.select_invert_stores.clicked.connect(self.stores_select_invert) + self.select_none_stores.clicked.connect(self.stores_select_none) + self.finished.connect(self.dialog_closed) + + self.restore_state() + + def resize_columns(self): + total = 600 + # Cover + self.results_view.setColumnWidth(0, 85) + total = total - 85 + # Title / Author + self.results_view.setColumnWidth(1,int(total*.40)) + # Price + self.results_view.setColumnWidth(2,int(total*.20)) + # DRM + self.results_view.setColumnWidth(3, int(total*.15)) + # Store / Formats + self.results_view.setColumnWidth(4, int(total*.25)) + + def do_search(self, checked=False): + # Stop all running threads. + self.checker.stop() + self.search_pool.abort() + # Clear the visible results. + self.results_view.model().clear_results() + + # Don't start a search if there is nothing to search for. + query = unicode(self.search_edit.text()) + if not query.strip(): + return + # Give the query to the results model so it can do + # futher filtering. + self.results_view.model().set_query(query) + + # Plugins are in alphebetic order. Randomize the + # order of plugin names. This way plugins closer + # to a don't have an unfair advantage over + # plugins further from a. + store_names = self.store_plugins.keys() + if not store_names: + return + # Remove all of our internal filtering logic from the query. + query = self.clean_query(query) + shuffle(store_names) + # Add plugins that the user has checked to the search pool's work queue. + for n in store_names: + if getattr(self, 'store_check_' + n).isChecked(): + self.search_pool.add_task(query, n, self.store_plugins[n], TIMEOUT) + if self.search_pool.has_tasks(): + self.hang_check = 0 + self.checker.start(100) + self.search_pool.start_threads() + self.pi.startAnimation() + + def clean_query(self, query): + query = query.lower() + # Remove control modifiers. + query = query.replace('\\', '') + query = query.replace('!', '') + query = query.replace('=', '') + query = query.replace('~', '') + query = query.replace('>', '') + query = query.replace('<', '') + # Remove the prefix. + for loc in ( 'all', 'author', 'authors', 'title'): + query = re.sub(r'%s:"?(?P
[^\s"]+)"?' % loc, '\g', query) + # Remove the prefix and search text. + for loc in ('cover', 'drm', 'format', 'formats', 'price', 'store'): + query = re.sub(r'%s:"[^"]"' % loc, '', query) + query = re.sub(r'%s:[^\s]*' % loc, '', query) + # Remove logic. + query = re.sub(r'(^|\s)(and|not|or)(\s|$)', ' ', query) + # Remove excess whitespace. + query = re.sub(r'\s{2,}', ' ', query) + query = query.strip() + return query + + def save_state(self): + self.config['geometry'] = bytearray(self.saveGeometry()) + self.config['store_splitter_state'] = bytearray(self.store_splitter.saveState()) + self.config['results_view_column_width'] = [self.results_view.columnWidth(i) for i in range(self.results_view.model().columnCount())] + self.config['sort_col'] = self.results_view.model().sort_col + self.config['sort_order'] = self.results_view.model().sort_order + + store_check = {} + for n in self.store_plugins: + store_check[n] = getattr(self, 'store_check_' + n).isChecked() + self.config['store_checked'] = store_check + + def restore_state(self): + geometry = self.config.get('geometry', None) + if geometry: + self.restoreGeometry(geometry) + + splitter_state = self.config.get('store_splitter_state', None) + if splitter_state: + self.store_splitter.restoreState(splitter_state) + + results_cwidth = self.config.get('results_view_column_width', None) + if results_cwidth: + for i, x in enumerate(results_cwidth): + if i >= self.results_view.model().columnCount(): + break + self.results_view.setColumnWidth(i, x) + else: + self.resize_columns() + + store_check = self.config.get('store_checked', None) + if store_check: + for n in store_check: + if hasattr(self, 'store_check_' + n): + getattr(self, 'store_check_' + n).setChecked(store_check[n]) + + self.results_view.model().sort_col = self.config.get('sort_col', 2) + self.results_view.model().sort_order = self.config.get('sort_order', Qt.AscendingOrder) + self.results_view.header().setSortIndicator(self.results_view.model().sort_col, self.results_view.model().sort_order) + + def get_results(self): + # We only want the search plugins to run + # a maximum set amount of time before giving up. + self.hang_check += 1 + if self.hang_check >= HANG_TIME: + self.search_pool.abort() + self.checker.stop() + self.pi.stopAnimation() + else: + # Stop the checker if not threads are running. + if not self.search_pool.threads_running() and not self.search_pool.has_tasks(): + self.checker.stop() + self.pi.stopAnimation() + + while self.search_pool.has_results(): + res, store_plugin = self.search_pool.get_result() + if res: + self.results_view.model().add_result(res, store_plugin) + + if not self.checker.isActive(): + if not self.results_view.model().has_results(): + info_dialog(self, _('No matches'), _('Couldn\'t find any books matching your query.'), show=True, show_copy_button=False) + + + def open_store(self, index): + result = self.results_view.model().get_result(index) + self.store_plugins[result.store_name].open(self, result.detail_item) + + def get_store_checks(self): + ''' + Returns a list of QCheckBox's for each store. + ''' + checks = [] + for x in self.store_plugins: + check = getattr(self, 'store_check_' + x, None) + if check: + checks.append(check) + return checks + + def stores_select_all(self): + for check in self.get_store_checks(): + check.setChecked(True) + + def stores_select_invert(self): + for check in self.get_store_checks(): + check.setChecked(not check.isChecked()) + + def stores_select_none(self): + for check in self.get_store_checks(): + check.setChecked(False) + + def dialog_closed(self, result): + self.results_view.model().closing() + self.search_pool.abort() + self.save_state() + diff --git a/src/calibre/gui2/store/search.ui b/src/calibre/gui2/store/search/search.ui similarity index 93% rename from src/calibre/gui2/store/search.ui rename to src/calibre/gui2/store/search/search.ui index dd7db939a4..bdf875113e 100644 --- a/src/calibre/gui2/store/search.ui +++ b/src/calibre/gui2/store/search/search.ui @@ -14,7 +14,7 @@ Get Books - + :/images/store.png:/images/store.png @@ -22,7 +22,7 @@ - + @@ -62,8 +62,8 @@ 0 0 - 170 - 138 + 215 + 116 @@ -110,7 +110,7 @@ Qt::Horizontal - + 1 @@ -178,6 +178,13 @@ + + + ResultsView + QTreeView +
results_view.h
+
+
diff --git a/src/calibre/gui2/store/smashwords_plugin.py b/src/calibre/gui2/store/smashwords_plugin.py index 629a85dca5..73700ed546 100644 --- a/src/calibre/gui2/store/smashwords_plugin.py +++ b/src/calibre/gui2/store/smashwords_plugin.py @@ -25,7 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog class SmashwordsStore(BasicStoreConfig, StorePlugin): def open(self, parent=None, detail_item=None, external=False): - settings = self.get_settings() url = 'http://www.smashwords.com/' aff_id = '?ref=usernone' @@ -38,12 +37,12 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin): detail_url = url + detail_item + aff_id url = url + aff_id - if external or settings.get(self.name + '_open_external', False): + if external or self.config.get('open_external', False): open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) else: d = WebStoreDialog(self.gui, url, parent, detail_url) d.setWindowTitle(self.name) - d.set_tags(settings.get(self.name + '_tags', '')) + d.set_tags(self.config.get('tags', '')) d.exec_() def search(self, query, max_results=10, timeout=60): diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index d7f6c22925..3702de45c5 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -1756,7 +1756,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): return books_to_refresh def set_metadata(self, id, mi, ignore_errors=False, set_title=True, - set_authors=True, commit=True, force_changes=False): + set_authors=True, commit=True, force_changes=False, + notify=True): ''' Set metadata for the book `id` from the `Metadata` object `mi` @@ -1865,7 +1866,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): label=user_mi[key]['label'], commit=False) if commit: self.conn.commit() - self.notify('metadata', [id]) + if notify: + self.notify('metadata', [id]) def authors_sort_strings(self, id, index_is_id=False): ''' @@ -2002,8 +2004,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): return False if isbytestring(title): title = title.decode(preferred_encoding, 'replace') + old_title = self.title(id, index_is_id=True) + # We cannot check if old_title == title as previous code might have + # already updated the cache + only_case_change = icu_lower(old_title) == icu_lower(title) self.conn.execute('UPDATE books SET title=? WHERE id=?', (title, id)) self.data.set(id, self.FIELD_MAP['title'], title, row_is_id=True) + if only_case_change: + # SQLite update trigger will not update sort on a case change + self.conn.execute('UPDATE books SET sort=? WHERE id=?', + (title_sort(title), id)) ts = self.conn.get('SELECT sort FROM books WHERE id=?', (id,), all=False) if ts: diff --git a/src/calibre/translations/ca.po b/src/calibre/translations/ca.po index a3adf23dd0..fee04ff0a8 100644 --- a/src/calibre/translations/ca.po +++ b/src/calibre/translations/ca.po @@ -11,14 +11,14 @@ msgstr "" "Project-Id-Version: ca\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-17 16:54+0000\n" -"PO-Revision-Date: 2011-04-17 19:55+0000\n" +"PO-Revision-Date: 2011-04-21 10:40+0000\n" "Last-Translator: FerranRius \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-18 04:49+0000\n" -"X-Generator: Launchpad (build 12735)\n" +"X-Launchpad-Export-Date: 2011-04-22 04:35+0000\n" +"X-Generator: Launchpad (build 12758)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:56 msgid "Does absolutely nothing" @@ -18718,6 +18718,85 @@ msgid "" "sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'}\n" "sony_collection_name_template='{category:||: }{value}'" msgstr "" +"Especifica les regles de canvi de nom per a les col·leccions Sony. Aquest " +"ajustament\n" +"només s’aplica si s’estableix la gestió de metadades a automàtica. Les " +"col·leccions\n" +"Sony s’anomenen depenent de si el camp és estàndard o personalitzat. Una\n" +"col·lecció derivada d’un camp estàndard rep el nom del valor del camp. Per " +"exemple,\n" +"si la columna estàndard «sèrie» conté el valor «Darkover», en nom de la " +"col·lecció\n" +"serà «Darkover». Una col·lecció derivada d’un camp personalitzat tindrà el " +"nom del\n" +"camp afegit al valor. Per exemple, si una columna personalitzada de sèrie " +"anomenada\n" +"«Sèries meves» conté el nom «Darkover», la col·lecció es dirà per defecte " +"«Darkover \n" +"(Sèries meves)». Pel que fa a aquesta documentació, considerem que " +"«Darkover» és\n" +"el valor i «Sèries meves» la categoria. Si dos llibres tenen camps que " +"generen el\n" +"mateix nom de col·lecció, els dos llibres estaran a la col·lecció.\n" +"Aquest conjunt d’ajustaments us permet especificar com s’anomenaran les \n" +"col·leccions per a camps estàndards o personalitzats. Es pot utilitzar per " +"afegir una\n" +"descripció a un camp estàndars, per exemple «Foo (Etiqueta)» en lloc de " +"«Foo».\n" +"També es pot utilitzar per forçar que múltiples camps acabin a una mateixa " +"col·lecció.\n" +"Per exemple, es pot forçar que els valors a «sèries», «#la_meva_sèrie_1» i \n" +"«#la_meva_sèrie_2» apareguin en col·leccions anomenades «algun_valor " +"(Sèrie)»,\n" +"fusionant els camps en un conjunt de col·leccions.\n" +"Hi ha dos ajustaments relacionats. El primer determina el nom de la " +"categoria que\n" +"s’utilitza per a un camp de metadades. El segon és una plantilla que " +"s’utilitza per\n" +"determinar com es combinen el valor i la categoria per crear el nom de la " +"col·lecció.\n" +"La sintaxi del primer ajustament, «sony_collection_renaming_rules», és:\n" +"{'nom_camp_de_cerca':'nom_categoria_a_utilitzar', 'nom_cerca':'nom', ...}\n" +"El segon ajustament «sony_collection_name_template», és una plantilla. " +"Utilitza el\n" +"mateix llenguatge que els quadres de connexions i les plantilles de desar. " +"Aquest\n" +"ajustament controla com es combinen el valor i la categoria per obtenir el " +"nom de la\n" +"col·lecció. Hi ha dos camps disponibles, {categoria} i {valor}. El camp " +"{valor} no\n" +"està mai buit. El camp {categoria} pot estar buit. Per defecte es posa el " +"valor primer\n" +"i després, si no està buida, la categoria entre parèntesis:\n" +"'{value} {category:|(|)}'\n" +"Exemples: Els primers tres exemples assumeixen que no s’ha canviat el segon\n" +"ajustament.\n" +"1: Es vol que tres columnes de sèries es fusionin en un conjunt de " +"col·leccions. El\n" +"nom de cerca de les columnes són «sèrie», «#sèrie_2» i «#sèrie_3». No es vol " +"res\n" +"entre parèntesis. El valor per a l’ajustament serà:\n" +"sony_collection_renaming_rules={'sèrie':'', '#sèrie_1':'', '#sèrie_2':''}\n" +"2: Es vol que la paraula «(Sèrie)» aparegui a les col·leccions obtingudes a " +"partir de\n" +"sèries i que la paraula «(Etiqueta)» aparegui a les col·leccions obtingudes " +"a partir\n" +"d’etiquetes. Serà:\n" +"sony_collection_renaming_rules={'series':'Sèrie', 'tags':'Etiqueta'}\n" +"3: Es vol fusionar «sèrie» i «#la_meva_sèrie» i que s’afegeixi al final del " +"nom de la\n" +"col lecció «(Sèrie)». La regla de canvi de nom serà:\n" +"sony_collection_renaming_rules={'series':'Sèrie', " +"'#la_meva_sèrie':'Series'}\n" +"4: Igual que a l’exemple 2, però en lloc de tenir el nom de la categoria " +"entre\n" +"parèntesis i afegit al final del valor, es vol abans del valor i separat per " +"dos punts,\n" +"com a «Sèrie: Darkover». S’ha de canviar la plantilla utilitzada per donar " +"format al\n" +"nom de categoria. Els dos ajustaments resultants seran:\n" +"sony_collection_renaming_rules={'series':'Sèrie', 'tags':'Etiqueta'}\n" +"sony_collection_name_template='{category:||: }{value}'" #: /home/kovid/work/calibre/resources/default_tweaks.py:221 msgid "Specify how SONY collections are sorted" diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 8895eb64b3..96a7cc9e1b 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -4,9 +4,9 @@ # msgid "" msgstr "" -"Project-Id-Version: calibre 0.7.56\n" -"POT-Creation-Date: 2011-04-17 09:36+MDT\n" -"PO-Revision-Date: 2011-04-17 09:36+MDT\n" +"Project-Id-Version: calibre 0.7.57\n" +"POT-Creation-Date: 2011-04-22 13:18+MDT\n" +"PO-Revision-Date: 2011-04-22 13:18+MDT\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -31,15 +31,15 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/prs500/books.py:267 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:660 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:467 -#: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:99 #: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:102 +#: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:105 #: /home/kovid/work/calibre/src/calibre/ebooks/chm/metadata.py:56 #: /home/kovid/work/calibre/src/calibre/ebooks/comic/input.py:435 #: /home/kovid/work/calibre/src/calibre/ebooks/epub/periodical.py:127 #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:100 #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:102 -#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:331 -#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:334 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:332 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:335 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1894 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1896 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/output.py:24 @@ -49,11 +49,11 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:74 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:428 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:433 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:678 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:680 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/ereader.py:36 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/ereader.py:61 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/extz.py:24 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:55 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:364 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:36 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:64 @@ -70,29 +70,30 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rtf.py:91 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rtf.py:101 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/snb.py:16 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:48 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/covers.py:79 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/covers.py:81 #: /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:256 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:258 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:302 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:304 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/identify.py:393 #: /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 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:82 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:125 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:159 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:667 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:885 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:887 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:701 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:948 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:950 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1001 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1006 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1072 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/reader.py:145 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/reader.py:152 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:999 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1004 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1070 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/reader.py:144 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/reader.py:151 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:65 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:112 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:119 @@ -120,19 +121,19 @@ 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:336 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:345 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:394 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:397 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:393 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:396 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:160 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:122 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:151 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:153 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1116 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1119 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1118 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:56 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:68 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:47 @@ -142,29 +143,30 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:366 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:152 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:167 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:436 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:455 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1023 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1197 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:454 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1024 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1198 #: /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:188 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:112 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:252 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:324 -#: /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/metadata/bulk_download2.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:155 #: /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/cli.py:217 #: /home/kovid/work/calibre/src/calibre/library/database.py:914 -#: /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:1800 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1924 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2913 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2915 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3048 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:499 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:507 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:518 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1797 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1922 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2923 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2925 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3058 #: /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 @@ -223,319 +225,319 @@ msgid "Preferences" msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:609 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:33 msgid "Store" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:19 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:18 msgid "Follow all local links in an HTML file and create a ZIP file containing all linked files. This plugin is run every time you add an HTML file to the library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:55 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:54 msgid "Character encoding for the input HTML files. Common choices include: cp1252, latin1, iso-8859-1 and utf-8." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:62 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:61 msgid "Create a PMLZ archive containing the PML file and all images in the directory pmlname_img or images. This plugin is run every time you add a PML file to the library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:92 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:91 msgid "Create a TXTZ archive when a TXT file is imported containing Markdown or Textile references to images. The referenced images as well as the TXT file are added to the archive." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:167 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:168 msgid "Extract cover from comic files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:204 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:215 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:227 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:237 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:247 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:258 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:269 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:279 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:289 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:299 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:309 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:319 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:329 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:340 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:352 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:373 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:384 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:394 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:405 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:415 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:426 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:205 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:216 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:228 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:238 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:248 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:259 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:270 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:280 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:290 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:300 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:310 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:320 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:330 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:341 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:353 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:374 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:385 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:395 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:406 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:416 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:427 msgid "Read metadata from %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:363 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:364 msgid "Read metadata from ebooks in RAR archives" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:437 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:438 msgid "Read metadata from ebooks in ZIP archives" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:450 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:471 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:481 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:503 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:514 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:524 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:451 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:472 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:482 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:504 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:515 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:525 msgid "Set metadata in %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:460 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:492 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:535 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:461 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:493 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:536 msgid "Set metadata from %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:880 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:882 msgid "Look and Feel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:882 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:894 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:905 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:916 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:928 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:884 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:896 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:907 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:918 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:930 msgid "Interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:886 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:888 msgid "Adjust the look and feel of the calibre interface to suit your tastes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:892 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:894 msgid "Behavior" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:898 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:900 msgid "Change the way calibre behaves" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:903 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:905 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:218 msgid "Add your own columns" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:909 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:911 msgid "Add/remove your own columns to the calibre book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:914 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:916 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:920 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:922 msgid "Customize the toolbars and context menus, changing which actions are available in each" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:926 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:928 msgid "Searching" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:932 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:934 msgid "Customize the way searching for books works in calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:937 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:939 msgid "Input Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:939 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:950 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:961 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:941 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:952 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:963 msgid "Conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:943 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:945 msgid "Set conversion options specific to each input format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:948 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:950 msgid "Common Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:954 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:956 msgid "Set conversion options common to all formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:959 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:961 msgid "Output Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:965 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:967 msgid "Set conversion options specific to each output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:970 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:972 msgid "Adding books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:972 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:984 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:996 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1008 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:974 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:986 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:998 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1010 msgid "Import/Export" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:976 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:978 msgid "Control how calibre reads metadata from files when adding books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:982 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:984 msgid "Saving books to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:988 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:990 msgid "Control how calibre exports files from its database to disk when using Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:994 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:996 msgid "Sending books to devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1000 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1002 msgid "Control how calibre transfers files to your ebook reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1006 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1008 msgid "Metadata plugboards" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1012 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1014 msgid "Change metadata fields before saving/sending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1017 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1019 msgid "Template Functions" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1019 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1066 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1078 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1089 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1021 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1068 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1080 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1091 msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1023 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1025 msgid "Create your own template functions" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1028 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1030 msgid "Sharing books by email" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1030 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1042 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1055 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1032 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1044 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1057 msgid "Sharing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1034 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1036 msgid "Setup sharing of books via email. Can be used for automatic sending of downloaded news to your devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1040 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1042 msgid "Sharing over the net" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1046 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1048 msgid "Setup the calibre Content Server which will give you access to your calibre library from anywhere, on any device, over the internet" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1053 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1055 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:57 msgid "Metadata download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1059 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1061 msgid "Control how calibre downloads ebook metadata from the net" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1064 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1066 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:269 msgid "Plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1070 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1072 msgid "Add/remove/customize various bits of calibre functionality" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1076 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1078 msgid "Tweaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1082 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1084 msgid "Fine tune how calibre behaves in various contexts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1087 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1089 msgid "Miscellaneous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1093 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1095 msgid "Miscellaneous advanced configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1107 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1109 msgid "Kindle books from Amazon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1112 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1114 msgid "Ebooks for readers." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1117 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1119 msgid "Books, Textbooks, eBooks, Toys, Games and More." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1122 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1124 msgid "Publishers of fine books." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1127 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1129 msgid "World Famous eBook Store." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1132 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1134 msgid "The digital bookstore." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1137 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1139 msgid "entertain, enrich, inspire." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1142 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1144 msgid "Read anywhere." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1147 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1149 msgid "The first producer of free ebooks." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1152 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1154 msgid "eReading: anytime. anyplace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1157 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1159 msgid "The best ebooks at the best price: free!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1162 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1164 msgid "Ebooks handcrafted with the utmost care" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1167 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1169 msgid "One web page for every book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1172 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1174 msgid "Your ebook. Your way." msgstr "" @@ -688,31 +690,31 @@ msgstr "" msgid "This profile is intended for the Sanda Bambook." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:27 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:32 msgid "Installed plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:28 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:33 msgid "Mapping for filetype plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:29 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:34 msgid "Local plugin customization" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:30 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:35 msgid "Disabled plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:31 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:36 msgid "Enabled plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:502 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:510 msgid "Initialization of plugin %s failed with traceback:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:535 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:547 msgid "" " %prog options\n" "\n" @@ -720,27 +722,27 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:541 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:553 msgid "Add a plugin by specifying the path to the zip file containing it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:543 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:555 msgid "Remove a custom plugin by name. Has no effect on builtin plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:545 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:557 msgid "Customize plugin. Specify name of plugin and customization string separated by a comma." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:547 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:559 msgid "List all installed plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:549 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:561 msgid "Enable the named plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:551 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:563 msgid "Disable the named plugin" msgstr "" @@ -804,41 +806,41 @@ msgstr "" msgid "Cannot copy books directly from iDevice. Drag from iTunes Library to desktop, then add to calibre's Library window." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:352 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:355 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:353 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:356 msgid "Updating device metadata listing..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:431 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:470 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1049 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1089 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3073 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3113 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:432 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:471 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1054 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1098 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3082 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3122 msgid "%d of %d" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:477 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1094 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3119 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:478 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1103 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3128 #: /home/kovid/work/calibre/src/calibre/gui2/ebook_download.py:106 msgid "finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:662 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:663 msgid "" "Some books not found in iTunes database.\n" "Delete using the iBooks app.\n" "Click 'Show Details' for a list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1013 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1014 msgid "" "Some cover art could not be converted.\n" "Click 'Show Details' for a list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2655 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2664 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:100 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:447 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:470 @@ -847,22 +849,22 @@ 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:299 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:312 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2777 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:298 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:311 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2787 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:159 msgid "News" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2656 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2665 #: /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:2739 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2757 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:633 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2747 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2765 msgid "Catalog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2977 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2986 msgid "Communicate with iTunes." msgstr "" @@ -1566,321 +1568,321 @@ msgstr "" msgid "Output saved to" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:102 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:103 msgid "Level of verbosity. Specify multiple times for greater verbosity." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:110 msgid "Save the output from different stages of the conversion pipeline to the specified directory. Useful if you are unsure at which stage of the conversion process a bug is occurring." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:118 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:119 msgid "Specify the input profile. The input profile gives the conversion system information on how to interpret various information in the input document. For example resolution dependent lengths (i.e. lengths in pixels). Choices are:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:129 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:130 msgid "Specify the output profile. The output profile tells the conversion system how to optimize the created document for the specified device. In some cases, an output profile is required to produce documents that will work on a device. For example EPUB on the SONY reader. Choices are:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:141 msgid "The base font size in pts. All font sizes in the produced book will be rescaled based on this size. By choosing a larger size you can make the fonts in the output bigger and vice versa. By default, the base font size is chosen based on the output profile you chose." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:150 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:151 msgid "Mapping from CSS font names to font sizes in pts. An example setting is 12,12,14,16,18,20,22,24. These are the mappings for the sizes xx-small to xx-large, with the final size being for huge fonts. The font rescaling algorithm uses these sizes to intelligently rescale fonts. The default is to use a mapping based on the output profile you chose." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:163 msgid "Disable all rescaling of font sizes." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:168 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:169 msgid "The minimum line height, as a percentage of the element's calculated font size. calibre will ensure that every element has a line height of at least this setting, irrespective of what the input document specifies. Set to zero to disable. Default is 120%. Use this setting in preference to the direct line height specification, unless you know what you are doing. For example, you can achieve \"double spaced\" text by setting this to 240." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:183 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:184 msgid "The line height in pts. Controls spacing between consecutive lines of text. Only applies to elements that do not define their own line height. In most cases, the minimum line height option is more useful. By default no line height manipulation is performed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:194 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:195 msgid "Some badly designed documents use tables to control the layout of text on the page. When converted these documents often have text that runs off the page and other artifacts. This option will extract the content from the tables and present it in a linear fashion." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:204 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:205 msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level one. If this is specified, it takes precedence over other forms of auto-detection." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:213 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:214 msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level two. Each entry is added under the previous level one entry." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:221 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:222 msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level three. Each entry is added under the previous level two entry." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:229 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:230 msgid "Normally, if the source file already has a Table of Contents, it is used in preference to the auto-generated one. With this option, the auto-generated one is always used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:237 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:238 msgid "Don't add auto-detected chapters to the Table of Contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:244 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:245 msgid "If fewer than this number of chapters is detected, then links are added to the Table of Contents. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:251 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:252 msgid "Maximum number of links to insert into the TOC. Set to 0 to disable. Default is: %default. Links are only added to the TOC if less than the threshold number of chapters were detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:259 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:260 msgid "Remove entries from the Table of Contents whose titles match the specified regular expression. Matching entries and all their children are removed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:270 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:271 msgid "An XPath expression to detect chapter titles. The default is to consider

or

tags that contain the words \"chapter\",\"book\",\"section\" or \"part\" as chapter titles as well as any tags that have class=\"chapter\". The expression used must evaluate to a list of elements. To disable chapter detection, use the expression \"/\". See the XPath Tutorial in the calibre User Manual for further help on using this feature." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:284 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:285 msgid "Specify how to mark detected chapters. A value of \"pagebreak\" will insert page breaks before chapters. A value of \"rule\" will insert a line before chapters. A value of \"none\" will disable chapter marking and a value of \"both\" will use both page breaks and lines to mark chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:294 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:295 msgid "Either the path to a CSS stylesheet or raw CSS. This CSS will be appended to the style rules from the source file, so it can be used to override those rules." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:303 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:304 msgid "An XPath expression. Page breaks are inserted before the specified elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:309 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:310 msgid "Some documents specify page margins by specifying a left and right margin on each individual paragraph. calibre will try to detect and remove these margins. Sometimes, this can cause the removal of margins that should not have been removed. In this case you can disable the removal." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:320 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:321 msgid "Set the top margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:325 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:326 msgid "Set the bottom margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:330 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:331 msgid "Set the left margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:335 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:336 msgid "Set the right margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:341 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:342 msgid "Change text justification. A value of \"left\" converts all justified text in the source to left aligned (i.e. unjustified) text. A value of \"justify\" converts all unjustified text to justified. A value of \"original\" (the default) does not change justification in the source file. Note that only some output formats support justification." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:351 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:352 msgid "Remove spacing between paragraphs. Also sets an indent on paragraphs of 1.5em. Spacing removal will not work if the source file does not use paragraphs (

or

tags)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:358 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:359 msgid "When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:365 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:366 msgid "Use the cover detected from the source file in preference to the specified cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:371 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:372 msgid "Insert a blank line between paragraphs. Will not work if the source file does not use paragraphs (

or

tags)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:378 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:379 msgid "Remove the first image from the input ebook. Useful if the first image in the source file is a cover and you are specifying an external cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:386 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:387 msgid "Insert the book metadata at the start of the book. This is useful if your ebook reader does not support displaying/searching metadata directly." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:394 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:395 msgid "Convert plain quotes, dashes and ellipsis to their typographically correct equivalents. For details, see http://daringfireball.net/projects/smartypants" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:403 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:404 msgid "Read metadata from the specified OPF file. Metadata read from this file will override any metadata in the source file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:410 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:411 msgid "Transliterate unicode characters to an ASCII representation. Use with care because this will replace unicode characters with ASCII. For instance it will replace \"%s\" with \"Mikhail Gorbachiov\". Also, note that in cases where there are multiple representations of a character (characters shared by Chinese and Japanese for instance) the representation based on the current calibre interface language will be used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:426 msgid "Preserve ligatures present in the input document. A ligature is a special rendering of a pair of characters like ff, fi, fl et cetera. Most readers do not have support for ligatures in their default fonts, so they are unlikely to render correctly. By default, calibre will turn a ligature into the corresponding pair of normal characters. This option will preserve them instead." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:437 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:438 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:38 msgid "Set the title." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:441 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:442 msgid "Set the authors. Multiple authors should be separated by ampersands." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:446 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:447 msgid "The version of the title to be used for sorting. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:450 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:451 msgid "String to be used when sorting by author. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:454 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:455 msgid "Set the cover to the specified file or URL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:458 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:459 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:54 msgid "Set the ebook description." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:462 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:463 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:56 msgid "Set the ebook publisher." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:466 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:467 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:60 msgid "Set the series this ebook belongs to." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:470 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:471 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:62 msgid "Set the index of the book in this series." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:474 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:475 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:64 msgid "Set the rating. Should be a number between 1 and 5." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:478 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:479 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:66 msgid "Set the ISBN of the book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:482 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:483 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:68 msgid "Set the tags for the book. Should be a comma separated list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:486 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:487 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:70 msgid "Set the book producer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:490 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:491 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:72 msgid "Set the language." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:494 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:495 msgid "Set the publication date." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:498 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:499 msgid "Set the book timestamp (used by the date column in calibre)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:502 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:503 msgid "Enable heuristic processing. This option must be set for any heuristic processing to take place." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:507 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:508 msgid "Detect unformatted chapter headings and sub headings. Change them to h2 and h3 tags. This setting will not create a TOC, but can be used in conjunction with structure detection to create one." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:514 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:515 msgid "Look for common words and patterns that denote italics and italicize them." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:519 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:520 msgid "Turn indentation created from multiple non-breaking space entities into CSS indents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:524 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:525 msgid "Scale used to determine the length at which a line should be unwrapped. Valid values are a decimal between 0 and 1. The default is 0.4, just below the median line length. If only a few lines in the document require unwrapping this value should be reduced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:532 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:533 msgid "Unwrap lines using punctuation and other formatting clues." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:536 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:537 msgid "Remove empty paragraphs from the document when they exist between every other paragraph" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:541 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:542 msgid "Left aligned scene break markers are center aligned. Replace soft scene breaks that use multiple blank lines withhorizontal rules." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:547 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:548 msgid "Replace scene breaks with the specified text. By default, the text from the input document is used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:552 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:553 msgid "Analyze hyphenated words throughout the document. The document itself is used as a dictionary to determine whether hyphens should be retained or removed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:558 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:559 msgid "Looks for occurrences of sequential

or

tags. The tags are renumbered to prevent splitting in the middle of chapter headings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:564 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:565 msgid "Search pattern (regular expression) to be replaced with sr1-replace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:569 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:570 msgid "Replacement to replace the text found with sr1-search." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:573 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:574 msgid "Search pattern (regular expression) to be replaced with sr2-replace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:578 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:579 msgid "Replacement to replace the text found with sr2-search." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:582 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:583 msgid "Search pattern (regular expression) to be replaced with sr3-replace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:587 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:588 msgid "Replacement to replace the text found with sr3-search." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:689 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:690 msgid "Could not find an ebook inside the archive" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:747 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:748 msgid "Values of series index and rating must be numbers. Ignoring" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:754 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:755 msgid "Failed to parse date/time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:909 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:913 msgid "Converting input to HTML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:936 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:940 msgid "Running transforms on ebook..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1032 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1036 msgid "Creating" msgstr "" @@ -1989,23 +1991,23 @@ msgstr "" msgid "Normally this input plugin re-arranges all the input files into a standard folder hierarchy. Only use this option if you know what you are doing as it can result in various nasty side effects in the rest of of the conversion pipeline." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:33 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:32 msgid "CSS file used for the output instead of the default file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:36 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:35 msgid "Template used for generation of the html index file instead of the default file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:39 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:38 msgid "Template used for the generation of the html contents of the book instead of the default file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:42 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/output.py:41 msgid "Extract the contents of the generated ZIP file to the specified directory. WARNING: The contents of the directory will be deleted." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/htmlz/output.py:29 +#: /home/kovid/work/calibre/src/calibre/ebooks/htmlz/output.py:28 msgid "" "Specify the handling of CSS. Default is class.\n" "class: Use CSS classes and have elements reference them.\n" @@ -2013,7 +2015,7 @@ msgid "" "tag: Turn as many CSS styles as possible into HTML tags." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/htmlz/output.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/htmlz/output.py:36 msgid "" "How to handle the CSS when using css-type = 'class'.\n" "Default is external.\n" @@ -2314,75 +2316,74 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:593 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:63 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:561 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:562 msgid "No" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:593 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:63 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:561 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:562 msgid "Yes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:677 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:679 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:130 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:75 #: /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:433 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1028 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:432 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1029 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:129 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:151 -#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_plugin.py:195 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_plugin.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:33 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:331 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:574 msgid "Title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:678 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:680 #: /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:438 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1029 -#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_plugin.py:195 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:437 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1030 +#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_plugin.py:207 msgid "Author(s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:679 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:681 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:63 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:148 msgid "Publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:680 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:682 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:49 msgid "Producer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:681 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:683 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:247 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:131 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:94 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:395 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1216 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1217 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:146 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:211 msgid "Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:683 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:685 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:170 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:31 #: /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:383 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1212 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:382 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1213 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:150 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:171 @@ -2390,39 +2391,39 @@ msgstr "" msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:685 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:687 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:168 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:30 #: /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:400 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1221 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1222 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:152 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:114 msgid "Series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:686 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:688 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:153 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:1204 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:690 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1205 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:690 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:692 #: /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:128 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:129 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:271 msgid "Published" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:692 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:694 msgid "Rights" msgstr "" @@ -2755,7 +2756,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1356 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1491 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:33 msgid "Cover" msgstr "" @@ -2783,7 +2784,7 @@ msgstr "" msgid "Amazon timed out. Try again later." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:155 msgid "Metadata source" msgstr "" @@ -2804,6 +2805,26 @@ msgstr "" msgid "Downloads covers from The Open Library" msgstr "" +#: +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/overdrive.py:33 +msgid "Downloads metadata from Overdrive's Content Reserve" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/overdrive.py:45 +msgid "Download all metadata (slow)" +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/overdrive.py:46 +msgid "Enable this option to gather all metadata available from Overdrive." +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/overdrive.py:49 +msgid "Additional metadata can be taken from Overdrive's book detail page. This includes a limited set of tags used by libraries, comments, language, and the ebook ISBN. Collecting this data is disabled by default due to the extra time required. Check the download all metadata option below to enable downloading this data." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/output.py:22 msgid "Modify images to meet Palm device size limitations." msgstr "" @@ -2837,7 +2858,7 @@ msgstr "" msgid "All articles" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:270 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:272 msgid "This is an Amazon Topaz book. It cannot be processed." msgstr "" @@ -2914,8 +2935,8 @@ 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:734 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:737 msgid "Book %s of %s" msgstr "" @@ -2924,7 +2945,7 @@ msgid "HTML TOC generation options." msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:169 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:69 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:68 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:149 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:759 @@ -2964,9 +2985,9 @@ msgid "Specify the character encoding of the output document. The default is cp1 msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/output.py:32 -#: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:36 #: /home/kovid/work/calibre/src/calibre/ebooks/rb/output.py:21 -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:41 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:40 msgid "Add Table of Contents to beginning of the book." msgstr "" @@ -3179,11 +3200,11 @@ msgstr "" msgid "Could not find pdftohtml, check it is in your PATH" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:33 +#: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:32 msgid "Specify the character encoding of the output document. The default is cp1252." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:39 msgid "Do not reduce the size or bit depth of images. Images have their size and depth reduced by default to accommodate applications that can not convert images on their own such as Dropbook." msgstr "" @@ -3204,12 +3225,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/snb/output.py:25 #: /home/kovid/work/calibre/src/calibre/ebooks/tcr/output.py:23 -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:37 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:36 msgid "Specify the character encoding of the output document. The default is utf-8." msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/snb/output.py:29 -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:44 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:43 msgid "The maximum number of characters per line. This splits on the first space before the specified value. If no space is found the line will be broken at the space after and will exceed the specified value. Also, there is a minimum of 25 characters. Use 0 to disable line splitting." msgstr "" @@ -3276,15 +3297,15 @@ msgstr "" msgid "Do not insert a Table of Contents into the output text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:31 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:30 msgid "Type of newline to use. Options are %s. Default is 'system'. Use 'old_mac' for compatibility with Mac OS 9 and earlier. For Mac OS X use 'unix'. 'system' will default to the newline type used by this OS." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:50 msgid "Force splitting on the max-line-length value when no space is present. Also allows max-line-length to be below the minimum" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:56 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:55 msgid "" "Formatting used within the document.\n" "* plain: Produce plain text.\n" @@ -3292,104 +3313,104 @@ msgid "" "* textile: Produce Textile formatted text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:62 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:61 msgid "Do not remove links 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/ebooks/txt/output.py:67 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:66 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:97 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:95 msgid "Send file to storage card instead of main memory by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:97 msgid "Confirm before deleting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:99 msgid "Main window geometry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:101 msgid "Notify when a new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:103 msgid "Use Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:105 msgid "Sort tags list by name, popularity, or rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:107 msgid "Match tags by any or all." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:109 msgid "Number of covers to show in the cover browsing mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:111 msgid "Defaults for conversion to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:113 msgid "Options for the LRF ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:116 msgid "Formats that are viewed using the internal viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:118 msgid "Columns to be displayed in the book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:119 msgid "Automatically launch content server on application startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:120 msgid "Oldest news kept in database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:121 msgid "Show system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:123 msgid "Upload downloaded news to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:125 msgid "Delete books from library after uploading to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127 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:131 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:129 msgid "Disable notifications from the system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:131 msgid "Default action to perform when send to device button is clicked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 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:141 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:139 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:159 -msgid "Maximum number of waiting worker processes" +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:157 +msgid "Maximum number of simultaneous conversion/news download jobs. This number is twice the actual value for historical reasons." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:161 @@ -3425,13 +3446,13 @@ msgstr "" msgid "tag browser categories not to display" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:449 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:451 msgid "Choose Files" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:30 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:308 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:545 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:553 msgid "Books" msgstr "" @@ -3603,58 +3624,66 @@ msgid "Add books to your calibre library from the connected device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:561 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:543 msgid "Fetch annotations (experimental)" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:56 +msgid "Not supported" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:241 +msgid "Fetching annotations is not supported for this device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:245 msgid "Use library only" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:62 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:246 msgid "User annotations generated from main library only" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:69 #: /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 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:88 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:154 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:250 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:287 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:286 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:92 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:66 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:70 msgid "No books selected to fetch annotations from" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:95 msgid "Merging user annotations into database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:123 msgid "%s
Last Page Read: %d (%d%%)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:129 msgid "%s
Last Page Read: Location %d (%d%%)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:148 msgid "Location %d • %s
%s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:157 msgid "Page %d • %s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:162 msgid "Location %d • %s
" msgstr "" @@ -3751,6 +3780,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:229 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:285 msgid "Already exists" msgstr "" @@ -3805,8 +3835,8 @@ msgstr "" #: /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:287 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:345 msgid "Success" msgstr "" @@ -3878,7 +3908,7 @@ msgid "Bulk convert" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/convert.py:86 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:561 msgid "Cannot convert" msgstr "" @@ -4000,14 +4030,14 @@ msgid "Main memory" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:176 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:486 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:468 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:477 msgid "Storage Card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:177 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:488 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:497 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:470 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:479 msgid "Storage Card B" msgstr "" @@ -4104,31 +4134,31 @@ msgstr "" msgid "Manage the collections on this device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:25 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:26 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:25 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:26 msgid "Edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:29 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:30 msgid "Merge book records" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:30 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:31 msgid "M" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:32 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:33 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:36 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:47 msgid "Download metadata and covers" msgstr "" @@ -4140,79 +4170,91 @@ msgstr "" msgid "Download only covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:52 msgid "Download only social metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:58 msgid "Merge into first selected book - delete others" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:62 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:61 msgid "Merge into first selected book - keep others" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:66 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:65 msgid "Merge only formats into first selected book - delete others" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:87 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:105 msgid "Cannot download metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:96 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:187 msgid "Failed to download metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:125 msgid "social metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:127 msgid "covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:127 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:227 msgid "metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:128 msgid "Downloading {0} for {1} book(s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:153 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:248 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:286 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:288 msgid "Cannot merge books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:290 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:289 msgid "At least two books must be selected for merging" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:292 msgid "You are about to merge more than 5 books. Are you sure you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:300 msgid "Book formats and metadata from the selected books will be added to the first selected book (%s). ISBN will not be merged.

The second and subsequently selected books will not be deleted or changed.

Please confirm you want to proceed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:312 msgid "Book formats from the selected books will be merged into the first selected book (%s). Metadata in the first selected book will not be changed.Author, Title, ISBN and all other metadata will not be merged.

After merger the second and subsequently selected books, with any metadata they have will be deleted.

All book formats of the first selected book will be kept and any duplicate formats in the second and subsequently selected books will be permanently deleted from your calibre library.

Are you sure you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:328 msgid "Book formats and metadata from the selected books will be merged into the first selected book (%s). ISBN will not be merged.

After merger the second and subsequently selected books will be deleted.

All book formats of the first selected book will be kept and any duplicate formats in the second and subsequently selected books will be permanently deleted from your calibre library.

Are you sure you want to proceed?" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:471 +msgid "Applying changed metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:538 +msgid "Some failures" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:539 +msgid "Failed to apply updated metadata for some books in your library. Click \"Show Details\" to see details." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/actions/fetch_news.py:19 msgid "F" msgstr "" @@ -4424,19 +4466,40 @@ msgstr "" msgid "Books with the same tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:19 msgid "Get books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:27 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:92 #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:276 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:653 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:280 msgid "Search" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:46 +msgid "Calibre helps you find the ebooks you want by searching the websites of various commercial and public domain book sources for you." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:50 +msgid "Using the integrated search you can easily find which store has the book you are looking for, at the best price. You also get DRM status and other useful information." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:54 +msgid "All transactions (paid or otherwise) are handled between you and the book seller. Calibre is not part of this process and any issues related to a purchase should be directed to the website you are buying from. Be sure to double check that any books you get will work with your e-book reader, especially if the book you are buying has
DRM." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:64 +msgid "Show this message again" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:65 +msgid "About Get Books" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/actions/tweak_epub.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tweak_epub_ui.py:54 msgid "Tweak ePub" @@ -4544,7 +4607,7 @@ msgid "The specified directory could not be processed." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add.py:274 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:841 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:843 msgid "No books" msgstr "" @@ -4727,23 +4790,24 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:63 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:487 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:145 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:498 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:147 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:160 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:148 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:162 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:390 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1202 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1203 msgid "Path" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:148 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:149 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:150 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:153 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:388 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:148 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:27 @@ -4752,8 +4816,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:1032 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1205 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1033 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1206 msgid "Collections" msgstr "" @@ -4763,15 +4827,16 @@ msgid "Click to open" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:382 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:388 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:394 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1211 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1215 +#: /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:393 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1212 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1216 #: /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 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:351 msgid "None" msgstr "" @@ -4786,10 +4851,15 @@ msgstr "" msgid "Copy Cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:486 +#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:497 msgid "Double-click to open Book Details window" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:499 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:113 +msgid "Cover size: %dx%d" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_bibtex.py:16 msgid "BibTeX Options" msgstr "" @@ -4874,8 +4944,8 @@ msgstr "" #: /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:100 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard_ui.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template_ui.py:46 @@ -5764,39 +5834,39 @@ msgid "Set the metadata. The output file will contain as much of this metadata a 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:677 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:680 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:685 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:688 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:686 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:689 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:694 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:697 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:695 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:698 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:705 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:708 msgid " is not a valid picture" msgstr "" @@ -5857,7 +5927,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:537 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:430 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:859 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:862 msgid "Tags categorize the book. This is particularly useful while searching.

They can be any words or phrases, separated by commas." msgstr "" @@ -5865,7 +5935,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:307 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:309 msgid "&Series:" msgstr "" @@ -5875,7 +5945,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:306 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:308 msgid "List of known series. You can add new series." msgstr "" @@ -6461,11 +6531,11 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:149 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:301 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:565 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:606 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:629 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:680 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:566 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:630 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:681 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:306 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:311 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:505 @@ -6475,151 +6545,151 @@ 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:1042 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1051 msgid "Undefined" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:126 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:637 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:638 msgid "star(s)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:638 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:639 msgid "Unrated" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:170 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:667 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:668 msgid "Set '%s' to today" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:172 -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:669 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:670 msgid "Clear '%s'" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:298 msgid " index:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:367 msgid "The enumeration \"{0}\" contains an invalid value that will be set to the default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:520 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:521 msgid "Apply changes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:714 msgid "Remove series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:716 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:717 msgid "Automatically number books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:720 msgid "Force numbers to start with " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:790 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:791 msgid "The enumeration \"{0}\" contains invalid values that will not appear in the list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:834 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:835 msgid "Remove all tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:854 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:855 msgid "tags to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:861 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:862 msgid "tags to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:45 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:43 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:144 msgid "No details available." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:168 msgid "Device no longer connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:310 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:291 msgid "Get device information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:305 msgid "Get list of books on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:315 msgid "Get annotations from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:327 msgid "Send metadata to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:332 msgid "Send collections to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:386 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:368 msgid "Upload %d books to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:383 msgid "Delete books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:400 msgid "Download books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:428 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:410 msgid "View book on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:469 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:451 msgid "Set default send to device action" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:457 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:477 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:459 msgid "Send to storage card A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:461 msgid "Send to storage card B" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:484 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:493 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:466 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:475 msgid "Main Memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:505 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:487 msgid "Send specific format to" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:488 msgid "Send and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:549 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:531 msgid "Eject device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:611 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:41 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:305 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:309 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:54 msgid "Error" msgstr "" @@ -6629,7 +6699,7 @@ msgid "Error communicating with device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:631 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1166 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1168 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:221 msgid "No suitable formats" msgstr "" @@ -6654,67 +6724,67 @@ msgstr "" msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:842 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:844 msgid "selected to send" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:861 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:863 msgid "%i of %i Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:864 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:866 msgid "0 of %i Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:865 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:867 msgid "Choose format to send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:873 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:875 msgid "No device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:874 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:876 msgid "Cannot send: No device is connected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:877 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:881 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:879 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:883 msgid "No card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:878 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:882 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:880 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:884 msgid "Cannot send: Device has no storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:943 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1026 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1160 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:945 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1028 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1162 msgid "Auto convert the following books before uploading to the device?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:972 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:974 msgid "Sending catalogs to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1073 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1075 msgid "Sending news to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1127 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1129 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1167 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1169 msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1239 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1241 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1240 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1242 msgid "

Cannot upload books to device there is no more free space available " msgstr "" @@ -6731,7 +6801,7 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget.py:137 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:402 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:255 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:274 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:61 msgid "Invalid template" msgstr "" @@ -6739,7 +6809,7 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget.py:138 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:403 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:275 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:62 msgid "The template %s is invalid:" msgstr "" @@ -6978,8 +7048,8 @@ 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:1201 -#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_plugin.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1202 +#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_plugin.py:207 msgid "Format" msgstr "" @@ -7170,8 +7240,8 @@ 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:1030 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1031 #: /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:73 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:241 @@ -7539,7 +7609,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:817 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:820 msgid "&Rating:" msgstr "" @@ -7547,7 +7617,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:818 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:821 msgid "Rating of this book. 0-5 stars" msgstr "" @@ -7621,7 +7691,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:1026 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1035 msgid "&Date:" msgstr "" @@ -7694,14 +7764,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:460 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:613 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:464 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:617 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:467 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:471 msgid "&Custom metadata" msgstr "" @@ -7855,114 +7925,114 @@ msgstr "" msgid "&Search and replace" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:97 msgid "Last modified: %s" 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:278 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:288 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:279 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:282 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:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:289 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:777 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:780 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:704 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:707 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:728 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:731 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:729 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:732 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 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:903 msgid "Downloading cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:262 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:267 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:273 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:263 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:274 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:278 msgid "Could not fetch cover.
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:263 msgid "The download timed out." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:267 msgid "Could not find cover for this book. Try specifying the ISBN first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:279 msgid "For the error message from each cover source, click Show details below." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:287 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:286 msgid "Bad cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:287 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:543 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:306 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:551 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:575 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:583 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:576 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:584 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:606 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:614 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:615 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:618 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:626 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:619 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:627 msgid "Could not read metadata from %s format" msgstr "" @@ -7996,14 +8066,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:415 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:424 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:50 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:820 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:821 #: /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 @@ -8012,22 +8082,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:965 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:974 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:968 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:977 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:894 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:897 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:895 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:898 msgid "You have changed the tags. In order to use the tags editor, you must either discard or apply these changes. Apply changes?" msgstr "" @@ -8056,12 +8126,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:362 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:366 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:363 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:367 msgid "Could not open %s. Is it being used by another program?" msgstr "" @@ -8126,7 +8196,7 @@ 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:1077 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1086 msgid "Publishe&d:" msgstr "" @@ -8135,7 +8205,7 @@ 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:638 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:646 msgid "&Browse" msgstr "" @@ -8144,7 +8214,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:640 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:648 msgid "T&rim" msgstr "" @@ -8153,12 +8223,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:642 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:650 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:648 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:656 msgid "Download co&ver" msgstr "" @@ -8167,7 +8237,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:649 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:657 msgid "&Generate cover" msgstr "" @@ -8184,7 +8254,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:461 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:463 msgid "Set the cover for the book from the selected format" msgstr "" @@ -8193,7 +8263,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:678 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:683 msgid "&Comments" msgstr "" @@ -8609,7 +8679,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:858 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:861 msgid "Ta&gs:" msgstr "" @@ -9073,8 +9143,9 @@ 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:458 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:712 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:196 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:459 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:713 msgid "Download failed" msgstr "" @@ -9399,43 +9470,39 @@ msgstr "" msgid "available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:159 -msgid "Books display will be restricted to those matching the selected saved search" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:169 msgid "Shift+Ctrl+F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:172 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:177 msgid "

Search the list of books by title, author, publisher, tags, comments, etc.

Words separated by spaces are ANDed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:183 msgid "&Go!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:191 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:189 msgid "Do Quick Search (you can also press the Enter key)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:197 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:195 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:211 msgid "Copy current search text (instead of search name)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:217 msgid "Save current search under the name shown in the box" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:254 +#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:252 msgid "Donate" msgstr "" @@ -9447,48 +9514,48 @@ msgstr "" msgid "Edit template" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:64 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:251 msgid "On Device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:66 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:311 msgid "Size (MB)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:400 msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:771 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1321 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:772 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1322 #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:797 msgid "The lookup/search name is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:777 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1323 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:778 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1324 msgid "This book's UUID is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1027 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1028 msgid "In Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1031 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1032 msgid "Size" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1221 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1222 msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1301 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1302 msgid "Marked for deletion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1304 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1305 msgid "Double click to edit me

" msgstr "" @@ -9561,7 +9628,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:467 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:468 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:503 msgid "No matches found" msgstr "" @@ -9612,119 +9679,119 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:30 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:33 msgid "Use the library located at the specified path." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:32 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:35 msgid "Start minimized to system tray." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:37 msgid "Log debugging information to console" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:36 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:39 msgid "Do not check for updates" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:41 msgid "Ignore custom plugins, useful if you installed a plugin that is preventing calibre from starting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:64 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:678 msgid "Calibre Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:91 msgid "Choose a location for your calibre e-book library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:100 msgid "Failed to create library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:101 msgid "Failed to create calibre library at: %r." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:102 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:190 msgid "Choose a location for your new calibre e-book library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:159 msgid "Initializing user interface..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:184 msgid "Repairing failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:185 msgid "The database repair failed. Starting with a new empty library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:197 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:231 msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:198 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:200 msgid "Bad database location %r. calibre will now quit." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:212 msgid "Corrupted database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:213 msgid "Your calibre database appears to be corrupted. Do you want calibre to try and repair it automatically? If you say No, a new empty calibre library will be created." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:219 msgid "Repairing database. This can take a very long time for a large collection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:232 msgid "Bad database location %r. Will start with a new, empty calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:242 msgid "Starting %s: Loading books..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:320 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:322 msgid "If you are sure it is not running" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:325 msgid "may be running in the system tray, in the" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:327 msgid "upper right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:329 msgid "lower right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:332 msgid "try rebooting your computer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:332 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:348 msgid "try deleting the file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:337 msgid "Cannot Start " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:338 msgid "%s is already running." msgstr "" @@ -9752,49 +9819,61 @@ msgstr "" msgid "Author s&ort:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:365 msgid "&Number:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:444 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:446 msgid "" "Last modified: %s\n" "\n" "Double click to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:747 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:471 +msgid "Set metadata for the book from the selected format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:478 +msgid "Add a format to this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:485 +msgid "Remove the selected format from this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:750 msgid "Invalid cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:748 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:751 msgid "Could not change cover as the image is invalid." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:775 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:778 msgid "This book has no cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:825 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:828 msgid "stars" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:918 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:921 msgid "I&ds:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:919 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:922 msgid "" "Edit the identifiers for this book. For example: \n" "\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:975 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:984 msgid "&Publisher:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1045 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1054 msgid "Clear date" msgstr "" @@ -9836,106 +9915,110 @@ msgstr "" msgid "Details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:38 msgid "Schedule download?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:49 msgid "The download of metadata for the %d selected book(s) will run in the background. Proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:51 msgid "You can monitor the progress of the download by clicking the rotating spinner in the bottom right corner." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:40 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:54 msgid "When the download completes you will be asked for confirmation before calibre applies the downloaded metadata." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:43 -msgid "Configure download" +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:65 +msgid "Download only &metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:69 +msgid "Download only &covers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:73 +msgid "&Configure download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:77 +msgid "Download &both" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:103 msgid "Download metadata for %d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:106 msgid "Metadata download started" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:74 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:766 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:767 #: /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/bulk_download2.py:81 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:773 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:774 msgid "Download log" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:103 -msgid "Applying downloaded metadata to your library" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:172 -msgid "Some failures" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:173 -msgid "Failed to apply updated metadata for some books in your library. Click \"Show Details\" to see details." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:212 msgid "Some books changed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:173 msgid "The metadata for some books in your library has changed since you started the download. If you proceed, some of those changes may be overwritten. Click \"Show details\" to see the list of changed books. Do you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:183 msgid "Metadata download completed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:228 -msgid "Could not download metadata and/or covers for %d of the books. Click \"Show details\" to see which books." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:189 msgid "(Failed metadata)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:191 msgid "(Failed cover)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:197 +msgid "Failed to download metadata or covers for any of the %d book(s)." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:202 +msgid "Could not download metadata and/or covers for %d of the books. Click \"Show details\" to see which books." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:204 msgid "Finished downloading metadata for %d book(s). Proceed with updating the metadata in your library?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:206 msgid "Download complete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:243 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:827 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:918 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:828 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:919 msgid "View log" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:292 msgid "Downloaded %d of %d" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/config.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:109 msgid "Downloaded metadata fields" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:240 msgid "Edit Metadata" msgstr "" @@ -9947,48 +10030,48 @@ msgstr "" msgid "Set author from author sort" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:171 msgid "&Download metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:181 msgid "Change how calibre downloads metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:508 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:697 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:702 msgid "Change cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:557 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:561 msgid "Co&mments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:596 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:600 msgid "&Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:601 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:605 msgid "&Cover and formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:620 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:624 msgid "Configure metadata downloading" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:666 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:671 msgid "C&ustom metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:129 msgid "Has cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:129 msgid "Has summary" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:186 msgid "" "The has cover indication is not fully\n" "reliable. Sometimes results marked as not\n" @@ -9996,55 +10079,55 @@ msgid "" "cover stage, and vice versa." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:254 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:255 msgid "See at" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:390 msgid "calibre is downloading metadata from: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:412 msgid "Please wait" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:440 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:441 msgid "Query: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:459 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:460 msgid "Failed to download metadata. Click Show Details to see details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:468 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:469 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:534 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:535 msgid "Current cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:537 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:538 msgid "Searching..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:683 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:684 msgid "Downloading covers for %s, please wait..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:714 msgid "Failed to download any covers, click \"Show details\" for details." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:720 msgid "Could not find any covers for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:721 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:722 msgid "Found %d covers of %s. Pick the one you like best." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:809 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:810 msgid "Downloading metadata..." msgstr "" @@ -10862,130 +10945,146 @@ msgid "Configure %s
%s" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:278 msgid "No source selected" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:279 msgid "No source selected, cannot configure." msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:104 msgid "Metadata sources" 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:105 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:104 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:107 msgid "Sources with a red X next to their names must be configured before they will be used. " msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:108 msgid "Configure selected source" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:110 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:108 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:111 msgid "Convert all downloaded comments to plain &text" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:112 msgid "Swap author names from FN LN to LN, FN" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:113 msgid "Max. number of &tags to download:" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:114 msgid "Max. &time to wait after first match is found:" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:112 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:117 #: /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:113 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:116 msgid "Max. time to wait after first &cover is found:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:42 +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:118 +msgid "" +"

Different metadata sources have different sets of tags for the same book. If this option is checked, then calibre will use the smaller tag sets. These tend to be more like genres, while the larger tag sets tend to describe the books content.\n" +"

Note that this option will only make a practical difference if one of the metadata sources has a genre like tag set for the book you are searching for. Most often, they all have large tag sets." +msgstr "" + +#: +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:120 +msgid "Prefer &fewer tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:50 msgid "Failed to install command line tools." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:45 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:53 msgid "Command line tools installed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:54 msgid "Command line tools installed in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:47 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:55 msgid "If you move calibre.app, you have to re-install the command line tools." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:61 -msgid "&Maximum number of waiting worker processes (needs restart):" +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:59 +msgid "Max. simultaneous conversion/news download jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:62 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:60 msgid "Limit the max. simultaneous jobs to the available CPU &cores" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:61 msgid "Debug &device detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:62 msgid "Open calibre &configuration directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:63 msgid "&Install command line tools" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:31 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:34 msgid "Open Editor" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:68 msgid "Device currently connected: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:71 msgid "Device currently connected: None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:238 msgid "That format and device already has a plugboard or conflicts with another plugboard." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:247 +msgid "The {0} device does not support the {1} format." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:280 msgid "Invalid destination" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:281 msgid "The destination field cannot be blank" msgstr "" @@ -11055,6 +11154,7 @@ msgid "Search for plugin" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:198 msgid "No matches" msgstr "" @@ -11070,55 +11170,55 @@ msgstr "" msgid "Installing plugins is a security risk. Plugins can contain a virus/malware. Only install it if you got it from a trusted source. Are you sure you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:292 msgid "Plugin {0} successfully installed under {1} plugins. You may have to restart calibre for the plugin to take effect." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:300 msgid "No valid plugin path" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:301 msgid "%s is not a valid plugin path" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:306 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:310 msgid "Select an actual plugin under %s to customize" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:316 msgid "Plugin cannot be disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:317 msgid "The plugin: %s cannot be disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:327 msgid "Plugin not customizable" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:328 msgid "Plugin: %s does not need customization" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:334 msgid "Must restart" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:331 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:335 msgid "You must restart calibre before you can configure the %s plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:340 msgid "Plugin {0} successfully removed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:348 msgid "Cannot remove builtin plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:349 msgid " cannot be removed. It is a builtin plugin. Try disabling it instead." msgstr "" @@ -11348,7 +11448,7 @@ msgid "Here you can control how calibre will save your books when you click the msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:70 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:425 msgid "Failed to start content server" msgstr "" @@ -11714,8 +11814,6 @@ msgid "Choose saved search or enter name for new saved search" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:439 -#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:34 -#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:42 msgid "*Current search" msgstr "" @@ -11724,15 +11822,23 @@ msgid "Restrict to" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:19 -#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:79 +#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:92 msgid "(all books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:21 +msgid "Books display will be restricted to those matching a selected saved search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:53 +msgid " or the search " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:87 msgid "({0} of {1})" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:94 msgid "({0} of all)" msgstr "" @@ -11801,6 +11907,10 @@ msgstr "" msgid "Open store in external web browswer" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/store/ebooks_com_plugin.py:95 +msgid "Not Available" +msgstr "" + #: #: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_store_dialog_ui.py:62 msgid "Search:" @@ -11813,36 +11923,70 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_store_dialog_ui.py:65 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:114 #: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:63 msgid "Close" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:33 +msgid "DRM" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:33 msgid "Price" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:104 -msgid "calibre Store Search" +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:179 +msgid "Detected price as: %s. Check with the store before making a purchase to verify this price is correct. This price often does not include promotions the store may be running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:182 +msgid "This book as been detected as having DRM restrictions. This book may not work with your reader and you will have limitations placed upon you as to what you can do with this book. Check with the store before making any purchases to ensure you can actually read this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:184 +msgid "This book has been detected as being DRM Free. You should be able to use this book on any device provided it is in a format calibre supports for conversion. However, before making a purchase double check the DRM status with the store. The store may not be disclosing the use of DRM." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:186 +msgid "The DRM status of this book could not be determined. There is a very high likelihood that this book is actually DRM restricted." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:198 +msgid "Couldn't find any books matching your query." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:107 +msgid "Get Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:108 msgid "Query:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:110 msgid "Stores" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:111 msgid "All" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:112 msgid "Invert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/web_control.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/store/web_control.py:73 +msgid "This ebook is a DRMed EPUB file. You will be prompted to save this file to your computer. Once it is saved, open it with Adobe Digital Editions (ADE).

ADE, in turn will download the actual ebook, which will be a .epub file. You can add this book to calibre using \"Add Books\" and selecting the file from the ADE library folder." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/web_control.py:86 msgid "File is not a supported ebook type. Save to disk?" msgstr "" @@ -11953,7 +12097,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:1157 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:418 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:417 msgid "Searches" msgstr "" @@ -12145,58 +12289,58 @@ 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:189 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:196 msgid "&Donate to support calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:232 msgid "&Restore" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:237 msgid "&Eject connected device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:282 msgid "Calibre Quick Start Guide" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:348 msgid "Debug mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:349 msgid "You have started calibre in debug mode. After you quit calibre, the debug log will be available in the file: %s

The log will be displayed automatically." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:549 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:572 msgid "Recipe Disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:581 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:588 msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:614 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:621 msgid "There are active jobs. Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:617 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:624 msgid "" " is communicating with the device!
\n" " Quitting may cause corruption on the device.
\n" " Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:621 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:628 msgid "Active jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:696 msgid "will keep running in the system tray. To close it, choose Quit in the context menu of the system tray." msgstr "" @@ -12997,7 +13141,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/library/caches.py:161 #: /home/kovid/work/calibre/src/calibre/library/caches.py:574 #: /home/kovid/work/calibre/src/calibre/library/caches.py:584 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:192 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:207 msgid "yes" msgstr "" @@ -13010,7 +13154,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/library/caches.py:163 #: /home/kovid/work/calibre/src/calibre/library/caches.py:571 #: /home/kovid/work/calibre/src/calibre/library/caches.py:581 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:192 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:207 msgid "no" msgstr "" @@ -13039,7 +13183,7 @@ msgstr "" msgid "empty" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:52 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:51 msgid "" "The fields to output when cataloging books in the database. Should be a comma-separated list of fields.\n" "Available fields: %s,\n" @@ -13049,7 +13193,7 @@ msgid "" "Applies to: CSV, XML output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:65 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:64 msgid "" "Output field to sort on.\n" "Available fields: author_sort, id, rating, size, timestamp, title.\n" @@ -13057,7 +13201,7 @@ msgid "" "Applies to: CSV, XML output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:232 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:231 msgid "" "The fields to output when cataloging books in the database. Should be a comma-separated list of fields.\n" "Available fields: %s.\n" @@ -13067,7 +13211,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:245 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:244 msgid "" "Output field to sort on.\n" "Available fields: author_sort, id, rating, size, timestamp, title.\n" @@ -13075,7 +13219,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:254 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:253 msgid "" "Create a citation for BibTeX entries.\n" "Boolean value: True, False\n" @@ -13083,7 +13227,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:263 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:262 msgid "" "Create a file entry if formats is selected for BibTeX entries.\n" "Boolean value: True, False\n" @@ -13091,7 +13235,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:272 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:271 msgid "" "The template for citation creation from database fields.\n" "Should be a template with {} enclosed fields.\n" @@ -13100,7 +13244,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:282 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:281 msgid "" "BibTeX file encoding output.\n" "Available types: utf8, cp1252, ascii.\n" @@ -13108,7 +13252,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:291 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:290 msgid "" "BibTeX file encoding flag.\n" "Available types: strict, replace, ignore, backslashreplace.\n" @@ -13116,7 +13260,7 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:300 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:299 msgid "" "Entry type for BibTeX catalog.\n" "Available types: book, misc, mixed.\n" @@ -13124,90 +13268,90 @@ msgid "" "Applies to: BIBTEX output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:607 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:606 msgid "" "Title of generated catalog used as title in metadata.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:614 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:613 msgid "" "Save the output from different stages of the conversion pipeline to the specified directory. Useful if you are unsure at which stage of the conversion process a bug is occurring.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:624 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:623 msgid "" "field:pattern specifying custom field/contents indicating book should be excluded.\n" "Default: '%default'\n" "Applies to ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:631 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:630 msgid "" "Regex describing tags to exclude as genres.\n" "Default: '%default' excludes bracketed tags, e.g. '[]'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:637 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:636 msgid "" "Comma-separated list of tag words indicating book should be excluded from output.For example: 'skip' will match 'skip this book' and 'Skip will like this'.Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:645 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:644 msgid "" "Include 'Authors' section in catalog.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:652 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:651 msgid "" "Include 'Descriptions' section in catalog.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:659 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:658 msgid "" "Include 'Genres' section in catalog.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:666 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:665 msgid "" "Include 'Titles' section in catalog.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:673 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:672 msgid "" "Include 'Series' section in catalog.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:680 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:679 msgid "" "Include 'Recently Added' section in catalog.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:687 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:686 msgid "" "Custom field containing note text to insert in Description header.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:694 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:693 msgid "" ":[before|after]:[True|False] specifying:\n" " Custom field containing notes to merge with Comments\n" @@ -13217,21 +13361,21 @@ msgid "" "Applies to ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:704 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:703 msgid "" "Specifies the output profile. In some cases, an output profile is required to optimize the catalog for the device. For example, 'kindle' or 'kindle_dx' creates a structured Table of Contents with Sections and Articles.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:711 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:710 msgid "" "field:pattern indicating book has been read.\n" "Default: '%default'\n" "Applies to ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:717 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:716 msgid "" "Size hint (in inches) for book covers in catalog.\n" "Range: 1.0 - 2.0\n" @@ -13239,23 +13383,23 @@ msgid "" "Applies to ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:725 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:724 msgid "" "Tag indicating book to be displayed as wishlist item.\n" "Default: '%default'\n" "Applies to: ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1408 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1407 msgid "" "No enabled genres found to catalog.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1412 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1411 msgid "No books available to catalog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1487 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1486 msgid "" "Inconsistent Author Sort values for\n" "Author '{0}':\n" @@ -13265,24 +13409,24 @@ msgid "" "Select all books by '{0}', apply correct Author Sort value in Edit Metadata dialog, then rebuild the catalog.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1504 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1503 msgid "" "Warning: inconsistent Author Sort values for\n" "Author '{0}':\n" "'{1}' <> '{2}'\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1700 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1699 msgid "" "No books found to catalog.\n" "Check 'Excluded books' criteria in E-book options.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1702 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:1701 msgid "No books available to include in catalog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalog.py:5030 +#: /home/kovid/work/calibre/src/calibre/library/catalog.py:5031 msgid "" "\n" "*** Adding 'By Authors' Section required for MOBI output ***" @@ -13328,65 +13472,65 @@ msgstr "" msgid "Folders raising exception" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:44 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:43 msgid "Path to the calibre library. Default is to use the path stored in the settings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:123 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:124 msgid "" "%prog list [options]\n" "\n" "List the books available in the calibre database.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:131 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:132 msgid "" "The fields to display when listing books in the database. Should be a comma separated list of fields.\n" "Available fields: %s\n" "Default: %%default. The special field \"all\" can be used to select all fields. Only has effect in the text output format." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:138 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:139 msgid "" "The field by which to sort the results.\n" "Available fields: %s\n" "Default: %%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:140 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:141 msgid "Sort results in ascending order" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:142 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:143 msgid "Filter the results by the search query. For the format of the search query, please see the search related documentation in the User Manual. Default is to do no filtering." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:144 -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1043 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:145 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1044 msgid "The maximum width of a single line in the output. Defaults to detecting screen size." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:145 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:146 msgid "The string used to separate fields. Default is a space." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:146 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:147 msgid "The prefix for all file paths. Default is the absolute path to the library folder." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:168 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:169 msgid "Invalid fields. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:175 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:176 msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:247 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:248 msgid "The following books were not added as they already exist in the database (see --duplicates option):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:271 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:272 msgid "" "%prog add [options] file1 file2 file3 ...\n" "\n" @@ -13394,65 +13538,65 @@ msgid "" "the directory related options below.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:280 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:281 msgid "Assume that each directory has only a single logical book and that all files in it are different e-book formats of that book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:283 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:284 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:285 msgid "Add books to database even if they already exist. Comparison is done based on book titles." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:286 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:287 msgid "Add an empty book (a book with no formats)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:288 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:289 msgid "Set the title of the added empty book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:291 msgid "Set the authors of the added empty book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:292 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:293 msgid "Set the ISBN of the added empty book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:318 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:319 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:335 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:336 msgid "" "%prog remove ids\n" "\n" "Remove the books identified by ids from the database. ids should be a comma separated list of id numbers (you can get id numbers by using the list command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:350 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:351 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:369 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:370 msgid "" "%prog add_format [options] id ebook_file\n" "\n" "Add the ebook in ebook_file to the available formats for the logical book identified by id. You can get id by using the list command. If the format already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:389 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:390 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:397 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:398 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -13460,11 +13604,11 @@ msgid "" "Remove the format fmt from the logical book identified by id. You can get id by using the list command. fmt should be a file extension like LRF or TXT or EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:414 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:415 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:432 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:433 msgid "" "\n" "%prog show_metadata [options] id\n" @@ -13473,15 +13617,15 @@ msgid "" "id is an id number from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:440 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:441 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:449 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:450 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:464 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:465 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -13492,11 +13636,11 @@ msgid "" "show_metadata command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:480 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:481 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:500 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:501 msgid "" "%prog export [options] ids\n" "\n" @@ -13505,27 +13649,27 @@ msgid "" "an opf file). You can get id numbers from the list command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:508 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:509 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:510 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:511 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:512 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:513 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:519 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:520 msgid "Specifying this switch will turn this behavior off." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:542 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:543 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:555 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:556 msgid "" "%prog add_custom_column [options] label name datatype\n" "\n" @@ -13534,19 +13678,19 @@ msgid "" "datatype is one of: {0}\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:564 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:565 msgid "This column stores tag like data (i.e. multiple comma separated values). Only applies if datatype is text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:568 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:569 msgid "A dictionary of options to customize how the data in this column will be interpreted. This is a JSON string. For enumeration columns, use --display='{\"enum_values\":[\"val1\", \"val2\"]}'" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:582 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:583 msgid "You must specify label, name and datatype" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:643 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:644 msgid "" "\n" " %prog catalog /path/to/destination.(CSV|EPUB|MOBI|XML ...) [options]\n" @@ -13556,29 +13700,29 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:657 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:658 msgid "" "Comma-separated list of database IDs to catalog.\n" "If declared, --search is ignored.\n" "Default: all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:661 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:662 msgid "" "Filter the results by the search query. For the format of the search query, please see the search-related documentation in the User Manual.\n" "Default: no filtering" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:667 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:668 #: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:499 msgid "Show detailed output information. Useful for debugging" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:680 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:681 msgid "Error: You must specify a catalog output file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:726 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:727 msgid "" "\n" " %prog set_custom [options] column id value\n" @@ -13590,15 +13734,15 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:737 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:738 msgid "If the column stores multiple values, append the specified values to the existing ones, instead of replacing them." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:748 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:749 msgid "Error: You must specify a field name, id and value" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:767 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:768 msgid "" "\n" " %prog custom_columns [options]\n" @@ -13607,19 +13751,19 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:774 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:775 msgid "Show details for each column." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:786 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:787 msgid "You will lose all data in the column: %r. Are you sure (y/n)? " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:788 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:789 msgid "y" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:794 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:795 msgid "" "\n" " %prog remove_custom_column [options] label\n" @@ -13629,15 +13773,15 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:802 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:803 msgid "Do not ask for confirmation" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:812 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:813 msgid "Error: You must specify a column label" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:822 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:823 msgid "" "\n" " %prog saved_searches [options] list\n" @@ -13650,73 +13794,73 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:840 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:841 msgid "Error: You must specify an action (add|remove|list)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:848 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:849 msgid "Name:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:849 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:850 msgid "Search string:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:855 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:856 msgid "Error: You must specify a name and a search string" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:858 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:859 msgid "added" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:863 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:864 msgid "Error: You must specify a name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:866 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:867 msgid "removed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:870 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:871 msgid "Error: Action %s not recognized, must be one of: (add|remove|list)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:878 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:879 msgid "" "%prog check_library [options]\n" "\n" "Perform some checks on the filesystem representing a library. Reports are {0}\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:885 -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1035 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:886 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1036 msgid "Output in CSV" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:888 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:889 msgid "" "Comma-separated list of reports.\n" "Default: all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:892 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:893 msgid "" "Comma-separated list of extensions to ignore.\n" "Default: all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:896 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:897 msgid "" "Comma-separated list of names to ignore.\n" "Default: all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:926 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:927 msgid "Unknown report check" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:959 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:960 msgid "" "%prog restore_database [options]\n" "\n" @@ -13731,15 +13875,15 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:974 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:975 msgid "Really do the recovery. The command will not run unless this option is specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:987 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:988 msgid "You must provide the %s option to do a recovery" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1024 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1025 msgid "" "%prog list_categories [options]\n" "\n" @@ -13747,29 +13891,29 @@ msgid "" "information is the equivalent of what is shown in the tags pane.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1032 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1033 msgid "Output only the number of items in a category instead of the counts per item within the category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1037 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1038 msgid "The character to put around the category value in CSV mode. Default is quotes (\")." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1040 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1041 msgid "" "Comma-separated list of category lookup names.\n" "Default: all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1046 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1047 msgid "The string used to separate fields in CSV mode. Default is a comma." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1084 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1085 msgid "CATEGORY ITEMS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:1153 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:1157 msgid "" "%%prog command [options] [arguments]\n" "\n" @@ -13789,7 +13933,7 @@ 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:65 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:64 msgid "%sAverage rating is %3.1f" msgstr "" @@ -13797,15 +13941,15 @@ msgstr "" msgid "Main" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3074 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3084 msgid "

Migrating old database to ebook library in %s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3103 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3113 msgid "Copying %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3120 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3130 msgid "Compacting database" msgstr "" @@ -13829,101 +13973,101 @@ msgstr "" msgid "creating custom column " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:32 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:31 msgid "The title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:33 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:32 msgid "The authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:34 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:33 msgid "The author sort string. To use only the first letter of the name use {author_sort[0]}" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:36 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:35 msgid "The tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:37 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:36 msgid "The series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:38 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:37 msgid "The series number. To get leading zeros use {series_index:0>3s} or {series_index:>3s} for leading spaces" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:41 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:40 msgid "The rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:42 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:41 msgid "The ISBN" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:43 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:42 msgid "The publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:44 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:43 msgid "The date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:45 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:44 msgid "The published date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:46 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:45 msgid "The calibre internal id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:56 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:72 msgid "Options to control saving to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:62 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:78 msgid "Normally, calibre will update the metadata in the saved files from what is in the calibre library. Makes saving to disk slower." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:65 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:81 msgid "Normally, calibre will write the metadata into a separate OPF file along with the actual e-book files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:68 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:84 msgid "Normally, calibre will save the cover in a separate file along with the actual e-book file(s)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:71 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:87 msgid "Comma separated list of formats to save for each book. By default all available formats are saved." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:74 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:90 msgid "The template to control the filename and directory structure of the saved files. Default is \"%s\" which will save books into a per-author subdirectory with filenames containing title and author. Available controls are: {%s}" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:79 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:95 msgid "The template to control the filename and directory structure of files sent to the device. Default is \"%s\" which will save books into a per-author directory with filenames containing title and author. Available controls are: {%s}" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:86 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:102 msgid "Normally, calibre will convert all non English characters into English equivalents for the file names. WARNING: If you turn this off, you may experience errors when saving, depending on how well the filesystem you are saving to supports unicode." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:92 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:95 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:108 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:111 msgid "The format in which to display dates. %d - day, %b - month, %Y - year. Default is: %b, %Y" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:98 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:114 msgid "Convert paths to lowercase." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:100 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:116 msgid "Replace whitespace with underscores." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:357 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:381 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:360 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:384 msgid "Requested formats not available" msgstr "" @@ -14147,88 +14291,88 @@ msgstr "" msgid "Books sorted by " msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:32 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:36 msgid "" "%sUsage%s: %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:76 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:87 msgid "Created by " msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:77 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:88 msgid "Whenever you pass arguments to %prog that have spaces in them, enclose the arguments in quotation marks." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:697 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:375 msgid "Path to the database in which books are stored" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:699 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:377 msgid "Pattern to guess metadata from filenames" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:701 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:379 msgid "Access key for isbndb.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:703 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:381 msgid "Default timeout for network operations (seconds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:705 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:383 msgid "Path to directory in which your library of books is stored" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:707 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:385 msgid "The language in which to display the user interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:709 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:387 msgid "The default output format for ebook conversions." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:713 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:391 msgid "Ordered list of formats to prefer for input." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:715 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:393 msgid "Read metadata from files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:717 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:395 msgid "The priority of worker processes. A higher priority means they run faster and consume more resources. Most tasks like conversion/news download/adding books/etc. are affected by this setting." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:722 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:400 msgid "Swap author first and last names when reading metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:724 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:402 msgid "Add new formats to existing book records" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:726 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:404 msgid "Tags to apply to books added to the library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:730 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:408 msgid "List of named saved searches" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:731 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:409 msgid "User-created tag browser categories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:733 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:411 msgid "How and when calibre updates metadata on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:735 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:413 msgid "When searching for text without using lookup prefixes, as for example, Red instead of title:Red, limit the columns searched to those named below." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:740 +#: /home/kovid/work/calibre/src/calibre/utils/config_base.py:418 msgid "Choose columns to be searched when not using prefixes, as for example, when searching for Redd instead of title:Red. Enter a list of search/lookup names separated by commas. Only takes effect if you set the option to limit search columns above." msgstr "" @@ -14420,6 +14564,10 @@ msgstr "" msgid "capitalize(val) -- return value of the field capitalized" msgstr "" +#: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:555 +msgid "booksize() -- return value of the field capitalized" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:43 msgid "Waiting..." msgstr "" diff --git a/src/calibre/translations/de.po b/src/calibre/translations/de.po index b7c5d3df0e..53f002de1d 100644 --- a/src/calibre/translations/de.po +++ b/src/calibre/translations/de.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-17 16:54+0000\n" -"PO-Revision-Date: 2011-04-20 15:20+0000\n" -"Last-Translator: Armin Geller \n" +"PO-Revision-Date: 2011-04-21 11:25+0000\n" +"Last-Translator: Christine Emrich \n" "Language-Team: American English \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-21 04:37+0000\n" +"X-Launchpad-Export-Date: 2011-04-22 04:36+0000\n" "X-Generator: Launchpad (build 12758)\n" "Generated-By: pygettext.py 1.5\n" @@ -500,7 +500,7 @@ msgstr "Metadaten laden" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1059 msgid "Control how calibre downloads ebook metadata from the net" msgstr "" -"Kontrolle der calibre-Vorhehensweise beim Herunterladen von E-Book-Metadaten " +"Kontrolle der calibre-Vorhehensweise beim Herunterladen von eBook-Metadaten " "aus dem Netz" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1064 @@ -4973,7 +4973,7 @@ msgstr "Fehlgeschlagen" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:317 msgid "Database integrity check failed, click Show details for details." msgstr "" -"Die Überprüfung der Datenbankintegrität hat Fehler gefunden. Clicken Sie auf " +"Die Überprüfung der Datenbankintegrität hat Fehler gefunden. Klicken Sie auf " "Details anzeigen für weitere Informationen." #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:322 @@ -9259,7 +9259,7 @@ msgstr "&Generate standard Cover" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:579 msgid "&Remove cover" -msgstr "&Remove Cover" +msgstr "&Remove Umschlag" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:580 msgid "Set from &ebook file(s)" @@ -10490,7 +10490,7 @@ msgstr "Neue Kategorie hinzufügen" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:174 msgid "Rename the current category to the what is in the box" -msgstr "" +msgstr "Derzeitige Kategorie zum Inhalt der Eingabebox umbenennen" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:176 msgid "Category filter: " @@ -11287,7 +11287,7 @@ msgstr "Schnellsuche durchführen (Sie können auch die Eingabetaste drücken)" #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:197 msgid "Reset Quick Search" -msgstr "Quick Search löschen" +msgstr "Schnellsuche löschen" #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:213 msgid "Copy current search text (instead of search name)" @@ -11789,10 +11789,13 @@ msgid "" "Failed to apply updated metadata for some books in your library. Click " "\"Show Details\" to see details." msgstr "" +"Die aktualisieren Metadaten konnten für einige Bücher Ihrer Bibliothek nicht " +"übernommen werden. Klicken Sie auf \"Zeige Details\" für weitere " +"Informationen." #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:212 msgid "Some books changed" -msgstr "" +msgstr "Einige Bücher haben sich geändert" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:213 msgid "" @@ -11801,16 +11804,23 @@ msgid "" "Click \"Show details\" to see the list of changed books. Do you want to " "proceed?" msgstr "" +"Die Metadaten einiger Bücher in Ihrer Bibliothek haben sich geändert seit " +"der Download gestartet wurde. Wenn Sie fortfahren, können diese Änderungen " +"verloren gehen. Klicken Sie auf \"Zeige Details\", um eine Liste aller " +"geändertern Bücher zu sehen. Möchten Sie fortfahren?" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:224 msgid "Metadata download completed" -msgstr "" +msgstr "Herunterladen der Metadaten abgeschlossen" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:228 msgid "" "Could not download metadata and/or covers for %d of the books. Click \"Show " "details\" to see which books." msgstr "" +"Für %d der Bücher konnten Metadaten und/oder Umschlagbilder nicht " +"heruntergeladen werden. Klicken Sie auf \"Zeige Details\", um betroffene " +"Bücher anzuzeigen." #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:234 msgid "(Failed metadata)" @@ -11825,30 +11835,32 @@ msgid "" "Finished downloading metadata for %d book(s). Proceed with updating " "the metadata in your library?" msgstr "" +"Erfolgreich Metadaten für %d Buch/Bücher heruntergeladen. Soll mit " +"dem Aktualisieren der Metadaten in Ihrer Bibliothek fortgefahren werden?" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:240 msgid "Download complete" -msgstr "" +msgstr "Herunterladen abgeschlossen" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:243 #: /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 "" +msgstr "Log-Datei anschauen" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download2.py:315 msgid "Downloaded %d of %d" -msgstr "" +msgstr "%d von %d heruntergeladen" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/config.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:106 msgid "Downloaded metadata fields" -msgstr "" +msgstr "Metadaten-Felder heruntergeladen" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:75 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:237 msgid "Edit Metadata" -msgstr "" +msgstr "Metadaten bearbeiten" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:112 msgid "Set author sort from author" @@ -11860,7 +11872,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:168 msgid "&Download metadata" -msgstr "" +msgstr "Metadaten &Herunterladen" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:178 msgid "Change how calibre downloads metadata" @@ -11869,7 +11881,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:508 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:697 msgid "Change cover" -msgstr "" +msgstr "Umschlag ändern" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:557 msgid "Co&mments" @@ -13823,7 +13835,7 @@ msgstr "Suche (Zur erweiterten Suche die Schaltfläche links klicken)" #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:369 msgid "Enable or disable search highlighting." -msgstr "" +msgstr "Hervorhebung von Suchergebnissen an- oder ausschalten" #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:424 msgid "Saved Searches" @@ -13838,7 +13850,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:34 #: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:42 msgid "*Current search" -msgstr "" +msgstr "*Aktuelle Suche" #: /home/kovid/work/calibre/src/calibre/gui2/search_restriction_mixin.py:12 msgid "Restrict to" @@ -14104,19 +14116,19 @@ msgstr "Der gespeicherte Such-Name %s wird schon verwendet." #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1834 msgid "Manage Authors" -msgstr "" +msgstr "Autoren verwalten" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1836 msgid "Manage Series" -msgstr "" +msgstr "Reihen verwalten" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1838 msgid "Manage Publishers" -msgstr "" +msgstr "Herausgeber verwalten" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1840 msgid "Manage Tags" -msgstr "" +msgstr "Etiketten verwalten" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1852 msgid "Invalid search restriction" @@ -14161,7 +14173,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:2089 msgid "Find item in tag browser" -msgstr "" +msgstr "Eintrag im Etiketten-Browser finden" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:2092 msgid "" @@ -14227,7 +14239,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:2171 msgid "Manage authors, tags, etc" -msgstr "" +msgstr "Autoren, Etiketten, etc. verwalten" #: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:2172 msgid "" diff --git a/src/calibre/translations/es.po b/src/calibre/translations/es.po index 361479be87..f8df6880ab 100644 --- a/src/calibre/translations/es.po +++ b/src/calibre/translations/es.po @@ -11,13 +11,13 @@ msgstr "" "Project-Id-Version: es\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-17 16:54+0000\n" -"PO-Revision-Date: 2011-04-18 09:40+0000\n" +"PO-Revision-Date: 2011-04-21 15:39+0000\n" "Last-Translator: Jellby \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-19 04:39+0000\n" +"X-Launchpad-Export-Date: 2011-04-22 04:37+0000\n" "X-Generator: Launchpad (build 12758)\n" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:528 @@ -18700,6 +18700,60 @@ msgid "" "sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'}\n" "sony_collection_name_template='{category:||: }{value}'" msgstr "" +"Especifica reglas para cambiar el nombre a las colecciones Sony. Este\n" +"ajuste sólo se aplica si la gestión de metadatos está establecida en\n" +"automática. Las colecciones en los lectores Sony se nombran según el campo\n" +"en que se basan sea predefinido o personalizado. Una colección derivada de\n" +"un campo predefinido se nombra con el valor contenido en dicho campo. Por\n" +"ejemplo, si el campo predefinido «series» contiene el valor «Darkover»,\n" +"entonces el nombre de la colección será «Darkover». Una colección derivada\n" +"de un campo personalizado tendrá el nombre del campo añadido al valor. Por\n" +"ejemplo, si un campo personalizado llamado «Mi serie» contiene el valor\n" +"«Darkover», entonces la colección se nombrará de manera predeterminada\n" +"«Darkover (Mi serie)». En lo que a esta documentación respecta, «Darkover»\n" +"se llamará el valor y «Mi serie» se llamará la categoría. Si dos libros\n" +"tienen campos que generan el mismo nombre de colección, ambos se incluirán\n" +"en la misma colección.\n" +"Este conjunto de ajustes le permite especificar, para un campo predefinido\n" +"o personalizado, cómo se nombrarán las colecciones. Puede usarlo para\n" +"añadir una descripción a una etiqueta, por ejemplo «Bla (etiqueta)» en\n" +"lugar de «Bla». También puede usarlo para hacer que distintos campos acaben\n" +"en la misma colección. Por ejemplo, puede hacer que los valores en\n" +"«series», «#mi_serie_1» y «#mi_serie_2» aparezcan en colecciones llamadas\n" +"«algún_valor (Serie)», uniendo todos los campos en un mismo grupo de\n" +"colecciones.\n" +"Hay dos ajustes relacionados. El primero determina el nombre de categoría\n" +"que se usará para un campo de metadatos. El segundo es una plantilla y se\n" +"usa para determinar cómo se combinarán el valor y la categoría para crear\n" +"el nombre de colección. La sintaxis del primer ajuste,\n" +"«sony_collection_renaming_rules», es:\n" +"{«nombre_de_búsqueda_del_campo»:«nombre_de_categoría»,\n" +"«nombre_de_búsqueda»:«categoría», ...}. El segundo ajuste,\n" +"«sony_collection_name_template», es una plantilla. Emplea el mismo lenguaje\n" +"de plantilla que los controles de metadatos y las plantillas de guardado.\n" +"Los únicos dos campos disponibles son «{category}» y «{value}». El campo\n" +"«{value}» nunca está vacío. El campo «{category}» puede estar vacío. El\n" +"comportamiento predeterminado es poner primero el valor y después la\n" +"categoría entre paréntesis si no está vacía: «{value} {category:|(|)}».\n" +"Ejemplos: Los dos primeros ejemplos suponen que el segundo ajuste no se ha\n" +"cambiado.\n" +"1: Quiero unir tres campos de serie en un solo conjunto de colecciones. Los\n" +"nombres de búsqueda de los campos son «series», «#serie_1» y «#serie_2». No\n" +"quiero nada entre paréntesis. El valor que se usaría para el ajuste es:\n" +"sony_collection_renaming_rules={'series':'', '#serie_1':'', '#serie_2':''}\n" +"2: Quiero que la palabra «(Serie)» aparezca en las colecciones creadas a\n" +"partir de series y la palabra «(Etiqueta)» en las creadas a partir de\n" +"etiquetas. Se usaría:\n" +"sony_collection_renaming_rules={'series':'Serie', 'tags':'Etiqueta'}\n" +"3: Quiero unir «series» y «#miserie» y añadir «(Serie)» al nombre de la\n" +"colección. Se usaría:\n" +"sony_collection_renaming_rules={'series':'Serie', '#myserie':'Serie'}\n" +"4: Como en el ejemplo 2, pero en lugar de añadir el nombre de categoría\n" +"entre paréntesis después del valor, lo quiero delante y separado por dos\n" +"puntos, como en «Serie: Darkover». Tengo que cambiar la plantilla usada\n" +"para dar formato al nombre de colección. Los ajustes resultantes son:\n" +"sony_collection_renaming_rules={'series':'Serie', 'tags':'Etiqueta'}\n" +"sony_collection_name_template='{category:||: }{value}'" #: /home/kovid/work/calibre/resources/default_tweaks.py:221 msgid "Specify how SONY collections are sorted" @@ -18731,6 +18785,28 @@ msgid "" "[ ( [list of fields], sort field ) , ( [ list of fields ] , sort field ) ]\n" "Default: empty (no rules), so no collection attributes are named." msgstr "" +"Especifica cómo se ordenan las colecciones Sony. Este ajuste sólo se\n" +"aplica si la gestión de metadatos está establecida en automática. Puede\n" +"definir qué campo de metadatos se usara para ordenar cada colección.\n" +"El formato del ajuste es una lista de campos de metadatos a partir de los\n" +"cuales se construyen las colecciones, seguida del nombre del campo que\n" +"contiene el valor de orden.\n" +"Ejemplo: Lo siguiente indica que las colecciones creadas a partir de " +"«pubdate»\n" +"y «tags» se ordenarán según el valor contenido en la columna personalizada\n" +"«#mifecha», que las colecciones creadas a partir de «series» se ordenan\n" +"según «series_index» y que el resto de las colecciones se ordenan por\n" +"título. Si un campo de colecciones no se nombra, entonces la colección\n" +"se ordenará por índice de serie si está basada en series y por título\n" +"en caso contrario.\n" +"[(['pubdate', 'tags'],'#mydate'), (['series'],'series_index'), (['*'], " +"'title')]\n" +"Tenga en cuenta que los corchetes y paréntesis son necesarios.\n" +"La sintaxis es:\n" +"[ ( [lista de campos], campo de orden ) , ( [ lista de campos ] , campo de " +"orden ) ]\n" +"Valor predeterminado: vacío (sin reglas), con lo que no se nombra\n" +"ningún atributo de colecciones." #: /home/kovid/work/calibre/resources/default_tweaks.py:240 msgid "Control how tags are applied when copying books to another library" @@ -18777,6 +18853,22 @@ msgid "" "content_server_will_display = ['*']\n" "content_server_wont_display['#mycomments']" msgstr "" +"«content_server_will_display» es una lista de campos personalizados que\n" +"se mostrarán, «content_server_wont_display» es una lista de campos\n" +"personalizados que no se mostrarán. El segundo tiene preferencia sobre\n" +"el primero.\n" +"El valor especial «*» indica todos los campos personalizados. El valor «[]»\n" +"indica que no hay entradas.\n" +"Valores predeterminados:\n" +"content_server_will_display = ['*']\n" +"content_server_wont_display = []\n" +"Ejemplos:\n" +"Para mostrar sólo los campos personalizados «#misetiquetas» y «#genero»:\n" +"content_server_will_display = ['#misetiquetas', '#genero']\n" +"content_server_wont_display = []\n" +"Para mostrar todos los campos excepto «#miscomentarios»:\n" +"content_server_will_display = ['*']\n" +"content_server_wont_display = ['#mycomments']" #: /home/kovid/work/calibre/resources/default_tweaks.py:268 msgid "" @@ -18806,6 +18898,24 @@ msgid "" "As above, this tweak affects only display of custom fields. The standard\n" "fields are not affected" msgstr "" +"«book_details_will_display» es una lista de campos personalizados que\n" +"se mostrarán, «book_details_wont_display» es una lista de campos\n" +"personalizados que no se mostrarán. El segundo tiene preferencia sobre\n" +"el primero.\n" +"El valor especial «*» indica todos los campos personalizados. El valor «[]»\n" +"indica que no hay entradas.\n" +"Valores predeterminados:\n" +"book_details_will_display = ['*']\n" +"book_details_wont_display = []\n" +"Ejemplos:\n" +"Para mostrar sólo los campos personalizados «#misetiquetas» y «#genero»:\n" +"book_details_will_display = ['#misetiquetas', '#genero']\n" +"book_details_wont_display = []\n" +"Para mostrar todos los campos excepto «#miscomentarios»:\n" +"book_details_will_display = ['*']\n" +"book_details_wont_display = ['#mycomments']\n" +"Este ajuste sólo afecta a los campos personalizados. Los campos\n" +"predefinidos no se ven afectados." #: /home/kovid/work/calibre/resources/default_tweaks.py:288 msgid "Set the maximum number of sort 'levels'" diff --git a/src/calibre/translations/ro.po b/src/calibre/translations/ro.po index cc35c2ee9f..6a403910c6 100644 --- a/src/calibre/translations/ro.po +++ b/src/calibre/translations/ro.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-17 16:54+0000\n" -"PO-Revision-Date: 2011-04-20 09:22+0000\n" +"PO-Revision-Date: 2011-04-21 07:36+0000\n" "Last-Translator: Anca Stratulat \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-21 04:37+0000\n" +"X-Launchpad-Export-Date: 2011-04-22 04:36+0000\n" "X-Generator: Launchpad (build 12758)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:56 @@ -2427,12 +2427,17 @@ msgid "" "Left aligned scene break markers are center aligned. Replace soft scene " "breaks that use multiple blank lines withhorizontal rules." msgstr "" +"Marker-ii separatorilor de text aliniaţi la stanga sunt aliniaţi central. " +"Înlocuiţi separatorii fini ai textului care utilizează multiple linii goale " +"cu reguli orizontale." #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:547 msgid "" "Replace scene breaks with the specified text. By default, the text from the " "input document is used." msgstr "" +"Înlocuieşte separatorii textului cu textul specificat. Împlicit, textul din " +"documentul iniţial este utilizat." #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:552 msgid "" @@ -2440,20 +2445,25 @@ msgid "" "used as a dictionary to determine whether hyphens should be retained or " "removed." msgstr "" +"Analizaţi cuvintele despărţite în silabe din întregul document. Documentul " +"în sine este folosit ca un dicţionar pentru a determina dacă cratimele ar " +"trebui să fie păstrate sau eliminate." #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:558 msgid "" "Looks for occurrences of sequential

or

tags. The tags are " "renumbered to prevent splitting in the middle of chapter headings." msgstr "" +"Caută evenimente secvenţale ale etichetelor

sau

. Etichetele sunt " +"renumerotate pentru a preveni scindarea în mijlocul capitolului." #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:564 msgid "Search pattern (regular expression) to be replaced with sr1-replace." -msgstr "" +msgstr "Model de cautare (expresie comună) înlocuit cu sr1." #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:569 msgid "Replacement to replace the text found with sr1-search." -msgstr "" +msgstr "Înlocuieste textul găsit cu o căutare sr1." #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:573 msgid "Search pattern (regular expression) to be replaced with sr2-replace."