From 5aa984020832ee87513570c5f5593b6f721c9eea Mon Sep 17 00:00:00 2001 From: Gonzalo Odiard Date: Sat, 12 Feb 2011 21:32:21 +0000 Subject: Get back functionalities in EPUB framework - TOC, zoom and find are working in epub - All the code specific to a backend is moved outsude of readactivity.py, readtoolbar.py and readtopbar.py - Rename adapter classes to avoid confusion --- diff --git a/activity/activity.info b/activity/activity.info index a6dcfac..35bff87 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -4,6 +4,6 @@ bundle_id = org.laptop.sugar.ReadActivity icon = activity-read exec = sugar-activity readactivity.ReadActivity show_launcher = no -activity_version = 78 +activity_version = 88 mime_types = application/pdf;image/vnd.djvu;image/x.djvu;image/tiff;application/x-cbz;application/x-cbr;application/epub+zip license = GPLv2+ diff --git a/epubadapter.py b/epubadapter.py index a11cdd7..2d4a913 100644 --- a/epubadapter.py +++ b/epubadapter.py @@ -3,15 +3,52 @@ import logging import epubview - _logger = logging.getLogger('read-activity') -class View(epubview.EpubView): +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, expand=True, fill=True) + self.show_all() + + def load_document(self, file_path): + self.set_document(EpubDocument(self, file_path.replace('file://', ''))) + + def load_metadata(self, activity): + pass + + def update_metadata(self, activity): + pass + + 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 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) @@ -23,6 +60,7 @@ class View(epubview.EpubView): return def find_set_highlight_search(self, set_highlight_search): + #TODO : what is this? return def set_current_page(self, n): @@ -38,12 +76,32 @@ class View(epubview.EpubView): def get_current_page(self): return int(self._loaded_page - 1) + def update_toc(self, activity): + if self._epub.has_document_links(): + activity._navigator_toolbar_button.show() + activity._navigator.show_all() + + activity._toc_model = self._epub.get_links_model() + activity._navigator.set_model(activity._toc_model) + activity._navigator.set_active(0) + return True + else: + return False + 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): @@ -63,5 +121,7 @@ class EpubDocument(epubview.Epub): 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) + 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/epubview.py b/epubview/epubview.py index 197dcd3..6159374 100644 --- a/epubview/epubview.py +++ b/epubview/epubview.py @@ -42,7 +42,8 @@ class _View(gtk.HBox): 0.5, 4.0, 1.0, gobject.PARAM_READWRITE), } __gsignals__ = { - 'page-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'page-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([int, int])), 'selection-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), } @@ -107,13 +108,13 @@ class _View(gtk.HBox): def do_get_property(self, property): if property.name == 'has-selection': return self._has_selection - elif property.name == 'zoom': + 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 == 'zoom': + if property.name == 'scale': self.__set_zoom(value) else: raise AttributeError, 'unknown property %s' % property.name @@ -128,20 +129,32 @@ class _View(gtk.HBox): ''' Returns the current zoom level ''' - return self.get_property('zoom') + return self.get_property('scale') * 100.0 def set_zoom(self, value): ''' Sets the current zoom level ''' - self.set_property('zoom', value) + self._view.set_zoom_level(value / 100.0) + + 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(): - self.set_zoom(self.get_zoom() + 0.1) + self._set_scale(self._get_scale() + 0.1) return True else: return False @@ -151,7 +164,7 @@ class _View(gtk.HBox): Zooms out (decreases zoom level by 0.1) ''' if self.can_zoom_out(): - self.set_zoom(self.get_zoom() - 0.1) + self._set_scale(self._get_scale() - 0.1) return True else: return False @@ -297,6 +310,7 @@ class _View(gtk.HBox): def __set_has_selection(self, value): if value != self._has_selection: self._has_selection = value + self.emit('selection-changed') def _view_populate_popup_cb(self, view, menu): menu.destroy() #HACK @@ -305,11 +319,13 @@ class _View(gtk.HBox): def _view_selection_changed_cb(self, view): # FIXME: This does not seem to be implemented in # webkitgtk yet - print view.has_selection() - self.emit('selection-changed') + print "epubview _view_selection_changed_cb", view.has_selection() + self.__set_has_selection(view.has_selection()) def _view_buttonrelease_event_cb(self, view, event): # Ugly hack + print "epubview _view_buttonrelease_event_cb", view.has_selection(), \ + view.can_copy_clipboard(), view.can_cut_clipboard() self.__set_has_selection(view.can_copy_clipboard() \ | view.can_cut_clipboard()) @@ -393,7 +409,7 @@ class _View(gtk.HBox): pageno = math.floor(base_pageno + offset) if pageno != self._loaded_page: - self._on_page_changed(int(pageno)) + self._on_page_changed(0, int(pageno)) def _scroll_page_end(self): v_upper = self._v_vscrollbar.props.adjustment.props.upper @@ -441,7 +457,7 @@ class _View(gtk.HBox): else: scrollfactor = 0 if scrollfactor >= scrollfactor_next: - self._on_page_changed(self._loaded_page + 1) + self._on_page_changed(self._loaded_page, self._loaded_page + 1) elif self.__going_back == True and self._loaded_page > 1: if self._paginator.get_file_for_pageno(self._loaded_page) != \ self._paginator.get_file_for_pageno(self._loaded_page - 1): @@ -454,22 +470,22 @@ class _View(gtk.HBox): scrollfactor = 0 if scrollfactor <= scrollfactor_cur: - self._on_page_changed(self._loaded_page - 1) + self._on_page_changed(self._loaded_page, self._loaded_page - 1) - def _on_page_changed(self, pageno): + def _on_page_changed(self, oldpage, pageno): 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) - self.emit('page-changed') + self.emit('page-changed', oldpage, pageno) def _load_page(self, pageno): if pageno > self._pagecount or pageno < 1: #TODO: Cause an exception return - self._on_page_changed(pageno) + self._on_page_changed(self._loaded_page, pageno) filename = self._paginator.get_file_for_pageno(pageno) if filename != self._loaded_filename: #self._loaded_filename = filename diff --git a/epubview/jobs.py b/epubview/jobs.py index 8dc26c7..bfd751d 100644 --- a/epubview/jobs.py +++ b/epubview/jobs.py @@ -154,7 +154,7 @@ class _JobPaginator(gobject.GObject): pagelen = 1 / pages self._pagemap[float(self._pagecount + i)] = (f.props.uri, (i - 1) / math.ceil(pages), pagelen) - self._pagecount += math.ceil(pages) + self._pagecount += int(math.ceil(pages)) self._filedict[f.props.uri.replace('file://', '')] = (math.ceil(pages), math.ceil(pages) - pages) self._bookheight += pageheight diff --git a/evinceadapter.py b/evinceadapter.py new file mode 100644 index 0000000..24a4c88 --- /dev/null +++ b/evinceadapter.py @@ -0,0 +1,221 @@ +import gobject +import logging +import gtk + +import evince + +_logger = logging.getLogger('read-activity') + + +class EvinceViewer(): + + def __init__(self): + self._view = evince.View() + + def setup(self, activity): + + self._view.connect('selection-changed', + activity._view_selection_changed_cb) + + activity._scrolled = gtk.ScrolledWindow() + activity._scrolled.set_policy(gtk.POLICY_AUTOMATIC, + gtk.POLICY_AUTOMATIC) + activity._scrolled.props.shadow_type = gtk.SHADOW_NONE + + activity._scrolled.add(self._view) + self._view.show() + + activity._hbox.pack_start(activity._scrolled, expand=True, fill=True) + activity._scrolled.show() + + self.dpi = activity.dpi + + def load_document(self, file_path): + try: + self._document = evince.document_factory_get_document(file_path) + except GError, e: + _logger.error('Can not load document: %s', e) + return + else: + self._model = evince.DocumentModel() + self._model.set_document(self._document) + self._view.set_model(self._model) + + # set dpi + min_scale = self._model.get_min_scale() + max_scale = self._model.get_max_scale() + self._model.set_min_scale(min_scale * self.dpi / 72.0) + self._model.set_max_scale(max_scale * self.dpi / 72.0) + + def get_current_page(self): + return self._model.props.page + + def set_current_page(self, page): + if page >= self._document.get_n_pages(): + page = self._document.get_n_pages() - 1 + elif page < 0: + page = 0 + self._model.props.page = page + + def get_pagecount(self): + ''' + Returns the pagecount of the loaded file + ''' + return self._document.get_n_pages() + + def load_metadata(self, activity): + self.metadata = activity.metadata + sizing_mode = self.metadata.get('Read_sizing_mode', 'fit-width') + _logger.debug('Found sizing mode: %s', sizing_mode) + if sizing_mode == "best-fit": + self._model.props.sizing_mode = evince.SIZING_BEST_FIT + if hasattr(self._view, 'update_view_size'): + self._view.update_view_size(self._scrolled) + elif sizing_mode == "free": + self._model.props.sizing_mode = evince.SIZING_FREE + self._model.props.scale = \ + float(self.metadata.get('Read_zoom', '1.0')) + _logger.debug('Set zoom to %f', self._model.props.scale) + elif sizing_mode == "fit-width": + self._model.props.sizing_mode = evince.SIZING_FIT_WIDTH + if hasattr(self._view, 'update_view_size'): + self._view.update_view_size(self._scrolled) + else: + # this may happen when we get a document from a buddy with a later + # version of Read, for example. + _logger.warning("Unknown sizing_mode state '%s'", sizing_mode) + if self.metadata.get('Read_zoom', None) is not None: + self._model.props.scale = float(self.metadata['Read_zoom']) + + def update_metadata(self, activity): + self.metadata = activity.metadata + self.metadata['Read_zoom'] = str(self._model.props.scale) + + if self._model.props.sizing_mode == evince.SIZING_BEST_FIT: + self.metadata['Read_sizing_mode'] = "best-fit" + elif self._model.props.sizing_mode == evince.SIZING_FREE: + self.metadata['Read_sizing_mode'] = "free" + elif self._model.props.sizing_mode == evince.SIZING_FIT_WIDTH: + self.metadata['Read_sizing_mode'] = "fit-width" + else: + _logger.error("Don't know how to save sizing_mode state '%s'" % + self._model.props.sizing_mode) + self.metadata['Read_sizing_mode'] = "fit-width" + + def get_zoom(self): + ''' + Returns the current zoom level + ''' + return self._model.props.scale * 100 + + def set_zoom(self, value): + ''' + Sets the current zoom level + ''' + self._model.props.sizing_mode = evince.SIZING_FREE + + if not self._view_notify_zoom_handler: + return + + self._model.disconnect(self._view_notify_zoom_handler) + try: + self._model.props.scale = value / 100.0 + finally: + self._view_notify_zoom_handler = self._model.connect( + 'notify::scale', self._zoom_handler) + + def zoom_in(self): + ''' + Zooms in (increases zoom level by 0.1) + ''' + self._model.props.sizing_mode = evince.SIZING_FREE + self._view.zoom_in() + + def zoom_out(self): + ''' + Zooms out (decreases zoom level by 0.1) + ''' + self._model.props.sizing_mode = evince.SIZING_FREE + self._view.zoom_out() + + def zoom_to_width(self): + self._model.props.sizing_mode = evince.SIZING_FIT_WIDTH + + def can_zoom_in(self): + ''' + Returns True if it is possible to zoom in further + ''' + return self._view.can_zoom_in() + + def can_zoom_out(self): + ''' + Returns True if it is possible to zoom out further + ''' + return self._view.can_zoom_out() + + def can_zoom_to_width(self): + return True + + def zoom_to_best_fit(self): + self._model.props.sizing_mode = evince.SIZING_BEST_FIT + + def zoom_to_actual_size(self): + self._model.props.sizing_mode = evince.SIZING_FREE + self._model.props.scale = 1.0 + + def connect_zoom_handler(self, handler): + self._zoom_handler = handler + self._view_notify_zoom_handler = \ + self._model.connect('notify::scale', handler) + return self._view_notify_zoom_handler + + def setup_find_job(self, text, updated_cb): + self._find_job = evince.JobFind(document=self._document, start_page=0, + n_pages=self._document.get_n_pages(), + text=text, case_sensitive=False) + self._find_updated_handler = self._find_job.connect('updated', + updated_cb) + evince.Job.scheduler_push_job(self._find_job, + evince.JOB_PRIORITY_NONE) + return self._find_job, self._find_updated_handler + + def connect_page_changed_handler(self, handler): + self._model.connect('page-changed', handler) + + def update_toc(self, activity): + return False + + def find_set_highlight_search(self, set_highlight_search): + self._view.find_set_highlight_search(set_highlight_search) + + def find_next(self): + ''' + Highlights the next matching item for current search + ''' + self._view.find_next() + + def find_previous(self): + ''' + Highlights the previous matching item for current search + ''' + self._view.find_previous() + + def find_changed(self, job, page=None): + self._view.find_changed(job, page) + + def scroll(self, scrolltype, horizontal): + ''' + Scrolls through the pages. + Scrolling is horizontal if horizontal is set to True + Valid scrolltypes are: + gtk.SCROLL_PAGE_BACKWARD and gtk.SCROLL_PAGE_FORWARD + ''' + if scrolltype == gtk.SCROLL_PAGE_BACKWARD: + self._view.scroll(gtk.SCROLL_PAGE_BACKWARD, -1) + elif scrolltype == gtk.SCROLL_PAGE_FORWARD: + self._view.scroll(gtk.SCROLL_PAGE_FORWARD, 1) + else: + print ('Got unsupported scrolltype %s' % str(scrolltype)) + + def copy(self): + self._view.copy() diff --git a/readactivity.py b/readactivity.py index ba8bbfa..48baaa2 100644 --- a/readactivity.py +++ b/readactivity.py @@ -25,7 +25,6 @@ import re import md5 import dbus -import evince import gobject import gtk import pango @@ -50,14 +49,8 @@ from readtoolbar import EditToolbar, ViewToolbar from readsidebar import Sidebar from readtopbar import TopBar - -_EPUB_SUPPORT = True -try: - import epubadapter -except ImportError, e: - _EPUB_SUPPORT = False - logging.warning('Epub support disabled because: %s' % e) - +import epubadapter +import evinceadapter _HARDWARE_MANAGER_INTERFACE = 'org.laptop.HardwareManager' _HARDWARE_MANAGER_SERVICE = 'org.laptop.HardwareManager' @@ -76,7 +69,7 @@ def _get_screen_dpi(): def get_md5(filename): #FIXME: Should be moved somewhere else - filename = filename.replace('file://', '') #XXX: hack + filename = filename.replace('file://', '') # XXX: hack fh = open(filename) digest = md5.new() while 1: @@ -139,10 +132,10 @@ class ReadActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) - self._epub = False self._document = None self._fileserver = None self._object_id = handle.object_id + self._toc_model = None self.connect('key-press-event', self._key_press_event_cb) self.connect('key-release-event', self._key_release_event_cb) @@ -151,7 +144,7 @@ class ReadActivity(activity.Activity): _logger.debug('Starting Read...') self._view = None - + self.dpi = _get_screen_dpi() self._sidebar = Sidebar() self._sidebar.show() @@ -408,12 +401,7 @@ class ReadActivity(activity.Activity): else: page = 0 - if page >= self._document.get_n_pages(): - page = self._document.get_n_pages() - 1 - elif page < 0: - page = 0 - - self._model.props.page = page + self._view.set_current_page(page) entry.props.text = str(page + 1) def __go_back_cb(self, button): @@ -429,23 +417,23 @@ class ReadActivity(activity.Activity): self._view.next_page() def __prev_bookmark_activate_cb(self, menuitem): - page = self._model.props.page + page = self._view.get_current_page() bookmarkmanager = self._sidebar.get_bookmarkmanager() prev_bookmark = bookmarkmanager.get_prev_bookmark_for_page(page) if prev_bookmark is not None: - self._model.props.page = prev_bookmark.page_no + self._view.set_current_page(prev_bookmark.page_no) def __next_bookmark_activate_cb(self, menuitem): - page = self._model.props.page + page = self._view.get_current_page() bookmarkmanager = self._sidebar.get_bookmarkmanager() next_bookmark = bookmarkmanager.get_next_bookmark_for_page(page) if next_bookmark is not None: - self._model.props.page = next_bookmark.page_no + self._view.set_current_page(next_bookmark.page_no) def __bookmarker_toggled_cb(self, button): - page = self._model.props.page + page = self._view.get_current_page() if self._bookmarker.props.active: self._sidebar.add_bookmark(page) else: @@ -453,27 +441,31 @@ class ReadActivity(activity.Activity): def __page_changed_cb(self, model, page_from, page_to): self._update_nav_buttons() - if hasattr(self._document, 'has_document_links'): - if self._document.has_document_links(): - self._toc_select_active_page() + if self._toc_model != None: + self._toc_select_active_page() - self._sidebar.update_for_page(self._model.props.page) + self._sidebar.update_for_page(self._view.get_current_page()) self._bookmarker.handler_block(self._bookmarker_toggle_handler_id) - self._bookmarker.props.active = self._sidebar.is_showing_local_bookmark() + self._bookmarker.props.active = \ + self._sidebar.is_showing_local_bookmark() self._bookmarker.handler_unblock(self._bookmarker_toggle_handler_id) def _update_nav_buttons(self): - current_page = self._model.props.page + current_page = self._view.get_current_page() self._back_button.props.sensitive = current_page > 0 self._forward_button.props.sensitive = \ - current_page < self._document.get_n_pages() - 1 + current_page < self._view.get_pagecount() - 1 self._num_page_entry.props.text = str(current_page + 1) self._total_page_label.props.label = \ - ' / ' + str(self._document.get_n_pages()) + ' / ' + str(self._view.get_pagecount()) def _update_toc(self): + if self._view.update_toc(self): + self._navigator_changed_handler_id = \ + self._navigator.connect('changed', self.__navigator_changed_cb) + if hasattr(self._document, 'has_document_links'): if self._document.has_document_links(): self._navigator_toolbar_button.show() @@ -515,7 +507,7 @@ class ReadActivity(activity.Activity): iter = self._navigator.get_active_iter() current_link = self._toc_model.get(iter, 1)[0] - current_page = self._model.props.page + current_page = self._view.get_current_page() if not hasattr(current_link, 'get_page'): filepath = self._view.get_current_file() @@ -526,7 +518,8 @@ class ReadActivity(activity.Activity): return self._navigator.handler_block(self._navigator_changed_handler_id) - self._toc_model.foreach(self._toc_select_active_page_foreach, current_page) + self._toc_model.foreach(self._toc_select_active_page_foreach, + current_page) self._navigator.handler_unblock(self._navigator_changed_handler_id) def _show_journal_object_picker(self): @@ -557,7 +550,8 @@ class ReadActivity(activity.Activity): # Now active, start initial suspend timeout if self._idle_timer > 0: gobject.source_remove(self._idle_timer) - self._idle_timer = gobject.timeout_add_seconds(15, self._suspend_cb) + self._idle_timer = gobject.timeout_add_seconds(15, + self._suspend_cb) self._sleep_inhibit = False else: # Now inactive @@ -597,8 +591,8 @@ class ReadActivity(activity.Activity): self._load_document('file://' + self._tempfile) # FIXME: This should obviously be fixed properly - gobject.timeout_add_seconds(1, self.__view_toolbar_needs_update_size_cb, - None) + gobject.timeout_add_seconds(1, + self.__view_toolbar_needs_update_size_cb, None) def write_file(self, file_path): """Write into datastore for Keep. @@ -616,21 +610,9 @@ class ReadActivity(activity.Activity): try: self.metadata['Read_current_page'] = \ - str(self._model.props.page) - - self.metadata['Read_zoom'] = str(self._model.props.scale) - - if not self._epub: - if self._model.props.sizing_mode == evince.SIZING_BEST_FIT: - self.metadata['Read_sizing_mode'] = "best-fit" - elif self._model.props.sizing_mode == evince.SIZING_FREE: - self.metadata['Read_sizing_mode'] = "free" - elif self._model.props.sizing_mode == evince.SIZING_FIT_WIDTH: - self.metadata['Read_sizing_mode'] = "fit-width" - else: - _logger.error("Don't know how to save sizing_mode state '%s'" % - self._model.props.sizing_mode) - self.metadata['Read_sizing_mode'] = "fit-width" + str(self._view.get_current_page()) + + self._view.update_metadata(self) self.metadata['Read_search'] = \ self._edit_toolbar._search_entry.props.text @@ -758,30 +740,6 @@ class ReadActivity(activity.Activity): self.watch_for_tubes() gobject.idle_add(self._get_document) - def _setup_epub_viewer(self): - self._view = epubadapter.View() - self._view.set_screen_dpi(_get_screen_dpi()) - self._view.connect('selection-changed', - self._view_selection_changed_cb) - - self._hbox.pack_start(self._view, expand=True, fill=True) - self._view.show_all() - - def _setup_evince_viewer(self): - self._view = evince.View() - self._view.connect('selection-changed', - self._view_selection_changed_cb) - - self._scrolled = gtk.ScrolledWindow() - self._scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self._scrolled.props.shadow_type = gtk.SHADOW_NONE - - self._scrolled.add(self._view) - self._view.show() - - self._hbox.pack_start(self._scrolled, expand=True, fill=True) - self._scrolled.show() - def _load_document(self, filepath): """Load the specified document and set up the UI. @@ -790,43 +748,19 @@ class ReadActivity(activity.Activity): """ mimetype = mime.get_for_file(filepath) if mimetype == 'application/epub+zip': - if not _EPUB_SUPPORT: - self.close() - return - self._epub = True - self._setup_epub_viewer() - self._document = epubadapter.EpubDocument(self._view, filepath.replace('file://', '')) - self._model = None - - self._view.set_document(self._document) + self._view = epubadapter.EpubViewer() else: - self._setup_evince_viewer() - try: - self._document = evince.document_factory_get_document(filepath) - except GError, e: - _logger.error('Can not load document: %s', e) - return - else: - self._model = evince.DocumentModel() - self._model.set_document(self._document) - self._view.set_model(self._model) + self._view = evinceadapter.EvinceViewer() - # set dpi - dpi = _get_screen_dpi() - min_scale = self._model.get_min_scale() - max_scale = self._model.get_max_scale() - self._model.set_min_scale(min_scale * dpi / 72.0) - self._model.set_max_scale(max_scale * dpi / 72.0) + self._view.setup(self) + self._view.load_document(filepath) self._want_document = False - # set dpi - - self._view_toolbar.set_view(self._view, self._model) + self._view_toolbar.set_view(self._view) self._edit_toolbar.set_view(self._view) - self._edit_toolbar.set_document(self._document) - self._topbar.set_document(self._document) + self._topbar.set_view(self._view) filehash = get_md5(filepath) self._sidebar.set_bookmarkmanager(filehash) @@ -834,34 +768,14 @@ class ReadActivity(activity.Activity): self._update_nav_buttons() self._update_toc() - self._model.connect('page-changed', self.__page_changed_cb) + self._view.connect_page_changed_handler(self.__page_changed_cb) if not self.metadata['title_set_by_user'] == '1': title = self._document.get_title() if title: self.metadata['title'] = title - if not self._epub: - sizing_mode = self.metadata.get('Read_sizing_mode', 'fit-width') - _logger.debug('Found sizing mode: %s', sizing_mode) - if sizing_mode == "best-fit": - self._model.props.sizing_mode = evince.SIZING_BEST_FIT - if hasattr(self._view, 'update_view_size'): - self._view.update_view_size(self._scrolled) - elif sizing_mode == "free": - self._model.props.sizing_mode = evince.SIZING_FREE - self._model.props.scale = float(self.metadata.get('Read_zoom', '1.0')) - _logger.debug('Set zoom to %f', self._model.props.scale) - elif sizing_mode == "fit-width": - self._model.props.sizing_mode = evince.SIZING_FIT_WIDTH - if hasattr(self._view, 'update_view_size'): - self._view.update_view_size(self._scrolled) - else: - # this may happen when we get a document from a buddy with a later - # version of Read, for example. - _logger.warning("Unknown sizing_mode state '%s'", sizing_mode) - if self.metadata.get('Read_zoom', None) is not None: - self._model.props.scale = float(self.metadata['Read_zoom']) + self._view.load_metadata(self) self._view_toolbar._update_zoom_buttons() @@ -870,7 +784,7 @@ class ReadActivity(activity.Activity): current_page = int(self.metadata.get('Read_current_page', '0')) _logger.debug('Setting page to: %d', current_page) - self._model.props.page = current_page + self._view.set_current_page(current_page) # We've got the document, so if we're a shared activity, offer it try: @@ -993,7 +907,7 @@ class ReadActivity(activity.Activity): if hasattr(self._view, 'update_view_size'): self._view.update_view_size(self._scrolled) else: - return False # No need to run this again and again + return False # No need again to run this again and def __view_toolbar_go_fullscreen_cb(self, view_toolbar): self.fullscreen() diff --git a/readtoolbar.py b/readtoolbar.py index 93612d2..ed57fde 100644 --- a/readtoolbar.py +++ b/readtoolbar.py @@ -19,12 +19,6 @@ import logging import gobject import gtk -import evince - -try: - import epubadapter -except ImportError: - pass from sugar.graphics.toolbutton import ToolButton from sugar.graphics.menuitem import MenuItem @@ -39,9 +33,8 @@ class EditToolbar(activity.EditToolbar): def __init__(self): activity.EditToolbar.__init__(self) - self._evince_view = None + self._view = None - self._document = None self._find_job = None search_item = gtk.ToolItem() @@ -78,11 +71,8 @@ class EditToolbar(activity.EditToolbar): self._next.show() def set_view(self, view): - self._evince_view = view - self._evince_view.find_set_highlight_search(True) - - def set_document(self, document): - self._document = document + self._view = view + self._view.find_set_highlight_search(True) def _clear_find_job(self): if self._find_job is None: @@ -96,13 +86,8 @@ class EditToolbar(activity.EditToolbar): self._clear_find_job() text = self._search_entry.props.text if text != "": - try: - self._find_job = evince.JobFind(document=self._document, start_page=0, n_pages=self._document.get_n_pages(), text=text, case_sensitive=False) - self._find_updated_handler = self._find_job.connect('updated', self._find_updated_cb) - evince.Job.scheduler_push_job(self._find_job, evince.JOB_PRIORITY_NONE) - except TypeError: - self._find_job = epubadapter.JobFind(document=self._document, start_page=0, n_pages=self._document.get_n_pages(), text=text, case_sensitive=False) - self._find_updated_handler = self._find_job.connect('updated', self._find_updated_cb) + self._find_job, self._find_updated_handler = \ + self._view.setup_find_job(text, self._find_updated_cb) else: # FIXME: highlight nothing pass @@ -111,14 +96,14 @@ class EditToolbar(activity.EditToolbar): self._update_find_buttons() def _search_find_next(self): - self._evince_view.find_next() + self._view.find_next() def _search_find_last(self): # FIXME: does Evince support find last? return def _search_find_prev(self): - self._evince_view.find_previous() + self._view.find_previous() def _search_entry_activate_cb(self, entry): if self._search_entry_changed: @@ -142,7 +127,7 @@ class EditToolbar(activity.EditToolbar): self._update_find_buttons() def _find_updated_cb(self, job, page=None): - self._evince_view.find_changed(job, page) + self._view.find_changed(job, page) def _find_prev_cb(self, button): if self._search_entry_changed: @@ -183,8 +168,7 @@ class ViewToolbar(gtk.Toolbar): def __init__(self): gtk.Toolbar.__init__(self) - self._evince_view = None - self._document = None + self._view = None self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Zoom out')) @@ -247,80 +231,59 @@ class ViewToolbar(gtk.Toolbar): self._view_notify_zoom_handler = None - def set_view(self, view, model): - # FIXME epubview needs fixing, until then toolbar is disabled - if model == None: - self._zoom_in.props.sensitive = False - self._zoom_out.props.sensitive = False - self._zoom_to_width.props.sensitive = False - self._zoom_spin.props.sensitive = False - return + def set_view(self, view): - self._evince_model = model - self._evince_view = view + self._view = view - self._zoom_spin.props.value = self._evince_model.props.scale * 100 - self._view_notify_zoom_handler = self._evince_model.connect( - 'notify::scale', self._view_notify_zoom_cb) + self._zoom_spin.props.value = self._view.get_zoom() + self._view_notify_zoom_handler = \ + self._view.connect_zoom_handler(self._view_notify_zoom_cb) self._update_zoom_buttons() def _zoom_spin_notify_value_cb(self, zoom_spin, pspec): - self._evince_model.props.sizing_mode = evince.SIZING_FREE - - if not self._view_notify_zoom_handler: - return - - self._evince_model.disconnect(self._view_notify_zoom_handler) - try: - self._evince_model.props.scale = zoom_spin.props.value / 100.0 - finally: - self._view_notify_zoom_handler = self._evince_model.connect( - 'notify::scale', self._view_notify_zoom_cb) + self._view.set_zoom(zoom_spin.props.value) - def _view_notify_zoom_cb(self, evince_model, pspec): + def _view_notify_zoom_cb(self, model, pspec): self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler) try: - self._zoom_spin.props.value = round(evince_model.props.scale * - 100.0) + self._zoom_spin.props.value = round(self._view.get_zoom()) finally: self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) def zoom_in(self): - self._evince_model.props.sizing_mode = evince.SIZING_FREE - self._evince_view.zoom_in() + self._view.zoom_in() self._update_zoom_buttons() def _zoom_in_cb(self, button): self.zoom_in() def zoom_out(self): - self._evince_model.props.sizing_mode = evince.SIZING_FREE - self._evince_view.zoom_out() + self._view.zoom_out() self._update_zoom_buttons() def _zoom_out_cb(self, button): self.zoom_out() def zoom_to_width(self): - self._evince_model.props.sizing_mode = evince.SIZING_FIT_WIDTH + self._view.zoom_to_width() self._update_zoom_buttons() def _zoom_to_width_cb(self, button): self.zoom_to_width() def _update_zoom_buttons(self): - self._zoom_in.props.sensitive = self._evince_view.can_zoom_in() - self._zoom_out.props.sensitive = self._evince_view.can_zoom_out() + self._zoom_in.props.sensitive = self._view.can_zoom_in() + self._zoom_out.props.sensitive = self._view.can_zoom_out() + self._zoom_to_width.props.sensitive = self._view.can_zoom_to_width() def _zoom_to_fit_menu_item_activate_cb(self, menu_item): - self._evince_model.props.sizing_mode = evince.SIZING_BEST_FIT + self._view.zoom_to_best_fit() self._update_zoom_buttons() def _actual_size_menu_item_activate_cb(self, menu_item): - self._evince_model.props.sizing_mode = evince.SIZING_FREE - self._evince_model.props.scale = 1.0 + self._view.zoom_to_actual_size() self._update_zoom_buttons() def _fullscreen_cb(self, button): diff --git a/readtopbar.py b/readtopbar.py index c6ce422..af7da4c 100644 --- a/readtopbar.py +++ b/readtopbar.py @@ -20,8 +20,6 @@ import gtk, gobject import dbus import logging -import evince - from sugar.graphics import style from sugar.graphics.icon import Icon, get_icon_state @@ -192,20 +190,17 @@ class TopBar(_TopBar): def __init__(self): _TopBar.__init__(self) - self._document = None - - def set_document(self, document): - self._document = document + self._view = None - model = evince.DocumentModel() - model.props.document = self._document - model.connect('page-changed', self._page_changed_cb) + def set_view(self, view): + self._view = view + self._view.connect_page_changed_handler(self._page_changed_cb) def _page_changed_cb(self, model, page_from, page_to): - current_page = self._model.props.page - n_pages = self._document.get_n_pages() + current_page = self._view.get_current_page() + n_pages = self._view.get_pagecount() - self.set_completion_level(current_page * 100 / n_pages) + self.set_completion_level(int(float(current_page) * 100 / float(n_pages))) #TRANS: Translate this as Page i of m (eg: Page 4 of 334) self._progressbar.set_text(_("Page %i of %i") % (current_page, n_pages)) -- cgit v0.9.1