mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk.
This commit is contained in:
commit
8c51a78c7f
@ -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
|
||||
|
||||
|
@ -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 <kovid@kovidgoyal.net>"
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -58,7 +58,7 @@ class OverDrive(Source):
|
||||
isbn = identifiers.get('isbn', None)
|
||||
|
||||
br = self.browser
|
||||
ovrdrv_data = self.to_ovrdrv_data(br, title, authors, ovrdrv_id)
|
||||
ovrdrv_data = self.to_ovrdrv_data(br, log, title, authors, ovrdrv_id)
|
||||
if ovrdrv_data:
|
||||
title = ovrdrv_data[8]
|
||||
authors = ovrdrv_data[6]
|
||||
@ -113,7 +113,7 @@ class OverDrive(Source):
|
||||
if ovrdrv_id is not None:
|
||||
referer = self.get_base_referer()+'ContentDetails-Cover.htm?ID='+ovrdrv_id
|
||||
req.add_header('referer', referer)
|
||||
req.add_header('referer', referer)
|
||||
|
||||
log('Downloading cover from:', cached_url)
|
||||
try:
|
||||
cdata = br.open_novisit(req, timeout=timeout).read()
|
||||
@ -186,7 +186,7 @@ class OverDrive(Source):
|
||||
|
||||
br.set_cookiejar(clean_cj)
|
||||
|
||||
def overdrive_search(self, br, q, title, author):
|
||||
def overdrive_search(self, br, log, q, title, author):
|
||||
# re-initialize the cookiejar to so that it's clean
|
||||
clean_cj = mechanize.CookieJar()
|
||||
br.set_cookiejar(clean_cj)
|
||||
@ -204,7 +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)
|
||||
q_xref = q+'SearchResults.svc/GetResults?iDisplayLength=50&sSearch='+xref_q
|
||||
query = '{"szKeyword":"'+initial_q+'"}'
|
||||
|
||||
@ -313,16 +314,16 @@ class OverDrive(Source):
|
||||
return self.sort_ovrdrv_results(raw, None, None, None, ovrdrv_id)
|
||||
|
||||
|
||||
def find_ovrdrv_data(self, br, title, author, isbn, ovrdrv_id=None):
|
||||
def find_ovrdrv_data(self, br, log, title, author, isbn, ovrdrv_id=None):
|
||||
q = base_url
|
||||
if ovrdrv_id is None:
|
||||
return self.overdrive_search(br, q, title, author)
|
||||
return self.overdrive_search(br, log, q, title, author)
|
||||
else:
|
||||
return self.overdrive_get_record(br, q, ovrdrv_id)
|
||||
|
||||
|
||||
|
||||
def to_ovrdrv_data(self, br, title=None, author=None, ovrdrv_id=None):
|
||||
def to_ovrdrv_data(self, br, log, title=None, author=None, ovrdrv_id=None):
|
||||
'''
|
||||
Takes either a title/author combo or an Overdrive ID. One of these
|
||||
two must be passed to this function.
|
||||
@ -335,10 +336,10 @@ class OverDrive(Source):
|
||||
elif ans is False:
|
||||
return None
|
||||
else:
|
||||
ovrdrv_data = self.find_ovrdrv_data(br, title, author, ovrdrv_id)
|
||||
ovrdrv_data = self.find_ovrdrv_data(br, log, title, author, ovrdrv_id)
|
||||
else:
|
||||
try:
|
||||
ovrdrv_data = self.find_ovrdrv_data(br, title, author, ovrdrv_id)
|
||||
ovrdrv_data = self.find_ovrdrv_data(br, log, title, author, ovrdrv_id)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
@ -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 = '<p>' + _('Finished downloading metadata for <b>%d book(s)</b>. '
|
||||
'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 += '<p>'+_('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'), '<p>'+
|
||||
_('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
|
||||
|
||||
# }}}
|
||||
|
||||
|
@ -6,13 +6,13 @@ __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__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('<pre style="font-family: monospace">%s</pre>' % 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([])
|
||||
|
@ -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)
|
||||
|
@ -7,19 +7,14 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__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('<pre style="font-family: monospace">%s</pre>' % 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'), '<p>'+
|
||||
_('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 = '<p>'+_('Could not download metadata and/or covers for %d of the books. Click'
|
||||
' "Show details" to see which books.')%len(failed_ids)
|
||||
msg = '<p>' + _('Finished downloading metadata for <b>%d book(s)</b>. '
|
||||
'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
|
||||
|
@ -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'])
|
||||
|
@ -55,7 +55,7 @@ class Matches(QAbstractItemModel):
|
||||
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
|
||||
|
||||
@ -95,7 +95,7 @@ class Matches(QAbstractItemModel):
|
||||
return self.matches[row]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def has_results(self):
|
||||
return len(self.matches) > 0
|
||||
|
||||
@ -221,7 +221,12 @@ class Matches(QAbstractItemModel):
|
||||
self.reset()
|
||||
|
||||
def reorder_matches(self):
|
||||
self.matches = sorted(self.matches, key=lambda x: self.all_matches.index(x))
|
||||
def keygen(x):
|
||||
try:
|
||||
return self.all_matches.index(x)
|
||||
except:
|
||||
return 100000
|
||||
self.matches = sorted(self.matches, key=keygen)
|
||||
|
||||
|
||||
class SearchFilter(SearchQueryParser):
|
||||
@ -327,5 +332,6 @@ class SearchFilter(SearchQueryParser):
|
||||
matches.add(sr)
|
||||
break
|
||||
except ValueError: # Unicode errors
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return matches
|
||||
|
@ -20,7 +20,7 @@ class ResultsView(QTreeView):
|
||||
self.setModel(self._model)
|
||||
|
||||
self.rt_delegate = RichTextDelegate(self)
|
||||
|
||||
|
||||
for i in self._model.HTML_COLS:
|
||||
self.setItemDelegateForColumn(i, self.rt_delegate)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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 <frius64@hotmail.com>\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"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 <Unknown>\n"
|
||||
"PO-Revision-Date: 2011-04-21 11:25+0000\n"
|
||||
"Last-Translator: Christine Emrich <Unknown>\n"
|
||||
"Language-Team: American English <kde-i18n-doc@lists.kde.org>\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 <b>%d book(s)</b>. Proceed with updating "
|
||||
"the metadata in your library?"
|
||||
msgstr ""
|
||||
"Erfolgreich Metadaten für <b>%d Buch/Bücher</b> 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 ""
|
||||
|
@ -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 <Unknown>\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'"
|
||||
|
@ -8,13 +8,13 @@ msgstr ""
|
||||
"Project-Id-Version: calibre\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\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 <Unknown>\n"
|
||||
"Language-Team: Romanian <ro@li.org>\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 <h1> or <h2> tags. The tags are "
|
||||
"renumbered to prevent splitting in the middle of chapter headings."
|
||||
msgstr ""
|
||||
"Caută evenimente secvenţale ale etichetelor <h1> sau <h2>. 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."
|
||||
|
Loading…
x
Reference in New Issue
Block a user