diff --git a/recipes/aif_ru.recipe b/recipes/aif_ru.recipe index b5d6015d0c..4e018203da 100644 --- a/recipes/aif_ru.recipe +++ b/recipes/aif_ru.recipe @@ -1,5 +1,5 @@ __license__ = 'GPL v3' -__copyright__ = '2010, Darko Miletic ' +__copyright__ = '2010 - 2012, Darko Miletic ' ''' www.aif.ru ''' @@ -19,12 +19,19 @@ class AIF_ru(BasicNewsRecipe): encoding = 'cp1251' language = 'ru' publication_type = 'magazine' - extra_css = ' @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: Verdana,Arial,Helvetica,sans1,sans-serif} ' - keep_only_tags = [dict(name='div',attrs={'id':'inner'})] + masthead_url = 'http://static3.aif.ru/glossy/index/i/logo.png' + extra_css = """ + @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} + body{font-family: Verdana,Arial,Helvetica,sans1,sans-serif} + img{display: block} + """ + keep_only_tags = [ + dict(name='div',attrs={'class':['content-header', 'zoom']}) + ,dict(name='div',attrs={'id':'article-text'}) + ] remove_tags = [ - dict(name=['iframe','object','link','base','input','img']) - ,dict(name='div',attrs={'class':'photo'}) - ,dict(name='p',attrs={'class':'resizefont'}) + dict(name=['iframe','object','link','base','input','meta']) + ,dict(name='div',attrs={'class':'in-topic'}) ] feeds = [(u'News', u'http://www.aif.ru/rss/all.php')] diff --git a/resources/compiled_coffeescript.zip b/resources/compiled_coffeescript.zip index 055e7b15ed..215d6a2cb4 100644 Binary files a/resources/compiled_coffeescript.zip and b/resources/compiled_coffeescript.zip differ diff --git a/setup/installer/windows/freeze.py b/setup/installer/windows/freeze.py index ce07205e09..73d9f0e38d 100644 --- a/setup/installer/windows/freeze.py +++ b/setup/installer/windows/freeze.py @@ -19,8 +19,8 @@ QT_DIR = os.environ.get('QT_DIR', 'Q:\\Qt\\4.8.2') QT_DLLS = ['Core', 'Gui', 'Network', 'Svg', 'WebKit', 'Xml', 'XmlPatterns'] LIBUNRAR = os.environ.get('UNRARDLL', 'C:\\Program Files\\UnrarDLL\\unrar.dll') SW = r'C:\cygwin\home\kovid\sw' -IMAGEMAGICK = os.path.join(SW, 'build', 'ImageMagick-6.7.6', - 'VisualMagick', 'bin') +IMAGEMAGICK = os.path.join(SW, 'build', + 'ImageMagick-*\\VisualMagick\\bin') CRT = r'C:\Microsoft.VC90.CRT' LZMA = r'Q:\easylzma\build\easylzma-0.0.8' @@ -283,8 +283,9 @@ class Win32Freeze(Command, WixMixIn): shutil.copy2(msrc, self.dll_dir) # Copy ImageMagick + impath = glob.glob(IMAGEMAGICK)[-1] for pat in ('*.dll', '*.xml'): - for f in glob.glob(self.j(IMAGEMAGICK, pat)): + for f in glob.glob(self.j(impath, pat)): ok = True for ex in ('magick++', 'x11.dll', 'xext.dll'): if ex in f.lower(): ok = False diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst index 31bd7ec06c..eee14151c1 100644 --- a/setup/installer/windows/notes.rst +++ b/setup/installer/windows/notes.rst @@ -420,16 +420,32 @@ Run:: Python Imaging Library ------------------------ +For 32-bit: Install as normal using installer at http://www.lfd.uci.edu/~gohlke/pythonlibs/ +For 64-bit: +Download from http://pypi.python.org/pypi/Pillow/ +Edit setup.py setting the ROOT values, like this:: + + SW = r'C:\cygwin\home\kovid\sw' + JPEG_ROOT = ZLIB_ROOT = FREETYPE_ROOT = (SW+r'\lib', SW+r'\include') + +Build and install with:: + python setup.py build + python setup.py install + +Note that the lcms module will not be built. PIL requires lcms-1.x but only +lcms-2.x can be compiled as a 64 bit library. + Test it on the target system with -calibre-debug -c "from PIL import _imaging, _imagingmath, _imagingft, _imagingcms" - +calibre-debug -c "from PIL import Image; import _imaging, _imagingmath, _imagingft" kdewin32-msvc ---------------- +I dont think this is needed any more, I've left it here just in case I'm wrong. + Get it from http://www.winkde.org/pub/kde/ports/win32/repository/kdesupport/ mkdir build Run cmake @@ -448,29 +464,34 @@ cp build/kdewin32-msvc-0.3.9/include/*.h include/ poppler ------------- -In Cmake: disable GTK, Qt, OPenjpeg, cpp, lcms, gtk_tests, qt_tests. Enable qt4, jpeg, png and zlib +mkdir build -NOTE: poppler must be built as a static library, unless you build the qt4 bindings +Run the cmake GUI which will find the various dependencies automatically. +On 64 bit cmake might not let you choose Visual Studio 2008, in whcih case +leave the source field blank, click configure choose Visual Studio 2008 and +then enter the source field. -cp build/utils/Release/*.exe ../../bin/ +In Cmake: disable GTK, Qt, OPenjpeg, cpp, lcms, gtk_tests, qt_tests. Enable +jpeg, png and zlib:: + cp build/utils/Release/*.exe ../../bin/ podofo ---------- +Download from http://podofo.sourceforge.net/download.html + Add the following three lines near the top of CMakeLists.txt SET(WANT_LIB64 FALSE) SET(PODOFO_BUILD_SHARED TRUE) SET(PODOFO_BUILD_STATIC FALSE) -cp build/podofo-*/build/src/Release/podofo.dll bin/ -cp build/podofo-*/build/src/Release/podofo.lib lib/ -cp build/podofo-*/build/src/Release/podofo.exp lib/ - -cp build/podofo-*/build/podofo_config.h include/podofo/ -cp -r build/podofo-*/src/* include/podofo/ - -You have to use >=0.9.1 +Run:: + cp "`find . -name *.dll`" ~/sw/bin/ + cp "`find . -name *.lib`" ~/sw/lib/ + mkdir ~/sw/include/podofo + cp build/podofo_config.h ~/sw/include/podofo + cp -r src/* ~/sw/include/podofo/ ImageMagick @@ -493,7 +514,7 @@ Undefine ProvideDllMain and MAGICKCORE_X11_DELEGATE Now open VisualMagick/VisualDynamicMT.sln set to Release Remove the CORE_xlib, UTIL_Imdisplay and CORE_Magick++ projects. -F7 for build project, you will get one error due to the removal of xlib, ignore +F7 for build solution, you will get one error due to the removal of xlib, ignore it. netifaces @@ -503,10 +524,10 @@ Download the source tarball from http://alastairs-place.net/projects/netifaces/ Rename netifaces.c to netifaces.cpp and make the same change in setup.py -Run +Run:: + python setup.py build + cp `find build/ -name *.pyd` /cygdrive/c/Python27/Lib/site-packages/ -python setup.py build -cp build/lib.win32-2.7/netifaces.pyd /cygdrive/c/Python27/Lib/site-packages/ psutil -------- diff --git a/setup/installer/windows/util.c b/setup/installer/windows/util.c index 86e077780e..fefc98476b 100644 --- a/setup/installer/windows/util.c +++ b/setup/installer/windows/util.c @@ -217,19 +217,15 @@ wchar_t* get_app_dirw() { void load_python_dll() { - char *app_dir, *fc_dir, *fc_file, *dll_dir, *qt_plugin_dir; + char *app_dir, *dll_dir, *qt_plugin_dir; size_t l; app_dir = get_app_dir(); l = strlen(app_dir)+20; dll_dir = (char*) calloc(l, sizeof(char)); - fc_dir = (char*) calloc(l, sizeof(char)); - fc_file = (char*) calloc(l, sizeof(char)); qt_plugin_dir = (char*) calloc(l, sizeof(char)); - if (!dll_dir || !qt_plugin_dir || !fc_dir) ExitProcess(_show_error(L"Out of memory", L"", 1)); + if (!dll_dir || !qt_plugin_dir) ExitProcess(_show_error(L"Out of memory", L"", 1)); _snprintf_s(dll_dir, l, _TRUNCATE, "%sDLLs", app_dir); - _snprintf_s(fc_dir, l, _TRUNCATE, "%sfontconfig", app_dir); - _snprintf_s(fc_file, l, _TRUNCATE, "%s\\fonts.conf", fc_dir); _snprintf_s(qt_plugin_dir, l, _TRUNCATE, "%sqt_plugins", app_dir); free(app_dir); @@ -237,8 +233,6 @@ void load_python_dll() { _putenv_s("MAGICK_CONFIGURE_PATH", dll_dir); _putenv_s("MAGICK_CODER_MODULE_PATH", dll_dir); _putenv_s("MAGICK_FILTER_MODULE_PATH", dll_dir); - _putenv_s("FC_CONFIG_DIR", fc_dir); - _putenv_s("FC_CONFIG_FILE", fc_file); _putenv_s("QT_PLUGIN_PATH", qt_plugin_dir); if (!SetDllDirectoryA(dll_dir)) ExitProcess(show_last_error(L"Failed to set DLL directory.")); diff --git a/src/calibre/constants.py b/src/calibre/constants.py index b6fa0b42d7..d15825d4b9 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -14,14 +14,6 @@ Various run time constants. import sys, locale, codecs, os, importlib, collections -_tc = None -def terminal_controller(): - global _tc - if _tc is None: - from calibre.utils.terminfo import TerminalController - _tc = TerminalController(sys.stdout) - return _tc - _plat = sys.platform.lower() iswindows = 'win32' in _plat or 'win64' in _plat isosx = 'darwin' in _plat @@ -37,6 +29,8 @@ isportable = os.environ.get('CALIBRE_PORTABLE_BUILD', None) is not None ispy3 = sys.version_info.major > 2 isxp = iswindows and sys.getwindowsversion().major < 6 isworker = os.environ.has_key('CALIBRE_WORKER') or os.environ.has_key('CALIBRE_SIMPLE_WORKER') +if isworker: + os.environ.pop('CALIBRE_FORCE_ANSI', None) try: preferred_encoding = locale.getpreferredencoding() diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 957a6ad473..73eecf8069 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1716,7 +1716,7 @@ if __name__ == '__main__': ret = 0 for x in ('lxml', 'calibre.ebooks.BeautifulSoup', 'uuid', - 'calibre.utils.terminfo', 'calibre.utils.magick', 'PIL', 'Image', + 'calibre.utils.terminal', 'calibre.utils.magick', 'PIL', 'Image', 'sqlite3', 'mechanize', 'httplib', 'xml'): if x in sys.modules: ret = 1 diff --git a/src/calibre/debug.py b/src/calibre/debug.py index a06096c593..6a05863c42 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -37,9 +37,6 @@ Run an embedded python interpreter. help='Run the ebook viewer',) parser.add_option('--paths', default=False, action='store_true', help='Output the paths necessary to setup the calibre environment') - parser.add_option('--migrate', action='store_true', default=False, - help='Migrate old database. Needs two arguments. Path ' - 'to library1.db and path to new library folder.') parser.add_option('--add-simple-plugin', default=None, help='Add a simple plugin (i.e. a plugin that consists of only a ' '.py file), by specifying the path to the py file containing the ' @@ -118,28 +115,6 @@ def reinit_db(dbpath, callback=None, sql_dump=None): os.remove(dest) prints('Database successfully re-initialized') -def migrate(old, new): - from calibre.utils.config import prefs - from calibre.library.database import LibraryDatabase - from calibre.library.database2 import LibraryDatabase2 - from calibre.utils.terminfo import ProgressBar - from calibre.constants import terminal_controller - class Dummy(ProgressBar): - def setLabelText(self, x): pass - def setAutoReset(self, y): pass - def reset(self): pass - def setRange(self, min, max): - self.min = min - self.max = max - def setValue(self, val): - self.update(float(val)/getattr(self, 'max', 1)) - - db = LibraryDatabase(old) - db2 = LibraryDatabase2(new) - db2.migrate_old(db, Dummy(terminal_controller(), 'Migrating database...')) - prefs['library_path'] = os.path.abspath(new) - print 'Database migrated to', os.path.abspath(new) - def debug_device_driver(): from calibre.devices import debug debug(ioreg_to_tmp=True, buf=sys.stdout) @@ -249,11 +224,6 @@ def main(args=sys.argv): exec opts.command elif opts.debug_device_driver: debug_device_driver() - elif opts.migrate: - if len(args) < 3: - print 'You must specify the path to library1.db and the path to the new library folder' - return 1 - migrate(args[1], args[2]) elif opts.add_simple_plugin is not None: add_simple_plugin(opts.add_simple_plugin) elif opts.paths: diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index 8a00957c8a..0e8b9abc87 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -240,6 +240,7 @@ class ITUNES(DriverBase): # iTunes enumerations Audiobooks = [ + 'AAC audio file', 'Audible file', 'MPEG audio file', 'Protected AAC audio file' diff --git a/src/calibre/devices/cli.py b/src/calibre/devices/cli.py index 0d5c7f2f19..e1a5375b6b 100755 --- a/src/calibre/devices/cli.py +++ b/src/calibre/devices/cli.py @@ -11,7 +11,6 @@ from optparse import OptionParser from calibre import __version__, __appname__, human_readable from calibre.devices.errors import PathError -from calibre.utils.terminfo import TerminalController from calibre.devices.errors import ArgumentError, DeviceError, DeviceLocked from calibre.customize.ui import device_plugins from calibre.devices.scanner import DeviceScanner @@ -20,8 +19,7 @@ from calibre.utils.config import device_prefs MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output class FileFormatter(object): - def __init__(self, file, term): - self.term = term + def __init__(self, file): self.is_dir = file.is_dir self.is_readonly = file.is_readonly self.size = file.size @@ -94,7 +92,7 @@ def info(dev): print "Software version:", info[2] print "Mime type: ", info[3] -def ls(dev, path, term, recurse=False, color=False, human_readable_size=False, ll=False, cols=0): +def ls(dev, path, recurse=False, human_readable_size=False, ll=False, cols=0): def col_split(l, cols): # split list l into columns rows = len(l) / cols if len(l) % cols: @@ -126,14 +124,13 @@ def ls(dev, path, term, recurse=False, color=False, human_readable_size=False, l for file in files: size = len(str(file.size)) if human_readable_size: - file = FileFormatter(file, term) + file = FileFormatter(file) size = len(file.human_readable_size) if size > maxlen: maxlen = size for file in files: - file = FileFormatter(file, term) + file = FileFormatter(file) name = file.name if ll else file.isdir_name lsoutput.append(name) - if color: name = file.name_in_color lscoloutput.append(name) if ll: size = str(file.size) @@ -173,10 +170,8 @@ def shutdown_plugins(): pass def main(): - term = TerminalController() - cols = term.COLS - if not cols: # On windows terminal width is unknown - cols = 80 + from calibre.utils.terminal import geometry + cols = geometry()[0] parser = OptionParser(usage="usage: %prog [options] command args\n\ncommand "+ "is one of: info, books, df, ls, cp, mkdir, touch, cat, rm, eject, test_file\n\n"+ @@ -260,7 +255,6 @@ def main(): dev.mkdir(args[0]) elif command == "ls": parser = OptionParser(usage="usage: %prog ls [options] path\nList files on the device\n\npath must begin with / or card:/") - parser.add_option("--color", help="show ls output in color", dest="color", action="store_true", default=False) parser.add_option("-l", help="In addition to the name of each file, print the file type, permissions, and timestamp (the modification time, in the local timezone). Times are local.", dest="ll", action="store_true", default=False) parser.add_option("-R", help="Recursively list subdirectories encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False) parser.remove_option("-h") @@ -269,7 +263,7 @@ def main(): if len(args) != 1: parser.print_help() return 1 - print ls(dev, args[0], term, color=options.color, recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols), + print ls(dev, args[0], recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols), elif command == "info": info(dev) elif command == "cp": diff --git a/src/calibre/ebooks/oeb/display/extract.coffee b/src/calibre/ebooks/oeb/display/extract.coffee new file mode 100644 index 0000000000..92ed91a24f --- /dev/null +++ b/src/calibre/ebooks/oeb/display/extract.coffee @@ -0,0 +1,53 @@ +#!/usr/bin/env coffee +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +### + Copyright 2012, Kovid Goyal + Released under the GPLv3 License +### + +if window?.calibre_utils + log = window.calibre_utils.log + +merge = (node, cnode) -> + rules = node.ownerDocument.defaultView.getMatchedCSSRules(node, '') + if rules + for rule in rules + style = rule.style + for name in style + val = style.getPropertyValue(name) + if val and not cnode.style.getPropertyValue(name) + cnode.style.setProperty(name, val) + +inline_styles = (node) -> + cnode = node.cloneNode(true) + merge(node, cnode) + nl = node.getElementsByTagName('*') + cnl = cnode.getElementsByTagName('*') + for node, i in nl + merge(node, cnl[i]) + + return cnode + +class CalibreExtract + # This class is a namespace to expose functions via the + # window.calibre_extract object. + + constructor: () -> + if not this instanceof arguments.callee + throw new Error('CalibreExtract constructor called as function') + this.marked_node = null + + mark: (node) => + this.marked_node = node + + extract: (node=null) => + if node == null + node = this.marked_node + cnode = inline_styles(node) + return cnode.outerHTML + +if window? + window.calibre_extract = new CalibreExtract() + + diff --git a/src/calibre/ebooks/oeb/transforms/flatcss.py b/src/calibre/ebooks/oeb/transforms/flatcss.py index f963f468aa..28ab4a362c 100644 --- a/src/calibre/ebooks/oeb/transforms/flatcss.py +++ b/src/calibre/ebooks/oeb/transforms/flatcss.py @@ -313,7 +313,7 @@ class CSSFlattener(object): if val in ('middle', 'bottom', 'top'): cssdict['vertical-align'] = val elif val in ('left', 'right'): - cssdict['text-align'] = val + cssdict['float'] = val del node.attrib['align'] if node.tag == XHTML('font'): tags = ['descendant::h:%s'%x for x in ('p', 'div', 'table', 'h1', diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 5fc4de3e38..69704de1c7 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -12,7 +12,7 @@ from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, pyqtProperty, QPainter, QPalette, QBrush, QDialog, QColor, QPoint, QImage, QRegion, QIcon, pyqtSignature, QAction, QMenu, QString, pyqtSignal, QSwipeGesture, QApplication, pyqtSlot) -from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings +from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings, QWebElement from calibre.gui2.viewer.flip import SlideFlip from calibre.gui2.shortcuts import Shortcuts @@ -24,6 +24,7 @@ from calibre.gui2.viewer.javascript import JavaScriptLoader from calibre.gui2.viewer.position import PagePosition from calibre.gui2.viewer.config import config, ConfigDialog, load_themes from calibre.gui2.viewer.image_popup import ImagePopup +from calibre.gui2.viewer.table_popup import TablePopup from calibre.ebooks.oeb.display.webview import load_html from calibre.constants import isxp, iswindows # }}} @@ -31,6 +32,7 @@ from calibre.constants import isxp, iswindows class Document(QWebPage): # {{{ page_turn = pyqtSignal(object) + mark_element = pyqtSignal(QWebElement) def set_font_settings(self, opts): settings = self.settings() @@ -182,6 +184,7 @@ class Document(QWebPage): # {{{ ensure_ascii=False))) for pl in self.all_viewer_plugins: pl.load_javascript(evaljs) + evaljs('py_bridge.mark_element.connect(window.calibre_extract.mark)') @pyqtSignature("") def animated_scroll_done(self): @@ -448,6 +451,10 @@ class Document(QWebPage): # {{{ self.height+amount) self.setPreferredContentsSize(s) + def extract_node(self): + return unicode(self.mainFrame().evaluateJavaScript( + 'window.calibre_extract.extract()').toString()) + # }}} class DocumentView(QWebView): # {{{ @@ -496,8 +503,11 @@ class DocumentView(QWebView): # {{{ self.dictionary_action.triggered.connect(self.lookup) self.addAction(self.dictionary_action) self.image_popup = ImagePopup(self) + self.table_popup = TablePopup(self) self.view_image_action = QAction(QIcon(I('view-image.png')), _('View &image...'), self) self.view_image_action.triggered.connect(self.image_popup) + self.view_table_action = QAction(QIcon(I('view.png')), _('View &table...'), self) + self.view_table_action.triggered.connect(self.popup_table) self.search_action = QAction(QIcon(I('dictionary.png')), _('&Search for next occurrence'), self) self.search_action.setShortcut(Qt.CTRL+Qt.Key_S) @@ -603,10 +613,26 @@ class DocumentView(QWebView): # {{{ t = t.replace(u'&', u'&&') return _("S&earch Google for '%s'")%t + def popup_table(self): + html = self.document.extract_node() + self.table_popup(html, QUrl.fromLocalFile(self.last_loaded_path), + self.document.font_magnification_step) + def contextMenuEvent(self, ev): mf = self.document.mainFrame() r = mf.hitTestContent(ev.pos()) img = r.pixmap() + elem = r.element() + if elem.isNull(): + elem = r.enclosingBlockElement() + table = None + parent = elem + while not parent.isNull(): + if (unicode(parent.tagName()) == u'table' or + unicode(parent.localName()) == u'table'): + table = parent + break + parent = parent.parent() self.image_popup.current_img = img self.image_popup.current_url = r.imageUrl() menu = self.document.createStandardContextMenu() @@ -615,6 +641,9 @@ class DocumentView(QWebView): # {{{ if not img.isNull(): menu.addAction(self.view_image_action) + if table is not None: + self.document.mark_element.emit(table) + menu.addAction(self.view_table_action) text = self._selectedText() if text and img.isNull(): diff --git a/src/calibre/gui2/viewer/javascript.py b/src/calibre/gui2/viewer/javascript.py index 179139d082..b9584562c3 100644 --- a/src/calibre/gui2/viewer/javascript.py +++ b/src/calibre/gui2/viewer/javascript.py @@ -34,11 +34,12 @@ class JavaScriptLoader(object): 'utils':'ebooks.oeb.display.utils', 'fs':'ebooks.oeb.display.full_screen', 'math': 'ebooks.oeb.display.mathjax', + 'extract': 'ebooks.oeb.display.extract', } ORDER = ('jquery', 'jquery_scrollTo', 'bookmarks', 'referencing', 'images', 'hyphenation', 'hyphenator', 'utils', 'cfi', 'indexing', 'paged', - 'fs', 'math') + 'fs', 'math', 'extract') def __init__(self, dynamic_coffeescript=False): diff --git a/src/calibre/gui2/viewer/table_popup.py b/src/calibre/gui2/viewer/table_popup.py new file mode 100644 index 0000000000..d466d63def --- /dev/null +++ b/src/calibre/gui2/viewer/table_popup.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import (QDialog, QDialogButtonBox, QVBoxLayout, QApplication, + QSize, QIcon, Qt) +from PyQt4.QtWebKit import QWebView + +from calibre.gui2 import gprefs, error_dialog + +class TableView(QDialog): + + def __init__(self, parent, font_magnification_step): + QDialog.__init__(self, parent) + self.font_magnification_step = font_magnification_step + dw = QApplication.instance().desktop() + self.avail_geom = dw.availableGeometry(parent) + + self.view = QWebView(self) + self.bb = bb = QDialogButtonBox(QDialogButtonBox.Close) + bb.accepted.connect(self.accept) + bb.rejected.connect(self.reject) + self.zi_button = zi = bb.addButton(_('Zoom &in'), bb.ActionRole) + self.zo_button = zo = bb.addButton(_('Zoom &out'), bb.ActionRole) + zi.setIcon(QIcon(I('plus.png'))) + zo.setIcon(QIcon(I('minus.png'))) + zi.clicked.connect(self.zoom_in) + zo.clicked.connect(self.zoom_out) + + self.l = l = QVBoxLayout() + self.setLayout(l) + l.addWidget(self.view) + l.addWidget(bb) + + def zoom_in(self): + self.view.setZoomFactor(self.view.zoomFactor() + + self.font_magnification_step) + + def zoom_out(self): + self.view.setZoomFactor(max(0.1, self.view.zoomFactor() + -self.font_magnification_step)) + + def __call__(self, html, baseurl): + self.view.setHtml( + '%s'%html, + baseurl) + geom = self.avail_geom + self.resize(QSize(int(geom.width()/2.5), geom.height()-50)) + geom = gprefs.get('viewer_table_popup_geometry', None) + if geom is not None: + self.restoreGeometry(geom) + self.setWindowTitle(_('View Table')) + self.show() + + def done(self, e): + gprefs['viewer_table_popup_geometry'] = bytearray(self.saveGeometry()) + return QDialog.done(self, e) + +class TablePopup(object): + + def __init__(self, parent): + self.parent = parent + self.dialogs = [] + + def __call__(self, html, baseurl, font_magnification_step): + if not html: + return error_dialog(self.parent, _('No table found'), + _('No table was found'), show=True) + d = TableView(self.parent, font_magnification_step) + self.dialogs.append(d) + d.finished.connect(self.cleanup, type=Qt.QueuedConnection) + d(html, baseurl) + + def cleanup(self): + for d in tuple(self.dialogs): + if not d.isVisible(): + self.dialogs.remove(d) + diff --git a/src/calibre/library/cli.py b/src/calibre/library/cli.py index 3993244215..676d3cd1bc 100644 --- a/src/calibre/library/cli.py +++ b/src/calibre/library/cli.py @@ -65,8 +65,7 @@ def get_db(dbpath, options): def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, separator, prefix, subtitle='Books in the calibre database'): - from calibre.constants import terminal_controller as tc - terminal_controller = tc() + from calibre.utils.terminal import ColoredStream, geometry if sort_by: db.sort(sort_by, ascending) if search_text: @@ -101,7 +100,7 @@ def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, se for j, field in enumerate(fields): widths[j] = max(widths[j], len(unicode(i[field]))) - screen_width = terminal_controller.COLS if line_width < 0 else line_width + screen_width = geometry()[0] if line_width < 0 else line_width if not screen_width: screen_width = 80 field_width = screen_width//len(fields) @@ -120,7 +119,8 @@ def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, se widths = list(base_widths) titles = map(lambda x, y: '%-*s%s'%(x-len(separator), y, separator), widths, title_fields) - print terminal_controller.GREEN + ''.join(titles)+terminal_controller.NORMAL + with ColoredStream(sys.stdout, fg='green'): + print ''.join(titles) wrappers = map(lambda x: TextWrapper(x-1), widths) o = cStringIO.StringIO() @@ -1288,8 +1288,7 @@ def command_list_categories(args, dbpath): fields = ['category', 'tag_name', 'count', 'rating'] def do_list(): - from calibre.constants import terminal_controller as tc - terminal_controller = tc() + from calibre.utils.terminal import geometry, ColoredStream separator = ' ' widths = list(map(lambda x : 0, fields)) @@ -1297,7 +1296,7 @@ def command_list_categories(args, dbpath): for j, field in enumerate(fields): widths[j] = max(widths[j], max(len(field), len(unicode(i[field])))) - screen_width = terminal_controller.COLS if opts.width < 0 else opts.width + screen_width = geometry()[0] if not screen_width: screen_width = 80 field_width = screen_width//len(fields) @@ -1316,7 +1315,8 @@ def command_list_categories(args, dbpath): widths = list(base_widths) titles = map(lambda x, y: '%-*s%s'%(x-len(separator), y, separator), widths, fields) - print terminal_controller.GREEN + ''.join(titles)+terminal_controller.NORMAL + with ColoredStream(sys.stdout, fg='green'): + print ''.join(titles) wrappers = map(lambda x: TextWrapper(x-1), widths) o = cStringIO.StringIO() diff --git a/src/calibre/test_build.py b/src/calibre/test_build.py index 0c5b430017..f8a5a9286b 100644 --- a/src/calibre/test_build.py +++ b/src/calibre/test_build.py @@ -74,8 +74,13 @@ def test_imaging(): print ('ImageMagick OK!') else: raise RuntimeError('ImageMagick choked!') - from PIL import Image, _imaging, _imagingmath, _imagingft, _imagingcms - _imaging, _imagingmath, _imagingft, _imagingcms + from PIL import Image + try: + import _imaging, _imagingmath, _imagingft + _imaging, _imagingmath, _imagingft + except ImportError: + from PIL import _imaging, _imagingmath, _imagingft + _imaging, _imagingmath, _imagingft i = Image.open(cStringIO.StringIO(data)) if i.size < (20, 20): raise RuntimeError('PIL choked!') diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index bcfd32cb8d..108b004bd6 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.9.6\n" -"POT-Creation-Date: 2012-11-10 07:44+IST\n" -"PO-Revision-Date: 2012-11-10 07:44+IST\n" +"POT-Creation-Date: 2012-11-22 09:19+IST\n" +"PO-Revision-Date: 2012-11-22 09:19+IST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -116,7 +116,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:264 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:266 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:860 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/iterator/spine.py:62 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/iterator/spine.py:63 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/parse_utils.py:353 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/parse_utils.py:356 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/parse_utils.py:360 @@ -131,13 +131,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/ztxt/writer.py:27 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:108 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:109 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:444 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:452 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:445 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:453 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:166 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:411 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:414 -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:159 -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:167 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:174 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:680 #: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:124 @@ -154,32 +154,32 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/email.py:193 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:208 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:408 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1068 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1279 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1282 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1069 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1285 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1373 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1288 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1291 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1379 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:85 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:250 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:261 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:402 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:174 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:178 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:204 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:202 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/google_books_plugin.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:189 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:191 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:884 #: /home/kovid/work/calibre/src/calibre/library/cli.py:244 #: /home/kovid/work/calibre/src/calibre/library/database.py:914 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:586 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:594 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:605 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2276 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2430 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2879 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3526 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3528 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3665 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:587 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:595 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:606 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2279 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2433 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2882 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3533 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3535 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3672 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:250 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:251 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:247 @@ -209,27 +209,27 @@ msgstr "" msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:318 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:322 msgid "File type" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:354 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:368 msgid "Metadata reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:384 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:398 msgid "Metadata writer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:414 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:428 msgid "Catalog generator" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:527 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:551 msgid "User Interface Action" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:561 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:585 #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:20 #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:197 @@ -239,12 +239,12 @@ msgstr "" msgid "Preferences" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:613 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:637 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 msgid "Store" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:617 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:641 msgid "An ebook store." msgstr "" @@ -446,7 +446,7 @@ msgid "Change the way calibre behaves" msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:964 -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:276 msgid "Add your own columns" msgstr "" @@ -827,12 +827,12 @@ msgstr "" msgid "Enabled plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:511 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:534 #, python-format msgid "Initialization of plugin %s failed with traceback:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:591 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:614 msgid "" " %prog options\n" "\n" @@ -840,31 +840,31 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:597 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:620 msgid "Add a plugin by specifying the path to the zip file containing it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:599 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:622 msgid "For plugin developers: Path to the directory where you are developing the plugin. This command will automatically zip up the plugin and update it in calibre." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:603 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:626 msgid "Remove a custom plugin by name. Has no effect on builtin plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:605 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:628 msgid "Customize plugin. Specify name of plugin and customization string separated by a comma." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:607 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:630 msgid "List all installed plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:609 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:632 msgid "Enable the named plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/ui.py:611 +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:634 msgid "Disable the named plugin" msgstr "" @@ -873,8 +873,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:320 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:747 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:135 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:144 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:136 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:145 #, python-format msgid "Path to library too long. Must be less than %d characters." msgstr "" @@ -883,35 +883,35 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:666 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:668 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1062 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1063 #: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:887 #: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:910 msgid "Yes" msgstr "" #: /home/kovid/work/calibre/src/calibre/db/fields.py:163 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1217 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1218 msgid "Main" msgstr "" #: /home/kovid/work/calibre/src/calibre/db/fields.py:165 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:77 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1219 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1220 msgid "Card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/db/fields.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:79 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1221 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1222 msgid "Card B" msgstr "" -#: /home/kovid/work/calibre/src/calibre/debug.py:67 +#: /home/kovid/work/calibre/src/calibre/debug.py:64 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:47 msgid "Cause a running calibre instance, if any, to be shutdown. Note that if there are running jobs, they will be silently aborted, so use with care." msgstr "" -#: /home/kovid/work/calibre/src/calibre/debug.py:189 +#: /home/kovid/work/calibre/src/calibre/debug.py:164 msgid "Debug log" msgstr "" @@ -996,42 +996,42 @@ msgstr "" msgid "

