diff --git a/Changelog.yaml b/Changelog.yaml index 12f1b570bc..bcf58ae03d 100644 --- a/Changelog.yaml +++ b/Changelog.yaml @@ -4,6 +4,126 @@ # for important features/bug fixes. # Also, each release can have new and improved recipes. +- version: 0.7.34 + date: 2010-12-17 + + new features: + - title: "Page turn animations in the e-book viewer" + type: major + description: > + "Now when you use the Page Down/Page Up keys or the next/previous page buttons in the viewer, page turning will be animated. The duration of the animation can be controlled in the viewer preferences. Setting it to 0 disables the animation completely." + + - title: "Conversion pipeline: Add an option to set the minimum line height of all elemnts as a percentage of the computed font size. By default, calibre now sets the line height to 120% of the computed font size." + + - title: "Large speedup in startup times and post metadata edit wait for large libraries" + + - title: "Allow changing the font used in the calibre interface via Preferences->Look and feel" + + - title: "Allow editing of the title sort value for a book via the edit metadata dialog" + + - title: "Disable the cover cache. This means that if you are running calibre on an underpowered machine, you might notice some slow down in the cover browser. On the other hand, calibre's memory consumption is reduced." + + - title: "You can now restart calibre in debug mode by clicking the arrow next to the Preferences button. In debug mode, after you quit calibre, a diagnostic log will popup" + tickets: [7359] + + - title: "When creating a new calibre library add an option to copy the custom column, saved searches, etc from the current library." + tickets: [7643] + + - title: "Add more tweaks to control how the next available series number is calculated." + tickets: [7892] + + - title: "Add a tweak to control layout of the custom metadata tab in the edit metadata dialog" + + - title: "Apple driver: Set series number as track number on windows when sending books to iTunes" + + - title: "Drivers for PocketBook 701 and Samsung E65" + + - title: "E-book viewer: Add option to have the mouse wheel flip pages" + + - title: "Add a load_resources method to the InterfaceAction and Plugin classes to facilitate loading of resources from plugin ZIP files" + + - title: "E-book viewer: Add option to not remember position in book when quitting." + tickets: [7699] + + - title: "When sorting the book list, keep the current book visible after the sort completes." + tickets: [7504] + + - title: "EPUB Output: Add an option to flatten the EPUB file structure, specially for FBReaderJ." + tickets: [7788] + + - title: "EPUB Output: Ensure all files inside the generated EPUB have unique filenames, to support broken EPUB readers like Stanza, Aldiko, FBReader and Sigil" + + - title: "FB2 Output: Add support for some 2.1 style tags." + + - title: "Bulk metadata edit: Add options to delete cover/generate default cover." + tickets: [7885] + + - title: "Fix a regression in 0.7.33 that broke updating covers in ebook files when saving to disk." + tickets: [7886] + + - title: "Don't refresh the Tag browser if it is hidden. Speeds up metadata editing with large libraries, if you hide teh Tag Browser." + + - title: "MOBI Output: Add option to ignore margins in input document" + tickets: [7877] + + - title: "Kobo driver: Add support for 1.8.x firmware" + + bug fixes: + - title: "Fix various memory leaks introduced in the last couple of releases" + + - title: "EPUB metadata: When rendering first page as the cover, handle embedded svg correctly." + tickets: [7909] + + - title: "Disable multiple library support when the CALIBRE_OVERRIDE_DATABASE_PATH env var is set" + + - title: "Content server: Fix bug that could cause saved search based restrictions to not exclude all books" + tickets: [7876] + + - title: "Topaz metadata: Read metadata correctly from Topaz files that have MOBI file extensions" + + - title: "MOBI Input: Handle the (rare) MOBI files that do not specify per paragraph text indents correctly." + tickets: [7869] + + - title: "MOBI metadata reader: Handle invalid PRC files with spurious image_offset headers" + + - title: "Fix drag/drop of new cover to book detail panel does not update cover browser" + tickets: [7890] + + - title: "Do not open the book details dialog when double click on the scrollbars in the book details panel" + tickets: [7826] + + - title: "Templates: Fix {tags} not working when no tags are present" + tickets: [7888] + + - title: "HTML metadata: Fix regression that broke parsing of some meta tags" + tickets: [7851] + + - title: "Preferences: Add tooltips to buddy labels as well." + tickets: [7873] + + - title: "Content server: Fix handling of root URL when using --url-prefix" + + - title: "Ensure that the default encoding used by python is never ASCII (needed when running a non frozen version of calibre on linux)" + + improved recipes: + - Astronomy Picture of the day + - New Scientist + - Radikal + - Times of India + - Economic Times + - Zeit Online + - Dilbert + + new recipes: + - title: "Various Japanes news sources, National Geographic and paper.li" + author: "Hiroshi Miura" + + - title: "Science based medicine" + author: "BuzzKill" + + - title: "Kompiutierra" + author: "Vadim Dyadkin" + - version: 0.7.33 date: 2010-12-10 diff --git a/imgsrc/edit_copy.svg b/imgsrc/edit-copy.svg similarity index 100% rename from imgsrc/edit_copy.svg rename to imgsrc/edit-copy.svg diff --git a/imgsrc/edit-cut.svg b/imgsrc/edit-cut.svg new file mode 100644 index 0000000000..f078b52e04 --- /dev/null +++ b/imgsrc/edit-cut.svg @@ -0,0 +1,831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imgsrc/edit-paste.svg b/imgsrc/edit-paste.svg new file mode 100644 index 0000000000..d22a8bb7dd --- /dev/null +++ b/imgsrc/edit-paste.svg @@ -0,0 +1,3302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/imgsrc/swap.svg b/imgsrc/swap.svg deleted file mode 100644 index aa62316b34..0000000000 --- a/imgsrc/swap.svg +++ /dev/null @@ -1,722 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/default_tweaks.py b/resources/default_tweaks.py index 081112444a..a420cd7d44 100644 --- a/resources/default_tweaks.py +++ b/resources/default_tweaks.py @@ -12,13 +12,24 @@ defaults. # The algorithm used to assign a new book in an existing series a series number. +# New series numbers assigned using this tweak are always integer values, except +# if a constant non-integer is specified. # Possible values are: -# next - Next available number +# next - First available integer larger than the largest existing number +# first_free - First available integer larger than 0 +# next_free - First available integer larger than the smallest existing number +# last_free - First available integer smaller than the largest existing number +# Return largest existing + 1 if no free number is found # const - Assign the number 1 always +# a number - Assign that number always. The number is not in quotes. Note that +# 0.0 can be used here. +# Examples: +# series_index_auto_increment = 'next' +# series_index_auto_increment = 'next_free' +# series_index_auto_increment = 16.5 series_index_auto_increment = 'next' - # The algorithm used to copy author to author_sort # Possible values are: # invert: use "fn ln" -> "ln, fn" (the original algorithm) @@ -30,6 +41,20 @@ series_index_auto_increment = 'next' # selecting 'manage authors', and pressing 'Recalculate all author sort values'. author_sort_copy_method = 'invert' +# Set which author field to display in the tags pane (the list of authors, +# series, publishers etc on the left hand side). The choices are author and +# author_sort. This tweak affects only what is displayed under the authors +# category in the tags pane and content server. Please note that if you set this +# to author_sort, it is very possible to see duplicate names in the list because +# although it is guaranteed that author names are unique, there is no such +# guarantee for author_sort values. Showing duplicates won't break anything, but +# it could lead to some confusion. When using 'author_sort', the tooltip will +# show the author's name. +# Examples: +# categories_use_field_for_author_name = 'author' +# categories_use_field_for_author_name = 'author_sort' +categories_use_field_for_author_name = 'author' + # Set whether boolean custom columns are two- or three-valued. # Two-values for true booleans @@ -235,3 +260,9 @@ doubleclick_on_library_view = 'open_viewer' # Example: locale_for_sorting = 'fr' -- sort using French rules. # Example: locale_for_sorting = 'nb' -- sort using Norwegian rules. locale_for_sorting = '' + + +# Set whether to use one or two columns for custom metadata when editing +# metadata one book at a time. If True, then the fields are laid out using two +# columns. If False, one column is used. +metadata_single_use_2_cols_for_custom_fields = True \ No newline at end of file diff --git a/resources/images/edit_copy.png b/resources/images/edit-copy.png similarity index 100% rename from resources/images/edit_copy.png rename to resources/images/edit-copy.png diff --git a/resources/images/edit-cut.png b/resources/images/edit-cut.png new file mode 100644 index 0000000000..b995283754 Binary files /dev/null and b/resources/images/edit-cut.png differ diff --git a/resources/images/edit-paste.png b/resources/images/edit-paste.png new file mode 100644 index 0000000000..b790efec25 Binary files /dev/null and b/resources/images/edit-paste.png differ diff --git a/resources/images/edit-redo.png b/resources/images/edit-redo.png new file mode 100644 index 0000000000..8de333fe8c Binary files /dev/null and b/resources/images/edit-redo.png differ diff --git a/resources/images/edit-select-all.png b/resources/images/edit-select-all.png new file mode 100644 index 0000000000..4393bc9dc7 Binary files /dev/null and b/resources/images/edit-select-all.png differ diff --git a/resources/images/edit-undo.png b/resources/images/edit-undo.png new file mode 100644 index 0000000000..f6d7e8ba56 Binary files /dev/null and b/resources/images/edit-undo.png differ diff --git a/resources/images/format-fill-color.png b/resources/images/format-fill-color.png new file mode 100644 index 0000000000..946bead5da Binary files /dev/null and b/resources/images/format-fill-color.png differ diff --git a/resources/images/format-indent-less.png b/resources/images/format-indent-less.png new file mode 100644 index 0000000000..8662c34871 Binary files /dev/null and b/resources/images/format-indent-less.png differ diff --git a/resources/images/format-indent-more.png b/resources/images/format-indent-more.png new file mode 100644 index 0000000000..e1244ef47c Binary files /dev/null and b/resources/images/format-indent-more.png differ diff --git a/resources/images/format-justify-center.png b/resources/images/format-justify-center.png new file mode 100644 index 0000000000..505160a1bb Binary files /dev/null and b/resources/images/format-justify-center.png differ diff --git a/resources/images/format-justify-fill.png b/resources/images/format-justify-fill.png new file mode 100644 index 0000000000..ee34b8272f Binary files /dev/null and b/resources/images/format-justify-fill.png differ diff --git a/resources/images/format-justify-left.png b/resources/images/format-justify-left.png new file mode 100644 index 0000000000..f5af823a82 Binary files /dev/null and b/resources/images/format-justify-left.png differ diff --git a/resources/images/format-justify-right.png b/resources/images/format-justify-right.png new file mode 100644 index 0000000000..9a3d8d6ee1 Binary files /dev/null and b/resources/images/format-justify-right.png differ diff --git a/resources/images/format-list-ordered.png b/resources/images/format-list-ordered.png new file mode 100644 index 0000000000..c7da85da3f Binary files /dev/null and b/resources/images/format-list-ordered.png differ diff --git a/resources/images/format-list-unordered.png b/resources/images/format-list-unordered.png new file mode 100644 index 0000000000..c959989958 Binary files /dev/null and b/resources/images/format-list-unordered.png differ diff --git a/resources/images/format-text-color.png b/resources/images/format-text-color.png new file mode 100644 index 0000000000..2ec27d559d Binary files /dev/null and b/resources/images/format-text-color.png differ diff --git a/resources/images/format-text-heading.png b/resources/images/format-text-heading.png new file mode 100644 index 0000000000..970acb7d60 Binary files /dev/null and b/resources/images/format-text-heading.png differ diff --git a/resources/images/format-text-subscript.png b/resources/images/format-text-subscript.png new file mode 100644 index 0000000000..7da8882aea Binary files /dev/null and b/resources/images/format-text-subscript.png differ diff --git a/resources/images/format-text-superscript.png b/resources/images/format-text-superscript.png new file mode 100644 index 0000000000..9dc31ab783 Binary files /dev/null and b/resources/images/format-text-superscript.png differ diff --git a/resources/images/insert-link.png b/resources/images/insert-link.png new file mode 100644 index 0000000000..b9e335d320 Binary files /dev/null and b/resources/images/insert-link.png differ diff --git a/resources/images/swap.png b/resources/images/swap.png index e5aeb60e22..7f8d40ca1d 100644 Binary files a/resources/images/swap.png and b/resources/images/swap.png differ diff --git a/resources/recipes/cnd.recipe b/resources/recipes/cnd.recipe new file mode 100644 index 0000000000..0e8206d07a --- /dev/null +++ b/resources/recipes/cnd.recipe @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2010, Derek Liang ' +''' +cnd.org +''' +import re + +from calibre.web.feeds.news import BasicNewsRecipe + +class TheCND(BasicNewsRecipe): + + title = 'CND' + __author__ = 'Derek Liang' + description = '' + INDEX = 'http://cnd.org' + language = 'zh' + conversion_options = {'linearize_tables':True} + + remove_tags_before = dict(name='div', id='articleHead') + remove_tags_after = dict(id='copyright') + remove_tags = [dict(name='table', attrs={'align':'right'}), dict(name='img', attrs={'src':'http://my.cnd.org/images/logo.gif'}), dict(name='hr', attrs={}), dict(name='small', attrs={})] + no_stylesheets = True + + preprocess_regexps = [(re.compile(r'', re.DOTALL), lambda m: '')] + + def print_version(self, url): + if url.find('news/article.php') >= 0: + return re.sub("^[^=]*", "http://my.cnd.org/modules/news/print.php?storyid", url) + else: + return re.sub("^[^=]*", "http://my.cnd.org/modules/wfsection/print.php?articleid", url) + + def parse_index(self): + soup = self.index_to_soup(self.INDEX) + + feeds = [] + articles = {} + + for a in soup.findAll('a', attrs={'target':'_cnd'}): + url = a['href'] + if url.find('article.php') < 0 : + continue + if url.startswith('/'): + url = 'http://cnd.org'+url + title = self.tag_to_string(a) + self.log('\tFound article: ', title, 'at', url) + date = a.nextSibling + if (date is not None) and len(date)>2: + if not articles.has_key(date): + articles[date] = [] + articles[date].append({'title':title, 'url':url, 'description': '', 'date':''}) + self.log('\t\tAppend to : ', date) + + self.log('log articles', articles) + mostCurrent = sorted(articles).pop() + self.title = 'CND ' + mostCurrent + + feeds.append((self.title, articles[mostCurrent])) + + return feeds + + def populate_article_metadata(self, article, soup, first): + header = soup.find('h3') + self.log('header: ' + self.tag_to_string(header)) + pass + diff --git a/resources/recipes/ecotrend.recipe b/resources/recipes/ecotrend.recipe new file mode 100644 index 0000000000..679f190e96 --- /dev/null +++ b/resources/recipes/ecotrend.recipe @@ -0,0 +1,42 @@ +__license__ = 'GPL v3' +__copyright__ = '2010, Darko Miletic ' +''' +globaleconomicanalysis.blogspot.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class GlobalEconomicAnalysis(BasicNewsRecipe): + title = "Mish's Global Economic Trend Analysis" + __author__ = 'Darko Miletic' + description = 'Thoughts on the global economy, housing, gold, silver, interest rates, oil, energy, China, commodities, the dollar, Euro, Renminbi, Yen, inflation, deflation, stagflation, precious metals, emerging markets, and policy decisions that affect the global markets.' + publisher = 'Mike Shedlock' + category = 'news, politics, economy, banking' + oldest_article = 7 + max_articles_per_feed = 200 + no_stylesheets = True + encoding = 'utf8' + use_embedded_content = True + language = 'en' + remove_empty_feeds = True + publication_type = 'blog' + masthead_url = 'http://www.pagina12.com.ar/commons/imgs/logo-home.gif' + extra_css = """ + body{font-family: Arial,Helvetica,sans-serif } + img{margin-bottom: 0.4em; display:block} + """ + + conversion_options = { + 'comment' : description + , 'tags' : category + , 'publisher' : publisher + , 'language' : language + } + + remove_tags = [ + dict(name=['meta','link','iframe','object','embed']) + ,dict(attrs={'class':'blogger-post-footer'}) + ] + remove_attributes=['border'] + + feeds = [(u'Articles', u'http://feeds2.feedburner.com/MishsGlobalEconomicTrendAnalysis')] diff --git a/resources/recipes/gva_be.recipe b/resources/recipes/gva_be.recipe index 34c4122394..f42bd23417 100644 --- a/resources/recipes/gva_be.recipe +++ b/resources/recipes/gva_be.recipe @@ -40,13 +40,12 @@ class GazetvanAntwerpen(BasicNewsRecipe): remove_tags_after = dict(name='span', attrs={'class':'author'}) feeds = [ - (u'Overzicht & Blikvanger', u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/overview/overzicht' ) + (u'Binnenland' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/binnenland' ) + ,(u'Buitenland' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/buitenland' ) ,(u'Stad & Regio' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/stadenregio' ) ,(u'Economie' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/economie' ) - ,(u'Binnenland' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/binnenland' ) - ,(u'Buitenland' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/buitenland' ) ,(u'Media & Cultur' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/mediaencultuur') - ,(u'Wetenschap' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/mediaencultuur') + ,(u'Wetenschap' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/wetenschap' ) ,(u'Sport' , u'http://www.gva.be/syndicationservices/artfeedservice.svc/rss/mostrecent/sport' ) ] diff --git a/resources/recipes/johm.recipe b/resources/recipes/johm.recipe index ee162b27c2..0f5625b806 100644 --- a/resources/recipes/johm.recipe +++ b/resources/recipes/johm.recipe @@ -1,88 +1,72 @@ -# -*- coding: utf-8 -*- - +import re from calibre.web.feeds.recipes import BasicNewsRecipe class JournalofHospitalMedicine(BasicNewsRecipe): title = 'Journal of Hospital Medicine' - __author__ = 'Krittika Goyal' + __author__ = 'Kovid Goyal' description = 'Medical news' timefmt = ' [%d %b, %Y]' needs_subscription = True language = 'en' no_stylesheets = True - #remove_tags_before = dict(name='div', attrs={'align':'center'}) - #remove_tags_after = dict(name='ol', attrs={'compact':'COMPACT'}) - remove_tags = [ - dict(name='iframe'), - dict(name='div', attrs={'class':'subContent'}), - dict(name='div', attrs={'id':['contentFrame']}), - #dict(name='form', attrs={'onsubmit':"return verifySearch(this.w,'Keyword, citation, or author')"}), - #dict(name='table', attrs={'align':'RIGHT'}), - ] - + keep_only_tags = [dict(id=['articleTitle', 'articleMeta', 'fulltext'])] + remove_tags = [dict(attrs={'class':'licensedContent'})] # TO LOGIN def get_browser(self): br = BasicNewsRecipe.get_browser() br.open('http://www3.interscience.wiley.com/cgi-bin/home') - br.select_form(name='siteLogin') - br['LoginName'] = self.username - br['Password'] = self.password + br.select_form(nr=0) + br['j_username'] = self.username + br['j_password'] = self.password response = br.submit() raw = response.read() - if 'userName = ""' in raw: + if '

LOGGED IN

