diff --git a/recipes/national_geographic_es.recipe b/recipes/national_geographic_es.recipe new file mode 100644 index 0000000000..95c0cd3468 --- /dev/null +++ b/recipes/national_geographic_es.recipe @@ -0,0 +1,21 @@ +__license__ = 'GPL v3' +__author__ = 'Vakya' +__version__ = 'v1.0' +__date__ = '14, May 2012' + +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1336226255(BasicNewsRecipe): + + title = u'National Geographic' + publisher = u'National Geographic' + __author__ = 'Vakya' + description = 'Revista National Geographic - Últimas noticias' + language = 'es' + + oldest_article = 15 + max_articles_per_feed = 100 + auto_cleanup = True + remove_tags_before = dict(name='p' , attrs={'class':['image']}) + remove_tags_after = dict(name='hr') + feeds = [(u'Vida salvage', u'http://www.nationalgeographic.com.es/feeds/rss.html')] diff --git a/recipes/shortlist.recipe b/recipes/shortlist.recipe new file mode 100644 index 0000000000..155cbd25aa --- /dev/null +++ b/recipes/shortlist.recipe @@ -0,0 +1,61 @@ +import re +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1324663493(BasicNewsRecipe): + title = u'Shortlist' + description = 'Articles From Shortlist.com' + # I've set oldest article to 7 days as the website updates weekly + oldest_article = 7 + max_articles_per_feed = 12 + remove_empty_feeds = True + remove_javascript = True + no_stylesheets = True + __author__ = 'Dave Asbury' + # last updated 19/5/12 + language = 'en_GB' + def get_cover_url(self): + soup = self.index_to_soup('http://www.shortlist.com') + cov = soup.find(attrs={'width' : '121'}) + #print '******** ',cov,' ***' + #cover_url = 'http://www.shortlist.com'+cov['src'] + cover_url =cov['src'] + return cover_url + + masthead_url = 'http://www.mediauk.com/logos/100/344096.png' + + preprocess_regexps = [ + (re.compile(r'…or.*?email to your friends.', re.IGNORECASE | re.DOTALL), lambda match: '')] + + keep_only_tags = [ + #dict(name='h1'), + dict(name='h2',attrs={'class' : 'title'}), + dict(name='h3',atts={'class' : 'subheading'}), + dict(attrs={'class' : [ 'hero-static','stand-first']}), + dict(attrs={'class' : 'hero-image'}), + dict(name='div',attrs={'id' : ['list','article','article alternate']}), + dict(name='div',attrs={'class' : 'stand-first'}), + ] + remove_tags = [dict(name='h2',attrs={'class' : 'graphic-header'}), + dict(attrs={'id' : ['share','twitter','facebook','digg','delicious','facebook-like']}), + dict(atts={'class' : ['related-content','related-content-item','related-content horizontal','more']}), + + ] + + remove_tags_after = [dict(name='p',attrs={'id' : 'tags'}) + ] + + feeds = [ + (u'Home carousel',u'http://feed43.com/7106317222455380.xml'), + (u'This Weeks Issue', u'http://feed43.com/0323588208751786.xml'), + (u'Cool Stuff',u'http://feed43.com/6253845228768456.xml'), + (u'Style',u'http://feed43.com/7217107577215678.xml'), + (u'Films',u'http://feed43.com/3101308515277265.xml'), + (u'Music',u'http://feed43.com/2416400550560162.xml'), + (u'TV',u'http://feed43.com/4781172470717123.xml'), + (u'Sport',u'http://feed43.com/5303151885853308.xml'), + (u'Gaming',u'http://feed43.com/8883764600355347.xml'), + (u'Women',u'http://feed43.com/2648221746514241.xml'), + (u'Instant Improver', u'http://feed43.com/1236541026275417.xml'), + + #(u'Articles', u'http://feed43.com/3428534448355545.xml') + ] diff --git a/session.vim b/session.vim index e9cfc39c87..f00c396cc7 100644 --- a/session.vim +++ b/session.vim @@ -12,3 +12,6 @@ fun! CalibreLog() endfun nnoremap \log :call CalibreLog() + +python import init_calibre +python import calibre diff --git a/setup/build_environment.py b/setup/build_environment.py index 82a6421ed5..46661d79a0 100644 --- a/setup/build_environment.py +++ b/setup/build_environment.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os, socket, struct, subprocess +import os, socket, struct, subprocess, glob from distutils.spawn import find_executable from PyQt4 import pyqtconfig @@ -128,8 +128,9 @@ if iswindows: elif isosx: fc_inc = '/sw/include/fontconfig' fc_lib = '/sw/lib' + poppler = glob.glob('/sw/build/poppler-*')[-1] poppler_inc_dirs = consolidate('POPPLER_INC_DIR', - '/sw/build/poppler-0.14.5/poppler:/sw/build/poppler-0.14.5') + '{0}/poppler:{0}'.format(poppler)) poppler_lib_dirs = consolidate('POPPLER_LIB_DIR', '/sw/lib') poppler_libs = ['poppler'] @@ -191,6 +192,9 @@ else: lh = os.path.join(poppler_inc_dirs[0], 'Link.h') if 'class AnnotLink' not in open(lh, 'rb').read(): poppler_cflags.append('-DPOPPLER_OLD_LINK_TYPE') + ph = os.path.join(poppler_inc_dirs[0], 'Page.h') + if 'getLinks(Catalog' in open(ph, 'rb').read(): + poppler_cflags.append('-DPOPPLER_PRE_20') magick_error = None if not magick_inc_dirs or not os.path.exists(os.path.join(magick_inc_dirs[0], diff --git a/setup/installer/linux/freeze2.py b/setup/installer/linux/freeze2.py index 7efae423e9..49ea1868f5 100644 --- a/setup/installer/linux/freeze2.py +++ b/setup/installer/linux/freeze2.py @@ -32,7 +32,7 @@ binary_includes = [ '/lib/libz.so.1', '/usr/lib/libtiff.so.5', '/lib/libbz2.so.1', - '/usr/lib/libpoppler.so.7', + '/usr/lib/libpoppler.so.25', '/usr/lib/libxml2.so.2', '/usr/lib/libopenjpeg.so.2', '/usr/lib/libxslt.so.1', diff --git a/setup/installer/osx/app/main.py b/setup/installer/osx/app/main.py index 3c694b706e..9584c80b67 100644 --- a/setup/installer/osx/app/main.py +++ b/setup/installer/osx/app/main.py @@ -385,7 +385,7 @@ class Py2App(object): @flush def add_poppler(self): info('\nAdding poppler') - for x in ('libpoppler.7.dylib',): + for x in ('libpoppler.25.dylib',): self.install_dylib(os.path.join(SW, 'lib', x)) self.install_dylib(os.path.join(SW, 'bin', 'pdftohtml'), False) diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst index 49fcd95cc1..c2e7dca8eb 100644 --- a/setup/installer/windows/notes.rst +++ b/setup/installer/windows/notes.rst @@ -295,7 +295,7 @@ NOTE: poppler must be built as a static library, unless you build the qt4 bindin Now do the same for the pdftohtml project -cp poppler/*.h ~/sw/include/poppler && cp goo/*.h ~/sw/include/poppler/goo && cp splash/*.h ~/sw/include/poppler/splash && cp build/Release/poppler.lib ../../lib/ && cp build/utils/Release/*.exe ../../bin/ +cp poppler/*.h ~/sw/include/poppler && cp goo/*.h ~/sw/include/poppler/goo && cp splash/*.h ~/sw/include/poppler/splash && cp build/Release/poppler.lib ../../lib/ && cp build/utils/Release/pdftohtml.exe ../../bin/ podofo diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 8b021dc22e..7d4db1e512 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -4,7 +4,7 @@ __copyright__ = '2008, Kovid Goyal ' __docformat__ = 'restructuredtext en' import sys, os, re, time, random, __builtin__, warnings -__builtin__.__dict__['dynamic_property'] = lambda(func): func(None) +__builtin__.__dict__['dynamic_property'] = lambda func: func(None) from math import floor from functools import partial diff --git a/src/calibre/debug.py b/src/calibre/debug.py index aa0bb1b2a8..e451b516cb 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -182,6 +182,12 @@ def main(args=sys.argv): from calibre.constants import debug debug() if len(args) > 2 and args[1] in ('-e', '--exec-file'): + + # Load all plugins user defined plugins so the script can import from the + # calibre_plugins namespace + import calibre.customize.ui as dummy + dummy + sys.argv = [args[2]] + args[3:] ef = os.path.abspath(args[2]) base = os.path.dirname(ef) diff --git a/src/calibre/ebooks/metadata/fb2.py b/src/calibre/ebooks/metadata/fb2.py index 552a762cb2..9139ef099c 100644 --- a/src/calibre/ebooks/metadata/fb2.py +++ b/src/calibre/ebooks/metadata/fb2.py @@ -257,9 +257,10 @@ def _set_title(title_info, mi): def _set_comments(title_info, mi): if not mi.is_null('comments'): + from calibre.utils.html2text import html2text _clear_meta_tags(title_info, 'annotation') title = _get_or_create(title_info, 'annotation') - title.text = mi.comments + title.text = html2text(mi.comments) def _set_authors(title_info, mi): diff --git a/src/calibre/ebooks/oeb/reader.py b/src/calibre/ebooks/oeb/reader.py index c9a8429f3b..3531ca0250 100644 --- a/src/calibre/ebooks/oeb/reader.py +++ b/src/calibre/ebooks/oeb/reader.py @@ -291,7 +291,10 @@ class OEBReader(object): href, _ = urldefrag(href) if not href: continue - href = item.abshref(urlnormalize(href)) + try: + href = item.abshref(urlnormalize(href)) + except ValueError: # Malformed URL + continue if href not in manifest.hrefs: continue found = manifest.hrefs[href] diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index be96a8dd03..969f7c763a 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -457,7 +457,9 @@ class Stylizer(object): value = primitives.pop() for key in composition: if key not in style: - style[key] = DEFAULTS[key] + val = ('inherit' if key in {'font-family', 'font-size'} + else 'normal') + style[key] = val return style def style(self, element): diff --git a/src/calibre/ebooks/oeb/transforms/rescale.py b/src/calibre/ebooks/oeb/transforms/rescale.py index 7f07e242af..f9f14b1cb9 100644 --- a/src/calibre/ebooks/oeb/transforms/rescale.py +++ b/src/calibre/ebooks/oeb/transforms/rescale.py @@ -57,6 +57,8 @@ class RescaleImages(object): try: img.size = (new_width, new_height) data = img.export(ext.lower()) + except KeyboardInterrupt: + raise except: self.log.exception('Failed to rescale image') else: diff --git a/src/calibre/ebooks/pdf/pdftohtml.py b/src/calibre/ebooks/pdf/pdftohtml.py index 4916ecc6c3..7c5e852b24 100644 --- a/src/calibre/ebooks/pdf/pdftohtml.py +++ b/src/calibre/ebooks/pdf/pdftohtml.py @@ -5,7 +5,7 @@ __copyright__ = '2008, Kovid Goyal , ' \ '2009, John Schember ' __docformat__ = 'restructuredtext en' -import errno, os, sys, subprocess, shutil +import errno, os, sys, subprocess, shutil, re from functools import partial from calibre.ebooks import ConversionError, DRMError @@ -96,8 +96,36 @@ def pdftohtml(output_dir, pdf_path, no_images): with open(index, 'r+b') as i: raw = i.read() + raw = flip_images(raw) raw = '\n' + raw i.seek(0) i.truncate() - i.write(raw) + # versions of pdftohtml >= 0.20 output self closing
tags, this + # breaks the pdf heuristics regexps, so replace them + i.write(raw.replace(b'
', b'
')) + +def flip_image(img, flip): + from calibre.utils.magick import Image + im = Image() + im.open(img) + if b'x' in flip: + im.flip(True) + if b'y' in flip: + im.flip() + im.save(img) + +def flip_images(raw): + for match in re.finditer(b']+/?>', raw): + img = match.group() + m = re.search(br'class="(x|y|xy)flip"', img) + if m is None: continue + flip = m.group(1) + src = re.search(br'src="([^"]+)"', img) + if src is None: continue + img = src.group(1) + if not os.path.exists(img): continue + print ('Flipping image %s: %s'%(img, flip)) + flip_image(img, flip) + raw = re.sub(br'\s*', b'', raw, flags=re.I|re.DOTALL) + return raw diff --git a/src/calibre/ebooks/pdf/reflow.cpp b/src/calibre/ebooks/pdf/reflow.cpp index 552e13efcb..c01f357d3c 100644 --- a/src/calibre/ebooks/pdf/reflow.cpp +++ b/src/calibre/ebooks/pdf/reflow.cpp @@ -647,7 +647,12 @@ void XMLOutputDev::process_link(AnnotLink* link){ void XMLOutputDev::endPage() { +#ifdef POPPLER_PRE_20 Links *slinks = catalog->getPage(current_page->number())->getLinks(catalog); +#else + Links *slinks = catalog->getPage(current_page->number())->getLinks(); +#endif + for (int i = 0; i < slinks->getNumLinks(); i++) { this->process_link(slinks->getLink(i)); @@ -878,7 +883,11 @@ vector* Reflow::render_first_page(bool use_crop_box, double x_res, throw ReflowException("Failed to allocate SplashOutputDev"); } try { +#ifdef POPPLER_PRE_20 out->startDoc(doc->getXRef()); +#else + out->startDoc(doc); +#endif out->startPage(1, NULL); double pg_w, pg_h; diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py index cf47684063..83d0219ca0 100644 --- a/src/calibre/gui2/actions/add.py +++ b/src/calibre/gui2/actions/add.py @@ -329,8 +329,10 @@ class AddAction(InterfaceAction): x.decode(preferred_encoding, 'replace') for x in self._adder.merged_books]) info_dialog(self.gui, _('Merged some books'), - _('The following duplicate books were found and incoming book formats were ' - 'processed and merged into your Calibre database according to your automerge settings:'), det_msg=books, show=True) + _('The following duplicate books were found and incoming ' + 'book formats were processed and merged into your ' + 'Calibre database according to your automerge ' + 'settings:'), det_msg=books, show=True) if getattr(self._adder, 'number_of_books_added', 0) > 0 or \ getattr(self._adder, 'merged_books', False): diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py index 5f9e58d7b8..7a5115865f 100644 --- a/src/calibre/gui2/actions/delete.py +++ b/src/calibre/gui2/actions/delete.py @@ -116,7 +116,7 @@ class DeleteAction(InterfaceAction): for action in list(self.delete_menu.actions())[1:]: action.setEnabled(enabled) - def _get_selected_formats(self, msg, ids): + def _get_selected_formats(self, msg, ids, exclude=False): from calibre.gui2.dialogs.select_formats import SelectFormats c = Counter() db = self.gui.library_view.model().db @@ -125,7 +125,7 @@ class DeleteAction(InterfaceAction): if fmts_: for x in frozenset([x.lower() for x in fmts_.split(',')]): c[x] += 1 - d = SelectFormats(c, msg, parent=self.gui) + d = SelectFormats(c, msg, parent=self.gui, exclude=exclude) if d.exec_() != d.Accepted: return None return d.selected_formats @@ -162,7 +162,8 @@ class DeleteAction(InterfaceAction): return fmts = self._get_selected_formats( '

