~ubuntu-branches/ubuntu/karmic/sugar-web-activity/karmic

« back to all changes in this revision

Viewing changes to Web.activity/browser.py

  • Committer: Bazaar Package Importer
  • Author(s): Jani Monoses
  • Date: 2008-01-31 15:17:08 UTC
  • Revision ID: james.westby@ubuntu.com-20080131151708-4tegqfae3vdhiylk
Tags: upstream-85
ImportĀ upstreamĀ versionĀ 85

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006, Red Hat, Inc.
 
2
# Copyright (C) 2007, One Laptop Per Child
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 
 
18
import os
 
19
import time
 
20
import logging
 
21
from gettext import gettext as _
 
22
 
 
23
import gobject
 
24
import gtk
 
25
import xpcom
 
26
from xpcom.nsError import *
 
27
from xpcom import components
 
28
from xpcom.components import interfaces
 
29
from hulahop.webview import WebView
 
30
 
 
31
from sugar.datastore import datastore
 
32
from sugar import profile
 
33
from sugar import env
 
34
from sugar.activity import activity
 
35
 
 
36
import sessionstore
 
37
 
 
38
_ZOOM_AMOUNT = 0.1
 
39
 
 
40
class GetSourceListener(gobject.GObject):
 
41
    _com_interfaces_ = interfaces.nsIWebProgressListener
 
42
    
 
43
    __gsignals__ = {    
 
44
        'finished':     (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
 
45
                             ([]))
 
46
    }
 
47
    
 
48
    def __init__(self, persist):
 
49
        gobject.GObject.__init__(self)
 
50
        self._persist = persist
 
51
 
 
52
    def onStateChange(self, progress, request, flags, status):
 
53
        finished = interfaces.nsIWebBrowserPersist.PERSIST_STATE_FINISHED
 
54
        if self._persist.currentState == finished:
 
55
            self.emit('finished')
 
56
 
 
57
    def onProgressChange(self, progress, request, curSelfProgress,
 
58
                         maxSelfProgress, curTotalProgress, maxTotalProgress):
 
59
        pass
 
60
 
 
61
    def onLocationChange(self, progress, request, location):
 
62
        pass
 
63
 
 
64
    def onStatusChange(self, progress, request, status, message):
 
65
        pass
 
66
 
 
67
    def onSecurityChange(self, progress, request, state):
 
68
        pass
 
69
 
 
70
class Browser(WebView):
 
71
 
 
72
    AGENT_SHEET = os.path.join(activity.get_bundle_path(), 'agent-stylesheet.css')
 
73
    USER_SHEET = os.path.join(env.get_profile_path(), 'gecko', 'user-stylesheet.css')
 
74
 
 
75
    def __init__(self):
 
76
        WebView.__init__(self)
 
77
 
 
78
        io_service_class = components.classes["@mozilla.org/network/io-service;1"]
 
79
        io_service = io_service_class.getService(interfaces.nsIIOService)
 
80
 
 
81
        cls = components.classes['@mozilla.org/content/style-sheet-service;1']
 
82
        style_sheet_service = cls.getService(interfaces.nsIStyleSheetService)
 
83
 
 
84
        if os.path.exists(Browser.AGENT_SHEET):
 
85
            agent_sheet_uri = io_service.newURI('file:///' + Browser.AGENT_SHEET,
 
86
                    None, None)
 
87
            style_sheet_service.loadAndRegisterSheet(agent_sheet_uri,
 
88
                    interfaces.nsIStyleSheetService.AGENT_SHEET)
 
89
 
 
90
        if os.path.exists(Browser.USER_SHEET):
 
91
            user_sheet_uri = io_service.newURI('file:///' + Browser.USER_SHEET,
 
92
                    None, None)
 
93
            style_sheet_service.loadAndRegisterSheet(user_sheet_uri,
 
94
                    interfaces.nsIStyleSheetService.USER_SHEET)
 
95
        
 
96
    def get_session(self):
 
97
        return sessionstore.get_session(self)
 
98
 
 
99
    def set_session(self, data):
 
100
        return sessionstore.set_session(self, data)
 
101
 
 
102
    def get_source(self):
 
103
        cls = components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
 
104
        persist = cls.createInstance(interfaces.nsIWebBrowserPersist)
 
105
        # get the source from the cache
 
106
        persist.persistFlags = interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE
 
107
 
 
108
        progresslistener = GetSourceListener(persist)
 
109
        persist.progressListener = xpcom.server.WrapObject(
 
110
            progresslistener, interfaces.nsIWebProgressListener)
 
111
        progresslistener.connect('finished', self._have_source_cb)
 
112
        
 
113
        temp_path = os.path.join(activity.get_activity_root(), 'instance')
 
114
        file_path = os.path.join(temp_path, '%i' % time.time())        
 
115
        cls = components.classes["@mozilla.org/file/local;1"]
 
116
        local_file = cls.createInstance(interfaces.nsILocalFile)
 
117
        local_file.initWithPath(file_path)
 
118
 
 
119
        uri = self.web_navigation.currentURI            
 
120
        persist.saveURI(uri, self.doc_shell, None, None, None, local_file)
 
121
        self._create_journal_object(file_path)
 
122
        self._jobject.file_path = file_path
 
123
        
 
124
    def _have_source_cb(self, progress_listener):
 
125
        logging.debug("Finished getting source - writing to datastore")                    
 
126
        datastore.write(self._jobject,
 
127
                        reply_handler=self._internal_save_cb,
 
128
                        error_handler=self._internal_save_error_cb)
 
129
 
 
130
    def _create_journal_object(self, file_path):        
 
131
        self._jobject = datastore.create()        
 
132
        title = _('Source') + ': ' + self.props.title 
 
133
        self._jobject.metadata['title'] = title
 
134
        self._jobject.metadata['keep'] = '0'
 
135
        self._jobject.metadata['buddies'] = ''
 
136
        self._jobject.metadata['preview'] = ''
 
137
        self._jobject.metadata['icon-color'] = profile.get_color().to_string()
 
138
        self._jobject.metadata['mime_type'] = 'text/html'
 
139
        self._jobject.metadata['source'] = '1'
 
140
        self._jobject.file_path = ''
 
141
        datastore.write(self._jobject)
 
142
 
 
143
    def _internal_save_cb(self):
 
144
        logging.debug("Saved source object to datastore.")
 
145
        activity.show_object_in_journal(self._jobject.object_id) 
 
146
        self._cleanup_jobject()
 
147
            
 
148
    def _internal_save_error_cb(self, err):
 
149
        logging.debug("Error saving source object to datastore: %s" % err)
 
150
        self._cleanup_jobject()
 
151
 
 
152
    def _cleanup_jobject(self):
 
153
        if self._jobject:
 
154
            if os.path.isfile(self._jobject.file_path):
 
155
                logging.debug('_cleanup_jobject: removing %r' % self._jobject.file_path)
 
156
                os.remove(self._jobject.file_path)            
 
157
            self._jobject.destroy()
 
158
            self._jobject = None
 
159
 
 
160
    def zoom_in(self):
 
161
        contentViewer = self.doc_shell.queryInterface(interfaces.nsIDocShell).contentViewer
 
162
        if contentViewer is not None:
 
163
            markupDocumentViewer = contentViewer.queryInterface(interfaces.nsIMarkupDocumentViewer)
 
164
            markupDocumentViewer.fullZoom += _ZOOM_AMOUNT
 
165
 
 
166
    def zoom_out(self):
 
167
        contentViewer = self.doc_shell.queryInterface(interfaces.nsIDocShell).contentViewer
 
168
        if contentViewer is not None:
 
169
            markupDocumentViewer = contentViewer.queryInterface(interfaces.nsIMarkupDocumentViewer)
 
170
            markupDocumentViewer.fullZoom -= _ZOOM_AMOUNT
 
171
 
 
172
class XULDialog(gtk.Window):
 
173
    def __init__(self):
 
174
        gtk.Window.__init__(self)
 
175
 
 
176
        self.view = WebView()
 
177
        self.add(self.view)
 
178
 
 
179
        self.connect('realize', self.__realize_cb)
 
180
 
 
181
    def __realize_cb(self, window):
 
182
        self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
 
183
 
 
184
class WindowCreator:
 
185
    _com_interfaces_ = interfaces.nsIWindowCreator
 
186
 
 
187
    def createChromeWindow(self, parent, chrome_flags):
 
188
        dialog = XULDialog()
 
189
        browser = dialog.view.browser
 
190
 
 
191
        dialog.view.is_chrome = True
 
192
        item = browser.queryInterface(interfaces.nsIDocShellTreeItem)
 
193
        item.itemType = interfaces.nsIDocShellTreeItem.typeChromeWrapper
 
194
 
 
195
        return browser.containerWindow
 
196
 
 
197
window_creator = WindowCreator()
 
198
cls = components.classes['@mozilla.org/embedcomp/window-watcher;1']
 
199
window_watcher = cls.getService(interfaces.nsIWindowWatcher)
 
200
window_watcher.setWindowCreator(window_creator)