' not in raw: raise Exception('Login failed. Check your username and password') return br #TO GET ARTICLE TOC def johm_get_index(self): - return self.index_to_soup('http://www3.interscience.wiley.com/journal/111081937/home') + return self.index_to_soup('http://onlinelibrary.wiley.com/journal/10.1002/(ISSN)1553-5606/currentissue') # To parse artice toc def parse_index(self): - parse_soup = self.johm_get_index() + soup = self.johm_get_index() + toc = soup.find(id='issueTocGroups') + feeds = [] + for group in toc.findAll('li', id=re.compile(r'group\d+')): + gtitle = group.find(attrs={'class':'subSectionHeading'}) + if gtitle is None: + continue + gtitle = self.tag_to_string(gtitle) + arts = group.find(attrs={'class':'articles'}) + if arts is None: + continue + self.log('Found section:', gtitle) + articles = [] + for art in arts.findAll(attrs={'class':lambda x: x and 'tocArticle' + in x}): + a = art.find('a', href=True) + if a is None: + continue + url = a.get('href') + if url.startswith('/'): + url = 'http://onlinelibrary.wiley.com' + url + url = url.replace('/abstract', '/full') + title = self.tag_to_string(a) + a.extract() + pm = art.find(attrs={'class':'productMenu'}) + if pm is not None: + pm.extract() + desc = self.tag_to_string(art) + self.log('\tFound article:', title, 'at', url) + articles.append({'title':title, 'url':url, 'description':desc, + 'date':''}) + if articles: + feeds.append((gtitle, articles)) - div = parse_soup.find(id='contentCell') - - current_section = None - current_articles = [] - feeds = [] - for x in div.findAll(True): - if x.name == 'h4': - # Section heading found - if current_articles and current_section: - feeds.append((current_section, current_articles)) - current_section = self.tag_to_string(x) - current_articles = [] - self.log('\tFound section:', current_section) - if current_section is not None and x.name == 'strong': - title = self.tag_to_string(x) - p = x.parent.parent.find('a', href=lambda x: x and '/HTMLSTART' in x) - if p is None: - continue - url = p.get('href', False) - if not url or not title: - continue - if url.startswith('/'): - url = 'http://www3.interscience.wiley.com'+url - url = url.replace('/HTMLSTART', '/main.html,ftx_abs') - self.log('\t\tFound article:', title) - self.log('\t\t\t', url) - #if url.startswith('/'): - #url = 'http://online.wsj.com'+url - current_articles.append({'title': title, 'url':url, - 'description':'', 'date':''}) - - if current_articles and current_section: - feeds.append((current_section, current_articles)) - - return feeds - - def preprocess_html(self, soup): - for img in soup.findAll('img', src=True): - img['src'] = img['src'].replace('tfig', 'nfig') - return soup + return feeds diff --git a/resources/recipes/lanacion.recipe b/resources/recipes/lanacion.recipe index 19f6c1c897..050cb2e79c 100644 --- a/resources/recipes/lanacion.recipe +++ b/resources/recipes/lanacion.recipe @@ -78,4 +78,6 @@ class Lanacion(BasicNewsRecipe): ] def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] return self.adeify_images(soup) diff --git a/resources/recipes/nejm.recipe b/resources/recipes/nejm.recipe index c860413926..bc12fbcedf 100644 --- a/resources/recipes/nejm.recipe +++ b/resources/recipes/nejm.recipe @@ -4,23 +4,14 @@ from calibre.web.feeds.recipes import BasicNewsRecipe class NYTimes(BasicNewsRecipe): title = 'New England Journal of Medicine' - __author__ = 'Krittika Goyal' + __author__ = 'Kovid Goyal' description = 'Medical news' timefmt = ' [%d %b, %Y]' needs_subscription = True language = 'en' no_stylesheets = True - remove_tags_before = dict(name='div', attrs={'align':'center'}) - remove_tags_after = dict(name='ol', attrs={'compact':'COMPACT'}) - remove_tags = [ - dict(name='iframe'), - #dict(name='div', attrs={'class':'related-articles'}), - dict(name='div', attrs={'id':['sidebar']}), - #dict(name='form', attrs={'onsubmit':"return verifySearch(this.w,'Keyword, citation, or author')"}), - dict(name='table', attrs={'align':'RIGHT'}), - ] - + keep_only_tags = dict(id='content') #TO LOGIN @@ -38,61 +29,50 @@ class NYTimes(BasicNewsRecipe): #TO GET ARTICLE TOC def nejm_get_index(self): - return self.index_to_soup('http://content.nejm.org/current.dtl') + return self.index_to_soup('http://content.nejm.org/current.dtl') # To parse artice toc def parse_index(self): - parse_soup = self.nejm_get_index() + parse_soup = self.nejm_get_index() - div = parse_soup.find(id='centerTOC') + feeds = [] - current_section = None - current_articles = [] - feeds = [] - for x in div.findAll(True): - if x.name == 'img' and '/toc/' in x.get('src', '') and 'uarrow.gif' not in x.get('src', ''): - # Section heading found - if current_articles and current_section and 'Week in the' not in current_section: - feeds.append((current_section, current_articles)) - current_section = x.get('alt') - current_articles = [] - self.log('\tFound section:', current_section) - if current_section is not None and x.name == 'strong': - title = self.tag_to_string(x) - a = x.parent.find('a', href=lambda x: x and '/full/' in x) - if a is None: - continue - url = a.get('href', False) - if not url or not title: - continue - if url.startswith('/'): - url = 'http://content.nejm.org'+url - self.log('\t\tFound article:', title) - self.log('\t\t\t', url) - if url.startswith('/'): - url = 'http://online.wsj.com'+url - current_articles.append({'title': title, 'url':url, - 'description':'', 'date':''}) - - if current_articles and current_section: - feeds.append((current_section, current_articles)) - - return feeds - - def preprocess_html(self, soup): - for a in soup.findAll(text=lambda x: x and '[in this window]' in x): - a = a.findParent('a') - url = a.get('href', None) - if not url: + div = parse_soup.find(attrs={'class':'tocContent'}) + for group in div.findAll(attrs={'class':'articleGrouping'}): + feed_title = group.find(attrs={'class':'articleType'}) + if feed_title is None: continue - if url.startswith('/'): - url = 'http://content.nejm.org'+url - isoup = self.index_to_soup(url) - img = isoup.find('img', src=lambda x: x and - x.startswith('/content/')) - if img is not None: - img.extract() - table = a.findParent('table') - table.replaceWith(img) - return soup + feed_title = self.tag_to_string(feed_title) + articles = [] + self.log('Found section:', feed_title) + for art in group.findAll(attrs={'class':lambda x: x and 'articleEntry' + in x}): + link = art.find(attrs={'class':lambda x:x and 'articleLink' in + x}) + if link is None: + continue + a = link.find('a', href=True) + if a is None: + continue + url = a.get('href') + if url.startswith('/'): + url = 'http://www.nejm.org'+url + title = self.tag_to_string(a) + self.log.info('\tFound article:', title, 'at', url) + article = {'title':title, 'url':url, 'date':''} + au = art.find(attrs={'class':'articleAuthors'}) + if au is not None: + article['author'] = self.tag_to_string(au) + desc = art.find(attrs={'class':'hover_text'}) + if desc is not None: + desc = self.tag_to_string(desc) + if 'author' in article: + desc = ' by ' + article['author'] + ' ' +desc + article['description'] = desc + articles.append(article) + if articles: + feeds.append((feed_title, articles)) + + return feeds + diff --git a/resources/recipes/wenxuecity-znjy.recipe b/resources/recipes/wenxuecity-znjy.recipe new file mode 100644 index 0000000000..ecce80222e --- /dev/null +++ b/resources/recipes/wenxuecity-znjy.recipe @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2010, Derek Liang ' +''' +wenxuecity.com +''' +import re + +from calibre.web.feeds.news import BasicNewsRecipe + +class TheCND(BasicNewsRecipe): + + title = 'wenxuecity - znjy' + __author__ = 'Derek Liang' + description = '' + INDEX = 'http://bbs.wenxuecity.com/znjy/?elite=1' + language = 'zh' + conversion_options = {'linearize_tables':True} + + remove_tags_before = dict(name='div', id='message') + remove_tags_after = dict(name='div', id='message') + remove_tags = [dict(name='div', id='postmeta'), dict(name='div', id='footer')] + no_stylesheets = True + + preprocess_regexps = [(re.compile(r'', re.DOTALL), lambda m: '')] + + def print_version(self, url): + return url + '?print' + + def parse_index(self): + soup = self.index_to_soup(self.INDEX) + + feeds = [] + articles = {} + + for a in soup.findAll('a', attrs={'class':'post'}): + url = a['href'] + if url.startswith('/'): + url = 'http://bbs.wenxuecity.com'+url + title = self.tag_to_string(a) + self.log('\tFound article: ', title, ' at:', url) + dateReg = re.search( '(\d\d?)/(\d\d?)/(\d\d)', self.tag_to_string(a.parent) ) + date = '%(y)s/%(m)02d/%(d)02d' % {'y' : dateReg.group(3), 'm' : int(dateReg.group(1)), 'd' : int(dateReg.group(2)) } + if not articles.has_key(date): + articles[date] = [] + articles[date].append({'title':title, 'url':url, 'description': '', 'date':''}) + self.log('\t\tAppend to : ', date) + + self.log('log articles', articles) + mostCurrent = sorted(articles).pop() + self.title = '文学城 - 子女教育 - ' + mostCurrent + + feeds.append((self.title, articles[mostCurrent])) + + return feeds + + def populate_article_metadata(self, article, soup, first): + header = soup.find('h3') + self.log('header: ' + self.tag_to_string(header)) + pass + diff --git a/setup/installer/linux/freeze2.py b/setup/installer/linux/freeze2.py index df2c1d6480..bd8463b1a7 100644 --- a/setup/installer/linux/freeze2.py +++ b/setup/installer/linux/freeze2.py @@ -318,7 +318,11 @@ class LinuxFreeze(Command): import codecs def set_default_encoding(): - locale.setlocale(locale.LC_ALL, '') + try: + locale.setlocale(locale.LC_ALL, '') + except: + print 'WARNING: Failed to set default libc locale, using en_US.UTF-8' + locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') enc = locale.getdefaultlocale()[1] if not enc: enc = locale.nl_langinfo(locale.CODESET) diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst index af4c871dac..b9aef39657 100644 --- a/setup/installer/windows/notes.rst +++ b/setup/installer/windows/notes.rst @@ -36,6 +36,16 @@ Install BeautifulSoup 3.0.x manually into site-packages (3.1.x parses broken HTM Install pywin32 and edit win32com\__init__.py setting _frozen = True and __gen_path__ to a temp dir (otherwise it tries to set it to a dir in the install tree which leads to permission errors) +Note that you should use:: + + import tempfile + __gen_path__ = os.path.join( + tempfile.gettempdir(), "gen_py", + "%d.%d" % (sys.version_info[0], sys.version_info[1])) + +Use gettempdir instead of the win32 api method as gettempdir returns a temp dir that is guaranteed to actually work. + + Also edit win32com\client\gencache.py and change the except IOError on line 57 to catch all exceptions. SQLite diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 9cc67b39e4..7f4d085b6a 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -2,7 +2,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = 'calibre' -__version__ = '0.7.33' +__version__ = '0.7.34' __author__ = "Kovid Goyal " import re diff --git a/src/calibre/devices/android/driver.py b/src/calibre/devices/android/driver.py index 8b30631528..492b00617d 100644 --- a/src/calibre/devices/android/driver.py +++ b/src/calibre/devices/android/driver.py @@ -24,11 +24,11 @@ class ANDROID(USBMS): 0xc92 : [0x100], 0xc97: [0x226]}, # Eken - 0x040d : { 0x8510 : [0x0001] }, + 0x040d : { 0x8510 : [0x0001], 0x0851 : [0x1] }, # Motorola 0x22b8 : { 0x41d9 : [0x216], 0x2d67 : [0x100], 0x41db : [0x216], - 0x4285 : [0x216]}, + 0x4285 : [0x216], 0x42a3 : [0x216] }, # Sony Ericsson 0xfce : { 0xd12e : [0x0100]}, @@ -49,8 +49,9 @@ class ANDROID(USBMS): # Dell 0x413c : { 0xb007 : [0x0100, 0x0224]}, - # Eken? - 0x040d : { 0x0851 : [0x0001]}, + # LG + 0x1004 : { 0x61cc : [0x100] }, + } EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books'] EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to ' @@ -59,13 +60,13 @@ class ANDROID(USBMS): EXTRA_CUSTOMIZATION_DEFAULT = ', '.join(EBOOK_DIR_MAIN) VENDOR_NAME = ['HTC', 'MOTOROLA', 'GOOGLE_', 'ANDROID', 'ACER', - 'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX'] + 'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE'] WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE', '__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897', 'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', - 'SCH-I500_CARD', 'SPH-D700_CARD', 'MB810'] + 'SCH-I500_CARD', 'SPH-D700_CARD', 'MB810', 'GT-P1000'] WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897', - 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID'] + 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD'] OSX_MAIN_MEM = 'HTC Android Phone Media' diff --git a/src/calibre/devices/eb600/driver.py b/src/calibre/devices/eb600/driver.py index bc8b87533c..246b753fa8 100644 --- a/src/calibre/devices/eb600/driver.py +++ b/src/calibre/devices/eb600/driver.py @@ -266,3 +266,12 @@ class POCKETBOOK701(USBMS): VENDOR_NAME = 'ANDROID' WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '__UMS_COMPOSITE' + def windows_sort_drives(self, drives): + if len(drives) < 2: return drives + main = drives.get('main', None) + carda = drives.get('carda', None) + if main and carda: + drives['main'] = carda + drives['carda'] = main + return drives + diff --git a/src/calibre/devices/misc.py b/src/calibre/devices/misc.py index e27aee4393..52952356f8 100644 --- a/src/calibre/devices/misc.py +++ b/src/calibre/devices/misc.py @@ -62,9 +62,9 @@ class SWEEX(USBMS): # Ordered list of supported formats FORMATS = ['epub', 'prc', 'fb2', 'html', 'rtf', 'chm', 'pdf', 'txt'] - VENDOR_ID = [0x0525] - PRODUCT_ID = [0xa4a5] - BCD = [0x0319] + VENDOR_ID = [0x0525, 0x177f] + PRODUCT_ID = [0xa4a5, 0x300] + BCD = [0x0319, 0x110] VENDOR_NAME = 'SWEEX' WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOKREADER' @@ -104,7 +104,7 @@ class PDNOVEL(USBMS): VENDOR_NAME = 'ANDROID' WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '__UMS_COMPOSITE' - THUMBNAIL_HEIGHT = 144 + THUMBNAIL_HEIGHT = 130 EBOOK_DIR_MAIN = 'eBooks' SUPPORTS_SUB_DIRS = False diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index af2948cf82..2c095d6f7b 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -605,8 +605,9 @@ class Device(DeviceConfig, DevicePlugin): main, carda, cardb = self.find_device_nodes() if main is None: - raise DeviceError(_('Unable to detect the %s disk drive. Your ' - ' kernel is probably exporting a deprecated version of SYSFS.') + raise DeviceError(_('Unable to detect the %s disk drive. Either ' + 'the device has already been ejected, or your ' + 'kernel is exporting a deprecated version of SYSFS.') %self.__class__.__name__) self._linux_mount_map = {} diff --git a/src/calibre/ebooks/fb2/fb2ml.py b/src/calibre/ebooks/fb2/fb2ml.py index 5efc360f1f..90c88c3cd0 100644 --- a/src/calibre/ebooks/fb2/fb2ml.py +++ b/src/calibre/ebooks/fb2/fb2ml.py @@ -27,13 +27,10 @@ class FB2MLizer(object): ''' Todo: * Include more FB2 specific tags in the conversion. * Handle a tags. - * Figure out some way to turn oeb_book.toc items into
- <p> to allow for readers to generate toc from the document. ''' def __init__(self, log): self.log = log - self.image_hrefs = {} self.reset_state() def reset_state(self): @@ -43,17 +40,25 @@ class FB2MLizer(object): # in different directories. FB2 images are all in a flat layout so we rename all images # into a sequential numbering system to ensure there are no collisions between image names. self.image_hrefs = {} + # Mapping of toc items and their + self.toc = {} + # Used to see whether a new <section> needs to be opened + self.section_level = 0 def extract_content(self, oeb_book, opts): self.log.info('Converting XHTML to FB2 markup...') self.oeb_book = oeb_book self.opts = opts + self.reset_state() + + # Used for adding <section>s and <title>s to allow readers + # to generate toc from the document. + if self.opts.sectionize == 'toc': + self.create_flat_toc(self.oeb_book.toc, 1) return self.fb2mlize_spine() def fb2mlize_spine(self): - self.reset_state() - output = [self.fb2_header()] output.append(self.get_text()) output.append(self.fb2mlize_images()) @@ -66,13 +71,19 @@ class FB2MLizer(object): return u'<?xml version="1.0" encoding="UTF-8"?>' + output def clean_text(self, text): - text = re.sub(r'(?miu)<section>\s*</section>', '', text) - text = re.sub(r'(?miu)\s+</section>', '</section>', text) - text = re.sub(r'(?miu)</section><section>', '</section>\n\n<section>', text) - text = re.sub(r'(?miu)<p>\s*</p>', '', text) - text = re.sub(r'(?miu)\s+</p>', '</p>', text) - text = re.sub(r'(?miu)</p><p>', '</p>\n\n<p>', text) + text = re.sub(r'(?miu)\s*</p>', '</p>', text) + text = re.sub(r'(?miu)</p>\s*<p>', '</p>\n\n<p>', text) + + text = re.sub(r'(?miu)<title>\s*', '', text) + text = re.sub(r'(?miu)\s+', '', text) + + text = re.sub(r'(?miu)
\s*
', '', text) + text = re.sub(r'(?miu)\s*
', '\n', text) + text = re.sub(r'(?miu)\s*', '\n\n', text) + text = re.sub(r'(?miu)\s*
', '\n
', text) + text = re.sub(r'(?miu)
\s*', '
\n', text) + text = re.sub(r'(?miu)
', '
\n\n
', text) if self.opts.insert_blank_line: text = re.sub(r'(?miu)

', '

', text) @@ -144,12 +155,34 @@ class FB2MLizer(object): def get_text(self): text = [''] + + # Create main section if there are no others to create + if self.opts.sectionize == 'nothing': + text.append('
') + self.section_level += 1 + for item in self.oeb_book.spine: self.log.debug('Converting %s to FictionBook2 XML' % item.href) stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile) - text.append('
') + + # Start a
if we must sectionize each file or if the TOC references this page + page_section_open = False + if self.opts.sectionize == 'files' or self.toc.get(item.href) == 'page': + text.append('
') + page_section_open = True + self.section_level += 1 + text += self.dump_text(item.data.find(XHTML('body')), stylizer, item) + + if page_section_open: + text.append('
') + self.section_level -= 1 + + # Close any open sections + while self.section_level > 0: text.append('
') + self.section_level -= 1 + return ''.join(text) + '' def fb2mlize_images(self): @@ -184,6 +217,17 @@ class FB2MLizer(object): '%s.' % (item.href, e)) return ''.join(images) + def create_flat_toc(self, nodes, level): + for item in nodes: + href, mid, id = item.href.partition('#') + if not id: + self.toc[href] = 'page' + else: + if not self.toc.get(href, None): + self.toc[href] = {} + self.toc[href][id] = level + self.create_flat_toc(item.nodes, level + 1) + def ensure_p(self): if self.in_p: return [], [] @@ -254,10 +298,38 @@ class FB2MLizer(object): # First tag in tree tag = barename(elem_tree.tag) + # Convert TOC entries to s and add <section>s + if self.opts.sectionize == 'toc': + # A section cannot be a child of any other element than another section, + # so leave the tag alone if there are parents + if not tag_stack: + # There are two reasons to start a new section here: the TOC pointed to + # this page (then we use the first non-<body> on the page as a <title>), or + # the TOC pointed to a specific element + newlevel = 0 + toc_entry = self.toc.get(page.href, None) + if toc_entry == 'page': + if tag != 'body' and hasattr(elem_tree, 'text') and elem_tree.text: + newlevel = 1 + self.toc[page.href] = None + elif toc_entry and elem_tree.attrib.get('id', None): + newlevel = toc_entry.get(elem_tree.attrib.get('id', None), None) + + # Start a new section if necessary + if newlevel: + if not (newlevel > self.section_level): + fb2_out.append('</section>') + self.section_level -= 1 + fb2_out.append('<section>') + self.section_level += 1 + fb2_out.append('<title>') + tags.append('title') + if self.section_level == 0: + # If none of the prior processing made a section, make one now to be FB2 spec compliant + fb2_out.append('<section>') + self.section_level += 1 + # Process the XHTML tag if it needs to be converted to an FB2 tag. - if tag == 'h1' and self.opts.h1_to_title or tag == 'h2' and self.opts.h2_to_title or tag == 'h3' and self.opts.h3_to_title: - fb2_out.append('<title>') - tags.append('title') if tag == 'img': if elem_tree.attrib.get('src', None): # Only write the image tag if it is in the manifest. diff --git a/src/calibre/ebooks/fb2/output.py b/src/calibre/ebooks/fb2/output.py index 33714c6e6e..e8b50d6f77 100644 --- a/src/calibre/ebooks/fb2/output.py +++ b/src/calibre/ebooks/fb2/output.py @@ -16,15 +16,15 @@ class FB2Output(OutputFormatPlugin): file_type = 'fb2' options = set([ - OptionRecommendation(name='h1_to_title', - recommended_value=False, level=OptionRecommendation.LOW, - help=_('Wrap all h1 tags with fb2 title elements.')), - OptionRecommendation(name='h2_to_title', - recommended_value=False, level=OptionRecommendation.LOW, - help=_('Wrap all h2 tags with fb2 title elements.')), - OptionRecommendation(name='h3_to_title', - recommended_value=False, level=OptionRecommendation.LOW, - help=_('Wrap all h3 tags with fb2 title elements.')), + OptionRecommendation(name='sectionize', + recommended_value='files', level=OptionRecommendation.LOW, + choices=['toc', 'files', 'nothing'], + help=_('Specify the sectionization of elements. ' + 'A value of "nothing" turns the book into a single section. ' + 'A value of "files" turns each file into a separate section; use this if your device is having trouble. ' + 'A value of "Table of Contents" turns the entries in the Table of Contents into titles and creates sections; ' + 'if it fails, adjust the "Structure Detection" and/or "Table of Contents" settings ' + '(turn on "Force use of auto-generated Table of Contents).')), ]) def convert(self, oeb_book, output_path, input_plugin, opts, log): diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index 01e5190640..25127ee591 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -57,6 +57,8 @@ _ignore_starts = u'\'"'+u''.join(unichr(x) for x in range(0x2018, 0x201e)+[0x203 def title_sort(title): title = title.strip() + if tweaks['title_series_sorting'] == 'strictly_alphabetic': + return title if title and title[0] in _ignore_starts: title = title[1:] match = _title_pat.search(title) diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index f0844e3711..22752ca09e 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -463,6 +463,8 @@ class Metadata(object): other_lang = getattr(other, 'language', None) if other_lang and other_lang.lower() != 'und': self.language = other_lang + if not getattr(self, 'series', None): + self.series_index = None def format_series_index(self, val=None): from calibre.ebooks.metadata import fmt_sidx diff --git a/src/calibre/ebooks/oeb/iterator.py b/src/calibre/ebooks/oeb/iterator.py index 10180541a1..6820709b3e 100644 --- a/src/calibre/ebooks/oeb/iterator.py +++ b/src/calibre/ebooks/oeb/iterator.py @@ -257,7 +257,6 @@ class EbookIterator(object): s.max_page = s.start_page + s.pages - 1 self.toc = self.opf.toc - self.find_embedded_fonts() self.read_bookmarks() return self diff --git a/src/calibre/ebooks/rtf/input.py b/src/calibre/ebooks/rtf/input.py index 57903a6711..8c7561f68c 100644 --- a/src/calibre/ebooks/rtf/input.py +++ b/src/calibre/ebooks/rtf/input.py @@ -245,7 +245,7 @@ class RTFInput(InputFormatPlugin): from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.rtf2xml.ParseRtf import RtfInvalidCodeException - self.options = options + self.opts = options self.log = log self.log('Converting RTF to XML...') #Name of the preprocesssed RTF file @@ -290,12 +290,12 @@ class RTFInput(InputFormatPlugin): res = transform.tostring(result) res = res[:100].replace('xmlns:html', 'xmlns') + res[100:] # Replace newlines inserted by the 'empty_paragraphs' option in rtf2xml with html blank lines - if not getattr(self.options, 'remove_paragraph_spacing', False): + if not getattr(self.opts, 'remove_paragraph_spacing', False): res = re.sub('\s*<body>', '<body>', res) res = re.sub('(?<=\n)\n{2}', u'<p>\u00a0</p>\n'.encode('utf-8'), res) - if self.options.preprocess_html: - preprocessor = PreProcessor(self.options, log=getattr(self, 'log', None)) + if self.opts.preprocess_html: + preprocessor = PreProcessor(self.opts, log=getattr(self, 'log', None)) res = preprocessor(res) f.write(res) self.write_inline_css(inline_class, border_styles) diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py index a0f49a7e9a..27973b5f5b 100644 --- a/src/calibre/gui2/actions/delete.py +++ b/src/calibre/gui2/actions/delete.py @@ -12,6 +12,7 @@ from PyQt4.Qt import QMenu, QObject, QTimer from calibre.gui2 import error_dialog from calibre.gui2.dialogs.delete_matching_from_device import DeleteMatchingFromDeviceDialog from calibre.gui2.dialogs.confirm_delete import confirm +from calibre.gui2.dialogs.confirm_delete_location import confirm_location from calibre.gui2.actions import InterfaceAction single_shot = partial(QTimer.singleShot, 10) @@ -96,10 +97,15 @@ class DeleteAction(InterfaceAction): for action in list(self.delete_menu.actions())[1:]: action.setEnabled(enabled) - def _get_selected_formats(self, msg): + def _get_selected_formats(self, msg, ids): from calibre.gui2.dialogs.select_formats import SelectFormats - fmts = self.gui.library_view.model().db.all_formats() - d = SelectFormats([x.lower() for x in fmts], msg, parent=self.gui) + fmts = set([]) + db = self.gui.library_view.model().db + for x in ids: + fmts_ = db.formats(x, index_is_id=True, verify_formats=False) + if fmts_: + fmts.update(frozenset([x.lower() for x in fmts_.split(',')])) + d = SelectFormats(list(sorted(fmts)), msg, parent=self.gui) if d.exec_() != d.Accepted: return None return d.selected_formats @@ -117,7 +123,7 @@ class DeleteAction(InterfaceAction): if not ids: return fmts = self._get_selected_formats( - _('Choose formats to be deleted')) + _('Choose formats to be deleted'), ids) if not fmts: return for id in ids: @@ -135,7 +141,7 @@ class DeleteAction(InterfaceAction): if not ids: return fmts = self._get_selected_formats( - '<p>'+_('Choose formats <b>not</b> to be deleted')) + '<p>'+_('Choose formats <b>not</b> to be deleted'), ids) if fmts is None: return for id in ids: @@ -223,7 +229,31 @@ class DeleteAction(InterfaceAction): rows = view.selectionModel().selectedRows() if not rows or len(rows) == 0: return + # Library view is visible. if self.gui.stack.currentIndex() == 0: + # Ask the user if they want to delete the book from the library or device if it is in both. + if self.gui.device_manager.is_device_connected: + on_device = False + on_device_ids = self._get_selected_ids() + for id in on_device_ids: + res = self.gui.book_on_device(id) + if res[0] or res[1] or res[2]: + on_device = True + if on_device: + break + if on_device: + loc = confirm_location('<p>' + _('Some of the selected books are on the attached device. ' + '<b>Where</b> do you want the selected files deleted from?'), + self.gui) + if not loc: + return + elif loc == 'dev': + self.remove_matching_books_from_device() + return + elif loc == 'both': + self.remove_matching_books_from_device() + # The following will run if the selected books are not on a connected device. + # The user has selected to delete from the library or the device and library. if not confirm('<p>'+_('The selected books will be ' '<b>permanently deleted</b> and the files ' 'removed from your calibre library. Are you sure?') @@ -239,7 +269,7 @@ class DeleteAction(InterfaceAction): else: self.__md = MultiDeleter(self.gui, rows, partial(self.library_ids_deleted, current_row=row)) - + # Device view is visible. else: if not confirm('<p>'+_('The selected books will be ' '<b>permanently deleted</b> ' diff --git a/src/calibre/gui2/comments_editor.py b/src/calibre/gui2/comments_editor.py index 8438fa3cfc..d19c97e87b 100644 --- a/src/calibre/gui2/comments_editor.py +++ b/src/calibre/gui2/comments_editor.py @@ -5,40 +5,207 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __docformat__ = 'restructuredtext en' +import re, os from lxml import html from lxml.html import soupparser -from PyQt4.Qt import QApplication, QFontInfo, QPalette, QSize, QWidget, \ - QToolBar, QVBoxLayout, QAction, QIcon +from PyQt4.Qt import QApplication, QFontInfo, QSize, QWidget, QPlainTextEdit, \ + QToolBar, QVBoxLayout, QAction, QIcon, QWebPage, Qt, QTabWidget, QUrl, \ + QSyntaxHighlighter, QColor, QChar, QColorDialog, QMenu, QInputDialog from PyQt4.QtWebKit import QWebView from calibre.ebooks.chardet import xml_to_unicode from calibre import xml_replace_entities +from calibre.gui2 import open_url -class EditorWidget(QWebView): +class PageAction(QAction): # {{{ + + def __init__(self, wac, icon, text, checkable, view): + QAction.__init__(self, QIcon(I(icon+'.png')), text, view) + self._page_action = getattr(QWebPage, wac) + self.setCheckable(checkable) + self.triggered.connect(self.trigger_page_action) + view.selectionChanged.connect(self.update_state, + type=Qt.QueuedConnection) + self.page_action.changed.connect(self.update_state, + type=Qt.QueuedConnection) + + @property + def page_action(self): + return self.parent().pageAction(self._page_action) + + def trigger_page_action(self, *args): + self.page_action.trigger() + + def update_state(self, *args): + if self.isCheckable(): + self.setChecked(self.page_action.isChecked()) + self.setEnabled(self.page_action.isEnabled()) + +# }}} + +class BlockStyleAction(QAction): # {{{ + + def __init__(self, text, name, view): + QAction.__init__(self, text, view) + self._name = name + self.triggered.connect(self.apply_style) + + def apply_style(self, *args): + self.parent().exec_command('formatBlock', self._name) + +# }}} + +class EditorWidget(QWebView): # {{{ def __init__(self, parent=None): QWebView.__init__(self, parent) - for name, icon, text, checkable in [ - ('bold', 'format-text-bold', _('Bold'), True), - ('italic', 'format-text-italic', _('Italic'), True), - ('underline', 'format-text-underline', _('Underline'), True), - ('strikethrough', 'format-text-underline', _('Underline'), True), + for wac, name, icon, text, checkable in [ + ('ToggleBold', 'bold', 'format-text-bold', _('Bold'), True), + ('ToggleItalic', 'italic', 'format-text-italic', _('Italic'), + True), + ('ToggleUnderline', 'underline', 'format-text-underline', + _('Underline'), True), + ('ToggleStrikethrough', 'strikethrough', 'format-text-strikethrough', + _('Strikethrough'), True), + ('ToggleSuperscript', 'superscript', 'format-text-superscript', + _('Superscript'), True), + ('ToggleSubscript', 'subscript', 'format-text-subscript', + _('Subscript'), True), + ('InsertOrderedList', 'ordered_list', 'format-list-ordered', + _('Ordered list'), True), + ('InsertUnorderedList', 'unordered_list', 'format-list-unordered', + _('Unordered list'), True), + + ('AlignLeft', 'align_left', 'format-justify-left', + _('Align left'), False), + ('AlignCenter', 'align_center', 'format-justify-center', + _('Align center'), False), + ('AlignRight', 'align_right', 'format-justify-right', + _('Align right'), False), + ('AlignJustified', 'align_justified', 'format-justify-fill', + _('Align justified'), False), + ('Undo', 'undo', 'edit-undo', _('Undo'), False), + ('Redo', 'redo', 'edit-redo', _('Redo'), False), + ('RemoveFormat', 'remove_format', 'trash', _('Remove formatting'), False), + ('Copy', 'copy', 'edit-copy', _('Copy'), False), + ('Paste', 'paste', 'edit-paste', _('Paste'), False), + ('Cut', 'cut', 'edit-cut', _('Cut'), False), + ('Indent', 'indent', 'format-indent-more', + _('Increase Indentation'), False), + ('Outdent', 'outdent', 'format-indent-less', + _('Decrease Indentation'), False), + ('SelectAll', 'select_all', 'edit-select-all', + _('Select all'), False), ]: - ac = QAction(QIcon(I(icon+'.png')), text, self) - ac.setCheckable(checkable) + ac = PageAction(wac, icon, text, checkable, self) setattr(self, 'action_'+name, ac) + self.action_color = QAction(QIcon(I('format-text-color')), _('Foreground color'), + self) + self.action_color.triggered.connect(self.foreground_color) + + self.action_background = QAction(QIcon(I('format-fill-color')), + _('Background color'), self) + self.action_background.triggered.connect(self.background_color) + + self.action_block_style = QAction(QIcon(I('format-text-heading')), + _('Style text block'), self) + self.action_block_style.setToolTip( + _('Style the selected text block')) + self.block_style_menu = QMenu(self) + self.action_block_style.setMenu(self.block_style_menu) + self.block_style_actions = [] + for text, name in [ + (_('Normal'), 'p'), + (_('Heading') +' 1', 'h1'), + (_('Heading') +' 2', 'h2'), + (_('Heading') +' 3', 'h3'), + (_('Heading') +' 4', 'h4'), + (_('Heading') +' 5', 'h5'), + (_('Heading') +' 6', 'h6'), + (_('Pre-formatted'), 'pre'), + (_('Blockquote'), 'blockquote'), + (_('Address'), 'address'), + ]: + ac = BlockStyleAction(text, name, self) + self.block_style_menu.addAction(ac) + self.block_style_actions.append(ac) + + self.action_insert_link = QAction(QIcon(I('insert-link.png')), + _('Insert link'), self) + self.action_insert_link.triggered.connect(self.insert_link) + + self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) + self.page().linkClicked.connect(self.link_clicked) + + def link_clicked(self, url): + open_url(url) + + def foreground_color(self): + col = QColorDialog.getColor(Qt.black, self, + _('Choose foreground color'), QColorDialog.ShowAlphaChannel) + if col.isValid(): + self.exec_command('foreColor', unicode(col.name())) + + def background_color(self): + col = QColorDialog.getColor(Qt.white, self, + _('Choose background color'), QColorDialog.ShowAlphaChannel) + if col.isValid(): + self.exec_command('hiliteColor', unicode(col.name())) + + def insert_link(self, *args): + link, ok = QInputDialog.getText(self, _('Create link'), + _('Enter URL')) + if not ok: + return + url = self.parse_link(unicode(link)) + if url.isValid(): + url = unicode(url.toString()) + self.exec_command('createLink', url) + + def parse_link(self, link): + link = link.strip() + has_schema = re.match(r'^[a-zA-Z]+:', link) + if has_schema is not None: + url = QUrl(link, QUrl.TolerantMode) + if url.isValid(): + return url + if os.path.exists(link): + return QUrl.fromLocalFile(link) + + if has_schema is None: + first, _, rest = link.partition('.') + prefix = 'http' + if first == 'ftp': + prefix = 'ftp' + url = QUrl(prefix +'://'+link, QUrl.TolerantMode) + if url.isValid(): + return url + + return QUrl(link, QUrl.TolerantMode) + def sizeHint(self): return QSize(150, 150) + def exec_command(self, cmd, arg=None): + frame = self.page().mainFrame() + if arg is not None: + js = 'document.execCommand("%s", false, "%s");' % (cmd, arg) + else: + js = 'document.execCommand("%s", false, null);' % cmd + frame.evaluateJavaScript(js) + @dynamic_property def html(self): def fget(self): ans = u'' + check = unicode(self.page().mainFrame().toPlainText()).strip() + if not check: + return ans try: raw = unicode(self.page().mainFrame().toHtml()) raw = xml_to_unicode(raw, strip_encoding_pats=True, @@ -67,12 +234,7 @@ class EditorWidget(QWebView): def fset(self, val): self.setHtml(val) f = QFontInfo(QApplication.font(self)).pixelSize() - b = unicode(QApplication.palette().color(QPalette.Normal, - QPalette.Base).name()) - c = unicode(QApplication.palette().color(QPalette.Normal, - QPalette.Text).name()) - style = 'font-size: %dpx; background-color: %s; color: %s' % (f, b, - c) + style = 'font-size: %dpx;' % (f,) for body in self.page().mainFrame().documentElement().findAll('body'): body.setAttribute('style', style) @@ -80,26 +242,316 @@ class EditorWidget(QWebView): return property(fget=fget, fset=fset) +# }}} -class Editor(QWidget): +# Highlighter {{{ +State_Text = -1 +State_DocType = 0 +State_Comment = 1 +State_TagStart = 2 +State_TagName = 3 +State_InsideTag = 4 +State_AttributeName = 5 +State_SingleQuote = 6 +State_DoubleQuote = 7 +State_AttributeValue = 8 + +class Highlighter(QSyntaxHighlighter): + + def __init__(self, doc): + QSyntaxHighlighter.__init__(self, doc) + self.colors = {} + self.colors['doctype'] = QColor(192, 192, 192) + self.colors['entity'] = QColor(128, 128, 128) + self.colors['tag'] = QColor(136, 18, 128) + self.colors['comment'] = QColor( 35, 110, 37) + self.colors['attrname'] = QColor(153, 69, 0) + self.colors['attrval'] = QColor( 36, 36, 170) + + def highlightBlock(self, text): + state = self.previousBlockState() + len_ = text.length() + start = 0 + pos = 0 + + while pos < len_: + + if state == State_Comment: + start = pos + while pos < len_: + if text.mid(pos, 3) == "-->": + pos += 3; + state = State_Text; + break + else: + pos += 1 + self.setFormat(start, pos - start, self.colors['comment']) + + elif state == State_DocType: + start = pos + while pos < len_: + ch = text.at(pos) + pos += 1 + if ch == QChar('>'): + state = State_Text + break + self.setFormat(start, pos - start, self.colors['doctype']) + + # at '<' in e.g. "<span>foo</span>" + elif state == State_TagStart: + start = pos + 1 + while pos < len_: + ch = text.at(pos) + pos += 1 + if ch == QChar('>'): + state = State_Text + break + if not ch.isSpace(): + pos -= 1 + state = State_TagName + break + + # at 'b' in e.g "<blockquote>foo</blockquote>" + elif state == State_TagName: + start = pos + while pos < len_: + ch = text.at(pos) + pos += 1 + if ch.isSpace(): + pos -= 1 + state = State_InsideTag + break + if ch == QChar('>'): + state = State_Text + break + self.setFormat(start, pos - start, self.colors['tag']); + + # anywhere after tag name and before tag closing ('>') + elif state == State_InsideTag: + start = pos + + while pos < len_: + ch = text.at(pos) + pos += 1 + + if ch == QChar('/'): + continue + + if ch == QChar('>'): + state = State_Text + break + + if not ch.isSpace(): + pos -= 1 + state = State_AttributeName + break + + # at 's' in e.g. <img src=bla.png/> + elif state == State_AttributeName: + start = pos + + while pos < len_: + ch = text.at(pos) + pos += 1 + + if ch == QChar('='): + state = State_AttributeValue + break + + if ch in (QChar('>'), QChar('/')): + state = State_InsideTag + break + + self.setFormat(start, pos - start, self.colors['attrname']) + + # after '=' in e.g. <img src=bla.png/> + elif state == State_AttributeValue: + start = pos + + # find first non-space character + while pos < len_: + ch = text.at(pos) + pos += 1 + + # handle opening single quote + if ch == QChar("'"): + state = State_SingleQuote + break + + # handle opening double quote + if ch == QChar('"'): + state = State_DoubleQuote + break + + if not ch.isSpace(): + break + + if state == State_AttributeValue: + # attribute value without quote + # just stop at non-space or tag delimiter + start = pos + while pos < len_: + ch = text.at(pos); + if ch.isSpace(): + break + if ch in (QChar('>'), QChar('/')): + break + pos += 1 + state = State_InsideTag + self.setFormat(start, pos - start, self.colors['attrval']) + + # after the opening single quote in an attribute value + elif state == State_SingleQuote: + start = pos + + while pos < len_: + ch = text.at(pos) + pos += 1 + if ch == QChar("'"): + break + + state = State_InsideTag + + self.setFormat(start, pos - start, self.colors['attrval']) + + # after the opening double quote in an attribute value + elif state == State_DoubleQuote: + start = pos + + while pos < len_: + ch = text.at(pos) + pos += 1 + if ch == QChar('"'): + break + + state = State_InsideTag + + self.setFormat(start, pos - start, self.colors['attrval']) + + else: + # State_Text and default + while pos < len_: + ch = text.at(pos) + if ch == QChar('<'): + if text.mid(pos, 4) == "<!--": + state = State_Comment + else: + if text.mid(pos, 9).toUpper() == "<!DOCTYPE": + state = State_DocType + else: + state = State_TagStart + break; + elif ch == QChar('&'): + start = pos + while pos < len_ and text.at(pos) != QChar(';'): + self.setFormat(start, pos - start, + self.colors['entity']) + pos += 1 + + else: + pos += 1 + + + self.setCurrentBlockState(state) + +# }}} + +class Editor(QWidget): # {{{ def __init__(self, parent=None): QWidget.__init__(self, parent) - self.toolbar = QToolBar(self) + self.toolbar1 = QToolBar(self) + self.toolbar2 = QToolBar(self) self.editor = EditorWidget(self) + self.tabs = QTabWidget(self) + self.tabs.setTabPosition(self.tabs.South) + self.wyswyg = QWidget(self.tabs) + self.code_edit = QPlainTextEdit(self.tabs) + self.source_dirty = False + self.wyswyg_dirty = True + self._layout = QVBoxLayout(self) + self.wyswyg.layout = l = QVBoxLayout(self.wyswyg) self.setLayout(self._layout) - self._layout.setContentsMargins(0, 0, 0, 0) - self._layout.addWidget(self.toolbar) - self._layout.addWidget(self.editor) + l.setContentsMargins(0, 0, 0, 0) + l.addWidget(self.toolbar1) + l.addWidget(self.toolbar2) + l.addWidget(self.editor) + self._layout.addWidget(self.tabs) + self.tabs.addTab(self.wyswyg, _('Normal view')) + self.tabs.addTab(self.code_edit, _('HTML Source')) + self.tabs.currentChanged[int].connect(self.change_tab) + self.highlighter = Highlighter(self.code_edit.document()) + + for x in ('bold', 'italic', 'underline', 'strikethrough', + 'superscript', 'subscript', 'indent', 'outdent'): + ac = getattr(self.editor, 'action_'+x) + if x in ('superscript', 'indent'): + self.toolbar2.addSeparator() + self.toolbar2.addAction(ac) + self.toolbar2.addSeparator() + + for x in ('left', 'center', 'right', 'justified'): + ac = getattr(self.editor, 'action_align_'+x) + self.toolbar2.addAction(ac) + self.toolbar2.addSeparator() + + self.toolbar1.addAction(self.editor.action_undo) + self.toolbar1.addAction(self.editor.action_redo) + self.toolbar1.addAction(self.editor.action_select_all) + self.toolbar1.addAction(self.editor.action_remove_format) + self.toolbar1.addSeparator() + + for x in ('copy', 'cut', 'paste'): + ac = getattr(self.editor, 'action_'+x) + self.toolbar1.addAction(ac) + self.toolbar1.addSeparator() + + for x in ('', 'un'): + ac = getattr(self.editor, 'action_%sordered_list'%x) + self.toolbar1.addAction(ac) + self.toolbar1.addSeparator() + + self.toolbar1.addAction(self.editor.action_color) + self.toolbar1.addAction(self.editor.action_background) + self.toolbar1.addSeparator() + + self.toolbar1.addAction(self.editor.action_block_style) + w = self.toolbar1.widgetForAction(self.editor.action_block_style) + w.setPopupMode(w.InstantPopup) + self.toolbar1.addAction(self.editor.action_insert_link) + + self.code_edit.textChanged.connect(self.code_dirtied) + self.editor.page().contentsChanged.connect(self.wyswyg_dirtied) @dynamic_property def html(self): def fset(self, v): self.editor.html = v - return property(fget=lambda self:self.editor.html, fset=fset) + def fget(self): + self.tabs.setCurrentIndex(0) + return self.editor.html + return property(fget=fget, fset=fset) + def change_tab(self, index): + #print 'reloading:', (index and self.wyswyg_dirty) or (not index and + # self.source_dirty) + if index == 1: # changing to code view + if self.wyswyg_dirty: + self.code_edit.setPlainText(self.editor.html) + self.wyswyg_dirty = False + elif index == 0: #changing to wyswyg + if self.source_dirty: + self.editor.html = unicode(self.code_edit.toPlainText()) + self.source_dirty = False + def wyswyg_dirtied(self, *args): + self.wyswyg_dirty = True + + def code_dirtied(self, *args): + self.source_dirty = True + +# }}} if __name__ == '__main__': app = QApplication([]) diff --git a/src/calibre/gui2/convert/fb2_output.py b/src/calibre/gui2/convert/fb2_output.py index 6b1497a9db..66296ee666 100644 --- a/src/calibre/gui2/convert/fb2_output.py +++ b/src/calibre/gui2/convert/fb2_output.py @@ -17,6 +17,8 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/fb2.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['h1_to_title', 'h2_to_title', 'h3_to_title']) + Widget.__init__(self, parent, ['sectionize']) self.db, self.book_id = db, book_id + for x in ('toc', 'files', 'nothing'): + self.opt_sectionize.addItem(x) self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/fb2_output.ui b/src/calibre/gui2/convert/fb2_output.ui index 436719aed4..891aa29857 100644 --- a/src/calibre/gui2/convert/fb2_output.ui +++ b/src/calibre/gui2/convert/fb2_output.ui @@ -14,7 +14,7 @@ <string>Form</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="3" column="0"> + <item row="1" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -28,23 +28,19 @@ </spacer> </item> <item row="0" column="0"> - <widget class="QCheckBox" name="opt_h1_to_title"> - <property name="text"> - <string>Wrap h1 tags with <title> elements</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="opt_h2_to_title"> - <property name="text"> - <string>Wrap h2 tags with <title> elements</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QCheckBox" name="opt_h3_to_title"> - <property name="text"> - <string>Wrap h3 tags with <title> elements</string> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Sectionize:</string> + </property> + <property name="buddy"> + <cstring>opt_sectionize</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="opt_sectionize"> + <property name="minimumContentsLength"> + <number>20</number> </property> </widget> </item> diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py index 14aca24db5..be9c5b4658 100644 --- a/src/calibre/gui2/convert/mobi_output.py +++ b/src/calibre/gui2/convert/mobi_output.py @@ -11,7 +11,6 @@ from PyQt4.Qt import Qt from calibre.gui2.convert.mobi_output_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.gui2.widgets import FontFamilyModel -from calibre.utils.fonts import fontconfig font_family_model = None @@ -28,6 +27,7 @@ class PluginWidget(Widget, Ui_Form): 'mobi_ignore_margins', 'dont_compress', 'no_inline_toc', 'masthead_font','personal_doc'] ) + from calibre.utils.fonts import fontconfig self.db, self.book_id = db, book_id global font_family_model diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 5ab8bb6940..6e4fc0a0ac 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -303,7 +303,7 @@ class Series(Base): if val == '': val = s_index = None elif s_index == 0.0: - if tweaks['series_index_auto_increment'] == 'next': + if tweaks['series_index_auto_increment'] != 'const': s_index = self.db.get_next_cc_series_num_for(val, num=self.col_id) else: @@ -572,7 +572,6 @@ class BulkSeries(BulkBase): val = None if clear else self.normalize_ui_val(val) if clear or val != '': extras = [] - next_index = self.db.get_next_cc_series_num_for(val, num=self.col_id) for book_id in book_ids: if clear: extras.append(None) @@ -581,9 +580,8 @@ class BulkSeries(BulkBase): if force_start: s_index = at_value at_value += 1 - elif tweaks['series_index_auto_increment'] == 'next': - s_index = next_index - next_index += 1 + elif tweaks['series_index_auto_increment'] != 'const': + s_index = self.db.get_next_cc_series_num_for(val, num=self.col_id) else: s_index = 1.0 else: diff --git a/src/calibre/gui2/dialogs/choose_library.py b/src/calibre/gui2/dialogs/choose_library.py index 32d45c6043..033b038b65 100644 --- a/src/calibre/gui2/dialogs/choose_library.py +++ b/src/calibre/gui2/dialogs/choose_library.py @@ -32,6 +32,11 @@ class ChooseLibrary(QDialog, Ui_Dialog): loc = unicode(self.old_location.text()).format(lp) self.old_location.setText(loc) self.browse_button.clicked.connect(self.choose_loc) + self.empty_library.toggled.connect(self.empty_library_toggled) + self.copy_structure.setEnabled(False) + + def empty_library_toggled(self, to_what): + self.copy_structure.setEnabled(to_what) def choose_loc(self, *args): loc = choose_dir(self, 'choose library location', @@ -64,7 +69,7 @@ class ChooseLibrary(QDialog, Ui_Dialog): def perform_action(self, ac, loc): if ac in ('new', 'existing'): prefs['library_path'] = loc - self.callback(loc) + self.callback(loc, copy_structure=self.copy_structure.isChecked()) else: move_library(self.db.library_path, loc, self.parent(), self.callback) diff --git a/src/calibre/gui2/dialogs/choose_library.ui b/src/calibre/gui2/dialogs/choose_library.ui index 6cf1b4386c..c281ecc0f4 100644 --- a/src/calibre/gui2/dialogs/choose_library.ui +++ b/src/calibre/gui2/dialogs/choose_library.ui @@ -49,11 +49,26 @@ </widget> </item> <item row="5" column="0" colspan="3"> - <widget class="QRadioButton" name="empty_library"> - <property name="text"> - <string>&Create an empty library at the new location</string> - </property> - </widget> + <layout class="QHBoxLayout" name="hbox1"> + <item> + <widget class="QRadioButton" name="empty_library"> + <property name="text"> + <string>&Create an empty library at the new location</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="copy_structure"> + <property name="text"> + <string>&Copy structure from the current library</string> + </property> + <property name="toolTip"> + <string>Copy the custom columns, saved searches, column widths, plugboards, +user categories, and other information from the old to the new library</string> + </property> + </widget> + </item> + </layout> </item> <item row="6" column="0" colspan="3"> <widget class="QRadioButton" name="move_library"> diff --git a/src/calibre/gui2/dialogs/confirm_delete_location.py b/src/calibre/gui2/dialogs/confirm_delete_location.py new file mode 100644 index 0000000000..b976b936b8 --- /dev/null +++ b/src/calibre/gui2/dialogs/confirm_delete_location.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' \ + '2010, John Schember <john@nachtimwald.com>' +__docformat__ = 'restructuredtext en' + +from functools import partial + +from calibre.gui2.dialogs.confirm_delete_location_ui import Ui_Dialog +from PyQt4.Qt import QDialog, Qt, QPixmap, QIcon + +class Dialog(QDialog, Ui_Dialog): + + def __init__(self, msg, name, parent): + QDialog.__init__(self, parent) + self.setupUi(self) + + self.loc = None + self.msg.setText(msg) + self.name = name + self.buttonBox.setFocus(Qt.OtherFocusReason) + self.button_lib.clicked.connect(partial(self.set_loc, 'lib')) + self.button_device.clicked.connect(partial(self.set_loc, 'dev')) + self.button_both.clicked.connect(partial(self.set_loc, 'both')) + + def set_loc(self, loc): + self.loc = loc + self.accept() + + def choice(self): + return self.loc + + def break_cycles(self): + for x in ('lib', 'device', 'both'): + b = getattr(self, 'button_'+x) + try: + b.clicked.disconnect() + except: + pass + + +def confirm_location(msg, name, parent=None, pixmap='dialog_warning.png'): + d = Dialog(msg, name, parent) + d.label.setPixmap(QPixmap(I(pixmap))) + d.setWindowIcon(QIcon(I(pixmap))) + d.resize(d.sizeHint()) + ret = d.exec_() + d.break_cycles() + if ret == d.Accepted: + return d.choice() + return None diff --git a/src/calibre/gui2/dialogs/confirm_delete_location.ui b/src/calibre/gui2/dialogs/confirm_delete_location.ui new file mode 100644 index 0000000000..9d70388627 --- /dev/null +++ b/src/calibre/gui2/dialogs/confirm_delete_location.ui @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>459</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Where do you want to delete from?</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/dialog_warning.png</normaloff>:/images/dialog_warning.png</iconset> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="pixmap"> + <pixmap resource="../../../../resources/images.qrc">:/images/dialog_warning.png</pixmap> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="msg"> + <property name="text"> + <string/> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="button_lib"> + <property name="text"> + <string>Library</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="button_device"> + <property name="text"> + <string>Device</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="button_both"> + <property name="text"> + <string>Library and Device</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../../resources/images.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Dialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Dialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index e0f1f83c73..e5292ee755 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -3,7 +3,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' '''Dialog to edit metadata in bulk''' -import re +import re, os from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \ pyqtSignal, QDialogButtonBox @@ -12,12 +12,41 @@ from PyQt4 import QtGui from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.ebooks.metadata import string_to_authors, authors_to_string +from calibre.ebooks.metadata.meta import get_metadata from calibre.gui2.custom_column_widgets import populate_metadata_page from calibre.gui2 import error_dialog from calibre.gui2.progress_indicator import ProgressIndicator from calibre.utils.config import dynamic from calibre.utils.titlecase import titlecase from calibre.utils.icu import sort_key, capitalize +from calibre.utils.config import prefs +from calibre.utils.magick.draw import identify_data + +def get_cover_data(path): + old = prefs['read_file_metadata'] + if not old: + prefs['read_file_metadata'] = True + cdata = area = None + + try: + mi = get_metadata(open(path, 'rb'), + os.path.splitext(path)[1][1:].lower()) + if mi.cover and os.access(mi.cover, os.R_OK): + cdata = open(mi.cover).read() + elif mi.cover_data[1] is not None: + cdata = mi.cover_data[1] + if cdata: + width, height, fmt = identify_data(cdata) + area = width*height + except: + cdata = area = None + + if old != prefs['read_file_metadata']: + prefs['read_file_metadata'] = old + + return cdata, area + + class MyBlockingBusy(QDialog): @@ -146,6 +175,20 @@ class MyBlockingBusy(QDialog): cdata = calibre_cover(mi.title, mi.format_field('authors')[-1], series_string=series_string) self.db.set_cover(id, cdata) + elif cover_action == 'fromfmt': + fmts = self.db.formats(id, index_is_id=True, verify_formats=False) + if fmts: + covers = [] + for fmt in fmts.split(','): + fmt = self.db.format_abspath(id, fmt, index_is_id=True) + if not fmt: continue + cdata, area = get_cover_data(fmt) + if cdata: + covers.append((cdata, area)) + covers.sort(key=lambda x: x[1]) + if covers: + self.db.set_cover(id, covers[-1][0]) + covers = [] elif self.current_phase == 2: # All of these just affect the DB, so we can tolerate a total rollback if do_auto_author: @@ -700,6 +743,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): cover_action = 'remove' elif self.cover_generate.isChecked(): cover_action = 'generate' + elif self.cover_from_fmt.isChecked(): + cover_action = 'fromfmt' args = (remove_all, remove, add, au, aus, do_aus, rating, pub, do_series, do_autonumber, do_remove_format, remove_format, do_swap_ta, diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index ecb34d8e5b..3f20958d47 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -414,6 +414,13 @@ Future conversion of these books will use the default settings.</string> </property> </widget> </item> + <item> + <widget class="QRadioButton" name="cover_from_fmt"> + <property name="text"> + <string>Set from &ebook file(s)</string> + </property> + </widget> + </item> </layout> </widget> </item> @@ -686,8 +693,8 @@ nothing should be put between the original text and the inserted text</string> <rect> <x>0</x> <y>0</y> - <width>122</width> - <height>38</height> + <width>726</width> + <height>334</height> </rect> </property> <layout class="QGridLayout" name="testgrid"> diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 4a9bb784c8..9cb9f7bbbc 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -23,7 +23,7 @@ from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.gui2.widgets import ProgressIndicator from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks.metadata import string_to_authors, \ - authors_to_string, check_isbn + authors_to_string, check_isbn, title_sort from calibre.ebooks.metadata.covers import download_cover from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata import MetaInformation @@ -34,6 +34,7 @@ from calibre.customize.ui import run_plugins_on_import, get_isbndb_key from calibre.gui2.preferences.social import SocialMetadata from calibre.gui2.custom_column_widgets import populate_metadata_page from calibre import strftime +from calibre.library.comments import comments_to_html class CoverFetcher(Thread): # {{{ @@ -195,7 +196,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): _file + _(" is not a valid picture")) d.exec_() else: - self.cover_path.setText(_file) self.cover.setPixmap(pix) self.update_cover_tooltip() self.cover_changed = True @@ -409,7 +409,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): if mi.series_index is not None: self.series_index.setValue(float(mi.series_index)) if mi.comments and mi.comments.strip(): - self.comments.setPlainText(mi.comments) + comments = comments_to_html(mi.comments) + self.comments.html = comments def sync_formats(self): @@ -444,13 +445,24 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.cover_fetcher = None self.bc_box.layout().setAlignment(self.cover, Qt.AlignCenter|Qt.AlignHCenter) base = unicode(self.author_sort.toolTip()) - self.ok_aus_tooltip = '<p>' + textwrap.fill(base+'<br><br>'+ + ok_tooltip = '<p>' + textwrap.fill(base+'<br><br>'+ _(' The green color indicates that the current ' 'author sort matches the current author')) - self.bad_aus_tooltip = '<p>'+textwrap.fill(base + '<br><br>'+ + bad_tooltip = '<p>'+textwrap.fill(base + '<br><br>'+ _(' The red color indicates that the current ' - 'author sort does not match the current author')) + 'author sort does not match the current author. ' + 'No action is required if this is what you want.')) + self.aus_tooltips = (ok_tooltip, bad_tooltip) + base = unicode(self.title_sort.toolTip()) + ok_tooltip = '<p>' + textwrap.fill(base+'<br><br>'+ + _(' The green color indicates that the current ' + 'title sort matches the current title')) + bad_tooltip = '<p>'+textwrap.fill(base + '<br><br>'+ + _(' The red color warns that the current ' + 'title sort does not match the current title. ' + 'No action is required if this is what you want.')) + self.ts_tooltips = (ok_tooltip, bad_tooltip) self.row_delta = 0 if prev: self.prev_button = QPushButton(QIcon(I('back.png')), _('Previous'), @@ -506,7 +518,13 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.remove_unused_series) QObject.connect(self.auto_author_sort, SIGNAL('clicked()'), self.deduce_author_sort) + QObject.connect(self.auto_title_sort, SIGNAL('clicked()'), + self.deduce_title_sort) self.trim_cover_button.clicked.connect(self.trim_cover) + self.connect(self.title_sort, SIGNAL('textChanged(const QString&)'), + self.title_sort_box_changed) + self.connect(self.title, SIGNAL('textChanged(const QString&)'), + self.title_box_changed) self.connect(self.author_sort, SIGNAL('textChanged(const QString&)'), self.author_sort_box_changed) self.connect(self.authors, SIGNAL('editTextChanged(const QString&)'), @@ -523,6 +541,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.title.setText(db.title(row)) + self.title_sort.setText(db.title_sort(row)) isbn = db.isbn(self.id, index_is_id=True) if not isbn: isbn = '' @@ -538,7 +557,9 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): if rating > 0: self.rating.setValue(int(rating/2.)) comments = self.db.comments(row) - self.comments.setPlainText(comments if comments else '') + if comments and comments.strip(): + comments = comments_to_html(comments) + self.comments.html = comments cover = self.db.cover(row) pubdate = db.pubdate(self.id, index_is_id=True) self.pubdate.setDate(QDate(pubdate.year, pubdate.month, @@ -598,8 +619,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): w = self.central_widget.widget(1) layout = w.layout() self.custom_column_widgets, self.__cc_spacers = \ - populate_metadata_page(layout, self.db, self.id, - parent=w, bulk=False, two_column=True) + populate_metadata_page(layout, self.db, self.id, parent=w, bulk=False, + two_column=tweaks['metadata_single_use_2_cols_for_custom_fields']) self.__custom_col_layouts = [layout] ans = self.custom_column_widgets for i in range(len(ans)-1): @@ -610,27 +631,40 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): for c in range(2, len(ans[i].widgets), 2): w.setTabOrder(ans[i].widgets[c-1], ans[i].widgets[c+1]) + def title_box_changed(self, txt): + ts = unicode(txt) + ts = title_sort(ts) + self.mark_box_as_ok(control = self.title_sort, tt=self.ts_tooltips, + normal=(unicode(self.title_sort.text()) == ts)) + + def title_sort_box_changed(self, txt): + ts = unicode(txt) + self.mark_box_as_ok(control = self.title_sort, tt=self.ts_tooltips, + normal=(title_sort(unicode(self.title.text())) == ts)) + def authors_box_changed(self, txt): aus = unicode(txt) aus = re.sub(r'\s+et al\.$', '', aus) aus = self.db.author_sort_from_authors(string_to_authors(aus)) - self.mark_author_sort(normal=(unicode(self.author_sort.text()) == aus)) + self.mark_box_as_ok(control = self.author_sort, tt=self.aus_tooltips, + normal=(unicode(self.author_sort.text()) == aus)) def author_sort_box_changed(self, txt): au = unicode(self.authors.text()) au = re.sub(r'\s+et al\.$', '', au) au = self.db.author_sort_from_authors(string_to_authors(au)) - self.mark_author_sort(normal=(au == txt)) + self.mark_box_as_ok(control = self.author_sort, tt=self.aus_tooltips, + normal=(au == txt)) - def mark_author_sort(self, normal=True): + def mark_box_as_ok(self, control, tt, normal=True): if normal: col = 'rgb(0, 255, 0, 20%)' else: col = 'rgb(255, 0, 0, 20%)' - self.author_sort.setStyleSheet('QLineEdit { color: black; ' - 'background-color: %s; }'%col) - tt = self.ok_aus_tooltip if normal else self.bad_aus_tooltip - self.author_sort.setToolTip(tt) + control.setStyleSheet('QLineEdit { color: black; ' + 'background-color: %s; }'%col) + tt = tt[0] if normal else tt[1] + control.setToolTip(tt) def validate_isbn(self, isbn): isbn = unicode(isbn).strip() @@ -652,12 +686,16 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): authors = string_to_authors(au) self.author_sort.setText(self.db.author_sort_from_authors(authors)) + def deduce_title_sort(self): + ts = unicode(self.title.text()) + self.title_sort.setText(title_sort(ts)) + def swap_title_author(self): title = self.title.text() self.title.setText(self.authors.text()) self.authors.setText(title) - self.author_sort.setText('') - + self.deduce_author_sort() + self.deduce_title_sort() def initialize_combos(self): self.initalize_authors() @@ -771,10 +809,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.pubdate.setDate(QDate(dt.year, dt.month, dt.day)) summ = book.comments if summ: - prefix = unicode(self.comments.toPlainText()) + prefix = self.comment.html if prefix: prefix += '\n' - self.comments.setPlainText(prefix + summ) + self.comments.html = prefix + comments_to_html(summ) if book.rating is not None: self.rating.setValue(int(book.rating)) if book.tags: @@ -804,7 +842,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): series = unicode(self.series.text()).strip() if series and series != self.original_series_name: ns = 1 - if tweaks['series_index_auto_increment'] == 'next': + if tweaks['series_index_auto_increment'] != 'const': ns = self.db.get_next_series_num_for(series) self.series_index.setValue(ns) self.original_series_name = series @@ -838,6 +876,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): title = unicode(self.title.text()).strip() if title != self.original_title: self.db.set_title(self.id, title, notify=False) + # This must be after setting the title because of the DB update trigger + ts = unicode(self.title_sort.text()).strip() + if ts: + self.db.set_title_sort(self.id, ts, notify=False, commit=False) au = unicode(self.authors.text()).strip() if au and au != self.original_author: self.db.set_authors(self.id, string_to_authors(au), notify=False) @@ -860,7 +902,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.db.set_series_index(self.id, self.series_index.value(), notify=False, commit=False) self.db.set_comment(self.id, - unicode(self.comments.toPlainText()).strip(), + self.comments.html, notify=False, commit=False) d = self.pubdate.date() d = qt_to_dt(d) @@ -897,16 +939,16 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): QDialog.reject(self, *args) def read_state(self): - wg = dynamic.get('metasingle_window_geometry', None) - ss = dynamic.get('metasingle_splitter_state', None) + wg = dynamic.get('metasingle_window_geometry2', None) + ss = dynamic.get('metasingle_splitter_state2', None) if wg is not None: self.restoreGeometry(wg) if ss is not None: self.splitter.restoreState(ss) def save_state(self): - dynamic.set('metasingle_window_geometry', bytes(self.saveGeometry())) - dynamic.set('metasingle_splitter_state', + dynamic.set('metasingle_window_geometry2', bytes(self.saveGeometry())) + dynamic.set('metasingle_splitter_state2', bytes(self.splitter.saveState())) def break_cycles(self): diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index 2bd85e30bb..dfa8c45797 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>887</width> - <height>750</height> + <width>994</width> + <height>726</height> </rect> </property> <property name="sizePolicy"> @@ -43,8 +43,8 @@ <rect> <x>0</x> <y>0</y> - <width>879</width> - <height>711</height> + <width>986</width> + <height>687</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_5"> @@ -66,8 +66,8 @@ <attribute name="title"> <string>&Basic metadata</string> </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> <widget class="QSplitter" name="splitter"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -100,27 +100,27 @@ </property> </widget> </item> - <item row="0" column="2" rowspan="2"> - <widget class="QToolButton" name="swap_button"> - <property name="toolTip"> - <string>Swap the author and title</string> - </property> + <item row="1" column="0"> + <widget class="QLabel" name="label"> <property name="text"> - <string>...</string> + <string>Title &sort: </string> </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> - <property name="iconSize"> - <size> - <width>16</width> - <height>16</height> - </size> + <property name="buddy"> + <cstring>title_sort</cstring> </property> </widget> </item> - <item row="1" column="0"> + <item row="1" column="1"> + <widget class="EnLineEdit" name="title_sort"> + <property name="toolTip"> + <string>Specify how this book should be sorted when by title. For example, The Exorcist might be sorted as Exorcist, The.</string> + </property> + </widget> + </item> + <item row="2" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> <string>&Author(s): </string> @@ -133,7 +133,14 @@ </property> </widget> </item> - <item row="2" column="0"> + <item row="2" column="1"> + <widget class="EnComboBox" name="authors"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Author S&ort: </string> @@ -146,34 +153,15 @@ </property> </widget> </item> - <item row="2" column="1" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="EnLineEdit" name="author_sort"> - <property name="toolTip"> - <string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles. + <item row="3" column="1"> + <widget class="EnLineEdit" name="author_sort"> + <property name="toolTip"> + <string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles. If the box is colored green, then text matches the individual author's sort strings. If it is colored red, then the authors and this text do not match.</string> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="auto_author_sort"> - <property name="toolTip"> - <string>Automatically create the author sort entry based on the current author entry. -Using this button to create author sort will change author sort from red to green.</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/auto_author_sort.png</normaloff>:/images/auto_author_sort.png</iconset> - </property> - </widget> - </item> - </layout> + </property> + </widget> </item> - <item row="3" column="0"> + <item row="4" column="0"> <widget class="QLabel" name="label_6"> <property name="text"> <string>&Rating:</string> @@ -186,7 +174,7 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item row="3" column="1" colspan="2"> + <item row="4" column="1" colspan="2"> <widget class="QSpinBox" name="rating"> <property name="toolTip"> <string>Rating of this book. 0-5 stars</string> @@ -205,7 +193,7 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item row="4" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>&Publisher: </string> @@ -218,7 +206,14 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item row="5" column="0"> + <item row="5" column="1" colspan="2"> + <widget class="EnComboBox" name="publisher"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="6" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Ta&gs: </string> @@ -231,32 +226,7 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item row="5" column="1" colspan="2"> - <layout class="QHBoxLayout" name="_2"> - <item> - <widget class="TagsLineEdit" name="tags"> - <property name="toolTip"> - <string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="tag_editor_button"> - <property name="toolTip"> - <string>Open Tag Editor</string> - </property> - <property name="text"> - <string>Open Tag Editor</string> - </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset> - </property> - </widget> - </item> - </layout> - </item> - <item row="6" column="0"> + <item row="7" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>&Series:</string> @@ -272,7 +242,7 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item row="6" column="1" colspan="2"> + <item row="7" column="1"> <layout class="QHBoxLayout" name="_3"> <property name="spacing"> <number>5</number> @@ -293,59 +263,9 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item> - <widget class="QToolButton" name="remove_series_button"> - <property name="toolTip"> - <string>Remove unused series (Series that have no books)</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset> - </property> - </widget> - </item> </layout> </item> - <item row="8" column="0"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>IS&BN:</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="buddy"> - <cstring>isbn</cstring> - </property> - </widget> - </item> <item row="8" column="1" colspan="2"> - <widget class="QLineEdit" name="isbn"/> - </item> - <item row="10" column="0"> - <widget class="QLabel" name="label_10"> - <property name="text"> - <string>Publishe&d:</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="buddy"> - <cstring>pubdate</cstring> - </property> - </widget> - </item> - <item row="4" column="1" colspan="2"> - <widget class="EnComboBox" name="publisher"> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="7" column="1" colspan="2"> <widget class="QDoubleSpinBox" name="series_index"> <property name="enabled"> <bool>false</bool> @@ -358,34 +278,23 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - <item row="10" column="1" colspan="2"> - <widget class="QDateEdit" name="pubdate"> - <property name="displayFormat"> - <string>MMM yyyy</string> + <item row="9" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>IS&BN:</string> </property> - <property name="calendarPopup"> - <bool>true</bool> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="EnComboBox" name="authors"> - <property name="editable"> - <bool>true</bool> + <property name="buddy"> + <cstring>isbn</cstring> </property> </widget> </item> <item row="9" column="1" colspan="2"> - <widget class="QDateEdit" name="date"> - <property name="displayFormat"> - <string>dd MMM yyyy</string> - </property> - <property name="calendarPopup"> - <bool>true</bool> - </property> - </widget> + <widget class="QLineEdit" name="isbn"/> </item> - <item row="9" column="0"> + <item row="10" column="0"> <widget class="QLabel" name="label_11"> <property name="text"> <string>&Date:</string> @@ -398,22 +307,181 @@ Using this button to create author sort will change author sort from red to gree </property> </widget> </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>&Comments</string> - </property> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <widget class="QTextEdit" name="comments"> - <property name="tabChangesFocus"> + <item row="10" column="1" colspan="2"> + <widget class="QDateEdit" name="date"> + <property name="displayFormat"> + <string>dd MMM yyyy</string> + </property> + <property name="calendarPopup"> <bool>true</bool> </property> - <property name="acceptRichText"> - <bool>false</bool> + </widget> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Publishe&d:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>pubdate</cstring> + </property> + </widget> + </item> + <item row="11" column="1" colspan="2"> + <widget class="QDateEdit" name="pubdate"> + <property name="displayFormat"> + <string>MMM yyyy</string> + </property> + <property name="calendarPopup"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="2" rowspan="4"> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="auto_title_sort"> + <property name="toolTip"> + <string>Automatically create the title sort entry based on the current title entry. +Using this button to create title sort will change title sort from red to green.</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/auto_author_sort.png</normaloff>:/images/auto_author_sort.png</iconset> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="swap_button"> + <property name="toolTip"> + <string>Swap the author and title</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="auto_author_sort"> + <property name="toolTip"> + <string>Automatically create the author sort entry based on the current author entry. +Using this button to create author sort will change author sort from red to green.</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/auto_author_sort.png</normaloff>:/images/auto_author_sort.png</iconset> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="6" column="1"> + <layout class="QHBoxLayout" name="_2"> + <item> + <widget class="TagsLineEdit" name="tags"> + <property name="toolTip"> + <string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="2"> + <widget class="QToolButton" name="tag_editor_button"> + <property name="toolTip"> + <string>Open Tag Editor</string> + </property> + <property name="text"> + <string>Open Tag Editor</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QToolButton" name="remove_series_button"> + <property name="toolTip"> + <string>Remove unused series (Series that have no books)</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset> </property> </widget> </item> @@ -431,6 +499,128 @@ Using this button to create author sort will change author sort from red to gree </widget> <widget class="QWidget" name="layoutWidget_2"> <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="bc_box"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>10</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Book Cover</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="ImageView" name="cover" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>100</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="_4"> + <property name="spacing"> + <number>6</number> + </property> + <property name="sizeConstraint"> + <enum>QLayout::SetMaximumSize</enum> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Change &cover image:</string> + </property> + <property name="buddy"> + <cstring>cover_button</cstring> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="_5"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="cover_button"> + <property name="text"> + <string>&Browse</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/document_open.png</normaloff>:/images/document_open.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="trim_cover_button"> + <property name="toolTip"> + <string>Remove border (if any) from cover</string> + </property> + <property name="text"> + <string>T&rim</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/trim.png</normaloff>:/images/trim.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="reset_cover"> + <property name="toolTip"> + <string>Reset cover to default</string> + </property> + <property name="text"> + <string>&Remove</string> + </property> + <property name="icon"> + <iconset resource="../../../../resources/images.qrc"> + <normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="_6"> + <item> + <widget class="QPushButton" name="fetch_cover_button"> + <property name="text"> + <string>Download co&ver</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="generate_cover_button"> + <property name="toolTip"> + <string>Generate a default cover based on the title and author</string> + </property> + <property name="text"> + <string>&Generate cover</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="layoutWidget"> + <layout class="QVBoxLayout" name="verticalLayout_3"> <item> <widget class="QGroupBox" name="af_group_box"> <property name="sizePolicy"> @@ -459,6 +649,12 @@ Using this button to create author sort will change author sort from red to gree <height>140</height> </size> </property> + <property name="baseSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> <property name="dragDropMode"> <enum>QAbstractItemView::DropOnly</enum> </property> @@ -557,129 +753,22 @@ Using this button to create author sort will change author sort from red to gree </widget> </item> <item> - <widget class="QGroupBox" name="bc_box"> + <widget class="QGroupBox" name="groupBox"> <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>10</verstretch> </sizepolicy> </property> <property name="title"> - <string>Book Cover</string> + <string>&Comments</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_4"> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <property name="margin"> + <number>0</number> + </property> <item> - <widget class="ImageView" name="cover" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>100</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="_4"> - <property name="spacing"> - <number>6</number> - </property> - <property name="sizeConstraint"> - <enum>QLayout::SetMaximumSize</enum> - </property> - <property name="margin"> - <number>0</number> - </property> - <item> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Change &cover image:</string> - </property> - <property name="buddy"> - <cstring>cover_path</cstring> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="_5"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>0</number> - </property> - <item> - <widget class="QLineEdit" name="cover_path"> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="cover_button"> - <property name="text"> - <string>&Browse</string> - </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/document_open.png</normaloff>:/images/document_open.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="trim_cover_button"> - <property name="toolTip"> - <string>Remove border (if any) from cover</string> - </property> - <property name="text"> - <string>T&rim</string> - </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/trim.png</normaloff>:/images/trim.png</iconset> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="reset_cover"> - <property name="toolTip"> - <string>Reset cover to default</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="_6"> - <item> - <widget class="QPushButton" name="fetch_cover_button"> - <property name="text"> - <string>Download co&ver</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="generate_cover_button"> - <property name="toolTip"> - <string>Generate a default cover based on the title and author</string> - </property> - <property name="text"> - <string>&Generate cover</string> - </property> - </widget> - </item> - </layout> + <widget class="Editor" name="comments" native="true"/> </item> </layout> </widget> @@ -741,13 +830,21 @@ Using this button to create author sort will change author sort from red to gree <header>calibre/gui2/widgets.h</header> <container>1</container> </customwidget> + <customwidget> + <class>Editor</class> + <extends>QWidget</extends> + <header location="global">calibre/gui2/comments_editor.h</header> + <container>1</container> + </customwidget> </customwidgets> <tabstops> <tabstop>title</tabstop> + <tabstop>auto_title_sort</tabstop> + <tabstop>title_sort</tabstop> <tabstop>swap_button</tabstop> <tabstop>authors</tabstop> - <tabstop>author_sort</tabstop> <tabstop>auto_author_sort</tabstop> + <tabstop>author_sort</tabstop> <tabstop>rating</tabstop> <tabstop>publisher</tabstop> <tabstop>tags</tabstop> @@ -758,20 +855,20 @@ Using this button to create author sort will change author sort from red to gree <tabstop>isbn</tabstop> <tabstop>date</tabstop> <tabstop>pubdate</tabstop> - <tabstop>comments</tabstop> <tabstop>fetch_metadata_button</tabstop> - <tabstop>add_format_button</tabstop> - <tabstop>remove_format_button</tabstop> <tabstop>button_set_cover</tabstop> <tabstop>button_set_metadata</tabstop> <tabstop>formats</tabstop> - <tabstop>cover_path</tabstop> + <tabstop>add_format_button</tabstop> + <tabstop>remove_format_button</tabstop> + <tabstop>cover_button</tabstop> + <tabstop>trim_cover_button</tabstop> <tabstop>reset_cover</tabstop> <tabstop>fetch_cover_button</tabstop> <tabstop>generate_cover_button</tabstop> + <tabstop>button_box</tabstop> <tabstop>scrollArea</tabstop> <tabstop>central_widget</tabstop> - <tabstop>button_box</tabstop> </tabstops> <resources> <include location="../../../../resources/images.qrc"/> diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index e0d5c64961..661f21e53d 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -772,7 +772,7 @@ class BooksModel(QAbstractTableModel): # {{{ self.db.set_series_index(id, float(match.group(1))) val = pat.sub('', val).strip() elif val: - if tweaks['series_index_auto_increment'] == 'next': + if tweaks['series_index_auto_increment'] != 'const': ni = self.db.get_next_series_num_for(val) if ni != 1: self.db.set_series_index(id, ni) diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index 0e0cc0eec2..a6285c6656 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -123,8 +123,8 @@ class BooksView(QTableView): # {{{ elif action == 'show': h.setSectionHidden(idx, False) if h.sectionSize(idx) < 3: - sz = h.sectionSizeHint(idx) - h.resizeSection(idx, sz) + sz = h.sectionSizeHint(idx) + h.resizeSection(idx, sz) elif action == 'ascending': self.sortByColumn(idx, Qt.AscendingOrder) elif action == 'descending': diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index d355fe600e..371c4df701 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -254,6 +254,7 @@ def run_in_debug_mode(logpath=None): e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0] import tempfile, subprocess fd, logpath = tempfile.mkstemp('.txt') + os.close(fd) if hasattr(sys, 'frameworks_dir'): base = os.path.dirname(sys.frameworks_dir) @@ -265,7 +266,13 @@ def run_in_debug_mode(logpath=None): base, ext = os.path.splitext(e) exe = base + '-debug' + ext print 'Starting debug executable:', exe - subprocess.Popen([exe, '--gui-debug', logpath], stdout=fd, stderr=fd) + creationflags = 0 + if iswindows: + import win32process + creationflags = win32process.CREATE_NO_WINDOW + subprocess.Popen([exe, '--gui-debug', logpath], stdout=open(logpath, 'w'), + stderr=subprocess.STDOUT, stdin=open(os.devnull, 'r'), + creationflags=creationflags) def run_gui(opts, args, actions, listener, app, gui_debug=None): initialize_file_icon_provider() @@ -299,7 +306,13 @@ def run_gui(opts, args, actions, listener, app, gui_debug=None): if runner.main.gui_debug is not None: e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0] import subprocess - subprocess.Popen([e, '--show-gui-debug', runner.main.gui_debug]) + creationflags = 0 + if iswindows: + import win32process + creationflags = win32process.CREATE_NO_WINDOW + subprocess.Popen([e, '--show-gui-debug', runner.main.gui_debug], + creationflags=creationflags, stdout=open(os.devnull, 'w'), + stderr=subprocess.PIPE, stdin=open(os.devnull, 'r')) return ret def cant_start(msg=_('If you are sure it is not running')+', ', diff --git a/src/calibre/gui2/tag_view.py b/src/calibre/gui2/tag_view.py index f75061da12..478f6b042f 100644 --- a/src/calibre/gui2/tag_view.py +++ b/src/calibre/gui2/tag_view.py @@ -18,6 +18,7 @@ from PyQt4.Qt import Qt, QTreeView, QApplication, pyqtSignal, \ from calibre.ebooks.metadata import title_sort from calibre.gui2 import config, NONE from calibre.library.field_metadata import TagsIcons, category_icon_map +from calibre.utils.config import tweaks from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import saved_searches from calibre.gui2 import error_dialog @@ -409,17 +410,31 @@ class TagTreeItem(object): # {{{ return NONE def tag_data(self, role): + tag = self.tag + if tag.category == 'authors' and \ + tweaks['categories_use_field_for_author_name'] == 'author_sort': + name = tag.sort + tt_author = True + else: + name = tag.name + tt_author = False if role == Qt.DisplayRole: - if self.tag.count == 0: - return QVariant('%s'%(self.tag.name)) + if tag.count == 0: + return QVariant('%s'%(name)) else: - return QVariant('[%d] %s'%(self.tag.count, self.tag.name)) + return QVariant('[%d] %s'%(tag.count, name)) if role == Qt.EditRole: - return QVariant(self.tag.name) + return QVariant(tag.name) if role == Qt.DecorationRole: - return self.icon_state_map[self.tag.state] - if role == Qt.ToolTipRole and self.tag.tooltip is not None: - return QVariant(self.tag.tooltip) + return self.icon_state_map[tag.state] + if role == Qt.ToolTipRole: + if tt_author: + if tag.tooltip is not None: + return QVariant('(%s) %s'%(tag.name, tag.tooltip)) + else: + return QVariant(tag.name) + if tag.tooltip is not None: + return QVariant(tag.tooltip) return NONE def toggle(self): diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index dd3925e732..f97589e466 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -378,13 +378,16 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ def booklists(self): return self.memory_view.model().db, self.card_a_view.model().db, self.card_b_view.model().db - def library_moved(self, newloc): + def library_moved(self, newloc, copy_structure=False): if newloc is None: return + default_prefs = None try: olddb = self.library_view.model().db + if copy_structure: + default_prefs = olddb.prefs except: olddb = None - db = LibraryDatabase2(newloc) + db = LibraryDatabase2(newloc, default_prefs=default_prefs) if self.content_server is not None: self.content_server.set_database(db) self.library_path = newloc diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index f131dd522d..d5f881d4b4 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -188,6 +188,7 @@ class Document(QWebPage): # Miscellaneous settings.setAttribute(QWebSettings.LinksIncludedInFocusChain, True) + settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True) self.set_user_stylesheet() self.misc_config() diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index f7b8a8d401..25f69b1558 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -650,7 +650,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.action_table_of_contents.setDisabled(not self.iterator.toc) self.current_book_has_toc = bool(self.iterator.toc) self.current_title = title - self.setWindowTitle(self.base_window_title+' - '+title) + self.setWindowTitle(self.base_window_title+' - '+title + + ' [%s]'%os.path.splitext(pathtoebook)[1][1:].upper()) self.pos.setMaximum(sum(self.iterator.pages)) self.pos.setSuffix(' / %d'%sum(self.iterator.pages)) self.vertical_scrollbar.setMinimum(100) diff --git a/src/calibre/gui2/viewer/main.ui b/src/calibre/gui2/viewer/main.ui index 4cfa1590da..d470a386c6 100644 --- a/src/calibre/gui2/viewer/main.ui +++ b/src/calibre/gui2/viewer/main.ui @@ -243,7 +243,7 @@ <action name="action_copy"> <property name="icon"> <iconset resource="../../../../resources/images.qrc"> - <normaloff>:/images/edit_copy.png</normaloff>:/images/edit_copy.png</iconset> + <normaloff>:/images/edit-copy.png</normaloff>:/images/edit-copy.png</iconset> </property> <property name="text"> <string>Copy to clipboard</string> diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index 12d64bbbcd..c5ae7fff85 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -19,7 +19,6 @@ from calibre.gui2 import NONE, error_dialog, pixmap_to_data, gprefs from calibre.constants import isosx from calibre.gui2.filename_pattern_ui import Ui_Form from calibre import fit_image -from calibre.utils.fonts import fontconfig from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks.metadata.meta import metadata_from_filename from calibre.utils.config import prefs, XMLConfig @@ -283,6 +282,7 @@ class FontFamilyModel(QAbstractListModel): def __init__(self, *args): QAbstractListModel.__init__(self, *args) + from calibre.utils.fonts import fontconfig try: self.families = fontconfig.find_font_families() except: diff --git a/src/calibre/library/cli.py b/src/calibre/library/cli.py index 01e8ad449b..c98b3be4d3 100644 --- a/src/calibre/library/cli.py +++ b/src/calibre/library/cli.py @@ -707,7 +707,7 @@ def parse_series_string(db, label, value): val = pat.sub('', val).strip() s_index = float(match.group(1)) elif val: - if tweaks['series_index_auto_increment'] == 'next': + if tweaks['series_index_auto_increment'] != 'const': s_index = db.get_next_cc_series_num_for(val, label=label) else: s_index = 1.0 diff --git a/src/calibre/library/custom_columns.py b/src/calibre/library/custom_columns.py index f544a9bf7e..e95ace2cd4 100644 --- a/src/calibre/library/custom_columns.py +++ b/src/calibre/library/custom_columns.py @@ -8,12 +8,12 @@ __docformat__ = 'restructuredtext en' import json, re from functools import partial -from math import floor from calibre import prints from calibre.constants import preferred_encoding from calibre.library.field_metadata import FieldMetadata from calibre.utils.date import parse_date +from calibre.utils.config import tweaks class CustomColumns(object): @@ -261,15 +261,15 @@ class CustomColumns(object): series_id = self.conn.get('SELECT id from %s WHERE value=?'%table, (series,), all=False) if series_id is None: + if isinstance(tweaks['series_index_auto_increment'], (int, float)): + return float(tweaks['series_index_auto_increment']) return 1.0 - # get the label of the associated series number table - series_num = self.conn.get(''' - SELECT MAX({lt}.extra) FROM {lt} + series_indices = self.conn.get(''' + SELECT {lt}.extra FROM {lt} WHERE {lt}.book IN (SELECT book FROM {lt} where value=?) - '''.format(lt=lt), (series_id,), all=False) - if series_num is None: - return 1.0 - return floor(series_num+1) + ORDER BY {lt}.extra + '''.format(lt=lt), (series_id,)) + return self._get_next_series_num_for_list(series_indices) def all_custom(self, label=None, num=None): if label is not None: diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 23375995ae..cba49ae6ae 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -8,7 +8,7 @@ The database used to store ebook metadata ''' import os, sys, shutil, cStringIO, glob, time, functools, traceback, re from itertools import repeat -from math import floor +from math import ceil from Queue import Queue from PyQt4.QtGui import QImage @@ -113,7 +113,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): def exists_at(cls, path): return path and os.path.exists(os.path.join(path, 'metadata.db')) - def __init__(self, library_path, row_factory=False): + def __init__(self, library_path, row_factory=False, default_prefs=None): self.field_metadata = FieldMetadata() self.dirtied_queue = Queue() if not os.path.exists(library_path): @@ -127,10 +127,29 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if isinstance(self.dbpath, unicode) and not iswindows: self.dbpath = self.dbpath.encode(filesystem_encoding) + apply_default_prefs = not os.path.exists(self.dbpath) self.connect() + self.is_case_sensitive = not iswindows and not isosx and \ not os.path.exists(self.dbpath.replace('metadata.db', 'MeTAdAtA.dB')) SchemaUpgrade.__init__(self) + + # if we are to copy the prefs and structure from some other DB, then + # we need to do it before we call initialize_dynamic + if apply_default_prefs and default_prefs is not None: + dbprefs = DBPrefs(self) + for key in default_prefs: + # be sure that prefs not to be copied are listed below + if key in ['news_to_be_synced']: + continue + try: + dbprefs[key] = default_prefs[key] + except: + pass # ignore options that don't exist anymore + fmvals = [f for f in default_prefs['field_metadata'].values() if f['is_custom']] + for f in fmvals: + self.create_custom_column(f['label'], f['name'], f['datatype'], + f['is_multiple'] is not None, f['is_editable'], f['display']) self.initialize_dynamic() def get_property(self, idx, index_is_id=False, loc=-1): @@ -1109,6 +1128,14 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): for l in list: (id, val, sort_val) = (l[0], l[1], l[2]) tids[category][val] = (id, sort_val) + elif cat['datatype'] == 'series': + for l in list: + (id, val) = (l[0], l[1]) + tids[category][val] = (id, title_sort(val)) + elif cat['datatype'] == 'rating': + for l in list: + (id, val) = (l[0], l[1]) + tids[category][val] = (id, '{0:05.2f}'.format(val)) else: for l in list: (id, val) = (l[0], l[1]) @@ -1237,12 +1264,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): # sort the list if sort == 'name': - def get_sort_key(x): - sk = x.s - if isinstance(sk, unicode): - sk = sort_key(sk) - return sk - kf = get_sort_key + kf = lambda x :sort_key(x.s) reverse=False elif sort == 'popularity': kf = lambda x: x.c @@ -1365,14 +1387,42 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): series_id = self.conn.get('SELECT id from series WHERE name=?', (series,), all=False) if series_id is None: + if isinstance(tweaks['series_index_auto_increment'], (int, float)): + return float(tweaks['series_index_auto_increment']) return 1.0 - series_num = self.conn.get( - ('SELECT MAX(series_index) FROM books WHERE id IN ' - '(SELECT book FROM books_series_link where series=?)'), - (series_id,), all=False) - if series_num is None: + series_indices = self.conn.get( + ('SELECT series_index FROM books WHERE id IN ' + '(SELECT book FROM books_series_link where series=?) ' + 'ORDER BY series_index'), + (series_id,)) + return self._get_next_series_num_for_list(series_indices) + + def _get_next_series_num_for_list(self, series_indices): + if not series_indices: + if isinstance(tweaks['series_index_auto_increment'], (int, float)): + return float(tweaks['series_index_auto_increment']) return 1.0 - return floor(series_num+1) + series_indices = [x[0] for x in series_indices] + if tweaks['series_index_auto_increment'] == 'next': + return series_indices[-1] + 1 + if tweaks['series_index_auto_increment'] == 'first_free': + for i in range(1, 10000): + if i not in series_indices: + return i + # really shouldn't get here. + if tweaks['series_index_auto_increment'] == 'next_free': + for i in range(int(ceil(series_indices[0])), 10000): + if i not in series_indices: + return i + # really shouldn't get here. + if tweaks['series_index_auto_increment'] == 'last_free': + for i in range(int(ceil(series_indices[-1])), 0, -1): + if i not in series_indices: + return i + return series_indices[-1] + 1 + if isinstance(tweaks['series_index_auto_increment'], (int, float)): + return float(tweaks['series_index_auto_increment']) + return 1.0 def set(self, row, column, val): ''' @@ -1565,6 +1615,20 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if notify: self.notify('metadata', [id]) + def set_title_sort(self, id, title_sort_, notify=True, commit=True): + if not title_sort_: + return False + if isbytestring(title_sort_): + title_sort_ = title_sort_.decode(preferred_encoding, 'replace') + self.conn.execute('UPDATE books SET sort=? WHERE id=?', (title_sort_, id)) + self.data.set(id, self.FIELD_MAP['sort'], title_sort_, row_is_id=True) + self.dirtied([id], commit=False) + if commit: + self.conn.commit() + if notify: + self.notify('metadata', [id]) + return True + def _set_title(self, id, title): if not title: return False @@ -1746,18 +1810,17 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): FROM books, books_series_link as lt WHERE books.id = lt.book AND lt.series=? ORDER BY books.series_index''', (old_id,)) - # Get the next series index - index = self.get_next_series_num_for(new_name) # Now update the link table self.conn.execute('''UPDATE books_series_link SET series=? WHERE series=?''',(new_id, old_id,)) # Now set the indices for (book_id,) in books: + # Get the next series index + index = self.get_next_series_num_for(new_name) self.conn.execute('''UPDATE books SET series_index=? WHERE id=?''',(index, book_id,)) - index = index + 1 self.dirty_books_referencing('series', new_id, commit=False) self.conn.commit() @@ -1907,7 +1970,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): @classmethod def cleanup_tags(cls, tags): - tags = [x.strip() for x in tags if x.strip()] + tags = [x.strip().replace(',', ';') for x in tags if x.strip()] tags = [x.decode(preferred_encoding, 'replace') \ if isbytestring(x) else x for x in tags] tags = [u' '.join(x.split()) for x in tags] diff --git a/src/calibre/library/schema_upgrades.py b/src/calibre/library/schema_upgrades.py index 5e581e3f86..1483743e4a 100644 --- a/src/calibre/library/schema_upgrades.py +++ b/src/calibre/library/schema_upgrades.py @@ -427,5 +427,17 @@ class SchemaUpgrade(object): def upgrade_version_15(self): 'Remove commas from tags' - self.conn.execute("UPDATE tags SET name=REPLACE(name, ',', ';')") + self.conn.execute("UPDATE OR IGNORE tags SET name=REPLACE(name, ',', ';')") + self.conn.execute("UPDATE OR IGNORE tags SET name=REPLACE(name, ',', ';;')") + self.conn.execute("UPDATE OR IGNORE tags SET name=REPLACE(name, ',', '')") + def upgrade_version_16(self): + self.conn.executescript(''' + DROP TRIGGER IF EXISTS books_update_trg; + CREATE TRIGGER books_update_trg + AFTER UPDATE ON books + BEGIN + UPDATE books SET sort=title_sort(NEW.title) + WHERE id=NEW.id AND OLD.title <> NEW.title; + END; + ''') diff --git a/src/calibre/library/server/browse.py b/src/calibre/library/server/browse.py index 37f024c08d..b1c4a4c2f9 100644 --- a/src/calibre/library/server/browse.py +++ b/src/calibre/library/server/browse.py @@ -15,7 +15,7 @@ from calibre import isbytestring, force_unicode, fit_image, \ prepare_string_for_xml as xml from calibre.utils.ordered_dict import OrderedDict from calibre.utils.filenames import ascii_filename -from calibre.utils.config import prefs +from calibre.utils.config import prefs, tweaks from calibre.utils.icu import sort_key from calibre.utils.magick import Image from calibre.library.comments import comments_to_html @@ -151,7 +151,11 @@ def get_category_items(category, items, restriction, datatype, prefix): # {{{ '<div>{1}</div>' '<div>{2}</div></div>') rating, rstring = render_rating(i.avg_rating, prefix) - name = xml(i.name) + if i.category == 'authors' and \ + tweaks['categories_use_field_for_author_name'] == 'author_sort': + name = xml(i.sort) + else: + name = xml(i.name) if datatype == 'rating': name = xml(_('%d stars')%int(i.avg_rating)) id_ = i.id diff --git a/src/calibre/library/server/content.py b/src/calibre/library/server/content.py index 5492c86fa9..8af70d5675 100644 --- a/src/calibre/library/server/content.py +++ b/src/calibre/library/server/content.py @@ -5,7 +5,7 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __docformat__ = 'restructuredtext en' -import re, os +import re, os, posixpath import cherrypy @@ -88,17 +88,24 @@ class ContentServer(object): def static(self, name): 'Serves static content' name = name.lower() - cherrypy.response.headers['Content-Type'] = { + fname = posixpath.basename(name) + try: + cherrypy.response.headers['Content-Type'] = { 'js' : 'text/javascript', 'css' : 'text/css', 'png' : 'image/png', 'gif' : 'image/gif', 'html' : 'text/html', - '' : 'application/octet-stream', - }[name.rpartition('.')[-1].lower()] + }[fname.rpartition('.')[-1].lower()] + except KeyError: + raise cherrypy.HTTPError(404, '%r not a valid resource type'%name) cherrypy.response.headers['Last-Modified'] = self.last_modified(self.build_time) - path = P('content_server/'+name) - if not os.path.exists(path): + basedir = os.path.abspath(P('content_server')) + path = os.path.join(basedir, name.replace('/', os.sep)) + path = os.path.abspath(path) + if not path.startswith(basedir): + raise cherrypy.HTTPError(403, 'Access to %s is forbidden'%name) + if not os.path.exists(path) or not os.path.isfile(path): raise cherrypy.HTTPError(404, '%s not found'%name) if self.opts.develop: lm = fromtimestamp(os.stat(path).st_mtime) diff --git a/src/calibre/library/server/opds.py b/src/calibre/library/server/opds.py index af635ebf48..e447c6966c 100644 --- a/src/calibre/library/server/opds.py +++ b/src/calibre/library/server/opds.py @@ -19,9 +19,10 @@ from calibre.ebooks.metadata import fmt_sidx from calibre.library.comments import comments_to_html from calibre.library.server import custom_fields_to_display from calibre.library.server.utils import format_tag_string, Offsets -from calibre import guess_type +from calibre import guess_type, prepare_string_for_xml as xml from calibre.utils.icu import sort_key from calibre.utils.ordered_dict import OrderedDict +from calibre.utils.config import tweaks BASE_HREFS = { 0 : '/stanza', @@ -113,8 +114,13 @@ def CATALOG_ENTRY(item, item_kind, base_href, version, updated, count = (_('%d books') if item.count > 1 else _('%d book'))%item.count if ignore_count: count = '' + if item.category == 'authors' and \ + tweaks['categories_use_field_for_author_name'] == 'author_sort': + name = xml(item.sort) + else: + name = xml(item.name) return E.entry( - TITLE(item.name + ('' if not add_kind else ' (%s)'%item_kind)), + TITLE(name + ('' if not add_kind else ' (%s)'%item_kind)), ID(id_), UPDATED(updated), E.content(count, type='text'), @@ -150,13 +156,13 @@ def ACQUISITION_ENTRY(item, version, db, updated, CFM, CKEYS, prefix): extra.append(_('RATING: %s<br />')%rating) tags = item[FM['tags']] if tags: - extra.append(_('TAGS: %s<br />')%format_tag_string(tags, ',', + extra.append(_('TAGS: %s<br />')%xml(format_tag_string(tags, ',', ignore_max=True, - no_tag_count=True)) + no_tag_count=True))) series = item[FM['series']] if series: extra.append(_('SERIES: %s [%s]<br />')%\ - (series, + (xml(series), fmt_sidx(float(item[FM['series_index']])))) for key in CKEYS: mi = db.get_metadata(item[CFM['id']['rec_index']], index_is_id=True) @@ -164,11 +170,11 @@ def ACQUISITION_ENTRY(item, version, db, updated, CFM, CKEYS, prefix): if val: datatype = CFM[key]['datatype'] if datatype == 'text' and CFM[key]['is_multiple']: - extra.append('%s: %s<br />'%(name, format_tag_string(val, ',', + extra.append('%s: %s<br />'%(xml(name), xml(format_tag_string(val, ',', ignore_max=True, - no_tag_count=True))) + no_tag_count=True)))) else: - extra.append('%s: %s<br />'%(name, val)) + extra.append('%s: %s<br />'%(xml(name), xml(unicode(val)))) comments = item[FM['comments']] if comments: comments = comments_to_html(comments) diff --git a/src/calibre/library/sqlite.py b/src/calibre/library/sqlite.py index ca6b0fc178..521c275efe 100644 --- a/src/calibre/library/sqlite.py +++ b/src/calibre/library/sqlite.py @@ -161,10 +161,7 @@ class DBThread(Thread): self.conn.create_aggregate('sort_concat', 2, SafeSortedConcatenate) self.conn.create_collation('PYNOCASE', partial(pynocase, encoding=encoding)) - if tweaks['title_series_sorting'] == 'strictly_alphabetic': - self.conn.create_function('title_sort', 1, lambda x:x) - else: - self.conn.create_function('title_sort', 1, title_sort) + self.conn.create_function('title_sort', 1, title_sort) self.conn.create_function('author_to_author_sort', 1, _author_to_author_sort) self.conn.create_function('uuid4', 0, lambda : str(uuid.uuid4())) diff --git a/src/calibre/manual/conversion.rst b/src/calibre/manual/conversion.rst index fea20a3163..3a7ae16598 100644 --- a/src/calibre/manual/conversion.rst +++ b/src/calibre/manual/conversion.rst @@ -541,7 +541,9 @@ Use the options to remove headers and footers to mitigate this issue. If the hea removed from the text it can throw off the paragraph unwrapping. Some limitations of PDF input is complex, multi-column, and image based documents are not supported. -Extraction of vector images and tables from within the document is also not supported. +Extraction of vector images and tables from within the document is also not supported. Some PDFs use special glyphs to +represent double ll or doubfle ff or fi,etc. Conversion of these may or may not work depending on jusy how they are +represented internally in the PDF. Comic Book Collections ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/calibre/translations/bs.po b/src/calibre/translations/bs.po index 96d9aa8e4f..8697b09317 100644 --- a/src/calibre/translations/bs.po +++ b/src/calibre/translations/bs.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-14 19:28+0000\n" -"Last-Translator: Kenan Dervišević <Unknown>\n" +"PO-Revision-Date: 2010-12-16 22:50+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Bosnian <bs@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-15 04:35+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/ca.po b/src/calibre/translations/ca.po index 0aa3925e02..cf18615439 100644 --- a/src/calibre/translations/ca.po +++ b/src/calibre/translations/ca.po @@ -11,13 +11,13 @@ msgstr "" "Project-Id-Version: ca\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-13 17:37+0000\n" +"PO-Revision-Date: 2010-12-16 23:54+0000\n" "Last-Translator: FerranRius <frius64@hotmail.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-14 04:50+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index df4cd9f764..6be44b3a3c 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -4,9 +4,9 @@ # msgid "" msgstr "" -"Project-Id-Version: calibre 0.7.33\n" -"POT-Creation-Date: 2010-12-10 14:25+MST\n" -"PO-Revision-Date: 2010-12-10 14:25+MST\n" +"Project-Id-Version: calibre 0.7.34\n" +"POT-Creation-Date: 2010-12-17 11:41+MST\n" +"PO-Revision-Date: 2010-12-17 11:41+MST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -25,7 +25,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:74 #: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:76 #: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:24 -#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:465 +#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:466 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71 #: /home/kovid/work/calibre/src/calibre/devices/prs500/books.py:267 @@ -35,11 +35,11 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:100 #: /home/kovid/work/calibre/src/calibre/ebooks/chm/metadata.py:56 #: /home/kovid/work/calibre/src/calibre/ebooks/comic/input.py:407 -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/periodical.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/periodical.py:127 #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:93 #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:95 -#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:338 -#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:341 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:332 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:335 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1894 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1896 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/output.py:24 @@ -53,7 +53,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/ereader.py:36 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/ereader.py:61 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:357 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:358 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:36 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:64 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:66 @@ -62,19 +62,19 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1022 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1134 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdb.py:39 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:28 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:29 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pml.py:23 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pml.py:49 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/snb.py:16 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/txt.py:14 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:39 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:65 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:78 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:119 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:153 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:631 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:837 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:839 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:42 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:68 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:81 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:122 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:634 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:849 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:851 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:914 @@ -109,40 +109,40 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:98 #: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:305 #: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:307 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:357 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:364 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:329 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:358 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:331 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:334 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:160 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:115 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:140 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:142 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1039 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1042 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1050 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1053 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:47 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:163 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:675 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:714 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:193 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:235 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:244 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:396 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:415 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:942 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1135 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:381 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:902 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1095 #: /home/kovid/work/calibre/src/calibre/gui2/metadata.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:190 #: /home/kovid/work/calibre/src/calibre/library/cli.py:215 #: /home/kovid/work/calibre/src/calibre/library/database.py:914 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:375 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:387 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1264 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1365 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2162 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2164 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2295 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:393 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:405 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1471 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1572 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2388 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2390 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2521 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:229 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:140 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:143 @@ -160,32 +160,32 @@ msgstr "" msgid "Base" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:172 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:200 msgid "File type" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:208 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:236 msgid "Metadata reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:238 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:266 msgid "Metadata writer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:268 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:296 msgid "Catalog generator" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:369 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:397 msgid "User Interface Action" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:395 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:17 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:22 +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:23 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:189 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:261 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:301 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:206 msgid "Preferences" msgstr "" @@ -249,163 +249,163 @@ msgstr "" msgid "Set metadata from %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:717 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:716 msgid "Look and Feel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:719 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:731 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:742 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:753 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:718 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:730 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:741 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:752 msgid "Interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:723 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:722 msgid "Adjust the look and feel of the calibre interface to suit your tastes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:729 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:728 msgid "Behavior" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:735 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:734 msgid "Change the way calibre behaves" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:740 -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:211 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:739 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:212 msgid "Add your own columns" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:746 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:745 msgid "Add/remove your own columns to the calibre book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:751 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:750 msgid "Customize the toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:757 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:756 msgid "Customize the toolbars and context menus, changing which actions are available in each" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:763 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:762 msgid "Input Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:765 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:776 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:787 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:764 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:775 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:786 msgid "Conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:769 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:768 msgid "Set conversion options specific to each input format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:774 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:773 msgid "Common Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:780 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:779 msgid "Set conversion options common to all formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:785 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:784 msgid "Output Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:791 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:790 msgid "Set conversion options specific to each output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:796 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:795 msgid "Adding books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:798 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:810 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:822 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:834 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:797 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:809 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:821 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:833 msgid "Import/Export" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:802 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:801 msgid "Control how calibre reads metadata from files when adding books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:808 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:807 msgid "Saving books to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:814 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:813 msgid "Control how calibre exports files from its database to disk when using Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:820 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:819 msgid "Sending books to devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:826 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:825 msgid "Control how calibre transfers files to your ebook reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:832 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:831 msgid "Metadata plugboards" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:838 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:837 msgid "Change metadata fields before saving/sending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:843 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:842 msgid "Sharing books by email" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:845 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:857 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:844 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:856 msgid "Sharing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:849 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:848 msgid "Setup sharing of books via email. Can be used for automatic sending of downloaded news to your devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:855 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:854 msgid "Sharing over the net" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:861 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:860 msgid "Setup the calibre Content Server which will give you access to your calibre library from anywhere, on any device, over the internet" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:868 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:867 msgid "Plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:870 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:882 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:893 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:869 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:881 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:892 msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:874 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:873 msgid "Add/remove/customize various bits of calibre functionality" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:880 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:879 msgid "Tweaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:886 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:885 msgid "Fine tune how calibre behaves in various contexts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:891 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:890 msgid "Miscellaneous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:897 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:896 msgid "Miscellaneous advanced configuration" msgstr "" @@ -606,6 +606,10 @@ msgstr "" msgid "Disable the named plugin" msgstr "" +#: /home/kovid/work/calibre/src/calibre/debug.py:148 +msgid "Debug log" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:13 msgid "Communicate with Android phones." msgstr "" @@ -643,14 +647,14 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:378 #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:947 #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:987 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2956 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2996 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2972 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3012 msgid "%d of %d" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:385 #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:992 -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3002 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:3018 msgid "finished" msgstr "" @@ -682,9 +686,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:888 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:918 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:264 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:189 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:202 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2026 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:207 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:220 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2252 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:150 msgid "News" msgstr "" @@ -692,12 +696,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2554 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:21 #: /home/kovid/work/calibre/src/calibre/library/catalog.py:560 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1989 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2007 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2215 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2233 msgid "Catalog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2860 +#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2876 msgid "Communicate with iTunes." msgstr "" @@ -710,6 +714,7 @@ msgid "Communicate with the Blackberry smart phone." msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/blackberry/driver.py:14 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:253 #: /home/kovid/work/calibre/src/calibre/devices/nuut2/driver.py:18 #: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:90 msgid "Kovid Goyal" @@ -739,6 +744,10 @@ msgstr "" msgid "Communicate with the PocketBook 602 reader." msgstr "" +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:252 +msgid "Communicate with the PocketBook 701" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/devices/edge/driver.py:17 msgid "Entourage Edge" msgstr "" @@ -895,12 +904,12 @@ msgstr "" msgid "Adding books to device metadata listing..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:445 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:272 +#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:279 msgid "Not Implemented" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:446 +#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:447 msgid "\".kobo\" files do not exist on the device as books instead, they are rows in the sqlite database. Currently they cannot be exported or viewed." msgstr "" @@ -1270,241 +1279,245 @@ msgstr "" msgid "Disable all rescaling of font sizes." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:166 -msgid "The line height in pts. Controls spacing between consecutive lines of text. By default no line height manipulation is performed." +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:165 +msgid "The minimum line height, as a percentage of the element's calculated font size. calibre will ensure that every element has a line height of at least this setting, irrespective of what the input document specifies. Set to zero to disable. Default is 120%. Use this setting in preference to the direct line height specification, unless you know what you are doing. For example, you can achieve \"double spaced\" text by setting this to 240." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:174 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:180 +msgid "The line height in pts. Controls spacing between consecutive lines of text. Only applies to elements that do not define their own line height. In most cases, the minimum line height option is more useful. By default no line height manipulation is performed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:191 msgid "Some badly designed documents use tables to control the layout of text on the page. When converted these documents often have text that runs off the page and other artifacts. This option will extract the content from the tables and present it in a linear fashion." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:184 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:201 msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level one. If this is specified, it takes precedence over other forms of auto-detection." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:193 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:210 msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level two. Each entry is added under the previous level one entry." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:201 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:218 msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level three. Each entry is added under the previous level two entry." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:209 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:226 msgid "Normally, if the source file already has a Table of Contents, it is used in preference to the auto-generated one. With this option, the auto-generated one is always used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:217 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:234 msgid "Don't add auto-detected chapters to the Table of Contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:224 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:241 msgid "If fewer than this number of chapters is detected, then links are added to the Table of Contents. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:231 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:248 msgid "Maximum number of links to insert into the TOC. Set to 0 to disable. Default is: %default. Links are only added to the TOC if less than the threshold number of chapters were detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:239 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:256 msgid "Remove entries from the Table of Contents whose titles match the specified regular expression. Matching entries and all their children are removed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:250 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:267 msgid "An XPath expression to detect chapter titles. The default is to consider <h1> or <h2> tags that contain the words \"chapter\",\"book\",\"section\" or \"part\" as chapter titles as well as any tags that have class=\"chapter\". The expression used must evaluate to a list of elements. To disable chapter detection, use the expression \"/\". See the XPath Tutorial in the calibre User Manual for further help on using this feature." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:264 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:281 msgid "Specify how to mark detected chapters. A value of \"pagebreak\" will insert page breaks before chapters. A value of \"rule\" will insert a line before chapters. A value of \"none\" will disable chapter marking and a value of \"both\" will use both page breaks and lines to mark chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:274 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:291 msgid "Either the path to a CSS stylesheet or raw CSS. This CSS will be appended to the style rules from the source file, so it can be used to override those rules." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:283 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:300 msgid "An XPath expression. Page breaks are inserted before the specified elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:289 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:306 msgid "Set the top margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:294 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:311 msgid "Set the bottom margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:299 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:316 msgid "Set the left margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:304 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:321 msgid "Set the right margin in pts. Default is %default. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:310 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:327 msgid "Change text justification. A value of \"left\" converts all justified text in the source to left aligned (i.e. unjustified) text. A value of \"justify\" converts all unjustified text to justified. A value of \"original\" (the default) does not change justification in the source file. Note that only some output formats support justification." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:320 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:337 msgid "Remove spacing between paragraphs. Also sets an indent on paragraphs of 1.5em. Spacing removal will not work if the source file does not use paragraphs (<p> or <div> tags)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:327 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:344 msgid "When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:334 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:351 msgid "Use the cover detected from the source file in preference to the specified cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:340 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:357 msgid "Insert a blank line between paragraphs. Will not work if the source file does not use paragraphs (<p> or <div> tags)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:347 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:364 msgid "Remove the first image from the input ebook. Useful if the first image in the source file is a cover and you are specifying an external cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:355 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:372 msgid "Insert the book metadata at the start of the book. This is useful if your ebook reader does not support displaying/searching metadata directly." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:363 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:380 msgid "Attempt to detect and correct hard line breaks and other problems in the source file. This may make things worse, so use with care." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:371 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:388 msgid "Scale used to determine the length at which a line should be unwrapped if preprocess is enabled. Valid values are a decimal between 0 and 1. The default is 0.40, just below the median line length. This will unwrap typical books with hard line breaks, but should be reduced if the line length is variable." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:380 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:397 msgid "Convert plain quotes, dashes and ellipsis to their typographically correct equivalents. For details, see http://daringfireball.net/projects/smartypants" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:388 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:405 msgid "Use a regular expression to try and remove the header." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:395 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:412 msgid "The regular expression to use to remove the header." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:401 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:418 msgid "Use a regular expression to try and remove the footer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:408 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:425 msgid "The regular expression to use to remove the footer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:415 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:432 msgid "Read metadata from the specified OPF file. Metadata read from this file will override any metadata in the source file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:422 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:439 msgid "Transliterate unicode characters to an ASCII representation. Use with care because this will replace unicode characters with ASCII. For instance it will replace \"%s\" with \"Mikhail Gorbachiov\". Also, note that in cases where there are multiple representations of a character (characters shared by Chinese and Japanese for instance) the representation used by the largest number of people will be used (Chinese in the previous example)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:437 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:454 msgid "Preserve ligatures present in the input document. A ligature is a special rendering of a pair of characters like ff, fi, fl et cetera. Most readers do not have support for ligatures in their default fonts, so they are unlikely to render correctly. By default, calibre will turn a ligature into the corresponding pair of normal characters. This option will preserve them instead." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:449 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:466 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:38 msgid "Set the title." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:453 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:470 msgid "Set the authors. Multiple authors should be separated by ampersands." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:458 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:475 msgid "The version of the title to be used for sorting. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:462 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:479 msgid "String to be used when sorting by author. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:466 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:483 msgid "Set the cover to the specified file or URL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:470 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:487 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:54 msgid "Set the ebook description." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:474 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:491 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:56 msgid "Set the ebook publisher." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:478 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:495 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:60 msgid "Set the series this ebook belongs to." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:482 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:499 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:62 msgid "Set the index of the book in this series." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:486 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:503 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:64 msgid "Set the rating. Should be a number between 1 and 5." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:490 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:507 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:66 msgid "Set the ISBN of the book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:494 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:511 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:68 msgid "Set the tags for the book. Should be a comma separated list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:498 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:515 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:70 msgid "Set the book producer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:502 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:519 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:72 msgid "Set the language." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:506 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:523 msgid "Set the publication date." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:510 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:527 msgid "Set the book timestamp (used by the date column in calibre)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:610 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:627 msgid "Could not find an ebook inside the archive" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:668 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:685 msgid "Values of series index and rating must be numbers. Ignoring" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:675 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:692 msgid "Failed to parse date/time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:830 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:847 msgid "Converting input to HTML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:858 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:875 msgid "Running transforms on ebook..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:945 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:962 msgid "Creating" msgstr "" @@ -1573,7 +1586,11 @@ msgstr "" msgid "When using an SVG cover, this option will cause the cover to scale to cover the available screen area, but still preserve its aspect ratio (ratio of width to height). That means there may be white borders at the sides or top and bottom of the image, but the image will never be distorted. Without this option the image may be slightly distorted, but there will be no borders." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:173 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:105 +msgid "This option is needed only if you intend to use the EPUB with FBReaderJ. It will flatten the file system inside the EPUB, putting all files into the top level." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:184 #: /home/kovid/work/calibre/src/calibre/ebooks/snb/output.py:203 msgid "Start" msgstr "" @@ -1927,13 +1944,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:607 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:106 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:108 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:75 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:59 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:66 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:393 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:907 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:304 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:570 msgid "Title" @@ -1942,8 +1959,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:608 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:68 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:398 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:948 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:908 msgid "Author(s)" msgstr "" @@ -1962,10 +1979,10 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:40 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:211 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:189 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:79 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:342 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1154 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1114 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:188 msgid "Comments" msgstr "" @@ -1975,10 +1992,10 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:30 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:74 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:330 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1150 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1110 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:161 -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:650 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:652 msgid "Tags" msgstr "" @@ -1987,8 +2004,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:29 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:347 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1159 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1119 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:109 msgid "Series" msgstr "" @@ -1998,7 +2015,7 @@ msgid "Language" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:618 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1142 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1102 msgid "Timestamp" msgstr "" @@ -2393,11 +2410,15 @@ msgstr "" msgid "Tag marking book to be filed with Personal Docs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/output.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/output.py:44 +msgid "Ignore margins in the input document. If False, then the MOBI output plugin will try to convert margins specified in the input document, otherwise it will ignore them." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/output.py:113 msgid "All articles" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:262 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:265 msgid "This is an Amazon Topaz book. It cannot be processed." msgstr "" @@ -2473,6 +2494,7 @@ msgid "%s format books are not supported" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/cover.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:141 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:218 msgid "Book %s of %s" msgstr "" @@ -2487,7 +2509,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:165 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:72 -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:648 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:650 msgid "Rating" msgstr "" @@ -2648,7 +2670,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:46 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:35 msgid "Author" msgstr "" @@ -2845,133 +2867,133 @@ msgstr "" msgid "Do not remove image references within the document. This is only useful when paired with the markdown-format option becauseimage references are always removed with plain text output." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:68 msgid "Send file to storage card instead of main memory by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:70 msgid "Confirm before deleting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:72 msgid "Main window geometry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:73 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:74 msgid "Notify when a new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:75 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:76 msgid "Use Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:78 msgid "Sort tags list by name, popularity, or rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:79 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:80 msgid "Number of covers to show in the cover browsing mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:82 msgid "Defaults for conversion to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:84 msgid "Options for the LRF ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:87 msgid "Formats that are viewed using the internal viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:89 msgid "Columns to be displayed in the book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:90 msgid "Automatically launch content server on application startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:91 msgid "Oldest news kept in database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:92 msgid "Show system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:94 msgid "Upload downloaded news to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:96 msgid "Delete books from library after uploading to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:98 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:99 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:100 msgid "Disable notifications from the system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:102 msgid "Default action to perform when send to device button is clicked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:122 msgid "Maximum number of waiting worker processes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:124 msgid "Download social metadata (tags/rating/etc.)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:126 msgid "Overwrite author and title with new metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:101 msgid "Automatically download the cover, if available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:130 msgid "Limit max simultaneous jobs to number of CPUs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:132 msgid "tag browser categories not to display" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:134 msgid "The layout of the user interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 msgid "Show the average rating per item indication in the tag browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 msgid "Disable UI animations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:186 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:509 msgid "Copied" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:220 msgid "Copy" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:220 msgid "Copy to Clipboard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:468 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:469 msgid "Choose Files" msgstr "" @@ -3015,87 +3037,87 @@ msgstr "" msgid "How many empty books should be added?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:154 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:159 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:220 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:171 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:306 msgid "Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:177 msgid "EPUB Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:178 msgid "LRF Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:179 msgid "HTML Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:180 msgid "LIT Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:181 msgid "MOBI Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:182 msgid "Topaz books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:183 msgid "Text books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:184 msgid "PDF Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:180 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:185 msgid "SNB Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:181 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:186 msgid "Comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:187 msgid "Archives" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:191 msgid "Supported books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:230 msgid "Merged some books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:231 msgid "Some duplicates were found and merged into the following existing books:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:240 msgid "Failed to read metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:241 msgid "Failed to read metadata from the following" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:255 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:260 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:286 msgid "Add to library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:267 #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:110 #: /home/kovid/work/calibre/src/calibre/gui2/actions/tweak_epub.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:85 @@ -3103,11 +3125,11 @@ msgstr "" msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:280 msgid "The following books are virtual and cannot be added to the calibre library:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:286 msgid "No book files found" msgstr "" @@ -3120,7 +3142,7 @@ msgid "Add books to your calibre library from the connected device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:549 msgid "Fetch annotations (experimental)" msgstr "" @@ -3137,11 +3159,11 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:64 #: /home/kovid/work/calibre/src/calibre/gui2/actions/catalog.py:30 #: /home/kovid/work/calibre/src/calibre/gui2/actions/convert.py:87 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:127 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:80 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:185 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:224 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:92 msgid "No books selected" msgstr "" @@ -3215,7 +3237,7 @@ msgid "Checking database integrity" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:128 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:593 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:599 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:41 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:54 msgid "Error" @@ -3248,124 +3270,130 @@ msgstr "" msgid "Switch/create library..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:168 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:77 msgid "Quick switch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:170 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:78 msgid "Rename library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:172 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:79 msgid "Delete library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:189 msgid "Library Maintenance" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:190 msgid "Library metadata backup status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:192 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:194 msgid "Start backing up metadata of all books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:196 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:198 msgid "Check library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:200 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:202 msgid "Check database integrity" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:204 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:206 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:347 msgid "Recover database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:273 msgid "Rename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:274 msgid "Choose a new name for the library <b>%s</b>. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:275 msgid "Note that the actual library folder will be renamed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:282 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:191 msgid "Already exists" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:283 msgid "The folder %s already exists. Delete it first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:289 msgid "Rename failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:290 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:296 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:300 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:53 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns.py:102 msgid "Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:301 msgid "All files from %s will be <b>permanently deleted</b>. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:320 msgid "none" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:321 msgid "Backup status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:318 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:322 msgid "Book metadata files remaining to be written: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:328 msgid "Backup metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:329 msgid "Metadata will be backed up while calibre is running, at the rate of approximately 1 book per second." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:348 msgid "This command rebuilds your calibre database from the information stored by calibre in the OPF files.<p>This function is not currently available in the GUI. You can recover your database using the 'calibredb restore_database' command line function." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:358 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:362 msgid "No library found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:363 msgid "No existing calibre library was found at %s. It will be removed from the list of known libraries." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:391 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:101 -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:748 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:750 msgid "Not allowed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:396 +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:401 msgid "You cannot change libraries while jobs are running." msgstr "" @@ -3405,42 +3433,46 @@ msgstr "" msgid "Copy selected books to the specified library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:117 msgid "(delete after copy)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:126 msgid "Cannot copy" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:131 msgid "No library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:132 msgid "No library found at %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:139 msgid "Copying" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:150 msgid "Could not copy books: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:147 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:664 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:701 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:675 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:723 #: /home/kovid/work/calibre/src/calibre/gui2/metadata.py:190 msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:153 msgid "Copied %d books to %s" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:168 +msgid "You cannot use other libraries while using the environment variable CALIBRE_OVERRIDE_DATABASE_PATH." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:31 msgid "Deleting..." msgstr "" @@ -3510,14 +3542,14 @@ msgid "Main memory" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:170 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:467 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:476 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:474 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:483 msgid "Storage Card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:171 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:469 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:476 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:485 msgid "Storage Card B" msgstr "" @@ -3667,32 +3699,32 @@ msgid "Downloading %s for %d book(s)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:126 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:186 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:221 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:226 msgid "Cannot merge books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:227 msgid "At least two books must be selected for merging" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:230 msgid "You are about to merge more than 5 books. Are you <b>sure</b> you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:236 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:238 msgid "Book formats and metadata from the selected books will be added to the <b>first selected book</b> (%s). ISBN will <i>not</i> be merged.<br><br> The second and subsequently selected books will not be deleted or changed.<br><br>Please confirm you want to proceed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:250 msgid "Book formats from the selected books will be merged into the <b>first selected book</b> (%s). Metadata in the first selected book will not be changed.Author, Title, ISBN and all other metadata will <i>not</i> be merged.<br><br>After merger the second and subsequently selected books, with any metadata they have will be <b>deleted</b>. <br><br>All book formats of the first selected book will be kept and any duplicate formats in the second and subsequently selected books will be permanently <b>deleted</b> from your calibre library.<br><br> Are you <b>sure</b> you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:266 msgid "Book formats and metadata from the selected books will be merged into the <b>first selected book</b> (%s). ISBN will <i>not</i> be merged.<br><br>After merger the second and subsequently selected books will be <b>deleted</b>. <br><br>All book formats of the first selected book will be kept and any duplicate formats in the second and subsequently selected books will be permanently <b>deleted</b> from your calibre library.<br><br> Are you <b>sure</b> you want to proceed?" msgstr "" @@ -3732,25 +3764,29 @@ msgstr "" msgid "O" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:17 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:18 msgid "Ctrl+P" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:24 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:200 msgid "Run welcome wizard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:33 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:28 +msgid "Restart in debug mode" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:43 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:39 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:44 msgid "Cannot configure before calibre is restarted." msgstr "" @@ -3820,7 +3856,7 @@ msgid "Click the show details button to see which ones." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/show_book_details.py:16 -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:655 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:657 msgid "Show book details" msgstr "" @@ -3962,7 +3998,7 @@ msgid "The specified directory could not be processed." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add.py:250 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:813 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:824 msgid "No books" msgstr "" @@ -3990,11 +4026,11 @@ msgstr "" msgid "Adding duplicates..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:417 msgid "Saving..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add.py:483 +#: /home/kovid/work/calibre/src/calibre/gui2/add.py:492 msgid "Saved" msgstr "" @@ -4070,19 +4106,20 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:71 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:57 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:142 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:176 #: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:84 #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:85 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:77 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:383 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:397 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:408 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:410 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:412 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:432 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:437 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:439 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:441 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:449 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:92 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:95 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:161 @@ -4136,32 +4173,32 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:26 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:50 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:418 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:423 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:124 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:136 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:337 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1140 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:319 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1100 msgid "Path" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:27 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:53 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:126 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:127 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:128 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:131 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:318 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:24 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:118 msgid "Formats" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:28 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:951 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1143 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:911 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1103 msgid "Collections" msgstr "" @@ -4171,11 +4208,11 @@ msgid "Click to open" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:53 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:329 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:335 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:341 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1149 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1153 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1109 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1113 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:78 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:83 @@ -4183,7 +4220,7 @@ msgstr "" msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:422 msgid "Double-click to open Book Details window" msgstr "" @@ -4234,13 +4271,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_tab_template_ui.py:32 #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:93 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:56 #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input_ui.py:33 #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_output_ui.py:39 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:120 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:74 #: /home/kovid/work/calibre/src/calibre/gui2/convert/page_setup_ui.py:120 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdb_input_ui.py:36 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdb_output_ui.py:40 @@ -4264,7 +4301,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/conversion_ui.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:81 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:65 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:119 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard_ui.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:81 @@ -4556,30 +4593,34 @@ msgstr "" msgid "EPUB Output" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:57 msgid "Do not &split on page breaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:58 msgid "No default &cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:59 msgid "No &SVG cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:60 msgid "Preserve cover &aspect ratio" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:61 msgid "Split files &larger than:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:62 msgid " KB" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:63 +msgid "&Flatten EPUB file structure" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input.py:12 msgid "FB2 Input" msgstr "" @@ -4625,15 +4666,15 @@ msgid "&Base font size:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:110 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:140 msgid "Font size &key:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:111 #: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:115 #: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:130 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:144 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:123 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:125 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:130 @@ -4684,70 +4725,78 @@ msgstr "" msgid "Justify text" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:137 msgid "&Disable font size rescaling" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:138 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:141 msgid "Wizard to help you choose an appropriate font size key" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:143 msgid "Line &height:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:145 msgid "Input character &encoding:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:146 msgid "Remove &spacing between paragraphs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:147 msgid "Indent size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:148 msgid "<p>When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:149 msgid " em" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:150 msgid "Text justification:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:151 msgid "&Linearize tables" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:152 msgid "Extra &CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:153 msgid "&Transliterate unicode characters to ASCII" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:154 msgid "Insert &blank line" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:155 msgid "Keep &ligatures" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:156 msgid "Smarten &punctuation" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:157 +msgid "Minimum &line height:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:158 +msgid " %" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output.py:19 msgid "LRF Output" msgstr "" @@ -4842,7 +4891,7 @@ msgid " is not a valid picture" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:172 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:414 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:443 msgid "Book Cover" msgstr "" @@ -4851,7 +4900,7 @@ msgid "Use cover from &source file" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:444 msgid "Change &cover image:" msgstr "" @@ -4860,18 +4909,18 @@ msgid "Browse for an image to use as the cover of this book." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:177 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:397 msgid "&Title: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:178 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:374 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:398 msgid "Change the title of this book" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:179 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:336 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:377 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:401 msgid "&Author(s): " msgstr "" @@ -4884,40 +4933,40 @@ msgid "Change the author(s) of this book. Multiple authors should be separated b msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:345 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:388 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:356 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:409 msgid "&Publisher: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:410 msgid "Ta&gs: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:184 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:347 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:390 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:358 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:428 msgid "Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:185 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:354 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:393 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:411 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:214 msgid "&Series:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:186 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:187 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:355 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:356 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:394 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:367 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:413 msgid "List of known series. You can add new series." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:188 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:414 msgid "Book " msgstr "" @@ -4925,42 +4974,46 @@ msgstr "" msgid "MOBI Output" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output.py:43 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output.py:44 msgid "Default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:75 msgid "&Title for Table of Contents:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:73 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:76 msgid "Rescale images for &Palm devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:77 msgid "Use author &sort for author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:75 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:78 msgid "Disable compression of the file contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:79 msgid "Do not add Table of Contents to book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:80 msgid "Kindle options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:78 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:81 msgid "Periodical masthead font:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:79 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:82 msgid "Personal Doc tag:" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:83 +msgid "Ignore &margins" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/convert/page_setup.py:35 msgid "Page Setup" msgstr "" @@ -5444,23 +5497,23 @@ msgid "Automatically number books" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:547 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:367 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:378 msgid "Force numbers to start with " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:609 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:607 msgid "The enumeration \"{0}\" contains invalid values that will not appear in the list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:665 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:663 msgid "Remove all tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:686 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:684 msgid "tags to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:691 +#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:689 msgid "tags to remove" msgstr "" @@ -5469,162 +5522,162 @@ msgstr "" msgid "No details available." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:190 msgid "Device no longer connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:308 msgid "Get device information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:319 msgid "Get list of books on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:322 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:329 msgid "Get annotations from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:341 msgid "Send metadata to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:346 msgid "Send collections to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:374 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:381 msgid "Upload %d books to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:396 msgid "Delete books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:413 msgid "Download books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:423 msgid "View book on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:457 msgid "Set default send to device action" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:456 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:463 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:458 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:465 msgid "Send to storage card A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:460 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:467 msgid "Send to storage card B" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:465 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:474 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:472 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:481 msgid "Main Memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:486 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:493 msgid "Send specific format to" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:487 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:494 msgid "Send and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:530 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:537 msgid "Eject device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:594 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:600 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:605 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1089 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:616 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1100 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:296 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:623 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:634 msgid "Select folder to open as device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:670 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:681 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:671 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:682 msgid "There was a temporary error talking to the device. Please unplug and reconnect the device and or reboot." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:725 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:716 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:727 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:814 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:825 msgid "selected to send" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:819 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:830 msgid "Choose format to send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:828 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:839 msgid "No device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:829 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:840 msgid "Cannot send: No device is connected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:832 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:836 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:843 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:847 msgid "No card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:833 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:837 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:844 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:848 msgid "Cannot send: Device has no storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:883 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:966 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1083 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:894 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:977 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1094 msgid "Auto convert the following books before uploading to the device?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:912 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:923 msgid "Sending catalogs to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:997 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1008 msgid "Sending news to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1050 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1061 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1090 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1101 msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1154 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1165 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1155 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1166 msgid "<p>Cannot upload books to device there is no more free space available " msgstr "" @@ -5695,7 +5748,7 @@ msgid "My Books" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/catalog_ui.py:74 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:304 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:308 msgid "Generate catalog" msgstr "" @@ -5777,72 +5830,82 @@ msgstr "" msgid "Choose Format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:43 msgid "Choose location for calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:45 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:50 msgid "Same as current" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:51 msgid "The location %s contains the current calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:51 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:56 msgid "No existing library found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:57 msgid "There is no existing calibre library at %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:61 msgid "Not empty" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:62 msgid "The folder %s is not empty. Please choose an empty folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:85 msgid "No location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:85 msgid "No location selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:89 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:654 msgid "Bad location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library.py:90 msgid "%s is not an existing folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:77 msgid "Choose your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:78 msgid "Your calibre library is currently located at {0}" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:73 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:79 msgid "New &Location:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:80 msgid "Use &existing library at the new location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:75 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:81 msgid "&Create an empty library at the new location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:82 +msgid "&Copy structure from the current library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:83 +msgid "" +"Copy the custom columns, saved searches, column widths, plugboards,\n" +"user categories, and other information from the old to the new library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:85 msgid "&Move current library to new location" msgstr "" @@ -5902,7 +5965,7 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:70 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:949 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:909 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:33 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:295 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:569 @@ -5911,7 +5974,7 @@ msgstr "" #: #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1139 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1099 msgid "Format" msgstr "" @@ -5920,19 +5983,19 @@ msgstr "" msgid "Delete from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:35 msgid "Author sort" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:689 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:697 msgid "Invalid author name" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:690 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:698 msgid "Author names cannot contain & characters." msgstr "" @@ -6078,170 +6141,170 @@ msgstr "" msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:204 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:386 msgid "Lower Case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:205 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:385 msgid "Upper Case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:189 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:206 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:388 msgid "Title Case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:190 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:207 msgid "Capitalize" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:210 msgid "Character match" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:211 msgid "Regular Expression" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:197 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:214 msgid "Replace field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:198 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:215 msgid "Prepend to field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:216 msgid "Append to field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:227 msgid "Editing meta information for <b>%d books</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:256 msgid "Immediately make all changes without closing the dialog. This operation cannot be canceled or undone" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:292 msgid "Book %d:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:290 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:307 msgid "<b>You can destroy your library using this feature.</b> Changes are permanent. There is no undo function. You are strongly encouraged to back up your library before proceeding.<p>Search and replace in text fields using character matching or regular expressions. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:298 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:315 msgid "In character mode, the field is searched for the entered search text. The text is replaced by the specified replacement text everywhere it is found in the specified field. After replacement is finished, the text can be changed to upper-case, lower-case, or title-case. If the case-sensitive check box is checked, the search text must match exactly. If it is unchecked, the search text will match both upper- and lower-case letters" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:326 msgid "In regular expression mode, the search text is an arbitrary python-compatible regular expression. The replacement text can contain backreferences to parenthesized expressions in the pattern. The search is not anchored, and can match and replace multiple times on the same string. The modification functions (lower-case etc) are applied to the matched text, not to the field as a whole. The destination box specifies the field where the result after matching and replacement is to be assigned. You can replace the text in the field, or prepend or append the matched text. See <a href=\"http://docs.python.org/library/re.html\"> this reference</a> for more information on python's regular expressions, and in particular the 'sub' function." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:454 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:471 msgid "You must specify a destination when source is a composite field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:546 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:554 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:649 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:571 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:666 msgid "Search/replace invalid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:547 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:564 msgid "Authors cannot be set to the empty string. Book title %s not processed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:555 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:572 msgid "Title cannot be set to the empty string. Book title %s not processed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:650 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:667 msgid "Search pattern is invalid: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:687 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:709 msgid "" "Applying changes to %d books.\n" "Phase {0} {1}%%." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:346 msgid "Edit Meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:348 msgid "A&utomatically set author sort" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:349 msgid "Author s&ort: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:350 msgid "Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:340 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:405 msgid "&Rating:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:341 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:342 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:385 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:386 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:407 msgid "Rating of this book. 0-5 stars" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:354 msgid "No change" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:344 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:387 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:408 msgid " stars" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:357 msgid "Add ta&gs: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:348 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:349 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:391 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:429 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:430 msgid "Open Tag Editor" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:361 msgid "&Remove tags:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:362 msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:363 msgid "Check this box to remove all tags from the books." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:364 msgid "Remove all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:368 msgid "If checked, the series will be cleared" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:358 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:369 msgid "Clear series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:370 msgid "" "If not checked, the series number for the books will be set to 1.\n" "If checked, selected books will be automatically numbered, in the order\n" @@ -6249,145 +6312,157 @@ msgid "" "Book A will have series number 1 and Book B series number 2." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:374 msgid "Automatically number books in this series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:375 msgid "" "Series will normally be renumbered from the highest number in the database\n" "for that series. Checking this box will tell calibre to start numbering\n" "from the value in the box" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:368 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:379 msgid "Remove &format:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:369 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:380 msgid "&Swap title and author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:370 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:381 msgid "" "Force the title to be in title case. If both this and swap authors are checked,\n" "title and author are swapped before the title case is set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:372 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:383 msgid "Change title to title case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:384 msgid "" "Remove stored conversion settings for the selected books.\n" "\n" "Future conversion of these books will use the default settings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:376 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:387 msgid "Remove &stored conversion settings for the selected books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:377 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:424 -msgid "&Basic metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:378 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:425 -msgid "&Custom metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:379 -msgid "Search &field:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:380 -msgid "The name of the field that you want to search" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:381 -msgid "Search mode:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:382 -msgid "Choose whether to use basic text matching or advanced regular expression matching" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:383 -msgid "&Search for:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:384 -msgid "Enter the what you are looking for, either plain text or a regular expression, depending on the mode" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:385 -msgid "Check this box if the search string must match exactly upper and lower case. Uncheck it if case is to be ignored" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:386 -msgid "Case sensitive" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:387 -msgid "&Replace with:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:388 -msgid "The replacement text. The matched search text will be replaced with this string" +msgid "Change &cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:389 -msgid "Apply function after replace:" +msgid "&Generate default cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:390 +msgid "&Remove cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:391 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:453 +msgid "&Basic metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:454 +msgid "&Custom metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:393 +msgid "Search &field:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:394 +msgid "The name of the field that you want to search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:395 +msgid "Search mode:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:396 +msgid "Choose whether to use basic text matching or advanced regular expression matching" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:397 +msgid "&Search for:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:398 +msgid "Enter the what you are looking for, either plain text or a regular expression, depending on the mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:399 +msgid "Check this box if the search string must match exactly upper and lower case. Uncheck it if case is to be ignored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:400 +msgid "Case sensitive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:401 +msgid "&Replace with:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:402 +msgid "The replacement text. The matched search text will be replaced with this string" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:403 +msgid "Apply function after replace:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:404 msgid "" "Specify how the text is to be processed after matching and replacement. In character mode, the entire\n" "field is processed. In regular expression mode, only the matched text is processed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:406 msgid "&Destination field:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:393 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:407 msgid "The field that the text will be put into after all replacements. If blank, the source field is used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:408 msgid "Mode:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:409 msgid "Specify how the text should be copied into the destination." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:410 msgid "" "If the replace mode is prepend or append, then this box indicates whether a comma or\n" "nothing should be put between the original text and the inserted text" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:398 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:412 msgid "use comma" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:413 msgid "Test &text" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:414 msgid "Test re&sult" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:415 msgid "Your test:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:402 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:416 msgid "&Search and replace" msgstr "" @@ -6424,237 +6499,259 @@ msgstr "" msgid "You must specify a title and author before generating a cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:244 msgid "Downloading cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:258 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:263 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:276 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:259 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:270 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 msgid "<b>Could not fetch cover.</b><br/>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:262 msgid "The download timed out." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:266 msgid "Could not find cover for this book. Try specifying the ISBN first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:278 msgid "For the error message from each cover source, click Show details below." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:285 msgid "Bad cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:286 msgid "The cover is not a valid picture" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:305 msgid "Choose formats for " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:336 msgid "No permission" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:337 msgid "You do not have permission to read the following files:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:361 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:365 msgid "No format selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:376 msgid "Could not read metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:374 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:377 msgid "Could not read metadata from %s format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:445 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:448 msgid " The green color indicates that the current author sort matches the current author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:448 -msgid " The red color indicates that the current author sort does not match the current author" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:451 +msgid " The red color indicates that the current author sort does not match the current author. No action is required if this is what you want." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:453 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:458 +msgid " The green color indicates that the current title sort matches the current title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:461 +msgid " The red color warns that the current title sort does not match the current title. No action is required if this is what you want." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:467 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:102 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:221 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:384 msgid "Previous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:456 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:464 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:470 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:478 msgid "Save changes and edit the metadata of %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:461 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:475 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:103 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:211 #: /home/kovid/work/calibre/src/calibre/web/feeds/templates.py:401 msgid "Next" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:635 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:640 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:670 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:675 msgid "This ISBN number is valid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:643 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:678 msgid "This ISBN number is invalid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:715 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:754 msgid "Tags changed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:716 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:755 msgid "You have changed the tags. In order to use the tags editor, you must either discard or apply these changes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:754 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:793 msgid "There were errors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:755 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:794 msgid "There were errors downloading social metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:789 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:828 msgid "Cannot fetch metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:790 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:829 msgid "You must specify at least one of ISBN, Title, Authors or Publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:885 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:924 msgid "Permission denied" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:886 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:925 msgid "Could not open %s. Is it being used by another program?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:371 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:395 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:372 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:396 msgid "Meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:375 -msgid "Swap the author and title" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:399 +msgid "Title &sort: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:378 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:400 +msgid "Specify how this book should be sorted when by title. For example, The Exorcist might be sorted as Exorcist, The." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:402 msgid "Author S&ort: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:379 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:403 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.\n" "If the box is colored green, then text matches the individual author's sort strings. If it is colored red, then the authors and this text do not match." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:381 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:415 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:416 +msgid "&Date:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:417 +msgid "dd MMM yyyy" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:418 +msgid "Publishe&d:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:420 +msgid "" +"Automatically create the title sort entry based on the current title entry.\n" +"Using this button to create title sort will change title sort from red to green." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:423 +msgid "Swap the author and title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:425 msgid "" "Automatically create the author sort entry based on the current author entry.\n" "Using this button to create author sort will change author sort from red to green." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:431 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:398 -msgid "IS&BN:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:399 -msgid "Publishe&d:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:402 -msgid "dd MMM yyyy" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:403 -msgid "&Date:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:404 -msgid "&Comments" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:405 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:433 msgid "&Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:434 +msgid "&Comments" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:435 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:407 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:436 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:438 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:440 msgid "Set the cover for the book from the selected format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:442 msgid "Update metadata from the metadata in the selected format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:445 msgid "&Browse" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:446 msgid "Remove border (if any) from cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:447 msgid "T&rim" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:448 msgid "Reset cover to default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:450 msgid "Download co&ver" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:451 msgid "Generate a default cover based on the title and author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:452 msgid "&Generate cover" msgstr "" @@ -7119,12 +7216,12 @@ msgid "%s (was %s)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor.py:74 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:679 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:687 msgid "Item is blank" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:680 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:688 msgid "An item cannot be set to nothing. Delete it instead." msgstr "" @@ -7515,34 +7612,34 @@ msgstr "" msgid "Shift+Alt+T" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:147 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:29 msgid "version" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:148 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:30 msgid "created by Kovid Goyal" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:166 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:178 msgid "Update found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:211 -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:223 msgid "Book Details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:215 msgid "Alt+D" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/init.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/init.py:225 msgid "Shift+Alt+D" msgstr "" @@ -7631,7 +7728,7 @@ msgid "Show books in the main memory of the device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:67 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:828 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:846 msgid "Card A" msgstr "" @@ -7640,7 +7737,7 @@ msgid "Show books in storage card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:69 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:830 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:848 msgid "Card B" msgstr "" @@ -7714,82 +7811,82 @@ msgstr "" msgid "Size (MB)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:330 msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:713 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1259 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:454 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:673 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1219 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:462 msgid "The lookup/search name is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:719 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1261 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:679 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1221 msgid "This book's UUID is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:946 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:906 msgid "In Library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:950 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:910 msgid "Size" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1159 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1119 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1239 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1199 msgid "Marked for deletion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1242 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1202 msgid "Double click to <b>edit</b> me<br><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:150 msgid "Hide column %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:155 msgid "Sort on %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:156 msgid "Ascending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:159 msgid "Descending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:171 msgid "Change text alignment for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:173 msgid "Left" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:173 msgid "Right" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:174 msgid "Center" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:192 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:193 msgid "Show column" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:204 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:205 msgid "Restore default layout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:749 +#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:751 msgid "Dropping onto a device is not supported. First add the book to the calibre library." msgstr "" @@ -7818,7 +7915,7 @@ msgid "<b>No matches</b> for the search phrase <i>%s</i> were found." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:160 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:448 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:453 msgid "No matches found" msgstr "" @@ -7835,12 +7932,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:503 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:522 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:504 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:523 msgid "Previous Page" msgstr "" @@ -7901,81 +7998,81 @@ msgid "Failed to create calibre library at: %r." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:99 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:185 msgid "Choose a location for your new calibre e-book library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 msgid "Initializing user interface..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Repairing failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:180 msgid "The database repair failed. Starting with a new empty library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:193 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:227 msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:195 msgid "Bad database location %r. calibre will now quit." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:208 msgid "Corrupted database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:208 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:209 msgid "Your calibre database appears to be corrupted. Do you want calibre to try and repair it automatically? If you say No, a new empty calibre library will be created." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:215 msgid "Repairing database. This can take a very long time for a large collection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:228 msgid "Bad database location %r. Will start with a new, empty calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:238 msgid "Starting %s: Loading books..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:318 msgid "If you are sure it is not running" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:320 msgid "Cannot Start " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:321 msgid "%s is already running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:324 msgid "may be running in the system tray, in the" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:290 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:326 msgid "upper right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:328 msgid "lower right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:331 msgid "try rebooting your computer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:297 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:345 msgid "try deleting the file" msgstr "" @@ -8034,7 +8131,7 @@ msgid "Successfully downloaded metadata for %d out of %d books" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata.py:291 -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:654 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:656 msgid "Details" msgstr "" @@ -8470,102 +8567,110 @@ msgstr "" msgid "new email address" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:24 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:25 msgid "Narrow" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:24 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:25 msgid "Wide" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:51 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:52 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:51 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:52 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:53 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:56 msgid "Always" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:56 msgid "Automatic" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:57 msgid "Never" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:120 msgid "User Interface &layout (needs restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:121 msgid "&Number of covers to show in browse mode (needs restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:122 msgid "Choose &language (requires restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:123 msgid "Show &average ratings in the tags browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:124 msgid "Disable all animations. Useful if you have a slow/old computer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:125 msgid "Disable &animations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:126 msgid "Enable system &tray icon (needs restart)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:127 msgid "Show &splash screen at startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:128 msgid "Disable ¬ifications in system tray" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:129 msgid "Use &Roman numerals for series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:130 msgid "Show cover &browser in a separate window (needs restart)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:131 msgid "Search as you type" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:132 msgid "&Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:133 msgid "&Icon size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:134 msgid "Show &text under icons:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:135 msgid "&Split the toolbar into two toolbars" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:136 +msgid "Interface font:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:137 +msgid "Change &font (needs restart)" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:222 msgid "&Apply" msgstr "" @@ -8582,19 +8687,19 @@ msgstr "" msgid "Cancel and return to overview" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:287 msgid "Restoring to defaults not supported for" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:304 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:322 msgid "Some of the changes you made require a restart. Please restart calibre as soon as possible." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:325 msgid "The changes you have made require calibre be restarted immediately. You will not be allowed set any more preferences, until you restart." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:330 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:120 msgid "Restart needed" msgstr "" @@ -8875,7 +8980,7 @@ msgid "Here you can control how calibre will save your books when you click the msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:340 msgid "Failed to start content server" msgstr "" @@ -9150,94 +9255,94 @@ msgstr "" msgid "&Alternate shortcut:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:225 msgid "Rename '%s'" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:229 msgid "Edit sort for '%s'" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:234 msgid "Hide category %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:237 msgid "Show category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:238 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:250 msgid "Manage %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:253 msgid "Manage Saved Searches" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:252 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:264 msgid "Manage User Categories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:271 msgid "Show all categories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:549 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:557 msgid "Changing the authors for several books can take a while. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:562 msgid "Changing the metadata for that many books can take a while. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:611 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:619 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:314 msgid "Searches" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:702 msgid "Duplicate search name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:695 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:703 msgid "The saved search name %s is already used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:976 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:985 msgid "Sort by name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:976 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:985 msgid "Sort by popularity" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:977 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:986 msgid "Sort by average rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:980 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:989 msgid "Set the sort order for entries in the Tag Browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:986 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:995 msgid "Match all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:986 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:995 msgid "Match any" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:991 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1000 msgid "When selecting multiple entries in the Tag Browser match any or all of them" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:995 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1004 msgid "Manage &user categories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:998 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:1007 msgid "Add your own categories to the Tag Browser" msgstr "" @@ -9264,71 +9369,79 @@ msgstr "" msgid "Queueing " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:250 msgid "Fetch news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:320 msgid "Convert existing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:321 msgid "The following books have already been converted to %s format. Do you wish to reconvert them?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:171 msgid "&Restore" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:173 msgid "&Donate to support calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:177 msgid "&Eject connected device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:216 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:218 msgid "Calibre Quick Start Guide" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:448 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:266 +msgid "Debug mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:267 +msgid "You have started calibre in debug mode. After you quit calibre, the debug log will be available in the file: %s<p>The log will be displayed automatically." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:451 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:462 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:449 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:463 msgid "<p>Could not convert: %s<p>It is a <a href=\"%s\">DRM</a>ed book. You must first remove the DRM using third party tools." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:463 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:477 msgid "Recipe Disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:493 msgid "<b>Failed</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:515 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:530 msgid "is the result of the efforts of many volunteers from all over the world. If you find it useful, please consider donating to support its development. Your donation helps keep calibre development going." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:556 msgid "There are active jobs. Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:544 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:559 msgid "" " is communicating with the device!<br>\n" " Quitting may cause corruption on the device.<br>\n" " Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:548 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:563 msgid "WARNING: Active jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:626 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:638 msgid "will keep running in the system tray. To close it, choose <b>Quit</b> in the context menu of the system tray." msgstr "" @@ -9400,188 +9513,224 @@ msgstr "" msgid "Import" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:159 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:178 msgid "Configure Ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:160 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:179 msgid "&Font options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:180 msgid "Se&rif family:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:181 msgid "&Sans family:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:182 msgid "&Monospace family:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:183 msgid "&Default font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:165 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:167 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:201 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:185 msgid "Monospace &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:187 msgid "S&tandard font:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:188 msgid "Serif" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:189 msgid "Sans-serif" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:190 msgid "Monospace" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:191 msgid "Remember last used &window size" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:174 -msgid "Maximum &view width:" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:192 +msgid "Remember the ¤t page when quitting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:193 msgid "H&yphenate (break line in the middle of large words)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:194 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:177 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:195 msgid "Default &language for hyphenation:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:196 msgid "&Resize images larger than the viewer window (needs restart)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:179 -msgid "&User stylesheet" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:197 +msgid "Page flip &duration:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:180 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:198 +msgid "disabled" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:199 +msgid " secs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:200 +msgid "Mouse &wheel flips pages" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:202 +msgid "Maximum &view width:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:203 msgid "&General" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:181 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:204 msgid "Double click to change a keyboard shortcut" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:205 msgid "&Keyboard shortcuts" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:206 +msgid "<p>A CSS stylesheet that can be used to control the look and feel of books. For examples, click <a href=\"http://www.mobileread.com/forums/showthread.php?t=51500\">here</a>." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:207 +msgid "User &Stylesheet" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/viewer/dictionary.py:53 msgid "No results found for:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:36 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:37 msgid "Options to customize the ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:43 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:720 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:44 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:728 msgid "Remember last used window size" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:93 msgid "Set the user CSS stylesheet. This can be used to customize the look of all books." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:47 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:48 msgid "Maximum width of the viewer window, in pixels." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:50 msgid "Resize images larger than the viewer window to fit inside it" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:51 msgid "Hyphenate text" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:53 msgid "Default language for hyphenation rules" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:54 -msgid "Font options" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:55 +msgid "Save the current position in the document, when quitting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:56 -msgid "The serif font family" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:57 +msgid "Have the mouse wheel turn pages" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:58 -msgid "The sans-serif font family" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:60 -msgid "The monospaced font family" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:61 -msgid "The standard font size in px" +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:59 +msgid "The time, in seconds, for the page flip animation. Default is half a second." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:62 +msgid "Font options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:64 +msgid "The serif font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:66 +msgid "The sans-serif font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:68 +msgid "The monospaced font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:69 +msgid "The standard font size in px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:70 msgid "The monospaced font size in px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:71 msgid "The standard font type" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:498 msgid "&Lookup in dictionary" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:482 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:501 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:138 msgid "Go to..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:494 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:513 msgid "Next Section" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:514 msgid "Previous Section" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:497 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:516 msgid "Document Start" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:498 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:517 msgid "Document End" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:500 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:519 msgid "Section Start" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:501 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:520 msgid "Section End" msgstr "" @@ -9657,75 +9806,75 @@ msgstr "" msgid "Connecting to dict.org to lookup: <b>%s</b>…" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:420 msgid "Choose ebook" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:421 msgid "Ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:449 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:454 msgid "No matches found for: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:492 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:497 msgid "Loading flow..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:530 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:535 msgid "Laying out %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:561 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:566 msgid "Bookmark #%d" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:570 msgid "Add bookmark" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:566 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:571 msgid "Enter title for bookmark:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:576 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:581 msgid "Manage Bookmarks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:613 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:621 msgid "Loading ebook..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:621 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:629 msgid "DRM Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:622 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:630 msgid "<p>This book is protected by <a href=\"%s\">DRM</a>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:626 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:634 msgid "Could not open ebook" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:707 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:715 msgid "Options to control the ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:714 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:722 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:717 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:725 msgid "If specified, viewer window will try to open full screen when started." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:722 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:730 msgid "Print javascript alert and console messages to the console" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:728 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:736 msgid "" "%prog [options] file\n" "\n" @@ -10099,50 +10248,50 @@ msgstr "" msgid "Turn on the &content server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:373 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:264 msgid "today" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:376 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:267 msgid "yesterday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:379 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:270 msgid "thismonth" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:382 -#: /home/kovid/work/calibre/src/calibre/library/caches.py:383 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:273 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:274 msgid "daysago" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:562 -#: /home/kovid/work/calibre/src/calibre/library/caches.py:572 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:453 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:463 msgid "unchecked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:562 -#: /home/kovid/work/calibre/src/calibre/library/caches.py:572 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:184 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:453 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:463 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:183 msgid "no" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:565 -#: /home/kovid/work/calibre/src/calibre/library/caches.py:575 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:456 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:466 msgid "checked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:565 -#: /home/kovid/work/calibre/src/calibre/library/caches.py:575 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:184 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:456 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:466 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:183 msgid "yes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:569 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:460 msgid "blank" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/caches.py:569 +#: /home/kovid/work/calibre/src/calibre/library/caches.py:460 msgid "empty" msgstr "" @@ -10807,35 +10956,35 @@ 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:59 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:58 msgid "%sAverage rating is %3.1f" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:826 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:844 msgid "Main" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2321 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2547 msgid "<p>Migrating old database to ebook library in %s<br><center>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2350 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2576 msgid "Copying <b>%s</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2367 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2593 msgid "Compacting database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2460 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2686 msgid "Checking SQL integrity..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2499 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2725 msgid "Checking for missing files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2527 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2753 msgid "Checked id" msgstr "" @@ -10948,8 +11097,8 @@ msgstr "" msgid "Replace whitespace with underscores." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:350 -#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:374 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:352 +#: /home/kovid/work/calibre/src/calibre/library/save_to_disk.py:376 msgid "Requested formats not available" msgstr "" @@ -11071,43 +11220,43 @@ msgstr "" msgid "Up" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:574 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:576 msgid "in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:577 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:579 msgid "Books in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:629 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:631 msgid "Other formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:636 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:638 msgid "Read %s in the %s format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:641 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:643 msgid "Get" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:656 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:658 msgid "Permalink" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:657 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:659 msgid "A permanent link to this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:668 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:670 msgid "This book has been deleted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:752 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:754 msgid "in search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:754 +#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:756 msgid "Matching books" msgstr "" diff --git a/src/calibre/translations/da.po b/src/calibre/translations/da.po index b3e5174764..30735c0a66 100644 --- a/src/calibre/translations/da.po +++ b/src/calibre/translations/da.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-11 22:59+0000\n" -"Last-Translator: Glenn <Unknown>\n" +"PO-Revision-Date: 2010-12-17 00:31+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Danish <da@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-13 04:57+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/de.po b/src/calibre/translations/de.po index 58a714522e..7b49dc71b3 100644 --- a/src/calibre/translations/de.po +++ b/src/calibre/translations/de.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-11 02:44+0000\n" -"Last-Translator: Kovid Goyal <Unknown>\n" +"PO-Revision-Date: 2010-12-16 12:49+0000\n" +"Last-Translator: Manichean <Unknown>\n" "Language-Team: American English <kde-i18n-doc@lists.kde.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-12 04:35+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" @@ -2470,23 +2470,23 @@ msgstr "Comic" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:26 msgid "Downloads metadata from amazon.fr" -msgstr "" +msgstr "Herunterladen der Metadaten von amazon.fr" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:43 msgid "Downloads metadata from amazon.com in spanish" -msgstr "" +msgstr "Herunterladen der spanischen Metadaten von amazon.com" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:60 msgid "Downloads metadata from amazon.com in english" -msgstr "" +msgstr "Herunterladen der englischen Metadaten von amazon.com" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:77 msgid "Downloads metadata from amazon.de" -msgstr "" +msgstr "Herunterladen der Metadaten von amazon.de" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:94 msgid "Downloads metadata from amazon.com" -msgstr "" +msgstr "Herunterladen der Metadaten von amazon.com" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:474 msgid "" @@ -2500,6 +2500,14 @@ msgid "" " All & english & french & german & spanish\n" " " msgstr "" +" %prog [Optionen]\n" +"\n" +" Lädt Metadaten von Amazon. Sie müssen einen Titel, Author,\n" +" ISBN, Herausgeber oder Stichwort angeben. Es werden maximal\n" +" 10 Treffer geladen, suchen Sie so spezifisch wie möglich.\n" +" Sie können die Sprache für die Metadaten auswählen:\n" +" Alle & Englisch & Französisch & Deutsch & Spanisch\n" +" " #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/archive.py:41 msgid "" @@ -2832,33 +2840,35 @@ msgstr "Lädt Reihe/Etiketten/Bewertung von librarything.com" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:25 msgid "Downloads metadata from Fictionwise" -msgstr "" +msgstr "Herunterladen der Metadaten von Fictionwise" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:90 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:108 msgid "Query: %s" -msgstr "" +msgstr "Abfrage: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:100 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:285 msgid "Fictionwise timed out. Try again later." -msgstr "" +msgstr "Timeout bei Fictionwise. Bitte später nochmal versuchen." #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:101 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:286 msgid "Fictionwise encountered an error." -msgstr "" +msgstr "Bei Fictionwise ist ein Fehler aufgetreten." #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:219 msgid "" "SUMMARY:\n" " %s" msgstr "" +"INHALTSANGABE:\n" +" %s" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:316 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:333 msgid "Failed to get all details for an entry" -msgstr "" +msgstr "Konnte für einen Eintrag nicht alle Details holen" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:354 msgid "" @@ -2871,41 +2881,49 @@ msgid "" " so you should make your query as specific as possible.\n" " " msgstr "" +" %prog [Optionen]\n" +"\n" +" Holt Metadaten von Fictionwise. Sie müssen einen Titel, Autor oder " +"Stichwort\n" +" angeben. Angabe einer ISBN ist nicht möglich. Maximal werden 20 " +"Treffer geholt,\n" +" suchen Sie also möglichst spezifisch.\n" +" " #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:362 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:363 msgid "Book title" -msgstr "" +msgstr "Titel" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:363 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:364 msgid "Book author(s)" -msgstr "" +msgstr "Autor(en)" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:364 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:365 msgid "Book publisher" -msgstr "" +msgstr "Herausgeber" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:365 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:367 msgid "Keywords" -msgstr "" +msgstr "Schlüsselworte" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:367 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:373 msgid "Maximum number of results to fetch" -msgstr "" +msgstr "Maximale Anzahl an zu holenden Ergebnissen" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:369 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:375 msgid "Be more verbose about errors" -msgstr "" +msgstr "Fehler ausführlicher berichten" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:383 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:390 msgid "No result found for this search!" -msgstr "" +msgstr "Keine Ergebnisse für diese Suche gefunden!" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107 msgid "" @@ -2983,11 +3001,11 @@ msgstr "Timeout von Nicebooks. Bitte versuchen Sie es später nochmal." #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:119 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:243 msgid "Nicebooks encountered an error." -msgstr "" +msgstr "Bei Nicebooks ist ein Fehler aufgetreten." #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:323 msgid "ISBN: %s not found." -msgstr "" +msgstr "ISBN: %s nicht gefunden." #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:324 msgid "An errror occured with Nicebooks cover fetcher" @@ -3007,7 +3025,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:366 msgid "Book ISBN" -msgstr "" +msgstr "ISBN" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:369 msgid "Covers: 1-Check/ 2-Download" diff --git a/src/calibre/translations/en_GB.po b/src/calibre/translations/en_GB.po index aedf656daa..47196d454c 100644 --- a/src/calibre/translations/en_GB.po +++ b/src/calibre/translations/en_GB.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-12 17:20+0000\n" -"Last-Translator: Vladimir Oka <Unknown>\n" +"PO-Revision-Date: 2010-12-16 23:27+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: English (United Kingdom) <en_GB@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-13 04:58+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/eu.po b/src/calibre/translations/eu.po index e8fcd22cab..199b5f9864 100644 --- a/src/calibre/translations/eu.po +++ b/src/calibre/translations/eu.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-15 17:49+0000\n" +"PO-Revision-Date: 2010-12-16 23:28+0000\n" "Last-Translator: gorkaazk <gorkaazkarate@euskalerria.org>\n" "Language-Team: Basque <eu@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-16 04:32+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/fr.po b/src/calibre/translations/fr.po index f16427ba9e..0bfeecba01 100644 --- a/src/calibre/translations/fr.po +++ b/src/calibre/translations/fr.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre 0.4.22\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-16 02:50+0000\n" -"Last-Translator: sengian <Unknown>\n" +"PO-Revision-Date: 2010-12-16 23:44+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Français <kde-i18n-doc@kde.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-16 04:33+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" "X-Poedit-Bookmarks: 1177,1104,-1,-1,-1,-1,-1,-1,-1,-1\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/gl.po b/src/calibre/translations/gl.po index 989337deb4..926372905b 100644 --- a/src/calibre/translations/gl.po +++ b/src/calibre/translations/gl.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-15 12:01+0000\n" +"PO-Revision-Date: 2010-12-17 00:16+0000\n" "Last-Translator: Miguel Anxo Bouzada <mbouzada@gmail.com>\n" "Language-Team: dev@gl.openoffice.org\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-16 04:33+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Language: gl\n" @@ -406,8 +406,8 @@ msgid "" "Setup sharing of books via email. Can be used for automatic sending of " "downloaded news to your devices" msgstr "" -"Configura a compartición de libros por correo electrónico. Pódese usar para " -"enviar automaticamente as noticias descargadas aos seus dispositivos" +"Configura a compartición de libros por correo. Pódese usar para enviar " +"automaticamente as noticias descargadas aos seus dispositivos" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:855 msgid "Sharing over the net" @@ -8751,7 +8751,7 @@ msgstr "Código fonte das receitas (pytom)" #: /home/kovid/work/calibre/src/calibre/gui2/email.py:145 msgid "Email %s to %s" -msgstr "Enviar por correo electrónico %s a %s" +msgstr "Enviar por correo %s a %s" #: /home/kovid/work/calibre/src/calibre/gui2/email.py:187 msgid "News:" @@ -9932,13 +9932,13 @@ msgid "" "automatically sent for downloaded news to all email addresses that have Auto-" "send checked." msgstr "" -"O Calibre pode enviarlle os libros por correo-e. Enviaránselle correos " +"O Calibre pode enviarlle os libros por correo. Enviaránselle correos " "automaticamente coas novas descargadas que teñen marcada a opción Enviar " "automaticamente." #: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:67 msgid "Add an email address to which to send books" -msgstr "Engadir un enderezo de correo electrónico ao que enviar os libros" +msgstr "Engadir un enderezo de correo ao que enviar os libros" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:68 msgid "&Add email" @@ -9958,7 +9958,7 @@ msgstr "Enviar automaticamente" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:24 msgid "Email" -msgstr "Correo electrónico" +msgstr "Correo" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:29 msgid "Formats to email. The first matching format will be sent." @@ -11668,15 +11668,14 @@ msgid "" "button below. You will also have to register your gmail address in your " "Amazon account." msgstr "" -"<p>Calibre pode enviar libros automaticamente por correo electrónico ao seu " -"Kindle. Debe configurar o envío por correo electrónico. A forma más doada e " -"facerse cunha <a href=\"http://gmail.com\">conta gratuíta de Gmail</a> e " -"premer o botón Usar gmail. Tamén deberá rexistrar o enderezo de gmail na súa " -"conta de Amazon." +"<p>Calibre pode enviar libros automaticamente por correo ao seu Kindle. Debe " +"configurar o envío por correo. A forma más doada e facerse cunha <a " +"href=\"http://gmail.com\">conta gratuíta de Gmail</a> e premer o botón Usar " +"gmail. Tamén deberá rexistrar o enderezo de gmail na súa conta de Amazon." #: /home/kovid/work/calibre/src/calibre/gui2/wizard/kindle_ui.py:50 msgid "&Kindle email:" -msgstr "Correo electrónico do &Kindle:" +msgstr "Correo do &Kindle:" #: /home/kovid/work/calibre/src/calibre/gui2/wizard/library_ui.py:57 msgid "Choose your &language:" @@ -11765,7 +11764,7 @@ msgstr "Configuración errada" #: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email.py:197 msgid "You must set the From email address" -msgstr "Debe estabelecer o enderezo de correo-e remitente" +msgstr "Debe estabelecer o enderezo de correo remitente" #: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email.py:204 msgid "You must set the username and password for the mail server." @@ -11781,8 +11780,8 @@ msgid "" "<p>This is what will be present in the From: field of emails sent by " "calibre.<br> Set it to your email address" msgstr "" -"<p>Isto é o que se mostrará no campo De: dos correos electrónicos enviados " -"por Calibre.<br>Poña o seu enderezo de correo-e." +"<p>Isto é o que se mostrará no campo De: dos correos enviados por " +"Calibre.<br>Poña o seu enderezo de correo." #: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:126 msgid "" diff --git a/src/calibre/translations/it.po b/src/calibre/translations/it.po index 4dc9779d97..c749e0a652 100644 --- a/src/calibre/translations/it.po +++ b/src/calibre/translations/it.po @@ -9,13 +9,13 @@ msgstr "" "Project-Id-Version: calibre_calibre-it\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-12 08:58+0000\n" -"Last-Translator: MeltingShell <Unknown>\n" +"PO-Revision-Date: 2010-12-16 23:08+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-13 04:57+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" "X-Poedit-Bookmarks: -1,-1,-1,-1,-1,1105,-1,1312,-1,-1\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/ja.po b/src/calibre/translations/ja.po index a00a5e0be5..339e847ee8 100644 --- a/src/calibre/translations/ja.po +++ b/src/calibre/translations/ja.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-12 12:28+0000\n" +"PO-Revision-Date: 2010-12-16 23:11+0000\n" "Last-Translator: Hiroshi Miura <miurahr@linux.com>\n" "Language-Team: Japanese <ja@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-13 04:58+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/ko.po b/src/calibre/translations/ko.po index c0fe0e9c52..26da233882 100644 --- a/src/calibre/translations/ko.po +++ b/src/calibre/translations/ko.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-11 02:28+0000\n" -"Last-Translator: Namsik Chu <Unknown>\n" +"PO-Revision-Date: 2010-12-17 01:06+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Korean <ko@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-12 04:37+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/ml.po b/src/calibre/translations/ml.po index 65613a9067..9fd18784eb 100644 --- a/src/calibre/translations/ml.po +++ b/src/calibre/translations/ml.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-16 03:36+0000\n" -"Last-Translator: geordee <Unknown>\n" +"PO-Revision-Date: 2010-12-16 23:06+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Malayalam <ml@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-16 04:33+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/pt_BR.po b/src/calibre/translations/pt_BR.po index 9b209ace57..f7dbf3e250 100644 --- a/src/calibre/translations/pt_BR.po +++ b/src/calibre/translations/pt_BR.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-05 04:33+0000\n" -"Last-Translator: Wespa Digital <Unknown>\n" +"PO-Revision-Date: 2010-12-16 16:26+0000\n" +"Last-Translator: marco cunha <Unknown>\n" "Language-Team: American English <kde-i18n-doc@kde.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-11 04:44+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 @@ -387,7 +387,7 @@ msgstr "Configuração dos Metadados" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:838 msgid "Change metadata fields before saving/sending" -msgstr "" +msgstr "Alterar campos de metadados antes de salvar / enviar" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:843 msgid "Sharing books by email" @@ -582,6 +582,7 @@ msgstr "Destinado ao iPad e dispositivos similares com resolução de 768x1024" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:437 msgid "Intended for generic tablet devices, does no resizing of images" msgstr "" +"Pretendido para dispositivos Tablets, não faz o redimensionamento de imagens" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:464 msgid "This profile is intended for the Kobo Reader." @@ -609,11 +610,11 @@ msgstr "Este perfil é destinado para o Kindle DX da Amazon." #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:686 msgid "This profile is intended for the B&N Nook Color." -msgstr "" +msgstr "Este perfil é destinado para a B & N Nook Color." #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:697 msgid "This profile is intended for the Sanda Bambook." -msgstr "" +msgstr "Este perfil é destinado para o Sanda Bambook" #: /home/kovid/work/calibre/src/calibre/customize/ui.py:34 msgid "Installed plugins" @@ -719,6 +720,9 @@ msgid "" "Cannot copy books directly from iDevice. Drag from iTunes Library to " "desktop, then add to calibre's Library window." msgstr "" +"Não é possível copiar livros diretamente do iDevice. Arraste a partir do " +"iTunes Library para o desktop, em seguida, adicione para a biblioteca " +"calibre." #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:260 #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:263 @@ -812,7 +816,7 @@ msgstr "Comunica-se com o leitor Cybook Gen 3 / Opus." #: /home/kovid/work/calibre/src/calibre/devices/cybook/driver.py:64 msgid "Communicate with the Cybook Orizon eBook reader." -msgstr "" +msgstr "Comunique-se com o leitor eBook Cybook Orizon." #: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:24 msgid "Communicate with the EB600 eBook reader." @@ -828,7 +832,7 @@ msgstr "Comunica-se com o leitor PocketBook 301" #: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:233 msgid "Communicate with the PocketBook 602 reader." -msgstr "" +msgstr "Comunique-se com o leitor PocketBook 602." #: /home/kovid/work/calibre/src/calibre/devices/edge/driver.py:17 msgid "Entourage Edge" @@ -917,7 +921,7 @@ msgstr "John Schember" #: /home/kovid/work/calibre/src/calibre/devices/interface.py:44 msgid "Cannot get files from this device" -msgstr "" +msgstr "Não é possível obter arquivos a partir deste dispositivo" #: /home/kovid/work/calibre/src/calibre/devices/irexdr/driver.py:16 msgid "Communicate with the IRex Digital Reader 1000 eBook reader." @@ -941,7 +945,7 @@ msgstr "Comunicar com o leitor MiBuk Wolder." #: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:116 msgid "Communicate with the JetBook Mini reader." -msgstr "" +msgstr "Comunique-se com o leitor Mini jetBook." #: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:43 msgid "Communicate with the Kindle eBook reader." diff --git a/src/calibre/translations/ro.po b/src/calibre/translations/ro.po index be60804288..2ac6e7dddd 100644 --- a/src/calibre/translations/ro.po +++ b/src/calibre/translations/ro.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-12 15:48+0000\n" -"Last-Translator: Mircea Dochia <Unknown>\n" +"PO-Revision-Date: 2010-12-17 00:09+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Romanian <ro@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-13 04:58+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/translations/ru.po b/src/calibre/translations/ru.po index 6925ab4c23..f751b04c72 100644 --- a/src/calibre/translations/ru.po +++ b/src/calibre/translations/ru.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: calibre 0.4.55\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-14 16:19+0000\n" -"Last-Translator: Konstantin <Unknown>\n" +"PO-Revision-Date: 2010-12-16 22:56+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: American English <kde-i18n-doc@lists.kde.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-15 04:36+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" "X-Poedit-Language: Russian\n" diff --git a/src/calibre/translations/sl.po b/src/calibre/translations/sl.po index 93283e2a4e..b8f9379684 100644 --- a/src/calibre/translations/sl.po +++ b/src/calibre/translations/sl.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: calibre 0.4.17\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-14 10:17+0000\n" -"Last-Translator: Stane Accetto <Unknown>\n" +"PO-Revision-Date: 2010-12-16 22:54+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-15 04:37+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/sr.po b/src/calibre/translations/sr.po index d4dca1eca2..0c646212dc 100644 --- a/src/calibre/translations/sr.po +++ b/src/calibre/translations/sr.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2010-12-10 22:25+0000\n" -"PO-Revision-Date: 2010-12-13 11:44+0000\n" -"Last-Translator: Vladimir Oka <Unknown>\n" +"PO-Revision-Date: 2010-12-16 23:13+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Serbian <sr@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-12-14 04:51+0000\n" +"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43 diff --git a/src/calibre/utils/fonts/__init__.py b/src/calibre/utils/fonts/__init__.py index 5cab0c4920..3db3a1b285 100644 --- a/src/calibre/utils/fonts/__init__.py +++ b/src/calibre/utils/fonts/__init__.py @@ -7,15 +7,19 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __docformat__ = 'restructuredtext en' import os, sys -from threading import Thread -from calibre.constants import plugins, iswindows +from calibre.constants import plugins, iswindows, islinux, isfreebsd _fc, _fc_err = plugins['fontconfig'] if _fc is None: raise RuntimeError('Failed to load fontconfig with error:'+_fc_err) +if islinux or isfreebsd: + Thread = object +else: + from threading import Thread + class FontConfig(Thread): def __init__(self): @@ -45,7 +49,8 @@ class FontConfig(Thread): self.failed = True def wait(self): - self.join() + if not (islinux or isfreebsd): + self.join() if self.failed: raise RuntimeError('Failed to initialize fontconfig') @@ -144,7 +149,13 @@ class FontConfig(Thread): return fonts if all else (fonts[0] if fonts else None) fontconfig = FontConfig() -fontconfig.start() +if islinux or isfreebsd: + # On X11 Qt also uses fontconfig, so initialization must happen in the + # main thread. In any case on X11 initializing fontconfig should be very + # fast + fontconfig.run() +else: + fontconfig.start() def test(): from pprint import pprint; diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index ad2991d620..7bd5301dfb 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -548,6 +548,7 @@ class BasicNewsRecipe(Recipe): } For an example, see the recipe for downloading `The Atlantic`. + In addition, you can add 'author' for the author of the article. ''' raise NotImplementedError