diff --git a/NEWS b/NEWS index 5b63446..e3b9fc7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +123 + +* Use named arguments in translatable strings (Hrishi Patel), +* Add dark mode for PDFs (Swarup N), +* Port to Python 3 (Rahul Bothra, James Cameron), +* Text objects show left justify and monospaced (James Cameron), +* Remove speech language choice (James Cameron), + +122 + +* Restore EPUB support for WebKit 3.0 API (Lubomir Rintel), + 121 * Add README.md (Rudra Sadhu), diff --git a/activity/activity.info b/activity/activity.info index 78128c5..59e36ce 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -2,12 +2,12 @@ name = Read bundle_id = org.laptop.sugar.ReadActivity icon = activity-read -exec = sugar-activity readactivity.ReadActivity -activity_version = 121 -mime_types = application/pdf;image/vnd.djvu;image/x.djvu;image/tiff;text/plain;application/zip;application/x-cbz +exec = sugar-activity3 readactivity.ReadActivity +activity_version = 123 +mime_types = application/pdf;image/vnd.djvu;image/x.djvu;image/tiff;application/epub+zip;text/plain;application/zip;application/x-cbz max_participants = 10 license = GPLv2+;LGPLv2+ summary = Use this activity when you are ready to read! Remember to flip your computer around to feel like you are really holding a book! -tags = Language;Documents;Media;System +tags = Language;Documents;Media url = https://help.sugarlabs.org/en/read.html repository = https://github.com/sugarlabs/read-activity diff --git a/activity/mimetypes.xml b/activity/mimetypes.xml new file mode 100644 index 0000000..5c27572 --- /dev/null +++ b/activity/mimetypes.xml @@ -0,0 +1,7 @@ + + + + Epub document + + + diff --git a/bookmarkview.py b/bookmarkview.py index aae14e9..c01eb1b 100644 --- a/bookmarkview.py +++ b/bookmarkview.py @@ -105,8 +105,8 @@ # TRANS: (the elapsed string gets translated automatically) tooltip_footer = ( _('Bookmark added by %(user)s %(time)s') - % {'user': bookmark.nick.decode('utf-8'), - 'time': time.decode('utf-8')}) + % {'user': bookmark.nick, + 'time': time}) l = Gtk.Label('%s' % tooltip_header) l.set_use_markup(True) @@ -196,7 +196,7 @@ dialog.show_all() def _real_add_bookmark(self, page, content): - self._bookmark_manager.add_bookmark(page, unicode(content)) + self._bookmark_manager.add_bookmark(page, str(content)) self.update_for_page(page) def del_bookmark(self, page): diff --git a/epubadapter.py b/epubadapter.py new file mode 100644 index 0000000..d059a66 --- /dev/null +++ b/epubadapter.py @@ -0,0 +1,307 @@ +from gi.repository import GObject +import logging + +import epubview + +# import speech + +from io import StringIO + +_logger = logging.getLogger('read-activity') + + +class EpubViewer(epubview.EpubView): + + def __init__(self): + epubview.EpubView.__init__(self) + + def setup(self, activity): + self.set_screen_dpi(activity.dpi) + self.connect('selection-changed', + activity._view_selection_changed_cb) + + activity._hbox.pack_start(self, True, True, 0) + self.show_all() + self._modified_files = [] + + # text to speech initialization + self.current_word = 0 + self.word_tuples = [] + + def load_document(self, file_path): + self.set_document(EpubDocument(self, file_path.replace('file://', ''))) + # speech.highlight_cb = self.highlight_next_word + # speech.reset_cb = self.reset_text_to_speech + # speech.end_text_cb = self.get_more_text + + def load_metadata(self, activity): + + self.metadata = activity.metadata + + if not self.metadata['title_set_by_user'] == '1': + title = self._epub._info._get_title() + if title: + self.metadata['title'] = title + if 'Read_zoom' in self.metadata: + try: + logging.error('Loading zoom %s', self.metadata['Read_zoom']) + self.set_zoom(float(self.metadata['Read_zoom'])) + except: + pass + + def update_metadata(self, activity): + self.metadata = activity.metadata + self.metadata['Read_zoom'] = str(self.get_zoom()) + + def zoom_to_width(self): + pass + + def zoom_to_best_fit(self): + pass + + def zoom_to_actual_size(self): + pass + + def can_zoom_to_width(self): + return False + + def can_highlight(self): + return True + + def show_highlights(self, page): + # we save the highlights in the page as html + pass + + def toggle_highlight(self, highlight): + self._view.set_editable(True) + + if highlight: + js = 'document.execCommand("backColor", false, "yellow");' + else: + # need remove the highlight nodes + js = ''' + (function(){ + var selObj = window.getSelection(); + if (selObj.rangeCount < 1) + return; + var range = selObj.getRangeAt(0); + var node = range.startContainer; + while (node.parentNode != null) { + if (node.localName == "span") { + if (node.hasAttributes()) { + var attrs = node.attributes; + for (var i = attrs.length - 1; i >= 0; i--) { + if (attrs[i].name == "style" && + attrs[i].value == "background-color: yellow;") { + node.removeAttribute("style"); + break; + }; + }; + }; + }; + node = node.parentNode; + }; + }()) + ''' + + self._view.run_javascript(js) + + self._view.set_editable(False) + # mark the file as modified + current_file = self.get_current_file() + logging.error('file %s was modified', current_file) + if current_file not in self._modified_files: + self._modified_files.append(current_file) + GObject.idle_add(self._save_page) + + def _save_page(self): + html = self._view._execute_script_sync("document.documentElement.innerHTML") + file_path = self.get_current_file().replace('file:///', '/') + logging.error(html) + with open(file_path, 'w') as fd: + header = """ + + """ + fd.write(header) + fd.write(html) + fd.write('') + + def save(self, file_path): + if self._modified_files: + self._epub.write(file_path) + return True + + return False + + def in_highlight(self): + # Verify if the selection already exist or the cursor + # is in a highlighted area + return self._view._execute_script_sync(""" + (function(){ + var selObj = window.getSelection(); + if (selObj.rangeCount < 1) + return false; + var range = selObj.getRangeAt(0); + var node = range.startContainer; + while (node.parentNode != null) { + if (node.localName == "span") { + if (node.hasAttributes()) { + var attrs = node.attributes; + for(var i = attrs.length - 1; i >= 0; i--) { + if (attrs[i].name == "style" && + attrs[i].value == "background-color: yellow;") { + return true; + }; + }; + }; + }; + node = node.parentNode; + }; + return false; + })()""") == "true", None; + + def can_do_text_to_speech(self): + return False + + def can_rotate(self): + return False + + def get_marked_words(self): + "Adds a mark between each word of text." + i = self.current_word + file_str = StringIO() + file_str.write(' ') + end_range = i + 40 + if end_range > len(self.word_tuples): + end_range = len(self.word_tuples) + for word_tuple in self.word_tuples[self.current_word:end_range]: + file_str.write('' + + word_tuple[2].encode('utf-8')) + i = i + 1 + self.current_word = i + file_str.write('') + return file_str.getvalue() + + def get_more_text(self): + pass + """ + if self.current_word < len(self.word_tuples): + speech.stop() + more_text = self.get_marked_words() + speech.play(more_text) + else: + if speech.reset_buttons_cb is not None: + speech.reset_buttons_cb() + """ + + def reset_text_to_speech(self): + self.current_word = 0 + + def highlight_next_word(self, word_count): + pass + """ + TODO: disabled because javascript can't be executed + with the velocity needed + self.current_word = word_count + self._view.highlight_next_word() + return True + """ + + def connect_zoom_handler(self, handler): + self._zoom_handler = handler + self._view_notify_zoom_handler = \ + self.connect('notify::scale', handler) + return self._view_notify_zoom_handler + + def connect_page_changed_handler(self, handler): + self.connect('page-changed', handler) + + def _try_load_page(self, n): + if self._ready: + self._load_page(n) + return False + else: + return True + + def set_screen_dpi(self, dpi): + return + + def find_set_highlight_search(self, set_highlight_search): + pass + + def set_current_page(self, n): + # When the book is being loaded, calling this does not help + # In such a situation, we go into a loop and try to load the + # supplied page when the book has loaded completely + n += 1 + if self._ready: + self._load_page(n) + else: + GObject.timeout_add(200, self._try_load_page, n) + + def get_current_page(self): + return int(self._loaded_page) - 1 + + def get_current_link(self): + # the _loaded_filename include all the path, + # need only the part included in the link + return self._loaded_filename[len(self._epub._tempdir) + 1:] + + def update_toc(self, activity): + if self._epub.has_document_links(): + activity.show_navigator_button() + activity.set_navigator_model(self._epub.get_links_model()) + return True + else: + return False + + def get_link_iter(self, current_link): + """ + Returns the iter related to a link + """ + link_iter = self._epub.get_links_model().get_iter_first() + + while link_iter is not None and \ + self._epub.get_links_model().get_value(link_iter, 1) \ + != current_link: + link_iter = self._epub.get_links_model().iter_next(link_iter) + return link_iter + + def find_changed(self, job, page=None): + self._find_changed(job) + + def handle_link(self, link): + self._load_file(link) + + def setup_find_job(self, text, updated_cb): + self._find_job = JobFind(document=self._epub, + start_page=0, n_pages=self.get_pagecount(), + text=text, case_sensitive=False) + self._find_updated_handler = self._find_job.connect('updated', + updated_cb) + return self._find_job, self._find_updated_handler + + +class EpubDocument(epubview.Epub): + + def __init__(self, view, docpath): + epubview.Epub.__init__(self, docpath) + self._page_cache = view + + def get_n_pages(self): + return int(self._page_cache.get_pagecount()) + + def has_document_links(self): + return True + + def get_links_model(self): + return self.get_toc_model() + + +class JobFind(epubview.JobFind): + + def __init__(self, document, start_page, n_pages, text, + case_sensitive=False): + epubview.JobFind.__init__(self, document, start_page, n_pages, text, + case_sensitive=False) diff --git a/epubview/__init__.py b/epubview/__init__.py new file mode 100644 index 0000000..ffdb946 --- /dev/null +++ b/epubview/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2009 One Laptop Per Child +# Author: Sayamindu Dasgupta +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from .epub import _Epub as Epub +from .epubview import _View as EpubView +from .jobs import _JobFind as JobFind diff --git a/epubview/epub.py b/epubview/epub.py new file mode 100644 index 0000000..b059d5a --- /dev/null +++ b/epubview/epub.py @@ -0,0 +1,202 @@ +# Copyright 2009 One Laptop Per Child +# Author: Sayamindu Dasgupta +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import zipfile +import tempfile +import os +import xml.etree.ElementTree as etree +import shutil +import logging + +from . import navmap +from . import epubinfo + + +class _Epub(object): + + def __init__(self, _file): + """ + _file: can be either a path to a file (a string) or a file-like object. + """ + self._file = _file + self._zobject = None + self._opfpath = None + self._ncxpath = None + self._basepath = None + self._tempdir = tempfile.mkdtemp() + + if not self._verify(): + print('Warning: This does not seem to be a valid epub file') + + self._get_opf() + self._get_ncx() + + ncxfile = self._zobject.open(self._ncxpath) + opffile = self._zobject.open(self._opfpath) + self._navmap = navmap.NavMap(opffile, ncxfile, self._basepath) + + opffile = self._zobject.open(self._opfpath) + self._info = epubinfo.EpubInfo(opffile) + + self._unzip() + + def _unzip(self): + # This is broken upto python 2.7 + # self._zobject.extractall(path = self._tempdir) + orig_cwd = os.getcwd() + os.chdir(self._tempdir) + for name in self._zobject.namelist(): + # Some weird zip file entries start with a slash, + # and we don't want to write to the root directory + try: + if name.startswith(os.path.sep): + name = name[1:] + if name.endswith(os.path.sep) or name.endswith('\\'): + os.makedirs(name) + except: + logging.error('ERROR unziping %s', name) + else: + self._zobject.extract(name) + os.chdir(orig_cwd) + + def _get_opf(self): + containerfile = self._zobject.open('META-INF/container.xml') + + tree = etree.parse(containerfile) + root = tree.getroot() + + r_id = './/{urn:oasis:names:tc:opendocument:xmlns:container}rootfile' + for element in root.iterfind(r_id): + if element.get('media-type') == 'application/oebps-package+xml': + self._opfpath = element.get('full-path') + + if self._opfpath.rpartition('/')[0]: + self._basepath = self._opfpath.rpartition('/')[0] + '/' + else: + self._basepath = '' + + containerfile.close() + + def _get_ncx(self): + opffile = self._zobject.open(self._opfpath) + + tree = etree.parse(opffile) + root = tree.getroot() + + spine = root.find('.//{http://www.idpf.org/2007/opf}spine') + tocid = spine.get('toc') + + for element in root.iterfind('.//{http://www.idpf.org/2007/opf}item'): + if element.get('id') == tocid: + self._ncxpath = self._basepath + element.get('href') + + opffile.close() + + def _verify(self): + ''' + Method to crudely check to verify that what we + are dealing with is a epub file or not + ''' + if isinstance(self._file, str): + if not os.path.exists(self._file): + return False + + self._zobject = zipfile.ZipFile(self._file) + + if 'mimetype' not in self._zobject.namelist(): + return False + + mtypefile = self._zobject.open('mimetype') + mimetype = mtypefile.readline() + + # Some files seem to have trailing characters + if not mimetype.startswith(b'application/epub+zip'): + return False + + return True + + def get_toc_model(self): + ''' + Returns a GtkTreeModel representation of the + Epub table of contents + ''' + return self._navmap.get_gtktreestore() + + def get_flattoc(self): + ''' + Returns a flat (linear) list of files to be + rendered. + ''' + return self._navmap.get_flattoc() + + def get_basedir(self): + ''' + Returns the base directory where the contents of the + epub has been unzipped + ''' + return self._tempdir + + def get_info(self): + ''' + Returns a EpubInfo object title + ''' + return self._info.title + + def write(self, file_path): + '''Create the ZIP archive. + The mimetype must be the first file in the archive + and it must not be compressed.''' + + # The EPUB must contain the META-INF and mimetype files at the root, so + # we'll create the archive in the working directory first + # and move it later + current_dir = os.getcwd() + os.chdir(self._tempdir) + + # Open a new zipfile for writing + epub = zipfile.ZipFile(file_path, 'w') + + # Add the mimetype file first and set it to be uncompressed + epub.write('mimetype', compress_type=zipfile.ZIP_STORED) + + # For the remaining paths in the EPUB, add all of their files + # using normal ZIP compression + self._scan_dir('.', epub) + + epub.close() + os.chdir(current_dir) + + def _scan_dir(self, path, epub_file): + for p in os.listdir(path): + logging.error('add file %s', p) + if os.path.isdir(os.path.join(path, p)): + self._scan_dir(os.path.join(path, p), epub_file) + else: + if p != 'mimetype': + epub_file.write( + os.path.join(path, p), + compress_type=zipfile.ZIP_DEFLATED) + + def close(self): + ''' + Cleans up (closes open zip files and deletes + uncompressed content of Epub. + Please call this when a file is being closed or during + application exit. + ''' + self._zobject.close() + shutil.rmtree(self._tempdir) diff --git a/epubview/epubinfo.py b/epubview/epubinfo.py new file mode 100644 index 0000000..5014be4 --- /dev/null +++ b/epubview/epubinfo.py @@ -0,0 +1,114 @@ +import xml.etree.ElementTree as etree + + +class EpubInfo(): + + # TODO: Cover the entire DC range + + def __init__(self, opffile): + self._tree = etree.parse(opffile) + self._root = self._tree.getroot() + self._e_metadata = self._root.find( + '{http://www.idpf.org/2007/opf}metadata') + + self.title = self._get_title() + self.creator = self._get_creator() + self.date = self._get_date() + self.subject = self._get_subject() + self.source = self._get_source() + self.rights = self._get_rights() + self.identifier = self._get_identifier() + self.language = self._get_language() + self.summary = self._get_description() + self.cover_image = self._get_cover_image() + + def _get_data(self, tagname): + element = self._e_metadata.find(tagname) + return element.text + + def _get_title(self): + try: + ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}title') + except AttributeError: + return None + + return ret + + def _get_description(self): + try: + ret = self._get_data( + './/{http://purl.org/dc/elements/1.1/}description') + except AttributeError: + return None + + return ret + + def _get_creator(self): + try: + ret = self._get_data( + './/{http://purl.org/dc/elements/1.1/}creator') + except AttributeError: + return None + return ret + + def _get_date(self): + # TODO: iter + try: + ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}date') + except AttributeError: + return None + + return ret + + def _get_source(self): + try: + ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}source') + except AttributeError: + return None + + return ret + + def _get_rights(self): + try: + ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}rights') + except AttributeError: + return None + + return ret + + def _get_identifier(self): + # TODO: iter + element = self._e_metadata.find( + './/{http://purl.org/dc/elements/1.1/}identifier') + + if element is not None: + return {'id': element.get('id'), 'value': element.text} + else: + return None + + def _get_language(self): + try: + ret = self._get_data( + './/{http://purl.org/dc/elements/1.1/}language') + except AttributeError: + return None + + return ret + + def _get_subject(self): + try: + subjectlist = [] + for element in self._e_metadata.iterfind( + './/{http://purl.org/dc/elements/1.1/}subject'): + subjectlist.append(element.text) + except AttributeError: + return None + + return subjectlist + + def _get_cover_image(self): + element = self._e_metadata.find('{http://www.idpf.org/2007/opf}meta') + if element is not None and element.get('name') == 'cover': + return element.get('content') + else: + return None diff --git a/epubview/epubview.py b/epubview/epubview.py new file mode 100644 index 0000000..a5cdcf5 --- /dev/null +++ b/epubview/epubview.py @@ -0,0 +1,650 @@ +# Copyright 2009 One Laptop Per Child +# Author: Sayamindu Dasgupta +# WebKit2 port Copyright (C) 2018 Lubomir Rintel +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gi +gi.require_version('WebKit2', '4.0') + +from gi.repository import Gtk +from gi.repository import GObject +from gi.repository import Gdk +from gi.repository import WebKit2 +from . import widgets + +import logging +import os.path +import math +import shutil + +from .jobs import _JobPaginator as _Paginator + +LOADING_HTML = ''' + + +
+

