[Sugar-devel] [PATCH Browse 2/2] Add support for exporting ("printing") to PDF
Gonzalo Odiard
gonzalo at laptop.org
Sun May 29 19:18:31 EDT 2011
Thanks for working in this!
It's a great addition to Browse.
Gonzalo
On Sun, May 29, 2011 at 11:04 AM, Sascha Silbe <silbe at activitycentral.com>wrote:
> The content of the current tab gets exported as a new data store entry
> (independent from the current Browse session), including some of the
> metadata (title, original_url).
>
> Similar to the way it works for Turtle Art, we expose the functionality as
> a
> button in the Activity toolbar, with 'document-save' as icon. There is no
> way
> for the user to influence the result (i.e. to set print options).
>
> To work around a python-xpcom bug [1], we "patch" python-xpcom at runtime.
> Given the current state of affairs regarding python-xpcom, this is probably
> the best we can do.
>
> [1] http://bugs.debian.org/628484
>
> Signed-off-by: Sascha Silbe <silbe at activitycentral.com>
> ---
> browser.py | 68
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> webtoolbar.py | 10 ++++++++
> 2 files changed, 78 insertions(+), 0 deletions(-)
>
> diff --git a/browser.py b/browser.py
> index 649a71e..bd57e79 100644
> --- a/browser.py
> +++ b/browser.py
> @@ -20,6 +20,7 @@ import os
> import time
> import logging
> from gettext import gettext as _
> +import tempfile
>
> import gobject
> import gtk
> @@ -304,6 +305,73 @@ class Browser(WebView):
>
> self.emit('is-setup')
>
> + def export_pdf(self):
> + temp_dir = os.path.join(activity.get_activity_root(), 'instance')
> + pdf_file = tempfile.NamedTemporaryFile(suffix='.pdf',
> dir=temp_dir,
> + delete=False)
> +
> + logging.debug('pdf_file.name = %r', pdf_file.name)
> + try:
> + self._generate_pdf(pdf_file.name)
> + except:
> + os.remove(pdf_file.name)
> + raise
> +
> + def _generate_pdf(self, file_name):
> + cls = components.classes['@
> mozilla.org/gfx/printsettings-service;1']
> + setting_service =
> cls.getService(interfaces.nsIPrintSettingsService)
> + req =
> self.get_dom_window().QueryInterface(interfaces.nsIInterfaceRequestor)
> + print_iface = req.getInterface(interfaces.nsIWebBrowserPrint)
> +
> + settings = setting_service.newPrintSettings
> + settings.printSilent = True
> + settings.printToFile = True
> + settings.toFileName = file_name
> + settings.outputFormat =
> interfaces.nsIPrintSettings.kOutputFormatPDF
> +
> + try:
> + print_method = getattr(print_iface, 'print')
> + except SyntaxError:
> + # HACK: Run-time patch python-xpcom to work around a bug.
> + # 'print' is a reserved keyword, so it must not occur in
> generated
> + # code.
> + iid = interfaces.nsIWebBrowserPrint
> + internal_interface = print_iface.__dict__['_interfaces_'][iid]
> + info = internal_interface.__dict__['_method_infos_']['print']
> + info.name = 'print_'
> + print_method = getattr(print_iface, 'print')
> +
> + save_info = {'file_name': file_name, 'title': self.props.title,
> + 'uri': self.get_url_from_nsiuri(self.progress.location)}
> +
> + def save_callback(info):
> + # Even after the progress listener reports completion, the
> file
> + # is still empty. We need to wait for everything to calm down
> + # before triggering the save.
> + gobject.idle_add(self._save_pdf, info)
> +
> + listener = xpcom.server.WrapObject(SaveListener(save_info,
> + save_callback),
> +
> interfaces.nsIWebProgressListener)
> + print_method(settings, listener)
> +
> + def _save_pdf(self, info):
> + logging.debug('_save_pdf(%r)', info)
> + try:
> + if os.stat(info['file_name']).st_size == 0:
> + raise ValueError('Generated PDF file is empty')
> +
> + ds_object = datastore.create()
> + ds_object.file_path = info['file_name']
> + ds_object.metadata['mime_type'] = 'application/pdf'
> + ds_object.metadata['title'] = info['title']
> + ds_object.metadata['original_uri'] = info['uri']
> + datastore.write(ds_object, transfer_ownership=True)
> + except:
> + if os.path.exists(info['file_name']):
> + os.remove(info['file_name'])
> + raise
> +
> def get_url_from_nsiuri(self, uri):
> """
> get a nsIURI object and return a string with the url
> diff --git a/webtoolbar.py b/webtoolbar.py
> index 8b0e108..3ce4011 100644
> --- a/webtoolbar.py
> +++ b/webtoolbar.py
> @@ -255,6 +255,12 @@ class PrimaryToolbar(ToolbarBase):
> else:
> toolbar = self
>
> + export_pdf_button = ToolButton('document-save')
> + export_pdf_button.set_tooltip(_('Export as PDF'))
> + export_pdf_button.connect('clicked', self._export_pdf_cb)
> + activity_button.page.insert(export_pdf_button, -1)
> + export_pdf_button.show()
> +
> self._go_home = ToolButton('go-home')
> self._go_home.set_tooltip(_('Home page'))
> self._go_home.connect('clicked', self._go_home_cb)
> @@ -494,3 +500,7 @@ class PrimaryToolbar(ToolbarBase):
>
> def _link_add_clicked_cb(self, button):
> self.emit('add-link')
> +
> + def _export_pdf_cb(self, button):
> + browser = self._tabbed_view.props.current_browser
> + browser.export_pdf()
> --
> 1.7.2.5
>
> _______________________________________________
> Sugar-devel mailing list
> Sugar-devel at lists.sugarlabs.org
> http://lists.sugarlabs.org/listinfo/sugar-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sugarlabs.org/archive/sugar-devel/attachments/20110529/316d039c/attachment.html>
More information about the Sugar-devel
mailing list