Unable to communicate with iTunes.

Refer to this forum post for more information.

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:381 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:384 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:382 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:385 msgid "Updating device metadata listing..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:461 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:501 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1116 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1162 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3246 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3288 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:462 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:502 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1117 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1163 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3247 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3289 #, python-format msgid "%(num)d of %(tot)d" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:509 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1167 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3295 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:510 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1168 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3296 #: /home/kovid/work/calibre/src/calibre/gui2/ebook_download.py:110 msgid "finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:701 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:702 msgid "" "Some books not found in iTunes database.\n" "Delete using the iBooks app.\n" "Click 'Show Details' for a list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1079 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:1080 msgid "" "Some cover art could not be converted.\n" "Click 'Show Details' for a list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2769 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2770 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:106 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:448 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:471 @@ -1047,20 +1047,20 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:469 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1197 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1199 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:371 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:384 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3383 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:372 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:385 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3386 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187 msgid "News" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2770 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3339 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3357 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2771 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3342 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3360 msgid "Catalog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3138 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3139 msgid "Communicate with iTunes." msgstr "" @@ -3115,7 +3115,7 @@ msgstr "" msgid "Running transforms on ebook..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1149 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1153 #, python-format msgid "Running %s plugin" msgstr "" @@ -3408,10 +3408,10 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/quickview.py:85 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/template_dialog.py:222 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1073 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1074 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:146 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:162 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/models.py:23 #: /home/kovid/work/calibre/src/calibre/library/cli.py:564 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:375 @@ -3421,7 +3421,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:770 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1074 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1075 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/models.py:23 msgid "Author(s)" msgstr "" @@ -3587,7 +3587,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1487 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1279 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:969 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 msgid "Cover" msgstr "" @@ -3794,7 +3794,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/cover.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:186 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:966 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:967 #, python-format msgid "Book %(sidx)s of %(series)s" msgstr "" @@ -3853,154 +3853,154 @@ msgstr "" msgid "Table of Contents:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:119 msgid "Send file to storage card instead of main memory by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:121 msgid "Confirm before deleting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:123 msgid "Main window geometry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:125 msgid "Notify when a new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127 msgid "Use Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:129 msgid "Sort tags list by name, popularity, or rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:131 msgid "Match tags by any or all." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:133 msgid "Number of covers to show in the cover browsing mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:135 msgid "Defaults for conversion to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:137 msgid "Options for the LRF ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:141 msgid "Formats that are viewed using the internal viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:143 msgid "Columns to be displayed in the book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:144 msgid "Automatically launch content server on application startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:145 msgid "Oldest news kept in database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:146 msgid "Show system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:148 msgid "Upload downloaded news to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:150 msgid "Delete news books from library after uploading to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:152 msgid "Show the cover flow in a separate window instead of in the main calibre window" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:154 msgid "Disable notifications from the system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:156 msgid "Default action to perform when send to device button is clicked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:160 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:161 msgid "Start searching as you type. If this is disabled then search will only take place when the Enter or Return key is pressed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:164 msgid "When searching, show all books with search results highlighted instead of showing only the matches. You can use the N or F3 keys to go to the next match." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:189 msgid "Maximum number of simultaneous conversion/news download jobs. This number is twice the actual value for historical reasons." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:191 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:192 msgid "Download social metadata (tags/rating/etc.)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:194 msgid "Overwrite author and title with new metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:196 msgid "Automatically download the cover, if available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:197 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:198 msgid "Limit max simultaneous jobs to number of CPUs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:200 msgid "The layout of the user interface. Wide has the book details panel on the right and narrow has it at the bottom." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:203 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:204 msgid "Show the average rating per item indication in the tag browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:205 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:206 msgid "Disable UI animations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:211 msgid "tag browser categories not to display" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:277 msgid "WARNING:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:287 msgid "ERROR:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:298 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:299 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:258 msgid "Show this confirmation again" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:338 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:134 msgid "Restart needed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:340 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:741 msgid "Restart calibre now" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:568 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:569 msgid "Choose Files" msgstr "" @@ -4115,6 +4115,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:256 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:293 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:271 msgid "No books selected" msgstr "" @@ -4123,7 +4124,7 @@ msgid "Cannot add files as no books are selected" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:100 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:120 msgid "Are you sure" msgstr "" @@ -4412,57 +4413,66 @@ msgid "The folder %s already exists. Delete it first." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:319 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:381 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:97 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:746 msgid "Too long" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:324 +msgid "Not found" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:325 +#, python-format +msgid "Cannot rename as no library was found at %s. Try switching to this library first, then switch back and retry the renaming." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:335 msgid "Rename failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:328 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:336 #, python-format msgid "Failed to rename the library at %s. The most common cause for this is if one of the files in the library is open in another program." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:350 msgid "Library removed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:351 #, python-format msgid "The library %s has been removed from calibre. The files remain on your computer, if you want to delete them, you will have to do so manually." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:356 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:364 msgid "none" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:365 msgid "Backup status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:358 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:366 #, python-format msgid "Book metadata files remaining to be written: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:372 msgid "Backup metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:373 msgid "Metadata will be backed up while calibre is running, at the rate of approximately 1 book every three seconds." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:374 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:382 #, python-format msgid "Path to library too long. Must be less than %d characters. Move your library to a location with a shorter path using Windows Explorer, then point calibre to the new location and try again." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:417 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:736 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:83 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:88 @@ -4471,11 +4481,11 @@ msgstr "" msgid "Success" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:410 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:418 msgid "Found no errors in your calibre library database. Do you want calibre to check if the files in your library match the information in the database?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:423 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:197 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:975 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:1004 @@ -4486,35 +4496,35 @@ msgstr "" msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:424 msgid "Database integrity check failed, click Show details for details." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:428 msgid "Starting library scan, this may take a while" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:434 msgid "No problems found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:435 msgid "The files in your library match the information in the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:526 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:531 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:539 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:225 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:91 -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:1007 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:1016 msgid "Not allowed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:527 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:535 msgid "You cannot change libraries while using the environment variable CALIBRE_OVERRIDE_DATABASE_PATH." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:532 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:540 msgid "You cannot change libraries while jobs are running." msgstr "" @@ -4553,8 +4563,8 @@ msgid "Empty output file, probably the conversion process crashed" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:84 -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:392 -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:405 #: /home/kovid/work/calibre/src/calibre/gui2/auto_add.py:221 #, python-format msgid "%(title)s by %(author)s" @@ -5257,13 +5267,13 @@ msgid "Search for %s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:35 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:177 msgid "Stores" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:38 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_dialog.py:18 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:309 msgid "Choose stores" msgstr "" @@ -5437,6 +5447,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:137 #: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:217 #: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:270 msgid "Cannot view" msgstr "" @@ -5481,86 +5492,86 @@ msgstr "" msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:70 msgid "Searching in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:253 msgid "Adding..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:258 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:267 msgid "Searching in all sub-directories..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:278 msgid "Path error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:279 msgid "The specified directory could not be processed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:283 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1131 msgid "No books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:284 msgid "No books found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:297 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:802 msgid "No permission" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:289 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:298 msgid "Cannot add some files as you do not have permission to access them. Click Show Details to see the list of such files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:366 msgid "Added" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:370 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:379 msgid "Adding failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:371 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:380 msgid "The add books process seems to have hung. Try restarting calibre and adding the books in smaller increments, until you find the problem book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:387 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:396 msgid "Already in calibre:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:404 msgid "You are trying to add:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:409 #: /home/kovid/work/calibre/src/calibre/gui2/auto_add.py:223 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:410 msgid "Books with the same title as the following already exist in calibre. Add them anyway?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:404 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:413 msgid "Adding duplicates..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:473 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:482 msgid "Saving..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:480 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:489 msgid "Collecting data, please wait..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:561 msgid "Saved" msgstr "" @@ -5664,7 +5675,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:277 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:279 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:162 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:166 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:89 @@ -5680,8 +5691,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:80 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:85 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:79 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:143 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:181 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:75 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:206 msgid "..." @@ -5728,7 +5739,7 @@ msgid "Book %(sidx)s of %(series)s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:232 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1077 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1078 msgid "Collections" msgstr "" @@ -5853,7 +5864,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:79 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:40 #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:128 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:125 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:146 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/conversion_ui.py:54 @@ -5984,7 +5995,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:792 #: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:608 -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4679 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4683 msgid "False" msgstr "" @@ -6314,7 +6325,7 @@ msgid "Choose foreground color" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:189 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:235 msgid "Choose background color" msgstr "" @@ -6927,44 +6938,44 @@ msgid "Set the metadata. The output file will contain as much of this metadata a msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:99 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1008 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1009 msgid "This book has no cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:105 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1010 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1011 #, python-format msgid "Cover size: %(width)d x %(height)d pixels" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:172 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:909 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:910 msgid "Choose cover for " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:179 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:917 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:918 msgid "Cannot read" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:180 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:918 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:919 msgid "You do not have permission to read the file: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:188 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:195 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:926 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:927 msgid "Error reading file" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:189 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:927 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:928 msgid "