Loading...

+
+ + +''' + +class _View(Gtk.HBox): + + __gproperties__ = { + 'scale': (GObject.TYPE_FLOAT, 'the zoom level', + 'the zoom level of the widget', + 0.5, 4.0, 1.0, GObject.PARAM_READWRITE), + } + __gsignals__ = { + 'page-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([int, int])), + 'selection-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([])), + } + + def __init__(self): + GObject.threads_init() + Gtk.HBox.__init__(self) + + self.connect("destroy", self._destroy_cb) + + self._ready = False + self._paginator = None + self._loaded_page = -1 + # self._old_scrollval = -1 + self._loaded_filename = None + self._pagecount = -1 + self.__scroll_to_end = False + self.__page_changed = False + self._has_selection = False + self._scrollval = 0.0 + self.scale = 1.0 + self._epub = None + self._findjob = None + self.__in_search = False + self.__search_fwd = True + self._filelist = None + self._internal_link = None + + self._view = widgets._WebView() + self._view.load_html(LOADING_HTML, '/') + settings = self._view.get_settings() + settings.props.default_font_family = 'DejaVu LGC Serif' + settings.props.enable_plugins = False + settings.props.default_charset = 'utf-8' + self._view.connect('load-changed', self._view_load_changed_cb) + self._view.connect('scrolled', self._view_scrolled_cb) + self._view.connect('scrolled-top', self._view_scrolled_top_cb) + self._view.connect('scrolled-bottom', self._view_scrolled_bottom_cb) + self._view.connect('selection-changed', self._view_selection_changed_cb) + + find = self._view.get_find_controller() + find.connect('failed-to-find-text', self._find_failed_cb) + + self._eventbox = Gtk.EventBox() + self._eventbox.connect('scroll-event', self._eventbox_scroll_event_cb) + self._eventbox.add_events(Gdk.EventMask.SCROLL_MASK) + self._eventbox.add(self._view) + + self._scrollbar = Gtk.VScrollbar() + self._scrollbar_change_value_cb_id = self._scrollbar.connect( + 'change-value', self._scrollbar_change_value_cb) + + hbox = Gtk.HBox() + hbox.pack_start(self._eventbox, True, True, 0) + hbox.pack_end(self._scrollbar, False, True, 0) + + self.pack_start(hbox, True, True, 0) + self._view.set_can_default(True) + self._view.set_can_focus(True) + + def map_cp(widget): + widget.setup_touch() + widget.disconnect(self._setup_handle) + + self._setup_handle = self._view.connect('map', map_cp) + + def set_document(self, epubdocumentinstance): + ''' + Sets document (should be a Epub instance) + ''' + self._epub = epubdocumentinstance + GObject.idle_add(self._paginate) + + def do_get_property(self, property): + if property.name == 'has-selection': + return self._has_selection + elif property.name == 'scale': + return self.scale + else: + raise AttributeError('unknown property %s' % property.name) + + def do_set_property(self, property, value): + if property.name == 'scale': + self.__set_zoom(value) + else: + raise AttributeError('unknown property %s' % property.name) + + def get_has_selection(self): + ''' + Returns True if any part of the content is selected + ''' + return self._has_selection + + def get_zoom(self): + ''' + Returns the current zoom level + ''' + return self.get_property('scale') * 100.0 + + def set_zoom(self, value): + ''' + Sets the current zoom level + ''' + scrollbar_pos = self.get_vertical_pos() + self._view.set_zoom_level(value / 100.0) + self.set_vertical_pos(scrollbar_pos) + + def _get_scale(self): + ''' + Returns the current zoom level + ''' + return self.get_property('scale') + + def _set_scale(self, value): + ''' + Sets the current zoom level + ''' + self.set_property('scale', value) + + def zoom_in(self): + ''' + Zooms in (increases zoom level by 0.1) + ''' + if self.can_zoom_in(): + scrollbar_pos = self.get_vertical_pos() + self._set_scale(self._get_scale() + 0.1) + self.set_vertical_pos(scrollbar_pos) + return True + else: + return False + + def zoom_out(self): + ''' + Zooms out (decreases zoom level by 0.1) + ''' + if self.can_zoom_out(): + scrollbar_pos = self.get_vertical_pos() + self._set_scale(self._get_scale() - 0.1) + self.set_vertical_pos(scrollbar_pos) + return True + else: + return False + + def get_vertical_pos(self): + """ + Used to save the scrolled position and restore when needed + """ + return self._scrollval + + def set_vertical_pos(self, position): + """ + Used to save the scrolled position and restore when needed + """ + self._view.scroll_to(position) + + def can_zoom_in(self): + ''' + Returns True if it is possible to zoom in further + ''' + if self.scale < 4: + return True + else: + return False + + def can_zoom_out(self): + ''' + Returns True if it is possible to zoom out further + ''' + if self.scale > 0.5: + return True + else: + return False + + def get_current_page(self): + ''' + Returns the currently loaded page + ''' + return self._loaded_page + + def get_current_file(self): + ''' + Returns the currently loaded XML file + ''' + # return self._loaded_filename + if self._paginator: + return self._paginator.get_file_for_pageno(self._loaded_page) + else: + return None + + def get_pagecount(self): + ''' + Returns the pagecount of the loaded file + ''' + return self._pagecount + + def set_current_page(self, n): + ''' + Loads page number n + ''' + if n < 1 or n > self._pagecount: + return False + self._load_page(n) + return True + + def next_page(self): + ''' + Loads next page if possible + Returns True if transition to next page is possible and done + ''' + if self._loaded_page == self._pagecount: + return False + self._load_next_page() + return True + + def previous_page(self): + ''' + Loads previous page if possible + Returns True if transition to previous page is possible and done + ''' + if self._loaded_page == 1: + return False + self._load_prev_page() + return True + + def scroll(self, scrolltype, horizontal): + ''' + Scrolls through the pages. + Scrolling is horizontal if horizontal is set to True + Valid scrolltypes are: + Gtk.ScrollType.PAGE_BACKWARD, Gtk.ScrollType.PAGE_FORWARD, + Gtk.ScrollType.STEP_BACKWARD, Gtk.ScrollType.STEP_FORWARD + Gtk.ScrollType.STEP_START and Gtk.ScrollType.STEP_END + ''' + if scrolltype == Gtk.ScrollType.PAGE_BACKWARD: + pages = self._paginator.get_pagecount_for_file(self._loaded_filename) + self._view.scroll_by(self._page_height / pages * -1) + elif scrolltype == Gtk.ScrollType.PAGE_FORWARD: + pages = self._paginator.get_pagecount_for_file(self._loaded_filename) + self._view.scroll_by(self._page_height / pages * 1) + elif scrolltype == Gtk.ScrollType.STEP_BACKWARD: + self._view.scroll_by(self._view.get_settings().get_default_font_size() * -3) + elif scrolltype == Gtk.ScrollType.STEP_FORWARD: + self._view.scroll_by(self._view.get_settings().get_default_font_size() * 3) + elif scrolltype == Gtk.ScrollType.START: + self.set_current_page(0) + elif scrolltype == Gtk.ScrollType.END: + self.__scroll_to_end = True + self.set_current_page(self._pagecount - 1) + else: + print('Got unsupported scrolltype %s' % str(scrolltype)) + + def __touch_page_changed_cb(self, widget, forward): + if forward: + self.scroll(Gtk.ScrollType.PAGE_FORWARD, False) + else: + self.scroll(Gtk.ScrollType.PAGE_BACKWARD, False) + + def copy(self): + ''' + Copies the current selection to clipboard. + ''' + self._view.run_javascript('document.execCommand("copy")') + + def find_next(self): + ''' + Highlights the next matching item for current search + ''' + self._view.grab_focus() + self.__search_fwd = True + self._view.get_find_controller().search_next() + + def find_previous(self): + ''' + Highlights the previous matching item for current search + ''' + self._view.grab_focus() + self.__search_fwd = False + self._view.get_find_controller().search_previous() + + def _find_failed_cb(self, find_controller): + try: + if self.__search_fwd: + path = os.path.join(self._epub.get_basedir(), + self._findjob.get_next_file()) + else: + path = os.path.join(self._epub.get_basedir(), + self._findjob.get_prev_file()) + self.__in_search = True + self._load_file(path) + except IndexError: + # No match anywhere, no other file to pick + pass + + def _find_changed(self, job): + self._view.grab_focus() + self._findjob = job + find = self._view.get_find_controller() + find.search (self._findjob.get_search_text(), + self._findjob.get_flags(), + GObject.G_MAXUINT) + + def __set_zoom(self, value): + self._view.set_zoom_level(value) + self.scale = value + + def _view_scrolled_cb(self, view, scrollval): + if self._loaded_page < 1: + return + + self._scrollval = scrollval + scroll_upper = self._page_height + scroll_page_size = self._view.get_allocated_height() + + if scrollval > 0: + scrollfactor = scrollval / (scroll_upper - scroll_page_size) + else: + scrollfactor = 0 + + if not self._loaded_page == self._pagecount and \ + not self._paginator.get_file_for_pageno(self._loaded_page) != \ + self._paginator.get_file_for_pageno(self._loaded_page + 1): + + scrollfactor_next = \ + self._paginator.get_scrollfactor_pos_for_pageno( + self._loaded_page + 1) + if scrollfactor >= scrollfactor_next: + self._on_page_changed(self._loaded_page, self._loaded_page + 1) + return + + if self._loaded_page > 1 and \ + not self._paginator.get_file_for_pageno(self._loaded_page) != \ + self._paginator.get_file_for_pageno(self._loaded_page - 1): + + scrollfactor_cur = \ + self._paginator.get_scrollfactor_pos_for_pageno( + self._loaded_page) + if scrollfactor <= scrollfactor_cur: + self._on_page_changed(self._loaded_page, self._loaded_page - 1) + return + + def _view_scrolled_top_cb(self, view): + if self._loaded_page > 1: + self.__scroll_to_end = True + self._load_prev_page() + + def _view_scrolled_bottom_cb(self, view): + if self._loaded_page < self._pagecount: + self._load_next_page() + + def _view_selection_changed_cb(self, view, has_selection): + self._has_selection = has_selection + self.emit('selection-changed') + + def _eventbox_scroll_event_cb(self, view, event): + if event.direction == Gdk.ScrollDirection.DOWN: + self.scroll(Gtk.ScrollType.STEP_FORWARD, False) + elif event.direction == Gdk.ScrollDirection.UP: + self.scroll(Gtk.ScrollType.STEP_BACKWARD, False) + + def _view_load_changed_cb(self, v, load_event): + if load_event != WebKit2.LoadEvent.FINISHED: + return True + + filename = self._view.props.uri.replace('file://', '') + if os.path.exists(filename.replace('xhtml', 'xml')): + # Hack for making javascript work + filename = filename.replace('xhtml', 'xml') + + filename = filename.split('#')[0] # Get rid of anchors + + if self._loaded_page < 1 or filename is None: + return False + + self._loaded_filename = filename + + remfactor = self._paginator.get_remfactor_for_file(filename) + pages = self._paginator.get_pagecount_for_file(filename) + extra = int(math.ceil( + remfactor * self._view.get_page_height() / (pages - remfactor))) + if extra > 0: + self._view.add_bottom_padding(extra) + self._page_height = self._view.get_page_height() + + if self.__in_search: + self.__in_search = False + find = self._view.get_find_controller() + find.search (self._findjob.get_search_text(), + self._findjob.get_flags(self.__search_fwd), + GObject.G_MAXUINT) + else: + self._scroll_page() + + # process_file = True + if self._internal_link is not None: + self._view.go_to_link(self._internal_link) + vertical_pos = \ + self._view.get_vertical_position_element(self._internal_link) + # set the page number based in the vertical position + initial_page = self._paginator.get_base_pageno_for_file(filename) + self._loaded_page = initial_page + int( + vertical_pos / self._paginator.get_single_page_height()) + + # There are epub files, created with Calibre, + # where the link in the index points to the end of the previos + # file to the needed chapter. + # if the link is at the bottom of the page, we open the next file + one_page_height = self._paginator.get_single_page_height() + self._internal_link = None + if vertical_pos > self._page_height - one_page_height: + logging.error('bottom page link, go to next file') + next_file = self._paginator.get_next_filename(filename) + if next_file is not None: + logging.error('load next file %s', next_file) + self.__in_search = False + self.__scroll_to_end = False + # process_file = False + GObject.idle_add(self._load_file, next_file) + +# if process_file: +# # prepare text to speech +# html_file = open(self._loaded_filename) +# soup = BeautifulSoup.BeautifulSoup(html_file) +# body = soup.find('body') +# tags = body.findAll(text=True) +# self._all_text = ''.join([tag for tag in tags]) +# self._prepare_text_to_speech(self._all_text) + + def _prepare_text_to_speech(self, page_text): + i = 0 + j = 0 + word_begin = 0 + word_end = 0 + ignore_chars = [' ', '\n', '\r', '_', '[', '{', ']', '}', '|', + '<', '>', '*', '+', '/', '\\'] + ignore_set = set(ignore_chars) + self.word_tuples = [] + len_page_text = len(page_text) + while i < len_page_text: + if page_text[i] not in ignore_set: + word_begin = i + j = i + while j < len_page_text and page_text[j] not in ignore_set: + j = j + 1 + word_end = j + i = j + word_tuple = (word_begin, word_end, + page_text[word_begin: word_end]) + if word_tuple[2] != '\r': + self.word_tuples.append(word_tuple) + i = i + 1 + + def _scroll_page(self): + v_upper = self._page_height + if self.__scroll_to_end: + # We need to scroll to the last page + scrollval = v_upper + self.__scroll_to_end = False + else: + pageno = self._loaded_page + scrollfactor = self._paginator.get_scrollfactor_pos_for_pageno(pageno) + scrollval = math.ceil(v_upper * scrollfactor) + self._view.scroll_to(scrollval) + + def _paginate(self): + filelist = [] + for i in self._epub._navmap.get_flattoc(): + filelist.append(os.path.join(self._epub._tempdir, i)) + # init files info + self._filelist = filelist + self._paginator = _Paginator(filelist) + self._paginator.connect('paginated', self._paginated_cb) + + def get_filelist(self): + return self._filelist + + def get_tempdir(self): + return self._epub._tempdir + + def _load_next_page(self): + self._load_page(self._loaded_page + 1) + + def _load_prev_page(self): + self._load_page(self._loaded_page - 1) + + def _on_page_changed(self, oldpage, pageno): + if oldpage == pageno: + return + self.__page_changed = True + self._loaded_page = pageno + self._scrollbar.handler_block(self._scrollbar_change_value_cb_id) + self._scrollbar.set_value(pageno) + self._scrollbar.handler_unblock(self._scrollbar_change_value_cb_id) + # the indexes in read activity are zero based + self.emit('page-changed', (oldpage - 1), (pageno - 1)) + + def _load_page(self, pageno): + if pageno > self._pagecount or pageno < 1: + # TODO: Cause an exception + return + if self._loaded_page == pageno: + return + + oldpage = self._loaded_page + + filename = self._paginator.get_file_for_pageno(pageno) + filename = filename.replace('file://', '') + + if filename != self._loaded_filename: + self._loaded_filename = filename + + """ + TODO: disabled because javascript can't be executed + with the velocity needed + # Copy javascript to highligth text to speech + destpath, destname = os.path.split(filename.replace('file://', '')) + shutil.copy('./epubview/highlight_words.js', destpath) + self._insert_js_reference(filename.replace('file://', ''), + destpath) + IMPORTANT: Find a way to do this without modify the files + now text highlight is implemented and the epub file is saved + """ + + self._view.stop_loading() + if filename.endswith('xml'): + dest = filename.replace('xml', 'xhtml') + if not os.path.exists(dest): + os.symlink(filename, dest) + self._view.load_uri('file://' + dest) + else: + self._view.load_uri('file://' + filename) + else: + self._loaded_page = pageno + self._scroll_page() + self._on_page_changed(oldpage, pageno) + + def _insert_js_reference(self, file_name, path): + js_reference = '' + o = open(file_name + '.tmp', 'a') + for line in open(file_name): + line = line.replace('', js_reference + '') + o.write(line + "\n") + o.close() + shutil.copy(file_name + '.tmp', file_name) + + def _load_file(self, path): + self._internal_link = None + if path.find('#') > -1: + self._internal_link = path[path.find('#'):] + path = path[:path.find('#')] + + for filepath in self._filelist: + if filepath.endswith(path): + self._view.load_uri('file://' + filepath) + oldpage = self._loaded_page + self._loaded_page = \ + self._paginator.get_base_pageno_for_file(filepath) + self._scroll_page() + self._on_page_changed(oldpage, self._loaded_page) + break + + def _scrollbar_change_value_cb(self, range, scrolltype, value): + if scrolltype == Gtk.ScrollType.STEP_FORWARD or \ + scrolltype == Gtk.ScrollType.STEP_BACKWARD: + self.scroll(scrolltype, False) + elif scrolltype == Gtk.ScrollType.JUMP or \ + scrolltype == Gtk.ScrollType.PAGE_FORWARD or \ + scrolltype == Gtk.ScrollType.PAGE_BACKWARD: + if value > self._scrollbar.props.adjustment.props.upper: + self._load_page(self._pagecount) + else: + self._load_page(int(value)) + else: + print('Warning: unknown scrolltype %s with value %f' \ + % (str(scrolltype), value)) + + # FIXME: This should not be needed here + self._scrollbar.set_value(self._loaded_page) + + if self.__page_changed: + self.__page_changed = False + return False + else: + return True + + def _paginated_cb(self, object): + self._ready = True + + self._pagecount = self._paginator.get_total_pagecount() + self._scrollbar.set_range(1.0, self._pagecount) + self._scrollbar.set_increments(1.0, 1.0) + self._view.grab_focus() + self._view.grab_default() + + def _destroy_cb(self, widget): + self._epub.close() diff --git a/epubview/highlight_words.js b/epubview/highlight_words.js new file mode 100644 index 0000000..ffa5e9a --- /dev/null +++ b/epubview/highlight_words.js @@ -0,0 +1,89 @@ + var parentElement; + var actualChild; + var actualWord; + var words; + var originalNode = null; + var modifiedNode = null; + + function trim(s) { + s = ( s || '' ).replace( /^\s+|\s+$/g, '' ); + return s.replace(/[\n\r\t]/g,' '); + } + + + function init() { + parentElement = document.getElementsByTagName("body")[0]; + actualChild = new Array(); + actualWord = 0; + actualChild.push(0); + } + + function highLightNextWordInt() { + var nodeList = parentElement.childNodes; + ini_posi = actualChild[actualChild.length - 1]; + for (var i=ini_posi; i < nodeList.length; i++) { + var node = nodeList[i]; + if ((node.nodeName == "#text") && (trim(node.nodeValue) != '')) { + node_text = trim(node.nodeValue); + words = node_text.split(" "); + if (actualWord < words.length) { + originalNode = document.createTextNode(node.nodeValue); + + prev_text = ''; + for (var p1 = 0; p1 < actualWord; p1++) { + prev_text = prev_text + words[p1] + " "; + } + var textNode1 = document.createTextNode(prev_text); + var textNode2 = document.createTextNode(words[actualWord]+" "); + post_text = ''; + for (var p2 = actualWord + 1; p2 < words.length; p2++) { + post_text = post_text + words[p2] + " "; + } + var textNode3 = document.createTextNode(post_text); + var newParagraph = document.createElement('p'); + var boldNode = document.createElement('b'); + boldNode.appendChild(textNode2); + newParagraph.appendChild(textNode1); + newParagraph.appendChild(boldNode); + newParagraph.appendChild(textNode3); + + parentElement.insertBefore(newParagraph, node); + parentElement.removeChild(node); + modifiedNode = newParagraph; + + actualWord = actualWord + 1; + if (actualWord >= words.length) { + actualChild.pop(); + actualChild[actualChild.length - 1] = actualChild[actualChild.length - 1] + 2; + actualWord = 0; + parentElement = parentElement.parentNode; + } + } + throw "exit"; + } else { + if (node.childNodes.length > 0) { + parentElement = node; + actualChild.push(0); + actualWord = 0; + highLightNextWordInt(); + actualChild.pop(); + } + } + } + return; + } + + + function highLightNextWord() { + if (typeof parentElement == "undefined") { + init(); + } + if (originalNode != null) { + modifiedNode.parentNode.insertBefore(originalNode, modifiedNode); + modifiedNode.parentNode.removeChild(modifiedNode); + } + try { + highLightNextWordInt(); + } catch(er) { + } + } diff --git a/epubview/jobs.py b/epubview/jobs.py new file mode 100644 index 0000000..f9bb9b0 --- /dev/null +++ b/epubview/jobs.py @@ -0,0 +1,340 @@ +# Copyright 2009 One Laptop Per Child +# Author: Sayamindu Dasgupta +# WebKit2 port Copyright (C) 2018 Lubomir Rintel +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gi +gi.require_version('WebKit2', '4.0') + +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import WebKit2 +from . import widgets +import math +import os.path +import xml.etree.ElementTree as etree +import html.entities as html_entities + +import threading + +PAGE_WIDTH = 135 +PAGE_HEIGHT = 216 + + +def _pixel_to_mm(pixel, dpi): + inches = pixel / dpi + return int(inches / 0.03937) + + +def _mm_to_pixel(mm, dpi): + inches = mm * 0.03937 + return int(inches * dpi) + + +class SearchThread(threading.Thread): + + def __init__(self, obj): + threading.Thread.__init__(self) + self.obj = obj + self.stopthread = threading.Event() + + def _start_search(self): + for entry in self.obj.flattoc: + if self.stopthread.isSet(): + break + filepath = os.path.join(self.obj._document.get_basedir(), entry) + f = open(filepath) + if self._searchfile(f): + self.obj._matchfilelist.append(entry) + f.close() + + self.obj._finished = True + GObject.idle_add(self.obj.emit, 'updated') + + return False + + def _searchfile(self, fileobj): + parser = etree.XMLParser(html=1) + for name, codepoint in html_entities.name2codepoint.items(): + parser.entity[name] = chr(codepoint) + tree = etree.parse(fileobj, parser=parser) + root = tree.getroot() + + body = None + for child in root: + if child.tag.endswith('body'): + body = child + + if body is None: + return False + + for child in body.iter(): + if child.text is not None: + if child.text.lower().find(self.obj._text.lower()) > -1: + return True + + return False + + def run(self): + self._start_search() + + def stop(self): + self.stopthread.set() + + +class _JobPaginator(GObject.GObject): + + __gsignals__ = { + 'paginated': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])), + } + + def __init__(self, filelist): + GObject.GObject.__init__(self) + + self._filelist = filelist + self._filedict = {} + self._pagemap = {} + + self._bookheight = 0 + self._count = 0 + self._pagecount = 0 + + # TODO + """ + self._screen = Gdk.Screen.get_default() + self._old_fontoptions = self._screen.get_font_options() + options = cairo.FontOptions() + options.set_hint_style(cairo.HINT_STYLE_MEDIUM) + options.set_antialias(cairo.ANTIALIAS_GRAY) + options.set_subpixel_order(cairo.SUBPIXEL_ORDER_DEFAULT) + options.set_hint_metrics(cairo.HINT_METRICS_DEFAULT) + self._screen.set_font_options(options) + """ + + self._temp_win = Gtk.Window() + self._temp_view = widgets._WebView() + + settings = self._temp_view.get_settings() + settings.props.default_font_family = 'DejaVu LGC Serif' + settings.props.sans_serif_font_family = 'DejaVu LGC Sans' + settings.props.serif_font_family = 'DejaVu LGC Serif' + settings.props.monospace_font_family = 'DejaVu LGC Sans Mono' + # FIXME: This does not seem to work + # settings.props.auto_shrink_images = False + settings.props.enable_plugins = False + settings.props.default_font_size = 16 + settings.props.default_monospace_font_size = 13 + settings.props.default_charset = 'utf-8' + + self._dpi = Gdk.Screen.get_default().get_resolution() + self._single_page_height = _mm_to_pixel(PAGE_HEIGHT, self._dpi) + self._temp_view.set_size_request(_mm_to_pixel(PAGE_WIDTH, self._dpi), self._single_page_height) + + self._temp_win.add(self._temp_view) + self._temp_view.connect('load-changed', self._page_load_changed_cb) + + self._temp_win.show_all() + self._temp_win.unmap() + + self._temp_view.load_uri('file://' + self._filelist[self._count]) + + def get_single_page_height(self): + """ + Returns the height in pixels of a single page + """ + return self._single_page_height + + def get_next_filename(self, actual_filename): + for n in range(len(self._filelist)): + filename = self._filelist[n] + if filename == actual_filename: + if n < len(self._filelist): + return self._filelist[n + 1] + return None + + def _page_load_changed_cb(self, v, load_event): + if load_event != WebKit2.LoadEvent.FINISHED: + return True + + pageheight = v.get_page_height() + + if pageheight <= self._single_page_height: + pages = 1 + else: + pages = pageheight / float(self._single_page_height) + for i in range(1, int(math.ceil(pages) + 1)): + if pages - i < 0: + pagelen = (pages - math.floor(pages)) / pages + else: + pagelen = 1 / pages + self._pagemap[float(self._pagecount + i)] = \ + (v.get_uri(), (i - 1) / math.ceil(pages), pagelen) + + self._pagecount += int(math.ceil(pages)) + self._filedict[v.get_uri().replace('file://', '')] = \ + (math.ceil(pages), math.ceil(pages) - pages) + self._bookheight += pageheight + + if self._count + 1 >= len(self._filelist): + # TODO + # self._screen.set_font_options(self._old_fontoptions) + self.emit('paginated') + GObject.idle_add(self._cleanup) + + else: + self._count += 1 + self._temp_view.load_uri('file://' + self._filelist[self._count]) + + def _cleanup(self): + self._temp_win.destroy() + + def get_file_for_pageno(self, pageno): + ''' + Returns the file in which pageno occurs + ''' + return self._pagemap[pageno][0] + + def get_scrollfactor_pos_for_pageno(self, pageno): + ''' + Returns the position scrollfactor (fraction) for pageno + ''' + return self._pagemap[pageno][1] + + def get_scrollfactor_len_for_pageno(self, pageno): + ''' + Returns the length scrollfactor (fraction) for pageno + ''' + return self._pagemap[pageno][2] + + def get_pagecount_for_file(self, filename): + ''' + Returns the number of pages in file + ''' + return self._filedict[filename][0] + + def get_base_pageno_for_file(self, filename): + ''' + Returns the pageno which begins in filename + ''' + for key in list(self._pagemap.keys()): + if self._pagemap[key][0].replace('file://', '') == filename: + return key + + return None + + def get_remfactor_for_file(self, filename): + ''' + Returns the remainder + factor (1 - fraction length of last page in file) + ''' + return self._filedict[filename][1] + + def get_total_pagecount(self): + ''' + Returns the total pagecount for the Epub file + ''' + return self._pagecount + + def get_total_height(self): + ''' + Returns the total height of the Epub in pixels + ''' + return self._bookheight + + +class _JobFind(GObject.GObject): + __gsignals__ = { + 'updated': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])), + } + + def __init__(self, document, start_page, n_pages, text, + case_sensitive=False): + """ + Only case_sensitive=False is implemented + """ + GObject.GObject.__init__(self) + + self._finished = False + self._document = document + self._start_page = start_page + self._n_pages = n_pages + self._text = text + self._case_sensitive = case_sensitive + self.flattoc = self._document.get_flattoc() + self._matchfilelist = [] + self._current_file_index = 0 + self.threads = [] + + s_thread = SearchThread(self) + self.threads.append(s_thread) + s_thread.start() + + def cancel(self): + ''' + Cancels the search job + ''' + for s_thread in self.threads: + s_thread.stop() + + def is_finished(self): + ''' + Returns True if the entire search job has been finished + ''' + return self._finished + + def get_next_file(self): + ''' + Returns the next file which has the search pattern + ''' + self._current_file_index += 1 + try: + path = self._matchfilelist[self._current_file_index] + except IndexError: + self._current_file_index = 0 + path = self._matchfilelist[self._current_file_index] + + return path + + def get_prev_file(self): + ''' + Returns the previous file which has the search pattern + ''' + self._current_file_index -= 1 + try: + path = self._matchfilelist[self._current_file_index] + except IndexError: + self._current_file_index = -1 + path = self._matchfilelist[self._current_file_index] + + return path + + def get_search_text(self): + ''' + Returns the search text + ''' + return self._text + + def get_flags(self, forward=True): + ''' + Returns the search flags + ''' + flags = WebKit2.FindOptions.NONE + if self._case_sensitive: + flags = flags | WebKit2.FindOptions.CASE_INSENSITIVE + if not forward: + flags = flags | WebKit2.FindOptions.BACKWARDS + return flags diff --git a/epubview/navmap.py b/epubview/navmap.py new file mode 100644 index 0000000..bbb1f44 --- /dev/null +++ b/epubview/navmap.py @@ -0,0 +1,102 @@ +import xml.etree.ElementTree as etree +from gi.repository import Gtk + + +class NavPoint(object): + + def __init__(self, label, contentsrc, children=[]): + self._label = label + self._contentsrc = contentsrc + self._children = children + + def get_label(self): + return self._label + + def get_contentsrc(self): + return self._contentsrc + + def get_children(self): + return self._children + + +class NavMap(object): + def __init__(self, opffile, ncxfile, basepath): + self._basepath = basepath + self._opffile = opffile + self._tree = etree.parse(ncxfile) + self._root = self._tree.getroot() + self._gtktreestore = Gtk.TreeStore(str, str) + self._flattoc = [] + + self._populate_flattoc() + self._populate_toc() + + def _populate_flattoc(self): + tree = etree.parse(self._opffile) + root = tree.getroot() + + itemmap = {} + manifest = root.find('.//{http://www.idpf.org/2007/opf}manifest') + for element in manifest.iterfind('{http://www.idpf.org/2007/opf}item'): + itemmap[element.get('id')] = element + + spine = root.find('.//{http://www.idpf.org/2007/opf}spine') + for element in spine.iterfind('{http://www.idpf.org/2007/opf}itemref'): + idref = element.get('idref') + href = itemmap[idref].get('href') + self._flattoc.append(self._basepath + href) + + self._opffile.close() + + def _populate_toc(self): + navmap = self._root.find( + '{http://www.daisy.org/z3986/2005/ncx/}navMap') + for navpoint in navmap.iterfind( + './{http://www.daisy.org/z3986/2005/ncx/}navPoint'): + self._process_navpoint(navpoint) + + def _gettitle(self, navpoint): + text = navpoint.find( + './{http://www.daisy.org/z3986/2005/ncx/}' + + 'navLabel/{http://www.daisy.org/z3986/2005/ncx/}text') + return text.text + + def _getcontent(self, navpoint): + text = navpoint.find( + './{http://www.daisy.org/z3986/2005/ncx/}content') + if text is not None: + return self._basepath + text.get('src') + else: + return "" + + def _process_navpoint(self, navpoint, parent=None): + title = self._gettitle(navpoint) + content = self._getcontent(navpoint) + + # print title, content + + iter = self._gtktreestore.append(parent, [title, content]) + # self._flattoc.append((title, content)) + + childnavpointlist = list(navpoint.iterfind( + './{http://www.daisy.org/z3986/2005/ncx/}navPoint')) + + if len(childnavpointlist): + for childnavpoint in childnavpointlist: + self._process_navpoint(childnavpoint, parent=iter) + else: + return + + def get_gtktreestore(self): + ''' + Returns a GtkTreeModel representation of the + Epub table of contents + ''' + return self._gtktreestore + + def get_flattoc(self): + ''' + Returns a flat (linear) list of files to be + rendered. + ''' + return self._flattoc diff --git a/epubview/widgets.py b/epubview/widgets.py new file mode 100644 index 0000000..fa68bd9 --- /dev/null +++ b/epubview/widgets.py @@ -0,0 +1,190 @@ +import logging + +import gi +gi.require_version('WebKit2', '4.0') +gi.require_version('Gtk', '3.0') + +from gi.repository import GLib +from gi.repository import WebKit2 +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject + +class _WebView(WebKit2.WebView): + + __gsignals__ = { + 'touch-change-page': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([bool])), + 'scrolled': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([float])), + 'scrolled-top': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([])), + 'scrolled-bottom': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([])), + 'selection-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, + ([bool])), + } + + def __init__(self, **kwargs): + cm = WebKit2.UserContentManager() + + cm.register_script_message_handler('scrolled'); + cm.connect('script-message-received::scrolled', + lambda cm, result: self.emit('scrolled', + result.get_js_value().to_double())) + + cm.register_script_message_handler('scrolled_top'); + cm.connect('script-message-received::scrolled_top', + lambda cm, result: self.emit('scrolled-top')) + + cm.register_script_message_handler('scrolled_bottom'); + cm.connect('script-message-received::scrolled_bottom', + lambda cm, result: self.emit('scrolled-bottom')) + + cm.register_script_message_handler('selection_changed'); + cm.connect('script-message-received::selection_changed', + lambda cm, result: self.emit('selection-changed', + result.get_js_value().to_boolean())) + + cm.add_script(WebKit2.UserScript(''' + window.addEventListener("scroll", function(){ + var handler = window.webkit.messageHandlers.scrolled; + handler.postMessage(window.scrollY); + }); + document.addEventListener("selectionchange", function() { + var handler = window.webkit.messageHandlers.selection_changed; + handler.postMessage(window.getSelection() != ''); + }); + ''', + WebKit2.UserContentInjectedFrames.ALL_FRAMES, + WebKit2.UserScriptInjectionTime.START, None, None)) + + cm.add_style_sheet(WebKit2.UserStyleSheet(''' + html { margin: 50px; } + body { overflow: hidden; } + ''', + WebKit2.UserContentInjectedFrames.ALL_FRAMES, + WebKit2.UserStyleLevel.USER, None, None)) + + WebKit2.WebView.__init__(self, user_content_manager=cm, **kwargs) + self.get_settings().set_enable_write_console_messages_to_stdout(True) + + def do_context_menu (self, context_menu, event, hit_test_result): + # nope nope nope nopenopenopenenope + return True + + def setup_touch(self): + self.get_window().set_events( + self.get_window().get_events() | Gdk.EventMask.TOUCH_MASK) + self.connect('event', self.__event_cb) + + def __event_cb(self, widget, event): + if event.type == Gdk.EventType.TOUCH_BEGIN: + x = event.touch.x + view_width = widget.get_allocation().width + if x > view_width * 3 / 4: + self.emit('touch-change-page', True) + elif x < view_width * 1 / 4: + self.emit('touch-change-page', False) + + def _execute_script_sync(self, js): + ''' + This sad function aims to provide synchronous script execution like + WebKit-1.0's WebView.execute_script() to ease porting. + ''' + res = ["0"] + + def callback(self, task, user_data): + Gtk.main_quit() + result = self.run_javascript_finish(task) + if result is not None: + res[0] = result.get_js_value().to_string() + + self.run_javascript(js, None, callback, None) + Gtk.main() + return res[0] + + def get_page_height(self): + ''' + Gets height (in pixels) of loaded (X)HTML page. + This is done via javascript at the moment + ''' + return int(self._execute_script_sync(''' + (function(){ + if (document.body == null) { + return 0; + } else { + return Math.max(document.body.scrollHeight, + document.body.offsetHeight, + document.documentElement.clientHeight, + document.documentElement.scrollHeight, + document.documentElement.offsetHeight); + }; + })() + ''')) + + def add_bottom_padding(self, incr): + ''' + Adds incr pixels of margin to the end of the loaded (X)HTML page. + ''' + self.run_javascript('document.body.style.marginBottom = "%dpx";' % (incr + 50)) + + def highlight_next_word(self): + ''' + Highlight next word (for text to speech) + ''' + self.run_javascript('highLightNextWord();') + + def go_to_link(self, id_link): + self.run_javascript('window.location.href = "%s";' % id_link) + + def get_vertical_position_element(self, id_link): + ''' + Get the vertical position of a element, in pixels + ''' + # remove the first '#' char + id_link = id_link[1:] + return int(self._execute_script_sync(''' + (function(id_link){ + var obj = document.getElementById(id_link); + var top = 0; + if (obj.offsetParent) { + while(1) { + top += obj.offsetTop; + if (!obj.offsetParent) { + break; + }; + obj = obj.offsetParent; + }; + } else if (obj.y) { + top += obj.y; + } + return top; + })("%s") + ''' % id_link)) + + def scroll_to(self, to): + ''' + Set the vertical position in a document to a value in pixels. + ''' + self.run_javascript('window.scrollTo(-1, %d);' % to) + + def scroll_by(self, by): + ''' + Modify the vertical position in a document by a value in pixels. + ''' + self.run_javascript(''' + (function(by){ + var before = window.scrollY; + window.scrollBy(0, by); + if (window.scrollY == before) { + if (by < 0) { + var handler = window.webkit.messageHandlers.scrolled_top; + handler.postMessage(window.scrollY); + } else if (by > 0) { + var handler = window.webkit.messageHandlers.scrolled_bottom; + handler.postMessage(window.scrollY); + } + } + }(%d)) + ''' % by) diff --git a/evinceadapter.py b/evinceadapter.py index c3d7421..61f86f4 100644 --- a/evinceadapter.py +++ b/evinceadapter.py @@ -55,7 +55,7 @@ try: self._document = \ EvinceDocument.Document.factory_get_document(file_path) - except GObject.GError, e: + except GObject.GError as e: _logger.error('Can not load document: %s', e) return else: @@ -94,12 +94,12 @@ 'icon-color': profile.get_color().to_string(), 'mime_type': 'text/uri-list', } - for k, v in metadata.items(): + for k, v in list(metadata.items()): jobject.metadata[k] = v file_path = os.path.join(get_activity_root(), 'instance', '%i_' % time.time()) open(file_path, 'w').write(url + '\r\n') - os.chmod(file_path, 0755) + os.chmod(file_path, 0o755) jobject.set_file_path(file_path) datastore.write(jobject) show_object_in_journal(jobject.object_id) @@ -364,7 +364,7 @@ Gtk.ScrollType.STEP_BACKWARD, Gtk.ScrollType.STEP_FORWARD, Gtk.ScrollType.START and Gtk.ScrollType.END ''' - _logger.error('scroll: %s', scrolltype) + _logger.debug('scroll: %s', scrolltype) if scrolltype == Gtk.ScrollType.PAGE_BACKWARD: self._view.scroll(Gtk.ScrollType.PAGE_BACKWARD, horizontal) @@ -379,7 +379,7 @@ elif scrolltype == Gtk.ScrollType.END: self.set_current_page(self._document.get_n_pages()) else: - print ('Got unsupported scrolltype %s' % str(scrolltype)) + print('Got unsupported scrolltype %s' % str(scrolltype)) def _scroll_step(self, forward, horizontal): if horizontal: diff --git a/icons/dark-theme.svg b/icons/dark-theme.svg new file mode 100644 index 0000000..6a44324 --- /dev/null +++ b/icons/dark-theme.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + A + + diff --git a/icons/light-theme.svg b/icons/light-theme.svg new file mode 100644 index 0000000..8dea23f --- /dev/null +++ b/icons/light-theme.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + A + + diff --git a/linkbutton.py b/linkbutton.py index 3979f07..078832e 100644 --- a/linkbutton.py +++ b/linkbutton.py @@ -19,7 +19,7 @@ from gi.repository import Gdk from gi.repository import GObject -import StringIO +import io import cairo from gettext import gettext as _ @@ -42,7 +42,7 @@ # Color read from the Journal may be Unicode, but Rsvg needs # it as single byte string: self._color = color - if isinstance(color, unicode): + if isinstance(color, str): self._color = str(color) self._have_preview = False if buf is not None: @@ -61,7 +61,7 @@ stroke = self._color.split(',')[0] self._have_preview = True img = Gtk.Image() - str_buf = StringIO.StringIO(buf) + str_buf = io.BytesIO(buf) thumb_surface = cairo.ImageSurface.create_from_png(str_buf) bg_width, bg_height = style.zoom(120), style.zoom(110) diff --git a/po/Read.pot b/po/Read.pot index f8835f3..341ceda 100644 --- a/po/Read.pot +++ b/po/Read.pot @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-04-02 15:53+1000\n" +"POT-Creation-Date: 2019-03-07 20:17+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -66,65 +66,65 @@ msgid "Remove" msgstr "" -#: readactivity.py:379 +#: readactivity.py:385 msgid "Please wait" msgstr "" -#: readactivity.py:380 +#: readactivity.py:386 msgid "Starting connection..." msgstr "" -#: readactivity.py:388 +#: readactivity.py:394 msgid "No book" msgstr "" -#: readactivity.py:388 +#: readactivity.py:394 msgid "Choose something to read" msgstr "" -#: readactivity.py:393 +#: readactivity.py:399 msgid "Back" msgstr "" -#: readactivity.py:397 +#: readactivity.py:403 msgid "Previous page" msgstr "" -#: readactivity.py:399 +#: readactivity.py:405 msgid "Previous bookmark" msgstr "" -#: readactivity.py:411 +#: readactivity.py:417 msgid "Forward" msgstr "" -#: readactivity.py:415 +#: readactivity.py:421 msgid "Next page" msgstr "" -#: readactivity.py:417 +#: readactivity.py:423 msgid "Next bookmark" msgstr "" -#: readactivity.py:468 +#: readactivity.py:474 msgid "Index" msgstr "" -#: readactivity.py:564 +#: readactivity.py:570 msgid "Delete bookmark" msgstr "" -#: readactivity.py:565 +#: readactivity.py:571 msgid "All the information related with this bookmark will be lost" msgstr "" -#: readactivity.py:953 +#: readactivity.py:959 msgid "Receiving book..." msgstr "" -#: readactivity.py:1027 readactivity.py:1222 -#, python-format -msgid "%s (Page %d)" +#: readactivity.py:1036 readactivity.py:1229 +#, python-format +msgid "%(title)s (Page %(number)d)" msgstr "" #: readdialog.py:52 @@ -207,6 +207,10 @@ msgid "Rotate right" msgstr "" +#: readtoolbar.py:270 readtoolbar.py:348 +msgid "Inverted Colors" +msgstr "" + #: readtoolbar.py:324 msgid "Show Tray" msgstr "" @@ -215,10 +219,14 @@ msgid "Hide Tray" msgstr "" -#: speechtoolbar.py:55 +#: readtoolbar.py:345 +msgid "Normal Colors" +msgstr "" + +#: speechtoolbar.py:65 msgid "Play / Pause" msgstr "" -#: speechtoolbar.py:63 +#: speechtoolbar.py:73 msgid "Stop" msgstr "" diff --git a/po/agr.po b/po/agr.po deleted file mode 100644 index f8daa09..0000000 --- a/po/agr.po +++ /dev/null @@ -1,223 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: agr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.11.0\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/bi.po b/po/bi.po deleted file mode 100644 index 6d04921..0000000 --- a/po/bi.po +++ /dev/null @@ -1,203 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-11 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.1.1rc4\n" - -#. TRANS: "name" option from activity.info file -msgid "Read" -msgstr "" - -#. TRANS: "summary" option from activity.info file -#. TRANS: "description" option from activity.info file -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#. TRANS: This goes like Bookmark added by User 5 days ago -#. TRANS: (the elapsed string gets translated automatically) -#: bookmarkview.py:110 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:153 bookmarkview.py:204 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:200 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:201 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: evinceadapter.py:88 -msgid "URL from Read" -msgstr "" - -#: linkbutton.py:94 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:99 -msgid "Remove" -msgstr "" - -#: readactivity.py:333 -msgid "No book" -msgstr "" - -#: readactivity.py:333 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:338 -msgid "Back" -msgstr "" - -#: readactivity.py:342 -msgid "Previous page" -msgstr "" - -#: readactivity.py:344 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:356 -msgid "Forward" -msgstr "" - -#: readactivity.py:360 -msgid "Next page" -msgstr "" - -#: readactivity.py:362 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:413 -msgid "Index" -msgstr "" - -#: readactivity.py:534 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:535 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:895 readactivity.py:1090 -#, python-format -msgid "Page %d" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:116 -msgid "Title:" -msgstr "" - -#: readdialog.py:142 -msgid "Details:" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:189 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:198 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:204 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:210 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:216 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:222 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:233 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:301 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:303 -msgid "Hide Tray" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" diff --git a/po/cpp.po b/po/cpp.po deleted file mode 100644 index 6d04921..0000000 --- a/po/cpp.po +++ /dev/null @@ -1,203 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-11 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.1.1rc4\n" - -#. TRANS: "name" option from activity.info file -msgid "Read" -msgstr "" - -#. TRANS: "summary" option from activity.info file -#. TRANS: "description" option from activity.info file -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#. TRANS: This goes like Bookmark added by User 5 days ago -#. TRANS: (the elapsed string gets translated automatically) -#: bookmarkview.py:110 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:153 bookmarkview.py:204 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:200 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:201 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: evinceadapter.py:88 -msgid "URL from Read" -msgstr "" - -#: linkbutton.py:94 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:99 -msgid "Remove" -msgstr "" - -#: readactivity.py:333 -msgid "No book" -msgstr "" - -#: readactivity.py:333 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:338 -msgid "Back" -msgstr "" - -#: readactivity.py:342 -msgid "Previous page" -msgstr "" - -#: readactivity.py:344 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:356 -msgid "Forward" -msgstr "" - -#: readactivity.py:360 -msgid "Next page" -msgstr "" - -#: readactivity.py:362 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:413 -msgid "Index" -msgstr "" - -#: readactivity.py:534 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:535 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:895 readactivity.py:1090 -#, python-format -msgid "Page %d" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:116 -msgid "Title:" -msgstr "" - -#: readdialog.py:142 -msgid "Details:" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:189 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:198 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:204 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:210 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:216 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:222 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:233 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:301 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:303 -msgid "Hide Tray" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" diff --git a/po/da.po b/po/da.po index f09a470..23d7c3c 100644 --- a/po/da.po +++ b/po/da.po @@ -15,8 +15,8 @@ "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: 2017-11-03 09:26+0000\n" -"Last-Translator: dark159123 \n" +"PO-Revision-Date: 2018-10-22 18:39+0000\n" +"Last-Translator: scootergrisen \n" "Language-Team: LANGUAGE \n" "Language: da\n" "MIME-Version: 1.0\n" @@ -24,7 +24,7 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Pootle 2.5.1.1\n" -"X-POOTLE-MTIME: 1509701219.000000\n" +"X-POOTLE-MTIME: 1540233554.000000\n" #: activity/activity.info:2 msgid "Read" @@ -169,7 +169,7 @@ #: readtoolbar.py:209 msgid "Zoom to width" -msgstr "Tilpas til bredde" +msgstr "Zoom til bredde" #: readtoolbar.py:215 msgid "Zoom to fit" diff --git a/po/ff.po b/po/ff.po deleted file mode 100644 index 387d8d2..0000000 --- a/po/ff.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: ff\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/fi.po b/po/fi.po deleted file mode 100644 index 965a059..0000000 --- a/po/fi.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: fi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.1.1rc4\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/gu.po b/po/gu.po deleted file mode 100644 index ba18bb2..0000000 --- a/po/gu.po +++ /dev/null @@ -1,203 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-11 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#. TRANS: "name" option from activity.info file -msgid "Read" -msgstr "" - -#. TRANS: "summary" option from activity.info file -#. TRANS: "description" option from activity.info file -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#. TRANS: This goes like Bookmark added by User 5 days ago -#. TRANS: (the elapsed string gets translated automatically) -#: bookmarkview.py:110 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:153 bookmarkview.py:204 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:200 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:201 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: evinceadapter.py:88 -msgid "URL from Read" -msgstr "" - -#: linkbutton.py:94 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:99 -msgid "Remove" -msgstr "" - -#: readactivity.py:333 -msgid "No book" -msgstr "" - -#: readactivity.py:333 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:338 -msgid "Back" -msgstr "" - -#: readactivity.py:342 -msgid "Previous page" -msgstr "" - -#: readactivity.py:344 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:356 -msgid "Forward" -msgstr "" - -#: readactivity.py:360 -msgid "Next page" -msgstr "" - -#: readactivity.py:362 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:413 -msgid "Index" -msgstr "" - -#: readactivity.py:534 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:535 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:895 readactivity.py:1090 -#, python-format -msgid "Page %d" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:116 -msgid "Title:" -msgstr "" - -#: readdialog.py:142 -msgid "Details:" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:189 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:198 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:204 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:210 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:216 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:222 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:233 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:301 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:303 -msgid "Hide Tray" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" diff --git a/po/ha.po b/po/ha.po deleted file mode 100644 index dda3bbf..0000000 --- a/po/ha.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: ha\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/ibo.po b/po/ibo.po deleted file mode 100644 index 7cef20e..0000000 --- a/po/ibo.po +++ /dev/null @@ -1,223 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: ibo\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.11.0\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/ig.po b/po/ig.po deleted file mode 100644 index ba18bb2..0000000 --- a/po/ig.po +++ /dev/null @@ -1,203 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-11 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#. TRANS: "name" option from activity.info file -msgid "Read" -msgstr "" - -#. TRANS: "summary" option from activity.info file -#. TRANS: "description" option from activity.info file -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#. TRANS: This goes like Bookmark added by User 5 days ago -#. TRANS: (the elapsed string gets translated automatically) -#: bookmarkview.py:110 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:153 bookmarkview.py:204 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:200 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:201 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: evinceadapter.py:88 -msgid "URL from Read" -msgstr "" - -#: linkbutton.py:94 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:99 -msgid "Remove" -msgstr "" - -#: readactivity.py:333 -msgid "No book" -msgstr "" - -#: readactivity.py:333 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:338 -msgid "Back" -msgstr "" - -#: readactivity.py:342 -msgid "Previous page" -msgstr "" - -#: readactivity.py:344 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:356 -msgid "Forward" -msgstr "" - -#: readactivity.py:360 -msgid "Next page" -msgstr "" - -#: readactivity.py:362 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:413 -msgid "Index" -msgstr "" - -#: readactivity.py:534 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:535 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:895 readactivity.py:1090 -#, python-format -msgid "Page %d" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:116 -msgid "Title:" -msgstr "" - -#: readdialog.py:142 -msgid "Details:" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:189 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:198 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:204 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:210 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:216 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:222 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:233 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:301 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:303 -msgid "Hide Tray" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" diff --git a/po/kos.po b/po/kos.po deleted file mode 100644 index e2a58b2..0000000 --- a/po/kos.po +++ /dev/null @@ -1,203 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-11 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.3.0\n" - -#. TRANS: "name" option from activity.info file -msgid "Read" -msgstr "" - -#. TRANS: "summary" option from activity.info file -#. TRANS: "description" option from activity.info file -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#. TRANS: This goes like Bookmark added by User 5 days ago -#. TRANS: (the elapsed string gets translated automatically) -#: bookmarkview.py:110 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:153 bookmarkview.py:204 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:200 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:201 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: evinceadapter.py:88 -msgid "URL from Read" -msgstr "" - -#: linkbutton.py:94 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:99 -msgid "Remove" -msgstr "" - -#: readactivity.py:333 -msgid "No book" -msgstr "" - -#: readactivity.py:333 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:338 -msgid "Back" -msgstr "" - -#: readactivity.py:342 -msgid "Previous page" -msgstr "" - -#: readactivity.py:344 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:356 -msgid "Forward" -msgstr "" - -#: readactivity.py:360 -msgid "Next page" -msgstr "" - -#: readactivity.py:362 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:413 -msgid "Index" -msgstr "" - -#: readactivity.py:534 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:535 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:895 readactivity.py:1090 -#, python-format -msgid "Page %d" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:116 -msgid "Title:" -msgstr "" - -#: readdialog.py:142 -msgid "Details:" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:189 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:198 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:204 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:210 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:216 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:222 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:233 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:301 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:303 -msgid "Hide Tray" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" diff --git a/po/ml.po b/po/ml.po deleted file mode 100644 index f8bead8..0000000 --- a/po/ml.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: ml\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/ms.po b/po/ms.po deleted file mode 100644 index 99db609..0000000 --- a/po/ms.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: ms\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.1.1rc4\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/mvo.po b/po/mvo.po deleted file mode 100644 index dfd8995..0000000 --- a/po/mvo.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: mvo\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.1.1rc4\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/pa.po b/po/pa.po deleted file mode 100644 index dceda3c..0000000 --- a/po/pa.po +++ /dev/null @@ -1,231 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: pa\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/pseudo.po b/po/pseudo.po deleted file mode 100644 index 11168ac..0000000 --- a/po/pseudo.po +++ /dev/null @@ -1,89 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-09 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.0.1\n" - -#: activity/activity.info:2 readactivity.py:129 -msgid "Read" -msgstr "" - -#: readactivity.py:125 -msgid "Edit" -msgstr "" - -#: readactivity.py:137 -msgid "View" -msgstr "" - -#: readactivity.py:223 -msgid "Choose document" -msgstr "" - -#: readtoolbar.py:67 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:74 -msgid "Next" -msgstr "" - -#: readtoolbar.py:140 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:146 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:148 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:160 -msgid "Back" -msgstr "" - -#: readtoolbar.py:167 -msgid "Forward" -msgstr "" - -#: readtoolbar.py:271 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:277 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:283 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:289 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:294 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:312 -msgid "%" -msgstr "" - -#: readtoolbar.py:330 -msgid "Fullscreen" -msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po index ce5bd46..be386ee 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -15,8 +15,8 @@ "Project-Id-Version: pt_BR\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: 2017-06-14 21:01+0000\n" -"Last-Translator: Mariana \n" +"PO-Revision-Date: 2018-09-05 18:37+0000\n" +"Last-Translator: Paulo Francisco \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -24,7 +24,7 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Pootle 2.5.1.1\n" -"X-POOTLE-MTIME: 1497474090.000000\n" +"X-POOTLE-MTIME: 1536172654.000000\n" #: activity/activity.info:2 msgid "Read" @@ -45,7 +45,7 @@ #: readdialog.py:58 msgid "Ok" -msgstr "Confirma" +msgstr "Ok" #: readdialog.py:120 msgid "Title:" @@ -61,7 +61,7 @@ #: evinceadapter.py:92 msgid "URL from Read" -msgstr "URL a partir de Ler" +msgstr "URL de Ler" #: speechtoolbar.py:57 msgid "Play / Pause" @@ -93,7 +93,7 @@ #: readactivity.py:397 msgid "Previous page" -msgstr "página anterior" +msgstr "Página anterior" #: readactivity.py:399 msgid "Previous bookmark" @@ -101,7 +101,7 @@ #: readactivity.py:411 msgid "Forward" -msgstr "Ir adiante" +msgstr "Avançar" #: readactivity.py:415 msgid "Next page" @@ -171,7 +171,7 @@ # baseado na tradução que tenho do Evince #: readtoolbar.py:209 msgid "Zoom to width" -msgstr "Ajustar para largura" +msgstr "Ajustar para largura de tela" #: readtoolbar.py:215 msgid "Zoom to fit" @@ -191,19 +191,19 @@ #: readtoolbar.py:258 msgid "Rotate right" -msgstr "Girar para a direira" +msgstr "Girar para a direita" #: readtoolbar.py:324 msgid "Show Tray" -msgstr "Mostrar Trilha" +msgstr "Mostrar Bandeja" #: readtoolbar.py:326 msgid "Hide Tray" -msgstr "Ocultar Trilha" +msgstr "Ocultar Bandeja" #: linkbutton.py:133 msgid "Go to Bookmark" -msgstr "Vá para os favoritos" +msgstr "Ir para os favoritos" #: linkbutton.py:139 msgid "Remove" @@ -230,7 +230,7 @@ #: comicadapter.py:69 msgid "Can not read Comic Book Archive" -msgstr "Não é possível ler o Arquivo de Histórias em Quadrinhos" +msgstr "Não é possível ler o arquivo de Histórias em Quadrinhos" #: comicadapter.py:70 msgid "No readable images were found" diff --git a/po/tzo.po b/po/tzo.po deleted file mode 100644 index 13ec2d4..0000000 --- a/po/tzo.po +++ /dev/null @@ -1,223 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: tzo\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.7.0\n" - -#: activity/activity.info:2 -msgid "Read" -msgstr "" - -#: activity/activity.info:3 -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:120 -msgid "Title:" -msgstr "" - -#: readdialog.py:147 -msgid "Author:" -msgstr "" - -#: readdialog.py:163 -msgid "Details:" -msgstr "" - -#: evinceadapter.py:92 -msgid "URL from Read" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" - -#: readactivity.py:379 -msgid "Please wait" -msgstr "" - -#: readactivity.py:380 -msgid "Starting connection..." -msgstr "" - -#: readactivity.py:388 -msgid "No book" -msgstr "" - -#: readactivity.py:388 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:393 -msgid "Back" -msgstr "" - -#: readactivity.py:397 -msgid "Previous page" -msgstr "" - -#: readactivity.py:399 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:411 -msgid "Forward" -msgstr "" - -#: readactivity.py:415 -msgid "Next page" -msgstr "" - -#: readactivity.py:417 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:468 -msgid "Index" -msgstr "" - -#: readactivity.py:564 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:565 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:954 -msgid "Receiving book..." -msgstr "" - -#: readactivity.py:1032 readactivity.py:1227 -#, python-format -msgid "%s (Page %d)" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:188 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:197 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:203 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:209 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:215 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:221 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:232 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:252 -msgid "Rotate left" -msgstr "" - -#: readtoolbar.py:258 -msgid "Rotate right" -msgstr "" - -#: readtoolbar.py:324 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:326 -msgid "Hide Tray" -msgstr "" - -#: linkbutton.py:133 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:139 -msgid "Remove" -msgstr "" - -#: bookmarkview.py:107 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:143 bookmarkview.py:192 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:188 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:189 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: comicadapter.py:69 -msgid "Can not read Comic Book Archive" -msgstr "" - -#: comicadapter.py:70 -msgid "No readable images were found" -msgstr "" diff --git a/po/wa.po b/po/wa.po deleted file mode 100644 index 6d04921..0000000 --- a/po/wa.po +++ /dev/null @@ -1,203 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-11 00:31-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.1.1rc4\n" - -#. TRANS: "name" option from activity.info file -msgid "Read" -msgstr "" - -#. TRANS: "summary" option from activity.info file -#. TRANS: "description" option from activity.info file -msgid "" -"Use this activity when you are ready to read! Remember to flip your computer " -"around to feel like you are really holding a book!" -msgstr "" - -#. TRANS: This goes like Bookmark added by User 5 days ago -#. TRANS: (the elapsed string gets translated automatically) -#: bookmarkview.py:110 -#, python-format -msgid "Bookmark added by %(user)s %(time)s" -msgstr "" - -#: bookmarkview.py:153 bookmarkview.py:204 -msgid "Add notes for bookmark: " -msgstr "" - -#: bookmarkview.py:200 -#, python-format -msgid "%s's bookmark" -msgstr "" - -#: bookmarkview.py:201 -#, python-format -msgid "Bookmark for page %d" -msgstr "" - -#: evinceadapter.py:88 -msgid "URL from Read" -msgstr "" - -#: linkbutton.py:94 -msgid "Go to Bookmark" -msgstr "" - -#: linkbutton.py:99 -msgid "Remove" -msgstr "" - -#: readactivity.py:333 -msgid "No book" -msgstr "" - -#: readactivity.py:333 -msgid "Choose something to read" -msgstr "" - -#: readactivity.py:338 -msgid "Back" -msgstr "" - -#: readactivity.py:342 -msgid "Previous page" -msgstr "" - -#: readactivity.py:344 -msgid "Previous bookmark" -msgstr "" - -#: readactivity.py:356 -msgid "Forward" -msgstr "" - -#: readactivity.py:360 -msgid "Next page" -msgstr "" - -#: readactivity.py:362 -msgid "Next bookmark" -msgstr "" - -#: readactivity.py:413 -msgid "Index" -msgstr "" - -#: readactivity.py:534 -msgid "Delete bookmark" -msgstr "" - -#: readactivity.py:535 -msgid "All the information related with this bookmark will be lost" -msgstr "" - -#: readactivity.py:895 readactivity.py:1090 -#, python-format -msgid "Page %d" -msgstr "" - -#: readdialog.py:52 -msgid "Cancel" -msgstr "" - -#: readdialog.py:58 -msgid "Ok" -msgstr "" - -#: readdialog.py:116 -msgid "Title:" -msgstr "" - -#: readdialog.py:142 -msgid "Details:" -msgstr "" - -#: readtoolbar.py:61 -msgid "Previous" -msgstr "" - -#: readtoolbar.py:68 -msgid "Next" -msgstr "" - -#: readtoolbar.py:79 -msgid "Highlight" -msgstr "" - -#: readtoolbar.py:160 -msgid "Find first" -msgstr "" - -#: readtoolbar.py:166 -msgid "Find previous" -msgstr "" - -#: readtoolbar.py:168 -msgid "Find next" -msgstr "" - -#: readtoolbar.py:189 -msgid "Table of contents" -msgstr "" - -#: readtoolbar.py:198 -msgid "Zoom out" -msgstr "" - -#: readtoolbar.py:204 -msgid "Zoom in" -msgstr "" - -#: readtoolbar.py:210 -msgid "Zoom to width" -msgstr "" - -#: readtoolbar.py:216 -msgid "Zoom to fit" -msgstr "" - -#: readtoolbar.py:222 -msgid "Actual size" -msgstr "" - -#: readtoolbar.py:233 -msgid "Fullscreen" -msgstr "" - -#: readtoolbar.py:301 -msgid "Show Tray" -msgstr "" - -#: readtoolbar.py:303 -msgid "Hide Tray" -msgstr "" - -#: speechtoolbar.py:57 -msgid "Play / Pause" -msgstr "" - -#: speechtoolbar.py:65 -msgid "Stop" -msgstr "" diff --git a/po/zh_TW.po b/po/zh_TW.po index 6957d9a..b996ab1 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -11,7 +11,7 @@ "Project-Id-Version: OLPC XBook\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-03-24 17:39+1100\n" -"PO-Revision-Date: 2017-03-25 13:08+0000\n" +"PO-Revision-Date: 2019-01-22 11:46+0000\n" "Last-Translator: Yuan \n" "Language-Team: Yuan CHAO \n" "Language: zh_TW\n" @@ -20,7 +20,7 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Pootle 2.5.1.1\n" -"X-POOTLE-MTIME: 1490447313.000000\n" +"X-POOTLE-MTIME: 1548157587.000000\n" #: activity/activity.info:2 msgid "Read" @@ -46,7 +46,7 @@ #: readdialog.py:147 msgid "Author:" -msgstr "" +msgstr "作者:" #: readdialog.py:163 msgid "Details:" @@ -66,11 +66,11 @@ #: readactivity.py:379 msgid "Please wait" -msgstr "" +msgstr "請稍候" #: readactivity.py:380 msgid "Starting connection..." -msgstr "" +msgstr "開始連線…" #: readactivity.py:388 msgid "No book" @@ -118,12 +118,12 @@ #: readactivity.py:954 msgid "Receiving book..." -msgstr "" +msgstr "接收書本中…" #: readactivity.py:1032 readactivity.py:1227 #, python-format msgid "%s (Page %d)" -msgstr "" +msgstr "%s (第 %d 頁)" #: readtoolbar.py:61 msgid "Previous" @@ -179,11 +179,11 @@ #: readtoolbar.py:252 msgid "Rotate left" -msgstr "" +msgstr "向左旋轉" #: readtoolbar.py:258 msgid "Rotate right" -msgstr "" +msgstr "向右旋轉" #: readtoolbar.py:324 msgid "Show Tray" @@ -222,11 +222,11 @@ #: comicadapter.py:69 msgid "Can not read Comic Book Archive" -msgstr "" +msgstr "無法讀取漫畫書典藏" #: comicadapter.py:70 msgid "No readable images were found" -msgstr "" +msgstr "找不到可以讀取的圖片" #, python-format #~ msgid "Page %d" diff --git a/readactivity.py b/readactivity.py index 38a608d..d65d8b6 100644 --- a/readactivity.py +++ b/readactivity.py @@ -22,8 +22,8 @@ import time from gettext import gettext as _ import re -import md5 -import StringIO +import hashlib +import io import cairo import json @@ -93,11 +93,11 @@ def get_md5(filename): # FIXME: Should be moved somewhere else filename = filename.replace('file://', '') # XXX: hack - fh = open(filename) - digest = md5.new() + fh = open(filename, 'rb') + digest = hashlib.md5() while 1: buf = fh.read(4096) - if buf == "": + if buf == b'': break digest.update(buf) fh.close() @@ -235,9 +235,11 @@ self._view_toolbar.connect('go-fullscreen', self.__view_toolbar_go_fullscreen_cb) self._view_toolbar.connect('toggle-index-show', - self.__toogle_navigator_cb) + self.__toggle_navigator_cb) self._view_toolbar.connect('toggle-tray-show', - self.__toogle_tray_cb) + self.__toggle_tray_cb) + self._view_toolbar.connect('toggle-inverted-colors', + self.__toggle_inverted_colors_cb) view_toolbar_button = ToolbarButton(page=self._view_toolbar, icon_name='toolbar-view') self._view_toolbar.show() @@ -490,7 +492,7 @@ self._toc_model = model self._navigator.set_model(model) - def __toogle_navigator_cb(self, button, visible): + def __toggle_navigator_cb(self, button, visible): scrollbar_pos = -1 if hasattr(self._view, 'get_vertical_pos'): scrollbar_pos = self._view.get_vertical_pos() @@ -509,13 +511,17 @@ if scrollbar_pos > -1: self._view.set_vertical_pos(scrollbar_pos) - def __toogle_tray_cb(self, button, visible): + def __toggle_tray_cb(self, button, visible): if visible: logging.debug('Show tray') self.tray.show() else: logging.debug('Hide tray') self.tray.hide() + + def __toggle_inverted_colors_cb(self, button, active): + if hasattr(self._view._model, 'set_inverted_colors'): + self._view._model.set_inverted_colors(active) def __num_page_entry_insert_text_cb(self, entry, text, length, position): if not re.match('[0-9]', text): @@ -610,7 +616,11 @@ self._forward_button.props.sensitive = \ current_page < self._view.get_pagecount() - 1 + self._num_page_entry.handler_block_by_func( + self.__num_page_entry_insert_text_cb) self._num_page_entry.props.text = str(current_page + 1) + self._num_page_entry.handler_unblock_by_func( + self.__num_page_entry_insert_text_cb) self._set_total_page_label(self._view.get_pagecount()) def _update_toc(self): @@ -679,7 +689,7 @@ chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: - for key in jobject.metadata.keys(): + for key in list(jobject.metadata.keys()): self.metadata[key] = jobject.metadata[key] self.read_file(jobject.file_path) jobject.object_id = self._object_id @@ -763,7 +773,7 @@ self.metadata['Read_search'] = \ self._edit_toolbar._search_entry.props.text - except Exception, e: + except Exception as e: _logger.error('write_file(): %s', e) self.metadata['Read_search'] = \ @@ -785,7 +795,7 @@ self.filehash = get_md5(file_path) self.metadata['filehash'] = self.filehash - self._save_bookmars_in_metadata() + self._save_bookmarks_in_metadata() if self._close_requested: _logger.debug("Removing temp file %s because we will close", @@ -801,7 +811,7 @@ self._tempfile = None - def _save_bookmars_in_metadata(self): + def _save_bookmarks_in_metadata(self): # save bookmarks in the metadata bookmarks = [] for bookmark in self._bookmarkmanager.get_bookmarks(): @@ -828,7 +838,7 @@ del self.unused_download_tubes # Use the suggested file, the mime is not recognized if the extension - # is wrong in some cases + # is wrong in some cases (epub) temp_dir = os.path.dirname(tempfile) new_name = os.path.join(temp_dir, suggested_name) os.rename(tempfile, new_name) @@ -861,7 +871,7 @@ def _open_downloaded_file(self, shared_metadata): self._jobject = datastore.get(self._jobject.object_id) - for key in shared_metadata.keys(): + for key in list(shared_metadata.keys()): self.metadata[key] = shared_metadata[key] self.read_file(self._jobject.file_path) @@ -904,7 +914,7 @@ assert isinstance(addr, dbus.Struct) assert len(addr) == 2 assert isinstance(addr[0], str) - assert isinstance(addr[1], (int, long)) + assert isinstance(addr[1], int) assert addr[1] > 0 and addr[1] < 65536 ip = addr[0] port = int(addr[1]) @@ -939,7 +949,7 @@ # Pick an arbitrary tube we can try to download the document from try: tube_id = self.unused_download_tubes.pop() - except (ValueError, KeyError), e: + except (ValueError, KeyError) as e: _logger.debug('No tubes to get the document from right now: %s', e) return False @@ -982,7 +992,10 @@ else: mimetype = self.metadata['mime_type'] - if mimetype == 'text/plain' or mimetype == 'application/zip': + if mimetype == 'application/epub+zip': + import epubadapter + self._view = epubadapter.EpubViewer() + elif mimetype == 'text/plain' or mimetype == 'application/zip': import textadapter self._view = textadapter.TextViewer() elif mimetype == 'application/x-cbz': @@ -991,6 +1004,7 @@ else: import evinceadapter self._view = evinceadapter.EvinceViewer() + self._view_toolbar.show_inverted_colors_button() self._view.setup(self) self._view.load_document(filepath) @@ -1030,8 +1044,9 @@ thumb = self._get_screenshot() # The database is zero based num_page = int(page) + 1 - title = _('%s (Page %d)') % \ - (bookmark.get_note_title(), num_page) + title = _('%(title)s (Page %(number)d)') % \ + ({'title': bookmark.get_note_title(), + 'number': num_page}) self._add_link_totray(num_page, thumb, bookmark.color, title, bookmark.nick, bookmark.local) @@ -1059,7 +1074,7 @@ if self.get_shared(): self.watch_for_tubes() self._share_document() - except Exception, e: + except Exception as e: _logger.debug('Sharing failed: %s', e) def _update_toolbars(self): @@ -1094,11 +1109,11 @@ def create_metadata_file(self): # store the metadata in a json file - self._save_bookmars_in_metadata() + self._save_bookmarks_in_metadata() metadata_file_path = self._tempfile + '.json' shared_metadata = {} - for key in self.metadata.keys(): + for key in list(self.metadata.keys()): if key not in ['preview', 'cover_image']: shared_metadata[str(key)] = self.metadata[key] logging.debug('save metadata in %s', metadata_file_path) @@ -1178,6 +1193,9 @@ return True elif keyname == 'KP_End': self._view_toolbar.zoom_out() + return True + elif keyname == 'i' and event.state & Gdk.ModifierType.CONTROL_MASK: + self._view_toolbar.toggle_inverted_colors() return True elif keyname == 'Home': self._view.scroll(Gtk.ScrollType.START, False) @@ -1222,7 +1240,8 @@ def _added_bookmark_cb(self, bookmarkmanager, page, title): logging.debug('Bookmark added page %d', page) - title = _('%s (Page %d)') % (title, page) + title = _('%(title)s (Page %(number)d)') % \ + ({'title': title, 'number': page}) color = profile.get_color().to_string() owner = profile.get_nick_name() thumb = self._get_screenshot() @@ -1317,6 +1336,6 @@ cr.set_source_surface(screenshot_surface) cr.paint() - preview_str = StringIO.StringIO() + preview_str = io.BytesIO() preview_surface.write_to_png(preview_str) return preview_str.getvalue() diff --git a/readdb.py b/readdb.py index dda4c1d..bafbb3f 100644 --- a/readdb.py +++ b/readdb.py @@ -114,7 +114,7 @@ _init_db_highlights(self._conn) _init_db_previews(self._conn) - self._conn.text_factory = lambda x: unicode(x, "utf-8", "ignore") + self._conn.text_factory = lambda x: str(x, "utf-8", "ignore") self._bookmarks = [] self._populate_bookmarks() @@ -267,7 +267,7 @@ return self._highlights def update_highlights(self, highlights_dict): - for page in highlights_dict.keys(): + for page in list(highlights_dict.keys()): # json store the keys as strings # but the page is used as a int in all the code highlights_in_page = highlights_dict[page] diff --git a/readdialog.py b/readdialog.py index 82645c0..8066e01 100644 --- a/readdialog.py +++ b/readdialog.py @@ -207,8 +207,8 @@ def accept_clicked_cb(self, widget): title = self._title_entry.get_text() details = self._content_entry.get_buffer().props.text - content = {'title': title.decode('utf-8'), - 'body': details.decode('utf-8')} + content = {'title': title, + 'body': details} self._sidebarinstance._real_add_bookmark(self._page, json.dumps(content)) self.destroy() @@ -233,8 +233,8 @@ def accept_clicked_cb(self, widget): title = self._title_entry.get_text() details = self._content_entry.get_buffer().props.text - content = {'title': title.decode('utf-8'), - 'body': details.decode('utf-8')} + content = {'title': title, + 'body': details} self._sidebarinstance.del_bookmark(self._page) self._sidebarinstance._real_add_bookmark(self._page, json.dumps(content)) diff --git a/readtoolbar.py b/readtoolbar.py index 5d0626e..76af110 100644 --- a/readtoolbar.py +++ b/readtoolbar.py @@ -177,7 +177,9 @@ 'toggle-index-show': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([bool])), 'toggle-tray-show': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, - ([bool])), } + ([bool])), + 'toggle-inverted-colors': (GObject.SignalFlags.RUN_FIRST, + GObject.TYPE_NONE, ([bool])), } def __init__(self): Gtk.Toolbar.__init__(self) @@ -259,6 +261,17 @@ self._rotate_right.connect('clicked', self._rotate_right_cb) self.insert(self._rotate_right, -1) self._rotate_right.show() + + spacer = Gtk.SeparatorToolItem() + self.insert(spacer, -1) + spacer.show() + + self._inverted_colors = ToggleToolButton(icon_name='dark-theme') + self._inverted_colors.set_tooltip(_('Inverted Colors')) + self._inverted_colors.set_accelerator('i') + self._inverted_colors.connect( + 'toggled', self.__inverted_colors_toggled_cb) + self.insert(self._inverted_colors, -1) def set_view(self, view): self._view = view @@ -324,3 +337,19 @@ self.traybutton.set_tooltip(_('Show Tray')) else: self.traybutton.set_tooltip(_('Hide Tray')) + + def __inverted_colors_toggled_cb(self, button): + self.emit('toggle-inverted-colors', button.props.active) + if button.props.active: + button.set_icon_name('light-theme') + button.set_tooltip(_('Normal Colors')) + else: + button.set_icon_name('dark-theme') + button.set_tooltip(_('Inverted Colors')) + + def show_inverted_colors_button(self): + self._inverted_colors.show() + + def toggle_inverted_colors(self): + self._inverted_colors.set_active( + not self._inverted_colors.get_active()) diff --git a/speechtoolbar.py b/speechtoolbar.py index 02d26c3..8b09e7b 100644 --- a/speechtoolbar.py +++ b/speechtoolbar.py @@ -35,28 +35,6 @@ self._speech = SpeechManager() self._is_paused = False - self.load_speech_parameters() - - self._voices = self._speech.get_all_voices() # a dictionary - - locale = os.environ.get('LANG', '') - language_location = locale.split('.', 1)[0].lower() - language = language_location.split('_')[0] - # if the language is es but not es_es default to es_la (latin voice) - if language == 'es' and language_location != 'es_es': - language_location = 'es_la' - - self._voice = 'en_us' - if language_location in self._voices: - self._voice = language_location - elif language in self._voices: - self._voice = language - - voice_names = [] - for language, name in self._voices.iteritems(): - voice_names.append((language, name)) - voice_names.sort(self._compare_voice) - # Play button self._play_button = ToggleToolButton('media-playback-start') self._play_button.show() @@ -72,58 +50,7 @@ self.insert(self._stop_button, -1) self._stop_button.set_tooltip(_('Stop')) - # Language list - combo = ComboBox() - which = 0 - for pair in voice_names: - language, name = pair - combo.append_item(language, name) - if language == self._voice: - combo.set_active(which) - which += 1 - - combo.connect('changed', self._voice_changed_cb) - combotool = ToolComboBox(combo) - self.insert(combotool, -1) - combotool.show() - self._speech.connect('stop', self._reset_buttons_cb) - - def _compare_voice(self, a, b): - if a[1].lower() == b[1].lower(): - return 0 - if a[1].lower() < b[1].lower(): - return -1 - if a[1].lower() > b[1].lower(): - return 1 - - def _voice_changed_cb(self, combo): - self._voice = combo.props.value - self._speech.say_text(self._voices[self._voice]) - self.save_speech_parameters() - - def load_speech_parameters(self): - speech_parameters = {} - data_path = os.path.join(self._activity.get_activity_root(), 'data') - data_file_name = os.path.join(data_path, 'speech_params.json') - if os.path.exists(data_file_name): - f = open(data_file_name, 'r') - try: - speech_parameters = json.load(f) - self._voice = speech_parameters['voice'] - finally: - f.close() - - def save_speech_parameters(self): - speech_parameters = {} - speech_parameters['voice'] = self._voice - data_path = os.path.join(self._activity.get_activity_root(), 'data') - data_file_name = os.path.join(data_path, 'speech_params.json') - f = open(data_file_name, 'w') - try: - json.dump(speech_parameters, f) - finally: - f.close() def _reset_buttons_cb(self, widget=None): self._play_button.set_icon_name('media-playback-start') @@ -136,8 +63,7 @@ self._play_button.set_icon_name('media-playback-pause') if not self._is_paused: self._speech.say_text( - self._activity._view.get_marked_words(), - lang_code=self._voice) + self._activity._view.get_marked_words()) else: self._speech.restart() else: diff --git a/textadapter.py b/textadapter.py index b33b64e..b8236c2 100644 --- a/textadapter.py +++ b/textadapter.py @@ -43,7 +43,7 @@ self.textview.set_cursor_visible(False) self.textview.set_left_margin(50) self.textview.set_right_margin(50) - self.textview.set_justification(Gtk.Justification.FILL) + self.textview.set_justification(Gtk.Justification.LEFT) self.textview.set_wrap_mode(Gtk.WrapMode.WORD) self.textview.connect('button-release-event', self._view_buttonrelease_event_cb) @@ -77,11 +77,11 @@ activity._hbox.pack_start(overlay, True, True, 0) - self._font_size = style.zoom(10) - self.font_desc = Pango.FontDescription("sans %d" % self._font_size) + self._font_size = style.zoom(12) + self.font_desc = Pango.FontDescription("mono %d" % self._font_size) self.textview.modify_font(self.font_desc) self._zoom = 100 - self.font_zoom_relation = self._zoom / self._font_size + self.font_zoom_relation = self._zoom // self._font_size self._current_page = 0 self.highlight_tag = self.textview.get_buffer().create_tag() @@ -122,7 +122,7 @@ line = self._etext_file.readline() if not line: break - line_increment = (len(line) / 80) + 1 + line_increment = (len(line) // 80) + 1 linecount = linecount + line_increment if linecount >= PAGE_SIZE: position = self._etext_file.tell() @@ -131,10 +131,10 @@ pagecount = pagecount + 1 self._pagecount = pagecount + 1 self.set_current_page(0) - self._scrollbar.set_range(1.0, self._pagecount - 1.0) + self._scrollbar.set_range(0.0, self._pagecount - 1.0) self._scrollbar.set_increments(1.0, 1.0) - # TODO: if ever sugar3.speech has word signals + # TODO: now that sugar3.speech has word signals # call self.highlight_next_word on each word # call self.reset_text_to_speech at end @@ -149,8 +149,8 @@ break else: line = _clean_text(line) - label_text = label_text + unicode(line, "iso-8859-1") - line_increment = (len(line) / 80) + 1 + label_text = label_text + line + line_increment = (len(line) // 80) + 1 linecount = linecount + line_increment textbuffer = self.textview.get_buffer() label_text = label_text + '\n\n\n' @@ -177,7 +177,7 @@ def _scrollbar_change_value_cb(self, range, scrolltype, value): """ - This is the fake scrollbar visible, used to show the lenght of the book + This is the fake scrollbar visible, used to show the length of the book """ old_page = self._current_page if scrolltype == Gtk.ScrollType.STEP_FORWARD: @@ -190,7 +190,7 @@ scrolltype == Gtk.ScrollType.PAGE_FORWARD or \ scrolltype == Gtk.ScrollType.PAGE_BACKWARD: if value > self._scrollbar.props.adjustment.props.upper: - value = self._pagecount + value = self._pagecount - 1 self._show_page(int(value)) self._current_page = int(value) self.emit('page-changed', old_page, self._current_page) @@ -205,9 +205,9 @@ if event.type == Gdk.EventType.TOUCH_BEGIN: x = event.touch.x view_width = widget.get_allocation().width - if x > view_width * 3 / 4: + if x > view_width * 3 // 4: self.scroll(Gtk.ScrollType.PAGE_FORWARD, False) - elif x < view_width * 1 / 4: + elif x < view_width * 1 // 4: self.scroll(Gtk.ScrollType.PAGE_BACKWARD, False) def can_highlight(self): @@ -283,7 +283,7 @@ marked_up_text = marked_up_text + \ ' ' + word_tuple[2] i = i + 1 - print marked_up_text + print(marked_up_text) return marked_up_text + '' def reset_text_to_speech(self): @@ -294,8 +294,8 @@ j = 0 word_begin = 0 word_end = 0 - ignore_chars = [' ', '\n', u'\r', '_', '[', '{', ']', '}', '|', - '<', '>', '*', '+', '/', '\\'] + ignore_chars = [' ', '\n', '\r', '_', '[', '{', ']', '}', '|', + '<', '>', '*', '+', '/', '\\'] ignore_set = set(ignore_chars) self.word_tuples = [] len_page_text = len(page_text) @@ -309,7 +309,7 @@ i = j word_tuple = (word_begin, word_end, page_text[word_begin: word_end]) - if word_tuple[2] != u'\r': + if word_tuple[2] != '\r': self.word_tuples.append(word_tuple) i = i + 1 @@ -325,14 +325,14 @@ v_adjustment = self._sw.get_vadjustment() max_pos = v_adjustment.get_upper() - v_adjustment.get_page_size() max_pos = max_pos * word_count - max_pos = max_pos / len(self.word_tuples) + max_pos = max_pos // len(self.word_tuples) v_adjustment.set_value(max_pos) self.current_word = word_count return True def update_metadata(self, activity): self.metadata = activity.metadata - self.metadata['Read_zoom'] = self.get_zoom() + self.metadata['Read_zoom'] = str(self.get_zoom()) def load_metadata(self, activity): self.metadata = activity.metadata @@ -401,12 +401,13 @@ v_adjustment = self._sw.get_vadjustment() v_adjustment.set_value(v_adjustment.get_upper() - v_adjustment.get_page_size()) - self.set_current_page(self.get_current_page() - 1) + self.set_current_page(max(0, self.get_current_page() - 1)) def next_page(self): v_adjustment = self._sw.get_vadjustment() v_adjustment.set_value(v_adjustment.get_lower()) - self.set_current_page(self.get_current_page() + 1) + self.set_current_page( + min(self._pagecount - 1, self.get_current_page() + 1)) def get_current_page(self): return self._current_page @@ -476,7 +477,7 @@ def set_zoom(self, value): self._zoom = value - self._font_size = int(self._zoom / self.font_zoom_relation) + self._font_size = self._zoom // self.font_zoom_relation self.font_desc.set_size(self._font_size * 1024) self.textview.modify_font(self.font_desc) @@ -590,12 +591,12 @@ self._current_found_item = -1 self.obj._text_file.seek(0) while self.obj._text_file: - line = unicode(self.obj._text_file.readline(), "iso-8859-1") + line = self.obj._text_file.readline() line = _clean_text(line) line_length = len(line) if not line: break - line_increment = (len(line) / 80) + 1 + line_increment = (len(line) // 80) + 1 linecount = linecount + line_increment positions = self._allindices(line.lower(), self.obj._text.lower()) for position in positions: