From ef8da454e7679b3ff800165ac90135e153ce5c7f Mon Sep 17 00:00:00 2001 From: Gonzalo Odiard Date: Fri, 03 Jun 2011 19:37:46 +0000 Subject: Add pluggin to inline display of PDF files The mozplugger binaries were compiled applying the patches from Sayamindu (updated) in the last packaged version of mozplugger. The sugar-pdf-viewer utility was updated to follow evince changes. --- diff --git a/activity/activity.info b/activity/activity.info index 49179cb..d916357 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = Browse -activity_version = 129 +activity_version = 129.1 bundle_id = org.laptop.WebActivity icon = activity-web exec = sugar-activity webactivity.WebActivity -s diff --git a/bin/m4 b/bin/m4 new file mode 100755 index 0000000..b7c5640 --- /dev/null +++ b/bin/m4 Binary files differ diff --git a/bin/mozplugger-controller b/bin/mozplugger-controller new file mode 100755 index 0000000..b764962 --- /dev/null +++ b/bin/mozplugger-controller Binary files differ diff --git a/bin/mozplugger-helper b/bin/mozplugger-helper new file mode 100755 index 0000000..471db8f --- /dev/null +++ b/bin/mozplugger-helper Binary files differ diff --git a/bin/mozplugger-linker b/bin/mozplugger-linker new file mode 100755 index 0000000..9021249 --- /dev/null +++ b/bin/mozplugger-linker Binary files differ diff --git a/bin/sugar-pdf-viewer b/bin/sugar-pdf-viewer new file mode 100755 index 0000000..b9719ec --- /dev/null +++ b/bin/sugar-pdf-viewer @@ -0,0 +1,251 @@ +#!/usr/bin/env python +# Copyright (C) 2008, 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 gtk +import gobject +import evince +from sugar.datastore import datastore +from sugar.graphics.toolbutton import ToolButton +from sugar import mime + +import sys +import os + + +class ViewerToolbar(gtk.Toolbar): + __gtype_name__ = 'ViewerToolbar' + + __gsignals__ = { + 'needs-update-size': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([])) + } + + def __init__(self, evince_view): + gtk.Toolbar.__init__(self) + self.set_style(gtk.TOOLBAR_ICONS) + + self._evince_view = evince_view + self._document = None + + self._prev = ToolButton('go-previous-paired') + self._prev.connect('clicked', self._prev_cb) + self.insert(self._prev, -1) + self._prev.props.sensitive = False + self._prev.show() + + self._next = ToolButton('go-next-paired') + self._next.connect('clicked', self._next_cb) + self.insert(self._next, -1) + self._next.props.sensitive = False + self._next.show() + + self._page_spinner_adjustment = \ + gtk.Adjustment(value=1, lower=1, upper=1, step_incr=1) + self._page_spinner_adjustment_value_changed_id = \ + self._page_spinner_adjustment.connect('value-changed', + self._page_spinner_adjustment_value_changed_cb) + + self._page_spinner = \ + gtk.SpinButton(adjustment=self._page_spinner_adjustment, + climb_rate=0.2, digits=0) + self._page_spinner.props.sensitive = False + + item = gtk.ToolItem() + item.add(self._page_spinner) + self.insert(item, -1) + item.show_all() + + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + separator.set_expand(False) + self.insert(separator, -1) + separator.show() + + self._zoom_out = ToolButton('zoom-out') + self._zoom_out.connect('clicked', self._zoom_out_cb) + self.insert(self._zoom_out, -1) + self._zoom_out.show() + + self._zoom_in = ToolButton('zoom-in') + self._zoom_in.connect('clicked', self._zoom_in_cb) + self.insert(self._zoom_in, -1) + self._zoom_in.show() + + self._zoom_to_width = ToolButton('zoom-best-fit') + self._zoom_to_width.connect('clicked', self._zoom_to_width_cb) + self.insert(self._zoom_to_width, -1) + self._zoom_to_width.show() + + separator1 = gtk.SeparatorToolItem() + separator1.set_draw(False) + separator1.set_expand(True) + self.insert(separator1, -1) + separator1.show() + + self._save = gtk.ToolButton(gtk.STOCK_SAVE) + self._save.connect('clicked', self._save_cb) + self.insert(self._save, -1) + self._save.show() + + 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._update_zoom_buttons() + + def _zoom_out_cb(self, button): + self.zoom_out() + + def zoom_to_width(self): + self._model.props.sizing_mode = evince.SIZING_FIT_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() + + 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._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) + + self._update_zoom_buttons() + self._update_nav_buttons() + + def _prev_cb(self, button): + self._evince_view.previous_page() + + def _next_cb(self, button): + self._evince_view.next_page() + + def _update_nav_buttons(self): + current_page = self._model.props.page + self._prev.props.sensitive = current_page > 0 + self._next.props.sensitive = \ + current_page < self._document.get_n_pages() - 1 + + self._page_spinner_adjustment.handler_block( + self._page_spinner_adjustment_value_changed_id) + self._page_spinner_adjustment.set_value(current_page + 1) + self._page_spinner_adjustment.handler_unblock( + self._page_spinner_adjustment_value_changed_id) + + def _page_changed_cb(self, model, page_from, page_to): + self._update_nav_buttons() + + def _page_spinner_adjustment_value_changed_cb(self, adjustment): + page = adjustment.get_value() - 1 + if self._document: + self._model.props.page = int(page) + + +def toolbar_needs_update_size_cb(widget, view, scrolledwindow): + if hasattr(view, 'update_view_size'): + view.update_view_size(scrolledwindow) + + +def _get_screen_dpi(): + xft_dpi = gtk.settings_get_default().get_property('gtk-xft-dpi') + return float(xft_dpi / 1024) + + +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) + + win = gtk.Window() + win.connect('destroy', lambda w: gtk.main_quit()) + vbox = gtk.VBox() + scrolledwindow = gtk.ScrolledWindow() + + 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.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) + + vbox.pack_start(toolbar, expand=False, fill=False) + vbox.pack_start(scrolledwindow) + win.add(vbox) + + win.show_all() + + gtk.main() + +if __name__ == '__main__': + main(sys.argv[1]) diff --git a/plugins/conf/mozpluggerrc b/plugins/conf/mozpluggerrc new file mode 100644 index 0000000..e2c90cd --- /dev/null +++ b/plugins/conf/mozpluggerrc @@ -0,0 +1,52 @@ +# Modified mozpluggerrc for OLPC +# Contact: Sayamindu Dasgupta: sayamindu@laptop.org +# +# Configure file for MozPlugger 1.10 +# Version: January 4, 2008 +# +# Commands which are not installed on your system will not be used. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + + +################### +### m4 macros ### +################### + +changequote([,]) + +### Helpers + +#define(ENABLE_HELPERS) + +ifdef([ENABLE_HELPERS],[ + define(HELPER,[nokill noisy: $1]) +],[ + define(HELPER,[]) +]) + +####################### +### Documents ### +####################### + +application/pdf:pdf:PDF file +application/x-pdf:pdf:PDF file +text/pdf:pdf:PDF file +text/x-pdf:pdf:PDF file + repeat swallow(sugar-pdf-viewer) fill: sugar-pdf-viewer "$file" + +application/x-postscript:ps:PostScript file +application/postscript:ps:PostScript file + repeat swallow(sugar-pdf-viewer) fill: sugar-pdf-viewer "$file" diff --git a/plugins/mozplugger.so b/plugins/mozplugger.so new file mode 100644 index 0000000..fd9c1a7 --- /dev/null +++ b/plugins/mozplugger.so Binary files differ diff --git a/webactivity.py b/webactivity.py index eefb169..1e9280e 100644 --- a/webactivity.py +++ b/webactivity.py @@ -68,6 +68,12 @@ if not NEW_TOOLBARS: _TOOLBAR_EDIT = 1 _TOOLBAR_BROWSE = 2 +# Setup some env variables for the embedded PDF viewer +os.environ['MOZ_PLUGIN_PATH'] = os.path.join(os.environ['SUGAR_BUNDLE_PATH'], + 'plugins') +os.environ['OPERA_DIR'] = os.path.join(os.environ['SUGAR_BUNDLE_PATH'], + 'plugins', 'conf') + if os.path.exists(_version_file): f = open(_version_file) _profile_version = int(f.read()) -- cgit v0.9.1