Merge from trunk

This commit is contained in:
Charles Haley 2012-04-01 10:03:06 +02:00
commit 39fd2fa859
99 changed files with 44056 additions and 37704 deletions

View File

@ -19,6 +19,61 @@
# new recipes:
# - title:
- version: 0.8.45
date: 2012-03-30
new features:
- title: "E-book viewer: Allow the up and down keys to scroll past section boundaries"
- title: "calibredb: Allow specification of basic metadata on the command line when adding books."
tickets: [951063]
- title: "Driver for Samsung Galaxy Plus GT-I9001"
- title: "KF8 Input: Support KF8 format Amazon book samples."
tickets: [963418]
- title: "When a new plugin is added to calibre for the first time, have its icon (if any) show up even when a device is connected (this can be changed by the user at the time of plugin installation)"
- title: "Add keyboard shortcuts for Bold, Italic and Underline to the comments editor in the edit metadata dialog"
tickets: [963559]
bug fixes:
- title: "E-book viewer: Fix last read position (and bookmarks in general) being inaccurate for some books."
description: "The technique for marking locations in books used by the viewer has changed. The new technique should be much more accurate than the last one, especially when the font size at which the book is being viewed is changed. Note that this change means that bookmarks created with this release of calibre will not be read by previous calibre versions. On a technical note, the viewer now uses the CFI specification from the EPUB 3 standard for bookmarks."
type: major
- title: "Workarounds for a few regressions in the user interface in 0.8.44 caused by the update to Qt 4.8.0"
- title: "Books list: Preserve the horizontal scroll position when sorting by a column"
- title: "Fix saving to disk and then adding the book back not restoring tags-like custom columns"
- title: "Linux installer: Fix completion for ebook-convert not working."
tickets: [967834]
- title: "MOBI Output: Recognize type=text in addition to type=start guide elements"
- title: "Get Books: Updates to Nexto, Ebookpoint and Woblink stores"
- title: "Fix unable to clear username/password in Fetch news dialog"
- title: "PDF Output: Fix margin specifications not being applied"
- title: "Linux installer: Manually preserve the defaults.list mimetype association file to workaround buggy xdg-desktop-menu implementations in some distros."
tickets: [926559]
- title: "E-book viewer: Fix regression that caused the ebook viewer to stop functioning if it is launched from the main calibre program and then the main calibre program is closed."
tickets: [963960]
improved recipes:
- Our Daily Bread
new recipes:
- title: NRC Handelsblad (free)
author: veezh
- version: 0.8.44
date: 2012-03-23

View File

@ -13,7 +13,7 @@ class HighCountryNews(BasicNewsRecipe):
__author__ = 'Armin Geller' # 2012-01-31
publisher = 'High Country News'
timefmt = ' [%a, %d %b %Y]'
language = 'en-Us'
language = 'en'
encoding = 'UTF-8'
publication_type = 'newspaper'
oldest_article = 7

View File

@ -6,6 +6,7 @@ Rue89
__author__ = '2010-2012, Louis Gesbert <meta at antislash dot info>'
import re
from calibre.web.feeds.news import BasicNewsRecipe
class Rue89(BasicNewsRecipe):
@ -15,23 +16,24 @@ class Rue89(BasicNewsRecipe):
title = u'Rue89'
language = 'fr'
oldest_article = 7
max_articles_per_feed = 12
max_articles_per_feed = 50
use_embedded_content = False
# From http://www.rue89.com/les-flux-rss-de-rue89
feeds = [
(u'La Une', u'http://www.rue89.com/feed'),
(u'Rue69', u'http://www.rue89.com/rue69/feed'),
(u'Eco', u'http://www.rue89.com/rue89-eco/feed'),
(u'Planète', u'http://www.rue89.com/rue89-planete/feed'),
(u'Sport', u'http://www.rue89.com/rue89-sport/feed'),
(u'Culture', u'http://www.rue89.com/culture/feed'),
(u'Hi-tech', u'http://www.rue89.com/hi-tech/feed'),
(u'Media', u'http://www.rue89.com/medias/feed'),
(u'Monde', u'http://www.rue89.com/monde/feed'),
(u'Politique', u'http://www.rue89.com/politique/feed'),
(u'Societe', u'http://www.rue89.com/societe/feed'),
# Other feeds disabled, 'La Une' seems to include them all
# (u'Rue69', u'http://www.rue89.com/rue69/feed'),
# (u'Eco', u'http://www.rue89.com/rue89-eco/feed'),
# (u'Planète', u'http://www.rue89.com/rue89-planete/feed'),
# (u'Sport', u'http://www.rue89.com/rue89-sport/feed'),
# (u'Culture', u'http://www.rue89.com/culture/feed'),
# (u'Hi-tech', u'http://www.rue89.com/hi-tech/feed'),
# (u'Media', u'http://www.rue89.com/medias/feed'),
# (u'Monde', u'http://www.rue89.com/monde/feed'),
# (u'Politique', u'http://www.rue89.com/politique/feed'),
# (u'Societe', u'http://www.rue89.com/societe/feed'),
]
# Follow redirection from feedsportal.com
@ -41,19 +43,36 @@ class Rue89(BasicNewsRecipe):
def print_version(self, url):
return url + '?imprimer=1'
no_stylesheets = True
conversion_options = { 'smarten_punctuation' : True }
keep_only_tags = [
dict(name='div', attrs={'id':'article'}),
dict(name='div', attrs={'id':'content'}),
]
remove_tags_after = [
dict(name='div', attrs={'id':'plus_loin'}),
dict(name='div', attrs={'class':'stats'}),
]
remove_tags = [
dict(name='div', attrs={'id':'article_tools'}),
dict(name='div', attrs={'id':'plus_loin'}),
dict(name='div', attrs={'class':'stats'}),
dict(name='div', attrs={'class':'tools'}),
]
extra_css = "#content { padding: 0 0; }"
# Without this, parsing of video articles returns strange results
preprocess_regexps = [
(re.compile(r'<script.*?</script>', re.IGNORECASE|re.DOTALL), ''),
]
def preprocess_html(self, soup):
# Remove whole article if it's a "zapnet" (video)
if soup.find('h1', {'class':'zapnet_title'}):
return None
# Reduce h2 titles to h3
for title in soup.findAll('h2'):
title.name = 'h3'
return soup

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,14 @@ msgstr ""
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
"devel@lists.alioth.debian.org>\n"
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
"PO-Revision-Date: 2012-03-21 15:46+0000\n"
"Last-Translator: Иван Старчевић <ivanstar61@gmail.com>\n"
"PO-Revision-Date: 2012-03-25 12:19+0000\n"
"Last-Translator: Radan Putnik <srastral@gmail.com>\n"
"Language-Team: Serbian <gnu@prevod.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-03-22 04:56+0000\n"
"X-Generator: Launchpad (build 14981)\n"
"X-Launchpad-Export-Date: 2012-03-26 04:37+0000\n"
"X-Generator: Launchpad (build 15008)\n"
"Language: sr\n"
#. name for aaa
@ -888,7 +888,7 @@ msgstr "Ака-Кеде"
#. name for aky
msgid "Aka-Kol"
msgstr ""
msgstr "ака-кол"
#. name for akz
msgid "Alabama"
@ -968,11 +968,11 @@ msgstr "Алтајски;Јужни"
#. name for alu
msgid "'Are'are"
msgstr ""
msgstr "ареаре"
#. name for alw
msgid "Alaba-Kabeena"
msgstr ""
msgstr "алаба-кабеена"
#. name for alx
msgid "Amol"
@ -1004,7 +1004,7 @@ msgstr ""
#. name for amf
msgid "Hamer-Banna"
msgstr ""
msgstr "хаммер-банна"
#. name for amg
msgid "Amarag"
@ -1104,7 +1104,7 @@ msgstr "Ансус"
#. name for ane
msgid "Xârâcùù"
msgstr ""
msgstr "ксаракуу"
#. name for anf
msgid "Animere"
@ -1156,7 +1156,7 @@ msgstr "Јарава(Индија)"
#. name for anr
msgid "Andh"
msgstr ""
msgstr "андх"
#. name for ans
msgid "Anserma"
@ -1256,7 +1256,7 @@ msgstr "Таикат"
#. name for aot
msgid "A'tong"
msgstr ""
msgstr "атонг"
#. name for aox
msgid "Atorada"
@ -1284,7 +1284,7 @@ msgstr ""
#. name for apf
msgid "Agta; Pahanan"
msgstr ""
msgstr "агта (паханан)"
#. name for apg
msgid "Ampanang"
@ -1392,7 +1392,7 @@ msgstr "Атакапа"
#. name for aqr
msgid "Arhâ"
msgstr ""
msgstr "арга"
#. name for aqz
msgid "Akuntsu"
@ -1424,7 +1424,7 @@ msgstr "арагонски"
#. name for arh
msgid "Arhuaco"
msgstr ""
msgstr "архуако"
#. name for ari
msgid "Arikara"
@ -1504,7 +1504,7 @@ msgstr ""
#. name for asd
msgid "Asas"
msgstr ""
msgstr "асас"
#. name for ase
msgid "American Sign Language"
@ -1532,7 +1532,7 @@ msgstr "Нсари"
#. name for ask
msgid "Ashkun"
msgstr ""
msgstr "ашкун"
#. name for asl
msgid "Asilulu"
@ -1604,11 +1604,11 @@ msgstr "Заива"
#. name for atc
msgid "Atsahuaca"
msgstr ""
msgstr "атсахуака"
#. name for atd
msgid "Manobo; Ata"
msgstr ""
msgstr "манобо (Ата)"
#. name for ate
msgid "Atemble"
@ -1648,7 +1648,7 @@ msgstr "Атон"
#. name for atp
msgid "Atta; Pudtol"
msgstr ""
msgstr "атта (Пудтол)"
#. name for atq
msgid "Aralle-Tabulahan"
@ -1660,7 +1660,7 @@ msgstr ""
#. name for ats
msgid "Gros Ventre"
msgstr ""
msgstr "грос-вентре"
#. name for att
msgid "Atta; Pamplona"
@ -1692,7 +1692,7 @@ msgstr "Арта"
#. name for aua
msgid "Asumboa"
msgstr ""
msgstr "асумбоа"
#. name for aub
msgid "Alugu"
@ -1712,7 +1712,7 @@ msgstr ""
#. name for aug
msgid "Aguna"
msgstr ""
msgstr "агуна"
#. name for auh
msgid "Aushi"
@ -1752,7 +1752,7 @@ msgstr ""
#. name for auq
msgid "Anus"
msgstr ""
msgstr "анус"
#. name for aur
msgid "Aruek"
@ -1852,7 +1852,7 @@ msgstr "Авети"
#. name for awh
msgid "Awbono"
msgstr ""
msgstr "авбоно"
#. name for awi
msgid "Aekyom"
@ -1860,7 +1860,7 @@ msgstr ""
#. name for awk
msgid "Awabakal"
msgstr ""
msgstr "авабакал"
#. name for awm
msgid "Arawum"
@ -1884,7 +1884,7 @@ msgstr ""
#. name for awt
msgid "Araweté"
msgstr ""
msgstr "аравете"
#. name for awu
msgid "Awyu; Central"
@ -1912,7 +1912,7 @@ msgstr "Абипон"
#. name for axg
msgid "Arára; Mato Grosso"
msgstr ""
msgstr "арара (Мату-Гросу)"
#. name for axk
msgid "Yaka (Central African Republic)"
@ -1924,7 +1924,7 @@ msgstr ""
#. name for axx
msgid "Xaragure"
msgstr ""
msgstr "ксарагуре"
#. name for aya
msgid "Awar"

