[PATCH] Browse: add shortcuts for PDF that are consistent with Read
Manuel QuiƱones
manuq at laptop.org
Sun Jul 24 15:51:56 EDT 2011
This patch adds the same shortcuts as Read for zooming and scrolling
pdf files in Browse. This is a bug reported in #10514.
The patch is against the the repo [1] with a modified version of
Browse that allows pdf reading.
[1]: git://git.sugarlabs.org/~godiard/browse/inline-pdf-11-2.git
The shortcuts are:
- Arrow keys, as well as DPAD buttons, for step scrolling
- X and O buttons for vertical page scrolling, respectively
- Circle and Check buttons for zoom in and out, respectively
The DPAD buttons behaviour change accordingly when the screen is
rotated.
At the time of sending this patch, there is a related bug in Browse
that doesn't let the pdf area grab the focus. Please refer to the
comments in #10514.
Signed-off-by: Manuel QuiƱones <manuq at laptop.org>
---
bin/sugar-pdf-viewer | 226 ++++++++++++++++++++++++++++++++------------------
1 files changed, 146 insertions(+), 80 deletions(-)
diff --git a/bin/sugar-pdf-viewer b/bin/sugar-pdf-viewer
index b9719ec..b4d6ecc 100755
--- a/bin/sugar-pdf-viewer
+++ b/bin/sugar-pdf-viewer
@@ -36,12 +36,11 @@ class ViewerToolbar(gtk.Toolbar):
([]))
}
- def __init__(self, evince_view):
+ def __init__(self, evince_viewer):
gtk.Toolbar.__init__(self)
self.set_style(gtk.TOOLBAR_ICONS)
- self._evince_view = evince_view
- self._document = None
+ self._evince_viewer = evince_viewer
self._prev = ToolButton('go-previous-paired')
self._prev.connect('clicked', self._prev_cb)
@@ -105,81 +104,47 @@ class ViewerToolbar(gtk.Toolbar):
self._update_zoom_buttons()
- def zoom_in(self):
- self._model.props.sizing_mode = evince.SIZING_FREE
- self._evince_view.zoom_in()
- self._update_zoom_buttons()
-
def _zoom_in_cb(self, button):
- self.zoom_in()
-
- def zoom_out(self):
- self._model.props.sizing_mode = evince.SIZING_FREE
- self._evince_view.zoom_out()
+ self._evince_viewer.zoom_in()
self._update_zoom_buttons()
def _zoom_out_cb(self, button):
- self.zoom_out()
+ self._evince_viewer.zoom_out()
+ self._update_zoom_buttons()
- def zoom_to_width(self):
- self._model.props.sizing_mode = evince.SIZING_FIT_WIDTH
+ def _zoom_to_width_cb(self, button):
+ self._evince_viewer.zoom_to_width()
self.emit('needs-update-size')
self._update_zoom_buttons()
return False
- def _zoom_to_width_cb(self, button):
- self.zoom_to_width()
-
def _save_cb(self, button):
- title = self._document.get_title()
- fpath = sys.argv[1] # XXX: Bleh
-
- entry = datastore.create()
- entry.set_file_path(fpath)
-
- # For certain sites, PDFs get saved as foo.php, etc
- # An example would be the Nepali repository @ pustakalay.org
- # We need to force file sniffing here, otherwise the file gets
- # stored in the datastore with the mimetype application/x-php, etc
- entry.metadata['mime_type'] = mime.get_for_file(fpath)
-
- if title:
- entry.metadata['title'] = title
- else:
- entry.metadata['title'] = os.path.basename(sys.argv[1])
-
- datastore.write(entry)
-
- entry.destroy()
+ self._evince_viewer.save()
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()
-
- def set_document(self, document, model):
- self._document = document
- self._model = model
+ self._zoom_in.props.sensitive = self._evince_viewer.can_zoom_in()
+ self._zoom_out.props.sensitive = self._evince_viewer.can_zoom_out()
+ def setup(self):
self._page_spinner.props.sensitive = True
- self._page_spinner_adjustment.props.upper = \
- self._document.get_n_pages()
-
- self._model.connect('page-changed', self._page_changed_cb)
+ n_pages = self._evince_viewer.get_document_n_pages()
+ self._page_spinner_adjustment.props.upper = n_pages
+ self._evince_viewer.set_page_changed_callback(self._page_changed_cb)
self._update_zoom_buttons()
self._update_nav_buttons()
def _prev_cb(self, button):
- self._evince_view.previous_page()
+ self._evince_viewer.previous_page()
def _next_cb(self, button):
- self._evince_view.next_page()
+ self._evince_viewer.next_page()
def _update_nav_buttons(self):
- current_page = self._model.props.page
+ current_page = self._evince_viewer.get_current_page()
self._prev.props.sensitive = current_page > 0
self._next.props.sensitive = \
- current_page < self._document.get_n_pages() - 1
+ current_page < self._evince_viewer.get_document_n_pages() - 1
self._page_spinner_adjustment.handler_block(
self._page_spinner_adjustment_value_changed_id)
@@ -192,13 +157,12 @@ class ViewerToolbar(gtk.Toolbar):
def _page_spinner_adjustment_value_changed_cb(self, adjustment):
page = adjustment.get_value() - 1
- if self._document:
- self._model.props.page = int(page)
+ self._evince_viewer.change_to_page(page)
-def toolbar_needs_update_size_cb(widget, view, scrolledwindow):
- if hasattr(view, 'update_view_size'):
- view.update_view_size(scrolledwindow)
+def toolbar_needs_update_size_cb(widget, viewer_view, scrolledwindow):
+ if hasattr(viewer_view, 'update_view_size'):
+ viewer_view.update_view_size(scrolledwindow)
def _get_screen_dpi():
@@ -206,45 +170,147 @@ def _get_screen_dpi():
return float(xft_dpi / 1024)
+class EvinceViewer():
+ def __init__(self):
+ self._document = None
+ self._view = evince.View()
+ self._model = evince.DocumentModel()
+ self._view.set_model(self._model)
+
+ def load_document(self, filename):
+ try:
+ print "opening file %s" % filename
+ file_path = 'file://' + filename
+ self._document = evince.document_factory_get_document(file_path)
+ except gobject.GError, e:
+ _logger.error('Can not load document: %s', e)
+ return
+ else:
+ self._model.set_document(self._document)
+ # set scale based on 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)
+
+ def get_view(self):
+ return self._view
+
+ def change_to_page(self, page):
+ self._model.props.page = int(page)
+
+ def can_zoom_in(self):
+ return self._view.can_zoom_in()
+
+ def can_zoom_out(self):
+ return self._view.can_zoom_out()
+
+ def zoom_in(self):
+ self._model.props.sizing_mode = evince.SIZING_FREE
+ self._view.zoom_in()
+
+ def zoom_out(self):
+ 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 get_document_n_pages(self):
+ return self._document.get_n_pages()
+
+ def get_current_page(self):
+ return self._model.props.page
+
+ def set_page_changed_callback(self, callback):
+ self._model.connect('page-changed', callback)
+
+ def previous_page(self):
+ return self._view.previous_page()
+
+ def next_page(self):
+ return self._view.next_page()
+
+ def save(self):
+ title = self._document.get_title()
+ fpath = sys.argv[1] # XXX: Bleh
+
+ entry = datastore.create()
+ entry.set_file_path(fpath)
+
+ # For certain sites, PDFs get saved as foo.php, etc
+ # An example would be the Nepali repository @ pustakalay.org
+ # We need to force file sniffing here, otherwise the file gets
+ # stored in the datastore with the mimetype application/x-php, etc
+ entry.metadata['mime_type'] = mime.get_for_file(fpath)
+
+ if title:
+ entry.metadata['title'] = title
+ else:
+ entry.metadata['title'] = os.path.basename(sys.argv[1])
+
+ datastore.write(entry)
+
+ entry.destroy()
+
+
+def _key_press_event_cb(widget, event, evince_viewer):
+ keyname = gtk.gdk.keyval_name(event.keyval)
+ view = evince_viewer.get_view()
+ if keyname == 'KP_Home':
+ evince_viewer.zoom_in()
+ return True
+ elif keyname == 'KP_End':
+ evince_viewer.zoom_out()
+ return True
+ elif keyname == 'Page_Up' or keyname == 'KP_Page_Up':
+ view.scroll(gtk.SCROLL_PAGE_BACKWARD, False)
+ return True
+ elif keyname == 'Page_Down' or keyname == 'KP_Page_Down':
+ view.scroll(gtk.SCROLL_PAGE_FORWARD, False)
+ return True
+ elif keyname == 'Up' or keyname == 'KP_Up':
+ view.scroll(gtk.SCROLL_STEP_BACKWARD, False)
+ return True
+ elif keyname == 'Down' or keyname == 'KP_Down':
+ view.scroll(gtk.SCROLL_STEP_FORWARD, False)
+ return True
+ elif keyname == 'Left' or keyname == 'KP_Left':
+ view.scroll(gtk.SCROLL_STEP_BACKWARD, True)
+ return True
+ elif keyname == 'Right' or keyname == 'KP_Right':
+ view.scroll(gtk.SCROLL_STEP_FORWARD, True)
+ return True
+ else:
+ return False
+
+
def main(filename):
if hasattr(evince, 'evince_embed_init'):
# if we use evince-2.24
evince.evince_embed_init()
- print "opening file %s" % filename
- document = evince.document_factory_get_document('file://' + filename)
+
+ evince_viewer = EvinceViewer()
+ evince_viewer.load_document(filename)
win = gtk.Window()
win.connect('destroy', lambda w: gtk.main_quit())
vbox = gtk.VBox()
scrolledwindow = gtk.ScrolledWindow()
+ scrolledwindow.add(evince_viewer.get_view())
- view = evince.View()
- model = evince.DocumentModel()
- model.set_document(document)
- view.set_model(model)
-
- # set dpi
- dpi = _get_screen_dpi()
- min_scale = model.get_min_scale()
- max_scale = model.get_max_scale()
- model.set_min_scale(min_scale * dpi / 72.0)
- model.set_max_scale(max_scale * dpi / 72.0)
-
- scrolledwindow.add(view)
-
- toolbar = ViewerToolbar(view)
+ toolbar = ViewerToolbar(evince_viewer)
toolbar.connect('needs-update-size',
- toolbar_needs_update_size_cb, view, scrolledwindow)
- toolbar.set_document(document, model)
- # We need to wait for sometime before calling this
- #gobject.timeout_add(1200, toolbar.zoom_to_width)
+ toolbar_needs_update_size_cb, evince_viewer.get_view(), scrolledwindow)
+ toolbar.setup()
vbox.pack_start(toolbar, expand=False, fill=False)
vbox.pack_start(scrolledwindow)
win.add(vbox)
+ win.connect('key-press-event', _key_press_event_cb, evince_viewer)
win.show_all()
-
gtk.main()
if __name__ == '__main__':
--
1.7.4.4
More information about the Devel
mailing list