1 | diff --git a/src/jarabe/journal/misc.py b/src/jarabe/journal/misc.py |
---|
2 | index b29b744..aa689a0 100644 |
---|
3 | --- a/src/jarabe/journal/misc.py |
---|
4 | +++ b/src/jarabe/journal/misc.py |
---|
5 | @@ -132,16 +132,17 @@ def _get_activities_for_mime(mime_type): |
---|
6 | |
---|
7 | def get_activities(metadata): |
---|
8 | activities = [] |
---|
9 | + registry = bundleregistry.get_registry() |
---|
10 | |
---|
11 | bundle_id = metadata.get('activity', '') |
---|
12 | if bundle_id: |
---|
13 | - activity_info = bundleregistry.get_registry().get_bundle(bundle_id) |
---|
14 | + activity_info = registry.get_bundle(bundle_id) |
---|
15 | if activity_info: |
---|
16 | activities.append(activity_info) |
---|
17 | |
---|
18 | mime_type = metadata.get('mime_type', '') |
---|
19 | if mime_type: |
---|
20 | - activities_info = _get_activities_for_mime(mime_type) |
---|
21 | + activities_info = registry.get_activities_for_lineage(mime_type) |
---|
22 | for activity_info in activities_info: |
---|
23 | if activity_info not in activities: |
---|
24 | activities.append(activity_info) |
---|
25 | diff --git a/src/jarabe/model/bundleregistry.py b/src/jarabe/model/bundleregistry.py |
---|
26 | index 42d39b0..e687b75 100644 |
---|
27 | --- a/src/jarabe/model/bundleregistry.py |
---|
28 | +++ b/src/jarabe/model/bundleregistry.py |
---|
29 | @@ -29,6 +29,7 @@ from sugar.bundle.contentbundle import ContentBundle |
---|
30 | from sugar.bundle.bundle import MalformedBundleException, \ |
---|
31 | AlreadyInstalledException, RegistrationException |
---|
32 | from sugar import env |
---|
33 | +from sugar import mime |
---|
34 | |
---|
35 | from jarabe import config |
---|
36 | |
---|
37 | @@ -241,6 +242,13 @@ class BundleRegistry(gobject.GObject): |
---|
38 | else: |
---|
39 | return None |
---|
40 | |
---|
41 | + def get_activities_for_lineage(self, mime_type): |
---|
42 | + result = self.get_activities_for_type(mime_type) |
---|
43 | + if not result: |
---|
44 | + for parent_mime in mime.get_mime_parents(mime_type): |
---|
45 | + result.extend(self.get_activities_for_type(parent_mime)) |
---|
46 | + return result |
---|
47 | + |
---|
48 | def _find_bundle(self, bundle_id, version): |
---|
49 | for bundle in self._bundles: |
---|
50 | if bundle.get_bundle_id() == bundle_id and \ |
---|
51 | diff --git a/src/jarabe/view/viewsource.py b/src/jarabe/view/viewsource.py |
---|
52 | index 870b176..9f71987 100644 |
---|
53 | --- a/src/jarabe/view/viewsource.py |
---|
54 | +++ b/src/jarabe/view/viewsource.py |
---|
55 | @@ -33,15 +33,71 @@ from sugar.graphics.xocolor import XoColor |
---|
56 | from sugar.graphics.menuitem import MenuItem |
---|
57 | from sugar.graphics.toolbutton import ToolButton |
---|
58 | from sugar.graphics.radiotoolbutton import RadioToolButton |
---|
59 | -from sugar.bundle.activitybundle import ActivityBundle |
---|
60 | +from sugar.graphics.menuitem import MenuItem |
---|
61 | +from sugar.activity.bundlebuilder import XOPackager, Config, Builder |
---|
62 | +from sugar import mime |
---|
63 | +from sugar import profile |
---|
64 | +from sugar.activity import activityfactory |
---|
65 | +from sugar.activity.activity import SCOPE_PRIVATE |
---|
66 | from sugar.datastore import datastore |
---|
67 | from sugar import mime |
---|
68 | +from sugar.bundle.activitybundle import ActivityBundle |
---|
69 | +from jarabe.model import bundleregistry |
---|
70 | +from tempfile import gettempdir |
---|
71 | |
---|
72 | _SOURCE_FONT = pango.FontDescription('Monospace %d' % style.FONT_SIZE) |
---|
73 | |
---|
74 | _logger = logging.getLogger('ViewSource') |
---|
75 | map_activity_to_window = {} |
---|
76 | |
---|
77 | +ACTIVITY_MIME = "application/vnd.olpc-sugar" |
---|
78 | + |
---|
79 | +def _bundle_activity(path): |
---|
80 | + builder = XOPackager(Builder(Config(path, gettempdir(), None))) |
---|
81 | + builder.package() |
---|
82 | + |
---|
83 | + jobject = datastore.create() |
---|
84 | + |
---|
85 | + metadata = { |
---|
86 | + 'title': _('%s Bundle') % builder.config.activity_name, |
---|
87 | + 'title_set_by_user': '1', |
---|
88 | + 'suggested_filename': '%s-%d.xo' % (builder.config.bundle_name, |
---|
89 | + builder.config.version), |
---|
90 | + 'icon-color': profile.get_color().to_string(), |
---|
91 | + 'mime_type': 'application/vnd.olpc-sugar', |
---|
92 | + 'activity' : builder.config.bundle_id, |
---|
93 | + 'share-scope' : SCOPE_PRIVATE, |
---|
94 | + 'preview' : '', |
---|
95 | + 'source' : path, |
---|
96 | + } |
---|
97 | + for k, v in metadata.items(): |
---|
98 | + jobject.metadata[k] = v # dict.update method is missing =( |
---|
99 | + jobject.file_path = builder.package_path |
---|
100 | + datastore.write(jobject) |
---|
101 | + #jobject.destroy() |
---|
102 | + os.remove(builder.package_path) |
---|
103 | + return jobject.object_id |
---|
104 | + |
---|
105 | +class DocumentData(dict): |
---|
106 | + """'version' should always be a key. |
---|
107 | + |
---|
108 | + if version is 1, other keys should be |
---|
109 | + ('mime_type', 'title', 'path', 'human_readable')""" |
---|
110 | + def __init__(self, *args, **kwargs): |
---|
111 | + super(DocumentData, self).__init__(*args,**kwargs) |
---|
112 | + |
---|
113 | + required_keys = ('mime_type', 'title', 'path', 'human_readable') |
---|
114 | + |
---|
115 | + if self["version"] == 1: |
---|
116 | + if [1 for key in required_keys |
---|
117 | + if (key not in self.keys())]: |
---|
118 | + logging.error("Activity returned misversioned data on " |
---|
119 | + "current document") |
---|
120 | + else: |
---|
121 | + for key in required_keys: |
---|
122 | + self[key] = None |
---|
123 | + _logger.debug('Current document data in unknown version') |
---|
124 | + |
---|
125 | def setup_view_source(activity): |
---|
126 | service = activity.get_service() |
---|
127 | if service is not None: |
---|
128 | @@ -280,6 +336,10 @@ class Toolbar(gtk.Toolbar): |
---|
129 | self._add_separator() |
---|
130 | |
---|
131 | if bundle_path is not None and os.path.exists(bundle_path): |
---|
132 | + self._add_source(DocumentData(version=1, mime_type=ACTIVITY_MIME, |
---|
133 | + title=title, path=bundle_path, |
---|
134 | + human_readable=True), |
---|
135 | + 'printer') #TODO: get a better icon |
---|
136 | activity_button = RadioToolButton() |
---|
137 | icon = Icon(file=file_name, |
---|
138 | icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR, |
---|
139 | @@ -311,6 +371,53 @@ class Toolbar(gtk.Toolbar): |
---|
140 | self.insert(stop, -1) |
---|
141 | stop.show() |
---|
142 | |
---|
143 | + def _add_source(self, data, icon): |
---|
144 | + |
---|
145 | + button = RadioToolButton(named_icon=icon) |
---|
146 | + group = getattr(self, 'group', None) |
---|
147 | + if group: |
---|
148 | + button.props.group = group |
---|
149 | + else: |
---|
150 | + self.group = button |
---|
151 | + |
---|
152 | + if data["human_readable"]: |
---|
153 | + button.connect('toggled', self.__button_toggled_cb, data["path"]) |
---|
154 | + |
---|
155 | + button.props.tooltip = data["title"] |
---|
156 | + self.insert(button, -1) |
---|
157 | + button.show() |
---|
158 | + |
---|
159 | + if data["mime_type"]: |
---|
160 | + registry = bundleregistry.get_registry() |
---|
161 | + activities = registry.get_activities_for_lineage(data["mime_type"]) |
---|
162 | + if activities: |
---|
163 | + palette = button.get_palette() |
---|
164 | + |
---|
165 | + menuitem = gtk.SeparatorMenuItem() |
---|
166 | + palette.menu.append(menuitem) |
---|
167 | + menuitem.show() |
---|
168 | + |
---|
169 | + for activity in activities: |
---|
170 | + menuitem = MenuItem(activity.get_name(), |
---|
171 | + activity.get_icon()) |
---|
172 | + menuitem.connect('activate', self._launch_with, |
---|
173 | + (activity,data["path"],data["mime_type"])) |
---|
174 | + palette.menu.append(menuitem) |
---|
175 | + menuitem.show() |
---|
176 | + |
---|
177 | + def _launch_with(self, menuitem, options): |
---|
178 | + activity, path, mime_type = options |
---|
179 | + if mime_type == ACTIVITY_MIME: |
---|
180 | + object_id = _bundle_activity(path) |
---|
181 | + else: |
---|
182 | + object_id = self.activity_service.bundleSource(path, mime_type) |
---|
183 | + |
---|
184 | + if object_id: |
---|
185 | + activityfactory.create_with_object_id(activity, object_id) |
---|
186 | + else: |
---|
187 | + logging.error("Failed to rebundle activity for editing source." |
---|
188 | + "Mime type:" + mime_type) |
---|
189 | + |
---|
190 | def _add_separator(self, expand=False): |
---|
191 | separator = gtk.SeparatorToolItem() |
---|
192 | separator.props.draw = False |
---|