View File

@ -4,7 +4,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = u'calibre'
numeric_version = (0, 8, 44)
numeric_version = (0, 8, 45)
__version__ = u'.'.join(map(unicode, numeric_version))
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"

View File

@ -107,6 +107,7 @@ class ANDROID(USBMS):
0xc004 : [0x0226],
0x8801 : [0x0226, 0x0227],
0xe115 : [0x0216], # PocketBook A10
0xe107 : [0x326], # PocketBook 622
},
# Acer

View File

@ -10,13 +10,19 @@ __docformat__ = 'restructuredtext en'
import struct, re, os, imghdr
from collections import namedtuple
from itertools import repeat
from urlparse import urldefrag
from lxml import etree
from calibre.ebooks.mobi.reader.headers import NULL_INDEX
from calibre.ebooks.mobi.reader.index import read_index
from calibre.ebooks.mobi.reader.ncx import read_ncx, build_toc
from calibre.ebooks.mobi.reader.markup import expand_mobi8_markup
from calibre.ebooks.metadata.opf2 import Guide, OPFCreator
from calibre.ebooks.metadata.toc import TOC
from calibre.ebooks.mobi.utils import read_font_record
from calibre.ebooks.oeb.parse_utils import parse_html
from calibre.ebooks.oeb.base import XPath, XHTML, xml2text
Part = namedtuple('Part',
'num type filename start end aid')
@ -383,6 +389,19 @@ class Mobi8Reader(object):
len(resource_map)):
mi.cover = resource_map[self.cover_offset]
if len(list(toc)) < 2:
self.log.warn('KF8 has no metadata Table of Contents')
for ref in guide:
if ref.type == 'toc':
href = ref.href()
href, frag = urldefrag(href)
if os.path.exists(href.replace('/', os.sep)):
try:
toc = self.read_inline_toc(href, frag)
except:
self.log.exception('Failed to read inline ToC')
opf = OPFCreator(os.getcwdu(), mi)
opf.guide = guide
@ -397,4 +416,70 @@ class Mobi8Reader(object):
opf.render(of, ncx, 'toc.ncx')
return 'metadata.opf'
def read_inline_toc(self, href, frag):
ans = TOC()
base_href = '/'.join(href.split('/')[:-1])
with open(href.replace('/', os.sep), 'rb') as f:
raw = f.read().decode(self.header.codec)
root = parse_html(raw, log=self.log)
body = XPath('//h:body')(root)
reached = False
if body:
start = body[0]
else:
start = None
reached = True
if frag:
elems = XPath('//*[@id="%s"]'%frag)
if elems:
start = elems[0]
def node_depth(elem):
ans = 0
parent = elem.getparent()
while parent is not None:
parent = parent.getparent()
ans += 1
return ans
# Layer the ToC based on nesting order in the source HTML
current_depth = None
parent = ans
seen = set()
links = []
for elem in root.iterdescendants(etree.Element):
if reached and elem.tag == XHTML('a') and elem.get('href',
False):
href = elem.get('href')
href, frag = urldefrag(href)
href = base_href + '/' + href
text = xml2text(elem).strip()
if (text, href, frag) in seen:
continue
seen.add((text, href, frag))
links.append((text, href, frag, node_depth(elem)))
elif elem is start:
reached = True
depths = sorted(set(x[-1] for x in links))
depth_map = {x:i for i, x in enumerate(depths)}
for text, href, frag, depth in links:
depth = depth_map[depth]
if current_depth is None:
current_depth = 0
parent.add_item(href, frag, text)
elif current_depth == depth:
parent.add_item(href, frag, text)
elif current_depth < depth:
parent = parent[-1] if len(parent) > 0 else parent
parent.add_item(href, frag, text)
current_depth += 1
else:
delta = current_depth - depth
while delta > 0 and parent.parent is not None:
parent = parent.parent
delta -= 1
parent.add_item(href, frag, text)
current_depth = depth
return ans