'+_('Choose formats not to be deleted.

Note that ' - 'this will never remove all formats from a book.'), ids) + 'this will never remove all formats from a book.'), ids, + exclude=True) if fmts is None: return for id in ids: diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index 8af72e51c0..3cfd94cc6e 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -291,8 +291,8 @@ class PluginWidget(QWidget,Ui_Form): Currently using QLineEdit for all field types Possible to modify to switch QWidget type ''' - new_source = str(self.read_source_field.currentText()) - read_source_spec = self.read_source_fields[str(new_source)] + new_source = unicode(self.read_source_field.currentText()) + read_source_spec = self.read_source_fields[new_source] self.read_source_field_name = read_source_spec['field'] # Change pattern input widget to match the source field datatype @@ -314,7 +314,7 @@ class PluginWidget(QWidget,Ui_Form): new_source = str(self.exclude_source_field.currentText()) self.exclude_source_field_name = new_source if new_source > '': - exclude_source_spec = self.exclude_source_fields[str(new_source)] + exclude_source_spec = self.exclude_source_fields[unicode(new_source)] self.exclude_source_field_name = exclude_source_spec['field'] self.exclude_pattern.setEnabled(True) @@ -360,17 +360,17 @@ class PluginWidget(QWidget,Ui_Form): new_source = str(self.header_note_source_field.currentText()) self.header_note_source_field_name = new_source if new_source > '': - header_note_source_spec = self.header_note_source_fields[str(new_source)] + header_note_source_spec = self.header_note_source_fields[unicode(new_source)] self.header_note_source_field_name = header_note_source_spec['field'] def merge_source_field_changed(self,new_index): ''' - Process changes in the header_note_source_field combo box + Process changes in the merge_source_field combo box ''' new_source = str(self.merge_source_field.currentText()) self.merge_source_field_name = new_source if new_source > '': - merge_source_spec = self.merge_source_fields[str(new_source)] + merge_source_spec = self.merge_source_fields[unicode(new_source)] self.merge_source_field_name = merge_source_spec['field'] if not self.merge_before.isChecked() and not self.merge_after.isChecked(): self.merge_after.setChecked(True) diff --git a/src/calibre/gui2/dialogs/message_box.py b/src/calibre/gui2/dialogs/message_box.py index e15cd055b9..a107bf985b 100644 --- a/src/calibre/gui2/dialogs/message_box.py +++ b/src/calibre/gui2/dialogs/message_box.py @@ -159,7 +159,7 @@ _proceed_memory = [] class ProceedNotification(MessageBox): # {{{ ''' - WARNING: This class is deprecated. DO not use it as some users ahve + WARNING: This class is deprecated. DO not use it as some users have reported crashes when closing the dialog box generated by this class. Instead use: gui.proceed_question(...) The arguments are the same as for this class. diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index 64e3c2e0a3..2ae4619d7a 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -22,6 +22,7 @@ from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.date import utcnow from calibre.utils.network import internet_connected from calibre import force_unicode +from calibre.utils.localization import get_lang, canonicalize_lang def convert_day_time_schedule(val): day_of_week, hour, minute = val @@ -57,6 +58,8 @@ class DaysOfWeek(Base): self.time = QTimeEdit(self) self.time.setDisplayFormat('hh:mm AP') + if canonicalize_lang(get_lang()) in {'deu', 'nds'}: + self.time.setDisplayFormat('HH:mm') self.hl = QHBoxLayout() self.l1 = QLabel(_('&Download after:')) self.l1.setBuddy(self.time) diff --git a/src/calibre/gui2/dialogs/select_formats.py b/src/calibre/gui2/dialogs/select_formats.py index 814051479b..0d43864816 100644 --- a/src/calibre/gui2/dialogs/select_formats.py +++ b/src/calibre/gui2/dialogs/select_formats.py @@ -35,7 +35,7 @@ class Formats(QAbstractListModel): fmt = self.fmts[row] count = self.counts[fmt] return QVariant( - _('The are %(count)d book(s) with the %(fmt)s format')%dict( + _('There are %(count)d book(s) with the %(fmt)s format')%dict( count=count, fmt=fmt.upper())) return NONE @@ -47,7 +47,7 @@ class Formats(QAbstractListModel): class SelectFormats(QDialog): - def __init__(self, fmt_count, msg, single=False, parent=None): + def __init__(self, fmt_count, msg, single=False, parent=None, exclude=False): QDialog.__init__(self, parent) self._l = QVBoxLayout(self) self.setLayout(self._l) @@ -57,6 +57,10 @@ class SelectFormats(QDialog): self._l.addWidget(self._m) self.formats = Formats(fmt_count) self.fview = QListView(self) + if exclude: + self.fview.setStyleSheet(''' + QListView { background-color: #FAE7B5} + ''') self._l.addWidget(self.fview) self.fview.setModel(self.formats) self.fview.setSelectionMode(self.fview.SingleSelection if single else diff --git a/src/calibre/gui2/store/stores/kobo_plugin.py b/src/calibre/gui2/store/stores/kobo_plugin.py index c888c0a252..0b2fc1c9a1 100644 --- a/src/calibre/gui2/store/stores/kobo_plugin.py +++ b/src/calibre/gui2/store/stores/kobo_plugin.py @@ -31,7 +31,7 @@ class KoboStore(BasicStoreConfig, StorePlugin): if random.randint(1, 10) in (1, 2, 3): h_click = 'click-4913808-10762497' d_click = 'click-4913808-10772898' - + url = m_url + h_click detail_url = None if detail_item: @@ -47,9 +47,9 @@ class KoboStore(BasicStoreConfig, StorePlugin): def search(self, query, max_results=10, timeout=60): url = 'http://www.kobobooks.com/search/search.html?q=' + urllib2.quote(query) - + br = browser() - + counter = max_results with closing(br.open(url, timeout=timeout)) as f: doc = html.fromstring(f.read()) @@ -61,18 +61,18 @@ class KoboStore(BasicStoreConfig, StorePlugin): if not id: continue - price = ''.join(data.xpath('.//li[@class="OurPrice"]/strong/text()')) + price = ''.join(data.xpath('.//span[@class="OurPrice"]/strong/text()')) if not price: price = '$0.00' - + cover_url = ''.join(data.xpath('.//div[@class="SearchImageContainer"]//img[1]/@src')) - + title = ''.join(data.xpath('.//div[@class="SCItemHeader"]/h1/a[1]/text()')) author = ', '.join(data.xpath('.//div[@class="SCItemSummary"]//span//a/text()')) drm = data.xpath('boolean(.//span[@class="SCAvailibilityFormatsText" and not(contains(text(), "DRM-Free"))])') counter -= 1 - + s = SearchResult() s.cover_url = cover_url s.title = title.strip() @@ -81,5 +81,5 @@ class KoboStore(BasicStoreConfig, StorePlugin): s.detail_item = '?url=http://www.kobobooks.com/' + id.strip() s.drm = SearchResult.DRM_LOCKED if drm else SearchResult.DRM_UNLOCKED s.formats = 'EPUB' - + yield s diff --git a/src/calibre/gui2/viewer/config.ui b/src/calibre/gui2/viewer/config.ui index f876b87fc3..76532a8cfc 100644 --- a/src/calibre/gui2/viewer/config.ui +++ b/src/calibre/gui2/viewer/config.ui @@ -301,6 +301,13 @@ + + + + Line &scrolling stops at page breaks + + + diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 94d50cb54a..dd94025d20 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -60,6 +60,9 @@ def config(defaults=None): help=_('Save the current position in the document, when quitting')) c.add_opt('wheel_flips_pages', default=False, help=_('Have the mouse wheel turn pages')) + c.add_opt('line_scrolling_stops_on_pagebreaks', default=False, + help=_('Prevent the up and down arrow keys from scrolling past ' + 'page breaks')) c.add_opt('page_flip_duration', default=0.5, help=_('The time, in seconds, for the page flip animation. Default' ' is half a second.')) @@ -96,6 +99,8 @@ class ConfigDialog(QDialog, Ui_Dialog): if fms < 0.01 or fms > 1: fms = 0.2 self.opt_font_mag_step.setValue(int(fms*100)) + self.opt_line_scrolling_stops_on_pagebreaks.setChecked( + opts.line_scrolling_stops_on_pagebreaks) self.serif_family.setCurrentFont(QFont(opts.serif_family)) self.sans_family.setCurrentFont(QFont(opts.sans_family)) self.mono_family.setCurrentFont(QFont(opts.mono_family)) @@ -157,6 +162,8 @@ class ConfigDialog(QDialog, Ui_Dialog): idx = self.hyphenate_default_lang.currentIndex() c.set('hyphenate_default_lang', str(self.hyphenate_default_lang.itemData(idx).toString())) + c.set('line_scrolling_stops_on_pagebreaks', + self.opt_line_scrolling_stops_on_pagebreaks.isChecked()) return QDialog.accept(self, *args) # }}} @@ -242,6 +249,7 @@ class Document(QWebPage): # {{{ self.enable_page_flip = self.page_flip_duration > 0.1 self.font_magnification_step = opts.font_magnification_step self.wheel_flips_pages = opts.wheel_flips_pages + self.line_scrolling_stops_on_pagebreaks = opts.line_scrolling_stops_on_pagebreaks screen_width = QApplication.desktop().screenGeometry().width() # Leave some space for the scrollbar and some border self.max_fs_width = min(opts.max_fs_width, screen_width-50) @@ -955,13 +963,17 @@ class DocumentView(QWebView): # {{{ finally: self.is_auto_repeat_event = False elif key == 'Down': - if self.document.at_bottom: + if (not self.document.line_scrolling_stops_on_pagebreaks and + self.document.at_bottom): self.manager.next_document() - self.scroll_by(y=15) + else: + self.scroll_by(y=15) elif key == 'Up': - if self.document.at_top: + if (not self.document.line_scrolling_stops_on_pagebreaks and + self.document.at_top): self.manager.previous_document() - self.scroll_by(y=-15) + else: + self.scroll_by(y=-15) elif key == 'Left': self.scroll_by(x=-15) elif key == 'Right': diff --git a/src/calibre/manual/conversion.rst b/src/calibre/manual/conversion.rst index f6fe04dd90..5eaca5a469 100644 --- a/src/calibre/manual/conversion.rst +++ b/src/calibre/manual/conversion.rst @@ -669,7 +669,6 @@ Some limitations of PDF input are: * Complex, multi-column, and image based documents are not supported. * Extraction of vector images and tables from within the document is also not supported. * Some PDFs use special glyphs to represent ll or ff or fi, etc. Conversion of these may or may not work depending on just how they are represented internally in the PDF. - * Some PDFs store their images upside down with a rotation instruction, |app| currently doesn't support that instruction, so the images will be rotated in the output as well. * Links and Tables of Contents are not supported * PDFs that use embedded non-unicode fonts to represent non-English characters will result in garbled output for those characters * Some PDFs are made up of photographs of the page with OCRed text behind them. In such cases |app| uses the OCRed text, which can be very different from what you see when you view the PDF file diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 796831970c..0598471812 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.8.52\n" -"POT-Creation-Date: 2012-05-18 10:30+IST\n" -"PO-Revision-Date: 2012-05-18 10:30+IST\n" +"POT-Creation-Date: 2012-05-18 20:57+IST\n" +"PO-Revision-Date: 2012-05-18 20:57+IST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -29,7 +29,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:100 #: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:101 #: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:74 -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:77 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:78 #: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:24 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:616 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70 @@ -66,8 +66,8 @@ 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/extz.py:23 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:38 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:98 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:41 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:102 #: /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 @@ -101,9 +101,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/worker.py:26 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/txt.py:18 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:26 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:81 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:136 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:178 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:85 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:143 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:185 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/mobi6.py:615 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/utils.py:316 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer2/indexer.py:463 @@ -306,326 +306,327 @@ msgid "Read metadata from ebooks in ZIP archives" msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:418 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:439 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:428 #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:449 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:471 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:482 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:459 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:481 #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:492 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:502 #, python-format msgid "Set metadata in %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:428 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:460 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:503 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:438 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:470 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:513 #, python-format msgid "Set metadata from %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:751 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:761 msgid "Add books to calibre or the connected device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:756 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:766 msgid "Fetch annotations from a connected Kindle (experimental)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:761 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:771 msgid "Generate a catalog of the books in your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:766 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:776 msgid "Convert books to various ebook formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:771 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:781 msgid "Delete books from your calibre library or connected device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:776 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:786 msgid "Edit the metadata of books in your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:781 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:791 msgid "Read books in your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:786 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:796 msgid "Download news from the internet in ebook form" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:791 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:801 msgid "Show a list of related books quickly" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:796 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:806 msgid "Export books from your calibre library to the hard disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:801 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:811 msgid "Show book details in a separate popup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:806 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:816 msgid "Restart calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:811 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:821 msgid "Open the folder that contains the book files in your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:817 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:827 msgid "Send books to the connected device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:822 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:832 msgid "Send books via email or the web also connect to iTunes or folders on your computer as if they are devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:828 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:838 #: /home/kovid/work/calibre/src/calibre/gui2/actions/help.py:16 msgid "Browse the calibre User Manual" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:833 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:843 msgid "Customize calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:838 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:848 msgid "Easily find books similar to the currently selected one" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:843 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:853 msgid "Switch between different calibre libraries and perform maintenance on them" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:849 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:859 msgid "Copy books from the devce to your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:854 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:864 msgid "Edit the collections in which books are placed on your device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:859 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:869 msgid "Copy a book from one calibre library to another" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:864 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:874 msgid "Make small tweaks to epub or htmlz files in your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:869 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:879 msgid "Find the next or previous match when searching in your calibre library in highlight mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:875 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:885 msgid "Choose a random book from your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:882 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:892 msgid "Search for books from different book sellers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:898 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:908 msgid "Get new calibre plugins or update your existing ones" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:917 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:927 msgid "Look and Feel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:919 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:931 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:942 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:953 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:965 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:929 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:941 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:952 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:963 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:975 msgid "Interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:923 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:933 msgid "Adjust the look and feel of the calibre interface to suit your tastes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:929 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:939 msgid "Behavior" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:935 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:945 msgid "Change the way calibre behaves" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:940 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:950 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:267 msgid "Add your own columns" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:946 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:956 msgid "Add/remove your own columns to the calibre book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:951 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:961 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:957 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:967 msgid "Customize the toolbars and context menus, changing which actions are available in each" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:963 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:973 msgid "Searching" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:969 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:979 msgid "Customize the way searching for books works in calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:974 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:984 msgid "Input Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:976 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:987 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:998 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:986 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:997 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1008 msgid "Conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:980 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:990 msgid "Set conversion options specific to each input format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:985 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:995 msgid "Common Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:991 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1001 msgid "Set conversion options common to all formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:996 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1006 msgid "Output Options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1002 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1012 msgid "Set conversion options specific to each output format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1007 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1017 msgid "Adding books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1009 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1021 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1033 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1045 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1019 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1031 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1043 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1055 msgid "Import/Export" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1013 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1023 msgid "Control how calibre reads metadata from files when adding books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1019 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1029 msgid "Saving books to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1025 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1035 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:1031 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1041 msgid "Sending books to devices" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1037 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1047 msgid "Control how calibre transfers files to your ebook reader" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1043 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1053 msgid "Metadata plugboards" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1049 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1059 msgid "Change metadata fields before saving/sending" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1054 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1064 msgid "Template Functions" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1056 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1103 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1115 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1126 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1137 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1066 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1113 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1125 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1136 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1147 msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1060 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1070 msgid "Create your own template functions" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1065 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1075 msgid "Sharing books by email" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1067 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1079 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1092 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1077 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1089 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1102 msgid "Sharing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1071 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1081 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:1077 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1087 msgid "Sharing over the net" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1083 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1093 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:1090 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1100 msgid "Metadata download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1096 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1106 msgid "Control how calibre downloads ebook metadata from the net" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1101 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1111 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:292 msgid "Plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1107 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1117 msgid "Add/remove/customize various bits of calibre functionality" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1113 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1123 msgid "Tweaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1119 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1129 msgid "Fine tune how calibre behaves in various contexts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1124 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1134 msgid "Keyboard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1130 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1140 msgid "Customize the keyboard shortcuts used by calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1135 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1145 #: /home/kovid/work/calibre/src/calibre/gui2/keyboard.py:110 msgid "Miscellaneous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1141 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1151 msgid "Miscellaneous advanced configuration" msgstr "" @@ -1311,68 +1312,68 @@ msgstr "" msgid "Could not generate page mapping." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:44 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:45 msgid "Communicate with the Kindle eBook reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:185 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:186 #, python-format msgid "%(time)s
Last Page Read: %(loc)d (%(pr)d%%)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:191 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:192 #, python-format msgid "%(time)s
Last Page Read: Location %(loc)d (%(pr)d%%)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:210 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:211 #, python-format msgid "Location %(dl)d • %(typ)s
%(text)s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:219 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:220 #, python-format msgid "Page %(dl)d • %(typ)s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:224 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:225 #, python-format msgid "Location %(dl)d • %(typ)s
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:289 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:290 msgid "Communicate with the Kindle 2/3/4/Touch eBook reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:298 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:299 msgid "Send page number information when sending books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:300 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:301 msgid "The Kindle 3 and newer versions can use page number information in MOBI files. With this option, calibre will calculate and send this information to the Kindle when uploading MOBI files by USB. Note that the page numbers do not correspond to any paper book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:305 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:306 msgid "Use slower but more accurate page number calculation" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:307 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:308 msgid "There are two ways to generate the page number information. Using the more accurate generator will produce pages that correspond better to a printed book. However, this method is slower and will slow down sending files to the Kindle." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:311 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:312 msgid "Custom column name to retrieve page counts from" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:313 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:314 msgid "If you have a custom column in your library that you use to store the page count of books, you can have calibre use that information, instead of calculating a page count. Specify the name of the custom column here, for example, #pages. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:419 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:449 msgid "Communicate with the Kindle DX eBook reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:428 +#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:461 msgid "Communicate with the Kindle Fire" msgstr "" @@ -3317,7 +3318,7 @@ msgstr "" msgid "Downloads metadata and covers from OZON.ru" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:52 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader/headers.py:56 msgid "Sample Book" msgstr "" @@ -9689,7 +9690,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/select_formats.py:38 #, python-format -msgid "The are %(count)d book(s) with the %(fmt)s format" +msgid "There are %(count)d book(s) with the %(fmt)s format" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/select_formats.py:54 diff --git a/src/calibre/utils/magick/magick.c b/src/calibre/utils/magick/magick.c index 58954fb903..e14c966282 100644 --- a/src/calibre/utils/magick/magick.c +++ b/src/calibre/utils/magick/magick.c @@ -909,6 +909,24 @@ magick_Image_rotate(magick_Image *self, PyObject *args, PyObject *kwargs) { } // }}} +// Image.rotate {{{ + +static PyObject * +magick_Image_flip(magick_Image *self, PyObject *args, PyObject *kwargs) { + PyObject *obj = NULL; + MagickBooleanType ret = 0; + + NULL_CHECK(NULL) + + if (!PyArg_ParseTuple(args, "|O", &obj)) return NULL; + ret = (obj != NULL && PyObject_IsTrue(obj)) ? MagickFlopImage(self->wand) : MagickFlipImage(self->wand); + if (!ret) { PyErr_SetString(PyExc_ValueError, "Failed to flip image"); return NULL; } + + Py_RETURN_NONE; +} +// }}} + + // Image.set_page {{{ static PyObject * @@ -1174,6 +1192,10 @@ static PyMethodDef magick_Image_methods[] = { {"rotate", (PyCFunction)magick_Image_rotate, METH_VARARGS, "rotate(background_pixel_wand, degrees) \n\n Rotate image by specified degrees." }, + {"flip", (PyCFunction)magick_Image_flip, METH_VARARGS, + "flip(horizontal=False) \n\n Flip image about a vertical axis. If horizontal is True, flip about horizontal axis instead." + }, + {"normalize", (PyCFunction)magick_Image_normalize, METH_VARARGS, "normalize() \n\n enhances the contrast of a color image by adjusting the pixels color to span the entire range of colors available."