There was an error reading from file:
" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:196 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:937 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:938 msgid " is not a valid picture" msgstr "" @@ -7017,7 +7028,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:561 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1100 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1101 msgid "Tags categorize the book. This is particularly useful while searching.

They can be any words or phrases, separated by commas." msgstr "" @@ -7167,22 +7178,22 @@ msgid "Preserve &aspect ratio of cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:105 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:368 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:374 msgid "Se&rif family:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:106 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:369 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:375 msgid "&Sans family:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:107 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:370 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:376 msgid "&Monospace family:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:108 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:375 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:381 msgid "S&tandard font:" msgstr "" @@ -7192,17 +7203,17 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:110 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:112 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:372 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:374 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:389 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:391 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:393 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:378 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:395 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:397 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:403 msgid " px" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:111 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:379 msgid "Monospace &font size:" msgstr "" @@ -7273,7 +7284,7 @@ msgid "Occurrences:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/regex_builder_ui.py:94 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:185 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:78 msgid "0" msgstr "" @@ -7396,7 +7407,7 @@ msgid "Remove the currently selected expression" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/search_and_replace_ui.py:153 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:879 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:880 msgid "&Remove" msgstr "" @@ -7405,7 +7416,7 @@ msgid "Load a list of expressions from a previously saved file" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/search_and_replace_ui.py:155 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:433 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:441 msgid "&Load" msgstr "" @@ -7415,7 +7426,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/search_and_replace_ui.py:157 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/search_ui.py:188 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:431 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:439 #: /usr/src/qt-everywhere-opensource-src-4.8.2/src/gui/widgets/qdialogbuttonbox.cpp:661 msgid "&Save" msgstr "" @@ -7771,7 +7782,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:233 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:290 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:294 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1412 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1413 msgid "Undefined" msgstr "" @@ -8610,6 +8621,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:195 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:187 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/adv_search_builder_ui.py:181 msgid "&Title:" msgstr "" @@ -8678,7 +8690,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:77 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:62 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1075 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1076 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:35 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:76 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:365 @@ -8779,41 +8791,41 @@ 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:523 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:712 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:721 msgid "No matches found" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:160 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:406 msgid "Change Case" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:161 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:300 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:407 msgid "Upper Case" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:162 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:299 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:408 msgid "Lower Case" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:163 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:397 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:409 msgid "Swap Case" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:164 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:301 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:398 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:410 msgid "Title Case" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:165 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:302 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:411 msgid "Capitalize" msgstr "" @@ -8892,6 +8904,7 @@ msgid "Find next match" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:188 msgid "&Search" msgstr "" @@ -9115,13 +9128,13 @@ msgid "Specify how the author(s) of this book should be sorted. For example Char msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:554 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1058 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1059 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:555 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:556 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1059 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1060 msgid "Rating of this book. 0-5 stars" msgstr "" @@ -9188,7 +9201,7 @@ msgid "&Force numbers to start with:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:582 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1394 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1395 msgid "&Date:" msgstr "" @@ -9210,7 +9223,7 @@ msgid "Clear published date" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:591 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1163 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1164 msgid "&Languages:" msgstr "" @@ -9474,7 +9487,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:186 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:82 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:178 msgid "All" msgstr "" @@ -9804,9 +9817,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:95 #: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:288 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:80 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:144 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:637 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:652 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:281 msgid "Search" msgstr "" @@ -10245,12 +10257,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:197 #: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:172 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/adv_search_builder_ui.py:183 msgid "&Author:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:199 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1099 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1100 msgid "Ta&gs:" msgstr "" @@ -10988,7 +11001,7 @@ msgid "Regular expression (?P)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:149 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1296 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1297 msgid "ISBN:" msgstr "" @@ -11052,7 +11065,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:78 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:83 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:83 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:148 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:180 msgid "None" msgstr "" @@ -11290,7 +11303,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/keyboard.py:646 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:251 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks.py:440 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:360 msgid "No matches" msgstr "" @@ -11362,7 +11375,7 @@ msgid "Copy current search text (instead of search name)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:42 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1066 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1067 msgid "stars" msgstr "" @@ -11385,13 +11398,13 @@ msgid "Modified" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:785 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1411 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1417 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:312 msgid "The lookup/search name is \"{0}\"" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:791 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1413 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1419 msgid "This book's UUID is \"{0}\"" msgstr "" @@ -11420,71 +11433,71 @@ msgstr "" msgid "Could not set data, click Show Details to see why." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1072 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1073 msgid "In Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1076 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1077 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:355 msgid "Size" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1393 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1399 msgid "Marked for deletion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1396 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1402 msgid "Double click to edit me

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:208 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:211 #, python-format msgid "Hide column %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:216 #, python-format msgid "Sort on %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:217 msgid "Ascending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:220 msgid "Descending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:232 #, python-format msgid "Change text alignment for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:234 msgid "Left" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:234 msgid "Right" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:235 msgid "Center" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:254 msgid "Show column" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:266 msgid "Shrink column if it is too wide to fit" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:269 msgid "Restore default layout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:1008 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:1017 msgid "Dropping onto a device is not supported. First add the book to the calibre library." msgstr "" @@ -11526,12 +11539,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:517 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:534 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:518 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:535 msgid "Previous Page" msgstr "" @@ -11709,6 +11722,7 @@ msgid "&Preferences" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:212 msgid "&Quit" msgstr "" @@ -11813,70 +11827,70 @@ msgstr "" msgid "Could not read metadata from %s format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:875 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:876 msgid "&Browse" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:877 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:878 msgid "T&rim" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:885 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:886 msgid "Download co&ver" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:886 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:887 msgid "&Generate cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:936 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:937 msgid "Not a valid picture" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:960 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:961 msgid "Specify title and author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:961 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:962 msgid "You must specify a title and author before generating a cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:980 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:981 msgid "Invalid cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:981 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:982 msgid "Could not change cover as the image is invalid." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1135 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1136 msgid "Tags changed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1136 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1137 msgid "You have changed the tags. In order to use the tags editor, you must either discard or apply these changes. Apply changes?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1164 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1165 msgid "A comma separated list of languages for this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1187 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1188 msgid "Unknown language" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1188 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1189 #, python-format msgid "The language %s is not recognized" msgid_plural "The languages %s are not recognized" msgstr[0] "" msgstr[1] "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1200 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1201 msgid "I&ds:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1201 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1202 #, python-format msgid "" "Edit the identifiers for this book. For example: \n" @@ -11884,38 +11898,38 @@ msgid "" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1265 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1327 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1266 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1328 msgid "This ISBN number is valid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1268 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1330 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1269 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1331 msgid "This ISBN number is invalid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1293 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1315 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1294 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1316 msgid "Invalid ISBN" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1294 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1295 msgid "Enter an ISBN" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1316 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1317 msgid "The ISBN you entered is not valid. Try again." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1340 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1341 msgid "&Publisher:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1415 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1416 msgid "Clear date" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1449 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1450 msgid "Publishe&d:" msgstr "" @@ -12204,63 +12218,43 @@ msgstr "" msgid "Configure " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:32 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:33 msgid "Ignore duplicate incoming formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:33 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:34 msgid "Overwrite existing duplicate formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:35 msgid "Create new record for each duplicate format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:51 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:52 msgid "Choose a folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:109 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:116 msgid "Invalid folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:111 #, python-format msgid "You must specify an existing folder as your auto-add folder. %s does not exist." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:117 #, python-format msgid "You do not have read/write permissions for the folder: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding.py:121 #, python-format msgid "WARNING: Any files you place in %s will be automatically deleted after being added to calibre. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:123 -msgid "Here you can control how calibre will read metadata from the files you add to it. calibre can either read metadata from the contents of the file, or from the filename." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:124 -msgid "Read &metadata from file contents rather than file name" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:125 -msgid "Swap the firstname and lastname of the author. This affects only metadata read from file names." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:126 -msgid "&Swap author firstname and lastname" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:127 -msgid "When using the \"&Copy to library\" action to copy books between libraries, preserve the date" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:128 msgid "" "Automerge: If books with similar titles and authors found, merge the incoming formats automatically into\n" "existing book records. The box to the right controls what happens when an existing record already has\n" @@ -12269,11 +12263,11 @@ msgid "" "Title match ignores leading indefinite articles (\"the\", \"a\", \"an\"), punctuation, case, etc. Author match is exact." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:131 msgid "&Automerge added books if they already exist in the calibre library:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:132 msgid "" "Automerge: If books with similar titles and authors found, merge the incoming formats automatically into\n" "existing book records. This box controls what happens when an existing record already has\n" @@ -12287,23 +12281,47 @@ msgid "" "Author matching is exact." msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:142 +msgid "Here you can control how calibre will read metadata from the files you add to it. calibre can either read metadata from the contents of the file, or from the filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:143 +msgid "Read &metadata from file contents rather than file name" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:144 -msgid "&Tags to apply when adding a book:" +msgid "Swap the firstname and lastname of the author. This affects only metadata read from file names." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:145 -msgid "A comma-separated list of tags that will be applied to books added to the library" +msgid "&Swap author firstname and lastname" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:146 -msgid "&Configure metadata from file name" +msgid "&Tags to apply when adding a book:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:147 -msgid "The Add &Process" +msgid "A comma-separated list of tags that will be applied to books added to the library" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:148 +msgid "&Configure metadata from file name" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:149 +msgid "When using the \"&Copy to library\" action to copy books between libraries, preserve the date" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:150 +msgid "Automatically &convert added books to the current output format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:151 +msgid "The Add &Process" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:152 msgid "" "If set, this option will causes calibre to check if a file\n" " being auto-added is already in the calibre library.\n" @@ -12311,35 +12329,35 @@ msgid "" " you want to add it anyway." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:156 msgid "Check for &duplicates when auto-adding files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:157 msgid "Specify a folder. Any files you put into this folder will be automatically added to calibre (restart required)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:158 msgid "WARNING: Files in the above folder will be deleted after being added to calibre." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:159 msgid "Ignore files with the following extensions when automatically adding " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:160 msgid "Folder to auto-add files from" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:161 msgid "Browse for folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:159 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:163 msgid "Automatically &convert added files to the current output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:160 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:164 msgid "&Automatic Adding" msgstr "" @@ -13191,7 +13209,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:188 #: /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:245 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:247 msgid " or " msgstr "" @@ -13495,7 +13513,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:136 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:138 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:421 msgid " secs" msgstr "" @@ -14234,7 +14252,7 @@ msgid "Set this to -1 if the function takes a variable number of arguments" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/template_functions_ui.py:102 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:443 msgid "&Delete" msgstr "" @@ -14578,7 +14596,6 @@ msgid "Nam&e/Description ..." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:78 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:142 msgid "Query:" msgstr "" @@ -14587,12 +14604,12 @@ msgid "Enable" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:84 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:179 msgid "Invert" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:21 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 msgid "Affiliate" msgstr "" @@ -14630,7 +14647,7 @@ msgid "This store is headquartered in %s. This is a good indication of what mark msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:143 -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:247 #, python-format msgid "Buying from this store supports the calibre developer: %s." msgstr "" @@ -14701,36 +14718,36 @@ msgstr "" msgid "Titl&e/Author/Price ..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 msgid "DRM" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 msgid "Download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:39 msgid "Price" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:232 #, python-format msgid "Detected price as: %s. Check with the store before making a purchase to verify this price is correct. This price often does not include promotions the store may be running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:235 msgid "This book as been detected as having DRM restrictions. This book may not work with your reader and you will have limitations placed upon you as to what you can do with this book. Check with the store before making any purchases to ensure you can actually read this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:237 msgid "This book has been detected as being DRM Free. You should be able to use this book on any device provided it is in a format calibre supports for conversion. However, before making a purchase double check the DRM status with the store. The store may not be disclosing the use of DRM." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:239 msgid "The DRM status of this book could not be determined. There is a very high likelihood that this book is actually DRM restricted." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:244 #, python-format msgid "The following formats can be downloaded directly: %s." msgstr "" @@ -14743,49 +14760,71 @@ msgstr "" msgid "Goto in store..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:128 #, python-format msgid "Buying from this store supports the calibre developer: %s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:177 +msgid "No query" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:178 +msgid "You must enter a title, author or keyword to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:300 msgid "Customize get books search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:287 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:310 msgid "Configure search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:360 msgid "Couldn't find any books matching your query." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:374 msgid "Choose format to download to your library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:170 msgid "Get Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:171 +msgid "Search by title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:173 +msgid "Search by author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:175 +msgid "&Keyword:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:176 +msgid "Search by any keyword" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:182 msgid "Open a selected book in the system's web browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:183 msgid "Open in &external browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:184 #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:77 msgid "Books:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:154 -#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:79 -#: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:186 #: /usr/src/qt-everywhere-opensource-src-4.8.2/src/gui/widgets/qdialogbuttonbox.cpp:670 -msgid "Close" +msgid "&Close" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/store/stores/ebooks_com_plugin.py:95 @@ -14826,6 +14865,12 @@ msgstr "" msgid "&Query:" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:79 +#: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:63 +#: /usr/src/qt-everywhere-opensource-src-4.8.2/src/gui/widgets/qdialogbuttonbox.cpp:670 +msgid "Close" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/store/web_control.py:75 msgid "This ebook is a DRMed EPUB file. You will be prompted to save this file to your computer. Once it is saved, open it with Adobe Digital Editions (ADE).

ADE, in turn will download the actual ebook, which will be a .epub file. You can add this book to calibre using \"Add Books\" and selecting the file from the ADE library folder." msgstr "" @@ -14859,7 +14904,7 @@ msgid "Changing the metadata for that many books can take a while. Are you sure? msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:858 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:494 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:495 msgid "Searches" msgstr "" @@ -15372,8 +15417,8 @@ msgid "Edit" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager_ui.py:65 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:417 #: /usr/src/qt-everywhere-opensource-src-4.8.2/src/gui/widgets/qdialogbuttonbox.cpp:676 msgid "Reset" msgstr "" @@ -15391,17 +15436,17 @@ msgid "Options to customize the ebook viewer" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:30 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1107 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1116 msgid "Remember last used window size" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:32 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:101 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/config.py:34 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:402 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 "" @@ -15449,266 +15494,282 @@ msgstr "" msgid "Show the scrollbar in fullscreen mode." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:70 -msgid "Font options" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:63 +msgid "Start viewer in full screen mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:72 -msgid "The serif font family" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:65 +msgid "Show full screen usage help" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:74 -msgid "The sans-serif font family" +msgid "Font options" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:76 -msgid "The monospaced font family" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:77 -msgid "The standard font size in px" +msgid "The serif font family" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:78 +msgid "The sans-serif font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:80 +msgid "The monospaced font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:81 +msgid "The standard font size in px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:82 msgid "The monospaced font size in px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:79 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:83 msgid "The standard font type" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:141 msgid "Theme name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:142 msgid "Choose a name for this theme" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:151 #, python-format msgid "Saved settings as the theme named: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:167 #, python-format msgid "Loaded settings from the theme %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:174 #, python-format msgid "Deleted the theme named: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:234 msgid "Choose text color" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:254 msgid "Still editing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:255 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/config_ui.py:367 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:373 msgid "Configure Ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:371 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:377 msgid "&Default font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:376 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:382 msgid "Serif" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:377 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:383 msgid "Sans-serif" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:378 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:384 msgid "Monospace" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:379 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:385 msgid "Font &magnification step size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:386 msgid "" "The amount by which the font size is increased/decreased\n" " when you click the font size larger/smaller buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:382 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:388 msgid "%" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:383 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:389 msgid "&Font options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:390 msgid "

These options only apply in \"paged\" mode, where the text is broken up into pages, as in a paper book. To get into this mode, use the button with the yellow scroll icon in the top right corner of the viewer window." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:385 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:391 msgid "The number of &pages of text to show on screen " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:386 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:392 msgid " page(s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:387 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:393 msgid "&Override the page margin settings specified in the book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:388 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:394 msgid "&Top margin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:390 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:396 msgid "&Side margin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:398 msgid "&Bottom margin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:400 msgid "Text &layout in paged mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:401 msgid "Maximum text width in &fullscreen:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:398 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:404 msgid "Show &clock in full screen mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:405 msgid "Show reading &position in full screen mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:406 msgid "Show &scrollbar in full screen mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:407 +msgid "&Start viewer in full screen mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:408 +msgid "Show &help message when starting full screen mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:409 msgid "F&ull screen options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:402 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:410 msgid "Background color:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:403 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:407 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:415 msgid "Sample" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:416 msgid "Change" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:414 msgid "Text color:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:410 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:418 msgid "Colors and backgrounds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:419 msgid "Page flip &duration:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:420 msgid "disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:414 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:422 msgid "Mouse &wheel flips pages" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:423 msgid "Line &scrolling stops at page breaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:424 msgid "&Resize images larger than the viewer window (needs restart)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:425 msgid "Page Fl&ip options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:426 msgid "H&yphenate (break line in the middle of large words)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:427 msgid "Default &language for hyphenation:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:428 msgid "The default language to use for hyphenation rules. If the book does not specify a language, this will be used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:429 msgid "Remember last used &window size and layout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:430 msgid "Remember the ¤t page when quitting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:431 msgid "&Miscellaneous options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:432 msgid "&General" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:433 msgid "Double click to change a keyboard shortcut" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:434 msgid "&Keyboard shortcuts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:435 msgid "

A CSS stylesheet that can be used to control the look and feel of books. For examples, click here." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:428 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:436 msgid "User &Stylesheet" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:429 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:437 msgid "You can save and load the viewer settings as themes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:430 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:438 msgid "Save current settings as a theme:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:432 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:440 msgid "Load a previously saved theme:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:434 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:442 msgid "Delete a saved theme:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:436 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:444 msgid "&Theming" msgstr "" @@ -15716,68 +15777,87 @@ msgstr "" msgid "No results found for:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:483 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:497 msgid "&Lookup in dictionary" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:488 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:503 msgid "View &image..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:491 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:505 +msgid "View &table..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:508 msgid "&Search for next occurrence" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:496 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:513 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:141 msgid "Go to..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:525 msgid "Next Section" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:526 msgid "Previous Section" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:528 msgid "Document Start" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:529 msgid "Document End" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:531 msgid "Section Start" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:515 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:532 msgid "Section End" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:543 +msgid "Normal font size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:610 +#, python-format +msgid "S&earch Google for '%s'" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/viewer/image_popup.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/table_popup.py:38 msgid "Zoom &in" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/image_popup.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/table_popup.py:39 msgid "Zoom &out" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/image_popup.py:40 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/table_popup.py:40 msgid "&Save as" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/image_popup.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/table_popup.py:41 msgid "&Rotate" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/image_popup.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/table_popup.py:67 msgid "Choose a file to save to" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/image_popup.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/table_popup.py:100 #, python-format msgid "View Image: %s" msgstr "" @@ -15854,143 +15934,143 @@ msgstr "" msgid "Switch to flow mode - where the text is not broken up into pages" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:204 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:206 msgid "Search for text in book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:246 #, python-format msgid "Toggle full screen (%s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:286 msgid "Full screen mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:287 msgid "Right click to show controls" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:288 msgid "Tap in the left or right page margin to turn pages" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:287 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:289 msgid "Press Esc to quit" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:303 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:337 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:347 msgid "Clear list of recently opened books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:455 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:461 #, python-format msgid "Connecting to dict.org to lookup: %s…" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:620 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:631 msgid "No such location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:621 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:632 msgid "The location pointed to by this item does not exist." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:672 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:683 msgid "Choose ebook" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:673 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:684 msgid "Ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:693 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:700 #, python-format msgid "" "Make font size %(which)s\n" "Current magnification: %(mag).1f" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:695 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:702 msgid "larger" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:697 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:704 msgid "smaller" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:713 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:722 #, python-format msgid "No matches found for: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:762 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:771 msgid "Loading flow..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:840 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:849 #, python-format msgid "Laying out %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:907 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:916 #, python-format msgid "Bookmark #%d" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:911 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:920 msgid "Add bookmark" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:912 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:921 msgid "Enter title for bookmark:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:923 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:932 msgid "Manage Bookmarks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:965 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:974 msgid "Loading ebook..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:978 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:987 msgid "Could not open ebook" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:979 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:988 msgid "Unknown error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1094 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1103 msgid "Options to control the ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1101 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1110 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:1104 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1113 msgid "If specified, viewer window will try to open full screen when started." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1109 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1118 msgid "Print javascript alert and console messages to the console" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1111 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1120 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:1118 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1127 msgid "" "%prog [options] file\n" "\n" @@ -16069,11 +16149,11 @@ msgstr "" msgid "Load a theme" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/printing.py:66 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/printing.py:68 msgid "Failed to render" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/printing.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/printing.py:69 #, python-format msgid "Failed to render document %s" msgstr "" @@ -16087,19 +16167,19 @@ msgstr "" msgid "The name %r does not appear to end with a file extension. The name must end with a file extension like .epub or .mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:908 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:923 msgid "Drag to resize" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:936 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:951 msgid "Show" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:943 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:958 msgid "Hide" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:980 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:995 msgid "Toggle" msgstr "" @@ -16562,7 +16642,7 @@ msgid "" "Applies to: CSV, XML output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:41 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:42 #, python-format msgid "" "Title of generated catalog used as title in metadata.\n" @@ -16570,7 +16650,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:48 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:49 #, python-format msgid "" "Create cross-references in Authors section for books with multiple authors.\n" @@ -16578,7 +16658,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:55 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:56 #, python-format msgid "" "Save the output from different stages of the conversion pipeline to the specified directory. Useful if you are unsure at which stage of the conversion process a bug is occurring.\n" @@ -16586,7 +16666,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:65 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:66 #, python-format msgid "" "Regex describing tags to exclude as genres.\n" @@ -16594,7 +16674,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:72 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:73 msgid "" "Specifies the rules used to exclude books from the generated catalog.\n" "The model for an exclusion rule is either\n" @@ -16607,7 +16687,7 @@ msgid "" "Default: \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:85 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:86 #, python-format msgid "" "Include 'Authors' section in catalog.\n" @@ -16615,7 +16695,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:92 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:93 #, python-format msgid "" "Include 'Descriptions' section in catalog.\n" @@ -16623,7 +16703,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:99 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:100 #, python-format msgid "" "Include 'Genres' section in catalog.\n" @@ -16631,7 +16711,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:106 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:107 #, python-format msgid "" "Include 'Titles' section in catalog.\n" @@ -16639,7 +16719,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:113 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:114 #, python-format msgid "" "Include 'Series' section in catalog.\n" @@ -16647,7 +16727,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:120 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:121 #, python-format msgid "" "Include 'Recently Added' section in catalog.\n" @@ -16655,7 +16735,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:127 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:128 #, python-format msgid "" "Custom field containing note text to insert in Description header.\n" @@ -16663,7 +16743,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:134 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:135 #, python-format msgid "" "#:[before|after]:[True|False] specifying:\n" @@ -16674,7 +16754,7 @@ msgid "" "Applies to AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:144 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:145 #, python-format msgid "" "Specifies the output profile. In some cases, an output profile is required to optimize the catalog for the device. For example, 'kindle' or 'kindle_dx' creates a structured Table of Contents with Sections and Articles.\n" @@ -16682,7 +16762,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:151 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:152 msgid "" "Specifies the rules used to include prefixes indicating read books, wishlist items and other user-specified prefixes.\n" "The model for a prefix rule is ('','','','').\n" @@ -16690,7 +16770,7 @@ msgid "" "Default:\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:160 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:161 #, python-format msgid "" "Replace existing cover when generating the catalog.\n" @@ -16698,7 +16778,7 @@ msgid "" "Applies to: AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:167 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:168 #, python-format msgid "" "Size hint (in inches) for book covers in catalog.\n" @@ -16707,7 +16787,7 @@ msgid "" "Applies to AZW3, ePub, MOBI output formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:277 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi.py:279 msgid "" "\n" "*** Adding 'By Authors' Section required for MOBI output ***" @@ -16874,7 +16954,7 @@ msgstr "" msgid "Thumbnail" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4806 +#: /home/kovid/work/calibre/src/calibre/library/catalogs/epub_mobi_builder.py:4810 msgid "Saving NCX" msgstr "" @@ -17464,31 +17544,31 @@ msgstr "" msgid "The label must contain only lower case letters, digits and underscores, and start with a letter" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:71 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:72 #, python-format msgid "%(tt)sAverage rating is %(rating)3.1f" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:220 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:221 msgid "restored preference " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:225 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:226 #: /home/kovid/work/calibre/src/calibre/library/restore.py:234 msgid "creating custom column " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3691 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3698 #, python-format msgid "

Migrating old database to ebook library in %s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3720 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3727 #, python-format msgid "Copying %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3737 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3744 msgid "Compacting database" msgstr "" @@ -18864,10 +18944,6 @@ msgstr "" msgid "Open" msgstr "" -#: /usr/src/qt-everywhere-opensource-src-4.8.2/src/gui/widgets/qdialogbuttonbox.cpp:670 -msgid "&Close" -msgstr "" - #: /usr/src/qt-everywhere-opensource-src-4.8.2/src/gui/widgets/qdialogbuttonbox.cpp:673 msgid "Apply" msgstr "" diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index e79affb2f4..26e5616c09 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -12,7 +12,7 @@ from optparse import OptionParser as _OptionParser, OptionGroup from optparse import IndentedHelpFormatter from calibre.constants import (config_dir, CONFIG_DIR_MODE, __appname__, - __version__, __author__, terminal_controller) + __version__, __author__) from calibre.utils.lock import ExclusiveFile from calibre.utils.config_base import (make_config_dir, Option, OptionValues, OptionSet, ConfigInterface, Config, prefs, StringConfig, ConfigProxy, @@ -30,28 +30,28 @@ def check_config_write_access(): class CustomHelpFormatter(IndentedHelpFormatter): def format_usage(self, usage): - tc = terminal_controller() - return "%s%s%s: %s\n" % (tc.BLUE, _('Usage'), tc.NORMAL, usage) + from calibre.utils.terminal import colored + return colored(_('Usage'), fg='blue', bold=True) + ': ' + usage def format_heading(self, heading): - tc = terminal_controller() - return "%*s%s%s%s:\n" % (self.current_indent, tc.BLUE, - "", heading, tc.NORMAL) + from calibre.utils.terminal import colored + return "%*s%s:\n" % (self.current_indent, '', + colored(heading, fg='blue', bold=True)) def format_option(self, option): import textwrap - tc = terminal_controller() + from calibre.utils.terminal import colored result = [] opts = self.option_strings[option] opt_width = self.help_position - self.current_indent - 2 if len(opts) > opt_width: opts = "%*s%s\n" % (self.current_indent, "", - tc.GREEN+opts+tc.NORMAL) + colored(opts, fg='green')) indent_first = self.help_position else: # start help on same line as opts opts = "%*s%-*s " % (self.current_indent, "", opt_width + - len(tc.GREEN + tc.NORMAL), tc.GREEN + opts + tc.NORMAL) + len(colored('', fg='green')), colored(opts, fg='green')) indent_first = 0 result.append(opts) if option.help: @@ -78,11 +78,11 @@ class OptionParser(_OptionParser): conflict_handler='resolve', **kwds): import textwrap - tc = terminal_controller() + from calibre.utils.terminal import colored usage = textwrap.dedent(usage) if epilog is None: - epilog = _('Created by ')+tc.RED+__author__+tc.NORMAL + epilog = _('Created by ')+colored(__author__, fg='cyan') usage += '\n\n'+_('''Whenever you pass arguments to %prog that have spaces in them, ''' '''enclose the arguments in quotation marks.''') _OptionParser.__init__(self, usage=usage, version=version, epilog=epilog, @@ -95,6 +95,21 @@ class OptionParser(_OptionParser): _("show this help message and exit") _("show program's version number and exit") + def print_usage(self, file=None): + from calibre.utils.terminal import ANSIStream + s = ANSIStream(file) + _OptionParser.print_usage(self, file=s) + + def print_help(self, file=None): + from calibre.utils.terminal import ANSIStream + s = ANSIStream(file) + _OptionParser.print_help(self, file=s) + + def print_version(self, file=None): + from calibre.utils.terminal import ANSIStream + s = ANSIStream(file) + _OptionParser.print_version(self, file=s) + def error(self, msg): if self.gui_mode: raise Exception(msg) diff --git a/src/calibre/utils/logging.py b/src/calibre/utils/logging.py index ad4a40c57e..e9132e079a 100644 --- a/src/calibre/utils/logging.py +++ b/src/calibre/utils/logging.py @@ -33,21 +33,18 @@ class ANSIStream(Stream): def __init__(self, stream=sys.stdout): Stream.__init__(self, stream) - from calibre.utils.terminfo import TerminalController - tc = TerminalController(stream) self.color = { - DEBUG: bytes(tc.GREEN), - INFO: bytes(''), - WARN: bytes(tc.YELLOW), - ERROR: bytes(tc.RED) + DEBUG: u'green', + INFO: None, + WARN: u'yellow', + ERROR: u'red', } - self.normal = bytes(tc.NORMAL) def prints(self, level, *args, **kwargs): - self.stream.write(self.color[level]) kwargs['file'] = self.stream - self._prints(*args, **kwargs) - self.stream.write(self.normal) + from calibre.utils.terminal import ColoredStream + with ColoredStream(self.stream, self.color[level]): + self._prints(*args, **kwargs) def flush(self): self.stream.flush() diff --git a/src/calibre/utils/terminal.py b/src/calibre/utils/terminal.py new file mode 100644 index 0000000000..b20c05f8ac --- /dev/null +++ b/src/calibre/utils/terminal.py @@ -0,0 +1,285 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import os, sys, re +from itertools import izip + +from calibre.constants import iswindows + +def fmt(code): + return ('\033[%dm'%code).encode('ascii') + +RATTRIBUTES = dict( + izip(xrange(1, 9), ( + 'bold', + 'dark', + '', + 'underline', + 'blink', + '', + 'reverse', + 'concealed' + ) + )) +ATTRIBUTES = {v:fmt(k) for k, v in RATTRIBUTES.iteritems()} +del ATTRIBUTES[''] + +RBACKGROUNDS = dict( + izip(xrange(41, 48), ( + 'red', + 'green', + 'yellow', + 'blue', + 'magenta', + 'cyan', + 'white' + ), + )) +BACKGROUNDS = {v:fmt(k) for k, v in RBACKGROUNDS.iteritems()} + +RCOLORS = dict( + izip(xrange(31, 38), ( + 'red', + 'green', + 'yellow', + 'blue', + 'magenta', + 'cyan', + 'white', + ), + )) +COLORS = {v:fmt(k) for k, v in RCOLORS.iteritems()} + +RESET = fmt(0) + +if iswindows: + # From wincon.h + WCOLORS = {c:i for i, c in enumerate(( + 'black', 'blue', 'green', 'cyan', 'red', 'magenta', 'yellow', 'white'))} + + def to_flag(fg, bg, bold): + val = 0 + if bold: + val |= 0x08 + if fg in WCOLORS: + val |= WCOLORS[fg] + if bg in WCOLORS: + val |= (WCOLORS[bg] << 4) + return val + +def colored(text, fg=None, bg=None, bold=False): + prefix = [] + if fg is not None: + prefix.append(COLORS[fg]) + if bg is not None: + prefix.append(BACKGROUNDS[bg]) + if bold: + prefix.append(ATTRIBUTES['bold']) + prefix = b''.join(prefix) + suffix = RESET + if isinstance(text, type(u'')): + prefix = prefix.decode('ascii') + suffix = suffix.decode('ascii') + return prefix + text + suffix + +class Detect(object): + + def __init__(self, stream): + self.stream = stream or sys.stdout + self.isatty = getattr(self.stream, 'isatty', lambda : False)() + force_ansi = os.environ.has_key('CALIBRE_FORCE_ANSI') + if not self.isatty and force_ansi: + self.isatty = True + self.isansi = force_ansi or not iswindows + self.set_console = None + if not self.isansi: + try: + import msvcrt + self.msvcrt = msvcrt + self.file_handle = msvcrt.get_osfhandle(self.stream.fileno()) + from ctypes import windll + self.set_console = windll.kernel32.SetConsoleTextAttribute + except: + pass + +class ColoredStream(Detect): + + def __init__(self, stream=None, fg=None, bg=None, bold=False): + super(ColoredStream, self).__init__(stream) + self.fg, self.bg, self.bold = fg, bg, bold + if self.set_console is not None: + self.wval = to_flag(self.fg, self.bg, bold) + + def __enter__(self): + if not self.isatty: + return + if self.isansi: + if self.bold: + self.stream.write(ATTRIBUTES['bold']) + if self.bg is not None: + self.stream.write(BACKGROUNDS[self.bg]) + if self.fg is not None: + self.stream.write(COLORS[self.fg]) + elif self.set_console is not None: + if self.wval != 0: + self.set_console(self.file_handle, self.wval) + + def __exit__(self, *args, **kwargs): + if not self.isatty: + return + if not self.fg and not self.bg and not self.bold: + return + if self.isansi: + self.stream.write(RESET) + elif self.set_console is not None: + self.set_console(self.file_handle, WCOLORS['white']) + +class ANSIStream(Detect): + + ANSI_RE = re.compile(br'\033\[((?:\d|;)*)([a-zA-Z])') + + def __init__(self, stream=None): + super(ANSIStream, self).__init__(stream) + self.encoding = getattr(self.stream, 'encoding', 'utf-8') + + def write(self, text): + if isinstance(text, type(u'')): + text = text.encode(self.encoding, 'replace') + + if not self.isatty: + return self.strip_and_write(text) + + if self.isansi: + return self.stream.write(text) + + if not self.isansi and self.set_console is None: + return self.strip_and_write(text) + + self.write_and_convert(text) + + def strip_and_write(self, text): + self.stream.write(self.ANSI_RE.sub(b'', text)) + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + self.last_state = (None, None, False) + cursor = 0 + for match in self.ANSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + def write_plain_text(self, text, start, end): + if start < end: + self.stream.write(text[start:end]) + self.stream.flush() + + def convert_ansi(self, paramstring, command): + params = self.extract_params(paramstring) + self.call_win32(command, params) + + def extract_params(self, paramstring): + def split(paramstring): + for p in paramstring.split(b';'): + if p: + yield int(p) + return tuple(split(paramstring)) + + def call_win32(self, command, params): + if command != b'm': return + fg, bg, bold = self.last_state + + for param in params: + if param in RCOLORS: + fg = RCOLORS[param] + elif param in RBACKGROUNDS: + bg = RBACKGROUNDS[param] + elif param == 1: + bold = True + elif param == 0: + fg = 'white' + bg, bold = None, False + + self.last_state = (fg, bg, bold) + if fg or bg or bold: + self.set_console(self.file_handle, to_flag(fg, bg, bold)) + else: + self.set_console(self.file_handle, WCOLORS['white']) + +def windows_terminfo(): + from ctypes import Structure, byref + from ctypes.wintypes import SHORT, WORD + + class COORD(Structure): + """struct in wincon.h""" + _fields_ = [ + ('X', SHORT), + ('Y', SHORT), + ] + + class SMALL_RECT(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("Left", SHORT), + ("Top", SHORT), + ("Right", SHORT), + ("Bottom", SHORT), + ] + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", WORD), + ("srWindow", SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + import msvcrt + file_handle = msvcrt.get_osfhandle(sys.stdout.fileno()) + from ctypes import windll + success = windll.kernel32.GetConsoleScreenBufferInfo(file_handle, + byref(csbi)) + if not success: + raise Exception('stdout is not a console?') + return csbi + +def geometry(): + if iswindows: + try: + + ti = windows_terminfo() + return (ti.dwSize.X or 80, ti.dwSize.Y or 80) + except: + return 80, 80 + try: + import curses + curses.setupterm() + except: + return 80, 80 + else: + width = curses.tigetnum('cols') or 80 + height = curses.tigetnum('lines') or 80 + return width, height + +def test(): + s = ANSIStream() + + text = [colored(t, fg=t)+'. '+colored(t, fg=t, bold=True)+'.' for t in + ('red', 'yellow', 'green', 'white', 'cyan', 'magenta', 'blue',)] + s.write('\n'.join(text)) + print() + diff --git a/src/calibre/utils/terminfo.py b/src/calibre/utils/terminfo.py deleted file mode 100644 index 074b6388f2..0000000000 --- a/src/calibre/utils/terminfo.py +++ /dev/null @@ -1,215 +0,0 @@ -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal ' -import sys, re, os - -""" Get information about the terminal we are running in """ - -class TerminalController: - """ - A class that can be used to portably generate formatted output to - a terminal. - - `TerminalController` defines a set of instance variables whose - values are initialized to the control sequence necessary to - perform a given action. These can be simply included in normal - output to the terminal: - - >>> term = TerminalController() - >>> print 'This is '+term.GREEN+'green'+term.NORMAL - - Alternatively, the `render()` method can used, which replaces - '${action}' with the string required to perform 'action': - - >>> term = TerminalController() - >>> print term.render('This is ${GREEN}green${NORMAL}') - - If the terminal doesn't support a given action, then the value of - the corresponding instance variable will be set to ''. As a - result, the above code will still work on terminals that do not - support color, except that their output will not be colored. - Also, this means that you can test whether the terminal supports a - given action by simply testing the truth value of the - corresponding instance variable: - - >>> term = TerminalController() - >>> if term.CLEAR_SCREEN: - ... print 'This terminal supports clearing the screen.' - - Finally, if the width and height of the terminal are known, then - they will be stored in the `COLS` and `LINES` attributes. - """ - # Cursor movement: - BOL = '' #: Move the cursor to the beginning of the line - UP = '' #: Move the cursor up one line - DOWN = '' #: Move the cursor down one line - LEFT = '' #: Move the cursor left one char - RIGHT = '' #: Move the cursor right one char - - # Deletion: - CLEAR_SCREEN = '' #: Clear the screen and move to home position - CLEAR_EOL = '' #: Clear to the end of the line. - CLEAR_BOL = '' #: Clear to the beginning of the line. - CLEAR_EOS = '' #: Clear to the end of the screen - - # Output modes: - BOLD = '' #: Turn on bold mode - BLINK = '' #: Turn on blink mode - DIM = '' #: Turn on half-bright mode - REVERSE = '' #: Turn on reverse-video mode - NORMAL = '' #: Turn off all modes - - # Cursor display: - HIDE_CURSOR = '' #: Make the cursor invisible - SHOW_CURSOR = '' #: Make the cursor visible - - # Terminal size: - COLS = None #: Width of the terminal (None for unknown) - LINES = None #: Height of the terminal (None for unknown) - - # Foreground colors: - BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' - - # Background colors: - BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = '' - BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = '' - - _STRING_CAPABILITIES = """ - BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 - CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold - BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0 - HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split() - _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split() - _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() - - def __init__(self, term_stream=sys.stdout): - """ - Create a `TerminalController` and initialize its attributes - with appropriate values for the current terminal. - `term_stream` is the stream that will be used for terminal - output; if this stream is not a tty, then the terminal is - assumed to be a dumb terminal (i.e., have no capabilities). - """ - # Curses isn't available on all platforms - try: import curses - except: return - - # If the stream isn't a tty, then assume it has no capabilities. - if os.environ.get('CALIBRE_WORKER', None) is not None or not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return - - # Check the terminal type. If we fail, then assume that the - # terminal has no capabilities. - try: curses.setupterm() - except: return - - # Look up numeric capabilities. - self.COLS = curses.tigetnum('cols') - self.LINES = curses.tigetnum('lines') - - # Look up string capabilities. - for capability in self._STRING_CAPABILITIES: - (attrib, cap_name) = capability.split('=') - setattr(self, attrib, self._tigetstr(cap_name) or '') - - # Colors - set_fg = self._tigetstr('setf') - if set_fg: - for i,color in zip(range(len(self._COLORS)), self._COLORS): - setattr(self, color, curses.tparm(set_fg, i) or '') - set_fg_ansi = self._tigetstr('setaf') - if set_fg_ansi: - for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): - setattr(self, color, curses.tparm(set_fg_ansi, i) or '') - set_bg = self._tigetstr('setb') - if set_bg: - for i,color in zip(range(len(self._COLORS)), self._COLORS): - setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '') - set_bg_ansi = self._tigetstr('setab') - if set_bg_ansi: - for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): - setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '') - - def _tigetstr(self, cap_name): - # String capabilities can include "delays" of the form "$<2>". - # For any modern terminal, we should be able to just ignore - # these, so strip them out. - import curses - cap = curses.tigetstr(cap_name) or '' - return re.sub(r'\$<\d+>[/*]?', '', cap) - - def render(self, template): - """ - Replace each $-substitutions in the given template string with - the corresponding terminal control string (if it's defined) or - '' (if it's not). - """ - return re.sub(r'\$\$|\${\w+}', self._render_sub, template) - - def _render_sub(self, match): - s = match.group() - if s == '$$': return s - else: return getattr(self, s[2:-1]) - -####################################################################### -# Example use case: progress bar -####################################################################### - -class ProgressBar: - """ - A 3-line progress bar, which looks like:: - - Header - 20% [===========----------------------------------] - progress message - - The progress bar is colored, if the terminal supports color - output; and adjusts to the width of the terminal. - - If the terminal doesn't have the required capabilities, it uses a - simple progress bar. - """ - BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n' - HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n' - - def __init__(self, term, header, no_progress_bar = False): - self.term, self.no_progress_bar = term, no_progress_bar - self.fancy = self.term.CLEAR_EOL and self.term.UP and self.term.BOL - if self.fancy: - self.width = self.term.COLS or 75 - self.bar = term.render(self.BAR) - self.header = self.term.render(self.HEADER % header.center(self.width)) - if isinstance(self.header, unicode): - self.header = self.header.encode('utf-8') - self.cleared = 1 #: true if we haven't drawn the bar yet. - - def update(self, percent, message=''): - if isinstance(message, unicode): - message = message.encode('utf-8', 'replace') - - if self.no_progress_bar: - if message: - print message - elif self.fancy: - if self.cleared: - sys.stdout.write(self.header) - self.cleared = 0 - n = int((self.width-10)*percent) - msg = message.center(self.width) - sys.stdout.write( - self.term.BOL + self.term.UP + self.term.CLEAR_EOL + - (self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) + - self.term.CLEAR_EOL + msg) - sys.stdout.flush() - else: - if not message: - print '%d%%'%(percent*100), - else: - print '%d%%'%(percent*100), message - sys.stdout.flush() - - - def clear(self): - if self.fancy and not self.cleared: - sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL + - self.term.UP + self.term.CLEAR_EOL + - self.term.UP + self.term.CLEAR_EOL) - self.cleared = 1