View File

@ -40,27 +40,34 @@ def get_custom_size(opts):
custom_size = None
return custom_size
def get_pdf_printer(opts, for_comic=False):
def get_pdf_printer(opts, for_comic=False, output_file_name=None):
from calibre.gui2 import is_ok_to_use_qt
if not is_ok_to_use_qt():
raise Exception('Not OK to use Qt')
printer = QPrinter(QPrinter.HighResolution)
custom_size = get_custom_size(opts)
if opts.output_profile.short_name == 'default' or \
opts.output_profile.width > 9999:
if custom_size is None:
printer.setPaperSize(paper_size(opts.paper_size))
else:
printer.setPaperSize(QSizeF(custom_size[0], custom_size[1]), unit(opts.unit))
if isosx and not for_comic:
# On OSX, the native engine can only produce a single page size
# (usually A4). The Qt engine on the other hand produces image based
# PDFs. If we set a custom page size using QSizeF the native engine
# produces unreadable output, so we just ignore the custom size
# settings.
printer.setPaperSize(paper_size(opts.paper_size))
else:
w = opts.output_profile.comic_screen_size[0] if for_comic else \
opts.output_profile.width
h = opts.output_profile.comic_screen_size[1] if for_comic else \
opts.output_profile.height
dpi = opts.output_profile.dpi
printer.setPaperSize(QSizeF(float(w) / dpi, float(h) / dpi), QPrinter.Inch)
if opts.output_profile.short_name == 'default' or \
opts.output_profile.width > 9999:
if custom_size is None:
printer.setPaperSize(paper_size(opts.paper_size))
else:
printer.setPaperSize(QSizeF(custom_size[0], custom_size[1]), unit(opts.unit))
else:
w = opts.output_profile.comic_screen_size[0] if for_comic else \
opts.output_profile.width
h = opts.output_profile.comic_screen_size[1] if for_comic else \
opts.output_profile.height
dpi = opts.output_profile.dpi
printer.setPaperSize(QSizeF(float(w) / dpi, float(h) / dpi), QPrinter.Inch)
if for_comic:
# Comic pages typically have their own margins, or their background
@ -72,6 +79,12 @@ def get_pdf_printer(opts, for_comic=False):
printer.setOrientation(orientation(opts.orientation))
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setFullPage(for_comic)
if output_file_name:
printer.setOutputFileName(output_file_name)
if isosx and not for_comic:
# Ensure we are not generating enormous image based PDFs
printer.setOutputFormat(QPrinter.NativeFormat)
return printer
def get_printer_page_size(opts, for_comic=False):
@ -163,15 +176,7 @@ class PDFWriter(QObject): # {{{
if ok:
item_path = os.path.join(self.tmp_path, '%i.pdf' % len(self.combine_queue))
self.logger.debug('\tRendering item %s as %i.pdf' % (os.path.basename(str(self.view.url().toLocalFile())), len(self.combine_queue)))
printer = get_pdf_printer(self.opts)
printer.setOutputFileName(item_path)
# We have to set the engine to Native on OS X after the call to set
# filename. Setting a filename with .pdf as the extension causes
# Qt to set the format to use Qt's PDF engine even if native was
# previously set on the printer. Qt's PDF engine produces image
# based PDFs on OS X, so we cannot use it.
if isosx:
printer.setOutputFormat(QPrinter.NativeFormat)
printer = get_pdf_printer(self.opts, output_file_name=item_path)
self.view.page().mainFrame().evaluateJavaScript('''
document.body.style.backgroundColor = "white";
@ -193,10 +198,7 @@ class PDFWriter(QObject): # {{{
if self.cover_data is None:
return
item_path = os.path.join(self.tmp_path, 'cover.pdf')
printer = get_pdf_printer(self.opts)
printer.setOutputFileName(item_path)
if isosx:
printer.setOutputFormat(QPrinter.NativeFormat)
printer = get_pdf_printer(self.opts, output_file_name=item_path)
self.combine_queue.insert(0, item_path)
p = QPixmap()
p.loadFromData(self.cover_data)
@ -248,10 +250,8 @@ class ImagePDFWriter(object):
os.remove(f.name)
def render_images(self, outpath, mi, items):
printer = get_pdf_printer(self.opts, for_comic=True)
printer.setOutputFileName(outpath)
if isosx:
printer.setOutputFormat(QPrinter.NativeFormat)
printer = get_pdf_printer(self.opts, for_comic=True,
output_file_name=outpath)
printer.setDocName(mi.title)
printer.setCreator(u'%s [%s]'%(__appname__, __version__))
# Seems to be no way to set author

View File

@ -105,6 +105,7 @@ gprefs.defaults['show_files_after_save'] = True
gprefs.defaults['auto_add_path'] = None
gprefs.defaults['auto_add_check_for_duplicates'] = False
gprefs.defaults['blocked_auto_formats'] = []
gprefs.defaults['auto_add_auto_convert'] = True
# }}}
NONE = QVariant() #: Null value to return from the data function of item models

View File

@ -71,7 +71,7 @@ class AddAction(InterfaceAction):
ma('add-formats', _('Add files to selected book records'),
triggered=self.add_formats, shortcut=_('Shift+A'))
self.add_menu.addSeparator()
ma('add-config', _('Configure the adding of books'),
ma('add-config', _('Control the adding of books'),
triggered=self.add_config)
self.qaction.triggered.connect(self.add_books)

View File

@ -53,6 +53,24 @@ class ConvertAction(InterfaceAction):
self.queue_convert_jobs(jobs, changed, bad, rows, previous,
self.book_auto_converted, extra_job_args=[on_card])
def auto_convert_auto_add(self, book_ids):
previous = self.gui.library_view.currentIndex()
db = self.gui.current_db
needed = set()
of = prefs['output_format'].lower()
for book_id in book_ids:
fmts = db.formats(book_id, index_is_id=True)
fmts = set(x.lower() for x in fmts.split(',')) if fmts else set()
if of not in fmts:
needed.add(book_id)
if needed:
jobs, changed, bad = convert_single_ebook(self.gui,
self.gui.library_view.model().db, needed, True, of,
show_no_format_warning=False)
if not jobs: return
self.queue_convert_jobs(jobs, changed, bad, list(needed), previous,
self.book_converted, rows_are_ids=True)
def auto_convert_mail(self, to, fmts, delete_from_library, book_ids, format, subject):
previous = self.gui.library_view.currentIndex()
rows = [x.row() for x in \
@ -118,7 +136,7 @@ class ConvertAction(InterfaceAction):
num, 2000)
def queue_convert_jobs(self, jobs, changed, bad, rows, previous,
converted_func, extra_job_args=[]):
converted_func, extra_job_args=[], rows_are_ids=False):
for func, args, desc, fmt, id, temp_files in jobs:
func, _, same_fmt = func.partition(':')
same_fmt = same_fmt == 'same_fmt'
@ -140,7 +158,11 @@ class ConvertAction(InterfaceAction):
self.conversion_jobs[job] = tuple(args)
if changed:
self.gui.library_view.model().refresh_rows(rows)
m = self.gui.library_view.model()
if rows_are_ids:
m.refresh_ids(rows)
else:
m.refresh_rows(rows)
current = self.gui.library_view.currentIndex()
self.gui.library_view.model().current_changed(current, previous)

View File

@ -113,6 +113,7 @@ class Worker(Thread):
class AutoAdder(QObject):
metadata_read = pyqtSignal(object)
auto_convert = pyqtSignal(object)
def __init__(self, path, parent):
QObject.__init__(self, parent)
@ -124,6 +125,8 @@ class AutoAdder(QObject):
self.metadata_read.connect(self.add_to_db,
type=Qt.QueuedConnection)
QTimer.singleShot(2000, self.initialize)
self.auto_convert.connect(self.do_auto_convert,
type=Qt.QueuedConnection)
elif path:
prints(path,
'is not a valid directory to watch for new ebooks, ignoring')
@ -163,6 +166,7 @@ class AutoAdder(QObject):
needs_rescan = False
duplicates = []
added_ids = set()
for fname, tdir in data.iteritems():
paths = [os.path.join(self.worker.path, fname)]
@ -187,9 +191,12 @@ class AutoAdder(QObject):
continue
mi = [OPF(open(mi, 'rb'), tdir,
populate_spine=False).to_book_metadata()]
dups, num = m.add_books(paths,
dups, ids = m.add_books(paths,
[os.path.splitext(fname)[1][1:].upper()], mi,
add_duplicates=not gprefs['auto_add_check_for_duplicates'])
add_duplicates=not gprefs['auto_add_check_for_duplicates'],
return_ids=True)
added_ids |= set(ids)
num = len(ids)
if dups:
path = dups[0][0]
with open(os.path.join(tdir, 'dup_cache.'+dups[1][0].lower()),
@ -217,8 +224,10 @@ class AutoAdder(QObject):
_('Books with the same title as the following already '
'exist in the database. Add them anyway?'),
'\n'.join(files)):
dups, num = m.add_books(paths, formats, metadata,
add_duplicates=True)
dups, ids = m.add_books(paths, formats, metadata,
add_duplicates=True, return_ids=True)
added_ids |= set(ids)
num = len(ids)
count += num
for tdir in data.itervalues():
@ -227,6 +236,9 @@ class AutoAdder(QObject):
except:
pass
if added_ids and gprefs['auto_add_auto_convert']:
self.auto_convert.emit(added_ids)
if count > 0:
m.books_added(count)
gui.status_bar.show_message(_(
@ -238,4 +250,7 @@ class AutoAdder(QObject):
if needs_rescan:
QTimer.singleShot(2000, self.dir_changed)
def do_auto_convert(self, added_ids):
gui = self.parent()
gui.iactions['Convert Books'].auto_convert_auto_add(added_ids)

View File

@ -202,9 +202,9 @@ class ProceedNotification(MessageBox): # {{{
gui = get_gui()
gui.proceed_requested.emit(func, self.payload)
# Ensure this notification is garbage collected
self.vlb.clicked.disconnect()
self.callback = self.cancel_callback = self.payload = None
self.setParent(None)
self.vlb.clicked.disconnect()
_proceed_memory.remove(self)
def done(self, r):

View File

@ -140,34 +140,6 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_51">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>40</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="buddy">
<cstring>matchkind</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="maximumSize">

View File

@ -187,9 +187,10 @@ class BooksModel(QAbstractTableModel): # {{{
self.db = None
self.reset()
def add_books(self, paths, formats, metadata, add_duplicates=False):
def add_books(self, paths, formats, metadata, add_duplicates=False,
return_ids=False):
ret = self.db.add_books(paths, formats, metadata,
add_duplicates=add_duplicates)
add_duplicates=add_duplicates, return_ids=return_ids)
self.count_changed()
return ret

View File

@ -262,9 +262,11 @@ class BooksView(QTableView): # {{{
self.selected_ids = [idc(r) for r in selected_rows]
def sorting_done(self, indexc):
pos = self.horizontalScrollBar().value()
self.select_rows(self.selected_ids, using_ids=True, change_current=True,
scroll=True)
self.selected_ids = []
self.horizontalScrollBar().setValue(pos)
def sort_by_named_field(self, field, order, reset=True):
if field in self.column_map:

View File

@ -36,6 +36,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('new_book_tags', prefs, setting=CommaSeparatedList)
r('auto_add_path', gprefs, restart_required=True)
r('auto_add_check_for_duplicates', gprefs)
r('auto_add_auto_convert', gprefs)
self.filename_pattern = FilenamePattern(self)
self.metadata_box.layout().insertWidget(0, self.filename_pattern)

View File

@ -151,6 +151,19 @@ Author matching is exact.</string>
<string>&amp;Automatic Adding</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="opt_auto_add_check_for_duplicates">
<property name="toolTip">
<string>If set, this option will causes calibre to check if a file
being auto-added is already in the calibre library.
If it is, a meesage will pop up asking you whether
you want to add it anyway.</string>
</property>
<property name="text">
<string>Check for &amp;duplicates when auto-adding files</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
@ -168,7 +181,7 @@ Author matching is exact.</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Ignore files with the following extensions when automatically adding </string>
@ -187,7 +200,7 @@ Author matching is exact.</string>
</layout>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -225,16 +238,10 @@ Author matching is exact.</string>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="opt_auto_add_check_for_duplicates">
<property name="toolTip">
<string>If set, this option will causes calibre to check if a file
being auto-added is already in the calibre library.
If it is, a meesage will pop up asking you whether
you want to add it anyway.</string>
</property>
<item row="4" column="0">
<widget class="QCheckBox" name="opt_auto_add_auto_convert">
<property name="text">
<string>Check for &amp;duplicates when auto-adding files</string>
<string>Automatically &amp;convert added files to the current output format</string>
</property>
</widget>
</item>

View File

@ -73,11 +73,13 @@ class OpenSearchOPDSStore(StorePlugin):
type = link.get('type')
if rel and href and type:
if rel in ('http://opds-spec.org/thumbnail', 'http://opds-spec.org/image/thumbnail'):
if 'http://opds-spec.org/thumbnail' in rel:
s.cover_url = href
elif rel == u'http://opds-spec.org/acquisition/buy':
elif 'http://opds-spec.org/image/thumbnail' in rel:
s.cover_url = href
elif 'http://opds-spec.org/acquisition/buy' in rel:
s.detail_item = href
elif rel == u'http://opds-spec.org/acquisition':
elif 'http://opds-spec.org/acquisition' in rel:
if type:
ext = mimetypes.guess_extension(type)
if ext:

View File

@ -25,7 +25,7 @@ from calibre.ebooks.conversion.config import GuiRecommendations, \
from calibre.gui2.convert import bulk_defaults_for_input_format
def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{
out_format=None):
out_format=None, show_no_format_warning=True):
changed = False
jobs = []
bad = []
@ -91,7 +91,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{
except NoSupportedInputFormats:
bad.append(book_id)
if bad != []:
if bad and show_no_format_warning:
res = []
for id in bad:
title = db.title(id, True)

View File

@ -3243,7 +3243,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
return id
def add_books(self, paths, formats, metadata, add_duplicates=True):
def add_books(self, paths, formats, metadata, add_duplicates=True,
return_ids=False):
'''
Add a book to the database. The result cache is not updated.
:param:`paths` List of paths to book files or file-like objects
@ -3289,7 +3290,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
formats = list(duplicate[1] for duplicate in duplicates)
metadata = list(duplicate[2] for duplicate in duplicates)
return (paths, formats, metadata), len(ids)
return None, len(ids)
return None, (ids if return_ids else len(ids))
def import_book(self, mi, formats, notify=True, import_hooks=True,
apply_import_tags=True, preserve_uuid=False):

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,9 @@
#
msgid ""
msgstr ""
"Project-Id-Version: calibre 0.8.44\n"
"POT-Creation-Date: 2012-03-24 16:05+IST\n"
"PO-Revision-Date: 2012-03-24 16:05+IST\n"
"Project-Id-Version: calibre 0.8.45\n"
"POT-Creation-Date: 2012-03-30 09:11+IST\n"
"PO-Revision-Date: 2012-03-30 09:11+IST\n"
"Last-Translator: Automatically generated\n"
"Language-Team: LANGUAGE\n"
"MIME-Version: 1.0\n"
@ -100,10 +100,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/ozon.py:125
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/txt.py:18
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:26
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:117
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:159
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:78
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:133
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:175
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/mobi6.py:615
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/utils.py:312
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/utils.py:314
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer2/indexer.py:497
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:168
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:170
@ -135,8 +136,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:63
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:81
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:82
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:102
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:103
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:104
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:416
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:424
#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:166
@ -156,7 +157,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:128
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:811
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:375
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:377
#: /home/kovid/work/calibre/src/calibre/gui2/email.py:191
#: /home/kovid/work/calibre/src/calibre/gui2/email.py:206
#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:408
@ -174,7 +175,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:168
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:204
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/google_books_plugin.py:107
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:205
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:206
#: /home/kovid/work/calibre/src/calibre/library/cli.py:234
#: /home/kovid/work/calibre/src/calibre/library/database.py:914
#: /home/kovid/work/calibre/src/calibre/library/database2.py:561
@ -1007,7 +1008,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1057
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1092
#: /home/kovid/work/calibre/src/calibre/gui2/actions/fetch_news.py:73
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:464
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:466
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1154
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1156
#: /home/kovid/work/calibre/src/calibre/library/database2.py:346
@ -3315,7 +3316,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1239
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:15
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:56
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:57
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:199
msgid "Table of Contents"
msgstr ""
@ -3376,7 +3377,7 @@ msgstr ""
msgid "Main Text"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/iterator.py:43
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/iterator.py:45
#, python-format
msgid "%s format books are not supported"
msgstr ""
@ -4232,7 +4233,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:479
#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:224
#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:100
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:943
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:945
msgid "Not allowed"
msgstr ""
@ -6359,7 +6360,7 @@ msgid "&Monospaced font family:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:115
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:200
msgid "Metadata"
msgstr ""
@ -7622,7 +7623,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:342
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:89
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:90
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:257
msgid "Name"
msgstr ""
@ -7748,7 +7749,7 @@ msgstr ""
msgid "Select the toolbars and/or menus to add <b>%s</b> to:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_plugin_toolbars.py:45
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_plugin_toolbars.py:48
msgid "You can also customise the plugin locations using <b>Preferences -> Customise the toolbar</b>"
msgstr ""
@ -7935,7 +7936,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:160
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:496
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:622
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:624
msgid "No matches found"
msgstr ""
@ -9112,62 +9113,62 @@ msgstr ""
msgid "You must provide a username and/or password to use this news source."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:355
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:357
msgid "Account"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:356
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:358
msgid "(optional)"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:357
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:359
msgid "(required)"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:376
msgid "Created by: "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:378
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:380
#, python-format
msgid "Download %s now"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:382
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:384
msgid "Last downloaded: never"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:383
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:385
msgid "never"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:391
#, python-format
msgid "%(days)d days, %(hours)d hours and %(mins)d minutes ago"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:405
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:407
msgid "Last downloaded:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:426
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:428
msgid "Cannot download news as no internet connection is active"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:429
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:431
msgid "No internet connection"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:440
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:442
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:203
msgid "Schedule news download"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:443
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:445
msgid "Add a custom news source"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:448
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:450
msgid "Download all scheduled news sources"
msgstr ""
@ -10471,7 +10472,7 @@ msgstr ""
msgid "Restore default layout"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:944
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:946
msgid "Dropping onto a device is not supported. First add the book to the calibre library."
msgstr ""
@ -10513,12 +10514,12 @@ msgid "LRF Viewer toolbar"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:131
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:557
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:516
msgid "Next Page"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:132
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:558
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:517
msgid "Previous Page"
msgstr ""
@ -12123,7 +12124,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:182
#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:132
#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:223
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:272
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:273
msgid " or "
msgstr ""
@ -14200,27 +14201,27 @@ msgstr ""
msgid "Install and configure user plugins"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:43
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:44
msgid "Edit bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:43
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:44
msgid "New title for bookmark:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:52
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:53
msgid "Export Bookmarks"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:55
msgid "Saved Bookmarks (*.pickle)"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:62
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:63
msgid "Import Bookmarks"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:62
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:63
msgid "Pickled Bookmarks (*.pickle)"
msgstr ""
@ -14336,7 +14337,7 @@ msgid "Mouse &wheel flips pages"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:208
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:50
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:51
msgid "Set the maximum width that the book's text and pictures will take when in fullscreen mode. This allows you to read the book text without it becoming too wide."
msgstr ""
@ -14382,118 +14383,118 @@ msgstr ""
msgid "No results found for:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:39
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:40
msgid "Options to customize the ebook viewer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:46
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:929
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:941
msgid "Remember last used window size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:105
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:49
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:106
msgid "Set the user CSS stylesheet. This can be used to customize the look of all books."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:55
msgid "Resize images larger than the viewer window to fit inside it"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:56
msgid "Hyphenate text"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:57
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:58
msgid "Default language for hyphenation rules"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:60
msgid "Save the current position in the document, when quitting"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:61
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:62
msgid "Have the mouse wheel turn pages"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:64
msgid "The time, in seconds, for the page flip animation. Default is half a second."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:66
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:67
msgid "The amount by which to change the font size when clicking the font larger/smaller buttons. Should be a number between 0 and 1."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:71
msgid "Font options"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:72
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:73
msgid "The serif font family"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:74
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:75
msgid "The sans-serif font family"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:76
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:77
msgid "The monospaced font family"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:77
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:78
msgid "The standard font size in px"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:78
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:79
msgid "The monospaced font size in px"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:79
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:80
msgid "The standard font type"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:134
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:135
msgid "Still editing"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:135
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:136
msgid "You are in the middle of editing a keyboard shortcut first complete that, by clicking outside the shortcut editing box."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:526
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:485
msgid "&Lookup in dictionary"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:531
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:490
msgid "&Search for next occurrence"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:536
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:146
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:495
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:147
msgid "Go to..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:548
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:507
msgid "Next Section"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:549
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:508
msgid "Previous Section"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:551
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:510
msgid "Document Start"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:552
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:511
msgid "Document End"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:554
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:513
msgid "Section Start"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:555
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:514
msgid "Section End"
msgstr ""
@ -14545,147 +14546,147 @@ msgstr ""
msgid "Scroll right"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:117
msgid "Book format"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:134
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:135
msgid "Position in book"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:212
msgid "Go to a reference. To get reference numbers, use the reference mode."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:219
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:220
msgid "Search for text in book"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:271
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:272
#, python-format
msgid "Toggle full screen (%s)"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:306
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:307
msgid "Full screen mode"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:307
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:308
msgid "Right click to show controls"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:308
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:309
msgid "Press Esc to quit"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:322
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:323
msgid "Show/hide controls"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:334
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:335
msgid "Print Preview"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:344
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:345
msgid "Clear list of recently opened books"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:425
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:426
#, python-format
msgid "Connecting to dict.org to lookup: <b>%s</b>&hellip;"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:531
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:533
msgid "No such location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:532
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:534
msgid "The location pointed to by this item does not exist."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:582
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:584
msgid "Choose ebook"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:583
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:585
msgid "Ebooks"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:603
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:605
#, python-format
msgid ""
"Make font size %(which)s\n"
"Current magnification: %(mag).1f"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:605
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:607
msgid "larger"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:607
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:609
msgid "smaller"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:623
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:625
#, python-format
msgid "No matches found for: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:660
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:662
msgid "Loading flow..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:698
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:700
#, python-format
msgid "Laying out %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:741
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:751
#, python-format
msgid "Bookmark #%d"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:745
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:755
msgid "Add bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:746
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:756
msgid "Enter title for bookmark:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:756
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:767
msgid "Manage Bookmarks"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:797
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:809
msgid "Loading ebook..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:809
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:821
msgid "Could not open ebook"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:916
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:928
msgid "Options to control the ebook viewer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:923
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:935
msgid "If specified, viewer window will try to come to the front when started."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:926
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:938
msgid "If specified, viewer window will try to open full screen when started."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:931
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:943
msgid "Print javascript alert and console messages to the console"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:933
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:945
msgid "The position at which to open the specified book. The position is a location as displayed in the top left corner of the viewer."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:940
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:952
msgid ""
"%prog [options] file\n"
"\n"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff