Merge lp:~victored/granite/contractor-wrapper into lp:~elementary-pantheon/granite/granite
- contractor-wrapper
- Merge into granite
Status: | Merged |
---|---|
Merged at revision: | 559 |
Proposed branch: | lp:~victored/granite/contractor-wrapper |
Merge into: | lp:~elementary-pantheon/granite/granite |
Diff against target: |
508 lines (+269/-120) 6 files modified
demo/main.vala (+11/-37) lib/CMakeLists.txt (+1/-0) lib/Services/Contractor.vala (+67/-0) lib/Services/ContractorProxy.vala (+188/-83) lib/Widgets/ContractorMenu.vala (+1/-0) lib/Widgets/ContractorView.vala (+1/-0) |
To merge this branch: | bzr merge lp:~victored/granite/contractor-wrapper |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sergey "Shnatsel" Davidoff (community) | Approve | ||
Victor Martinez (community) | Approve | ||
Review via email: mp+159948@code.launchpad.net |
Commit message
Description of the change
I've modified the public API of Contractor to be contract-id independent, so that we encourage code that manages contracts "blindly".
---
Akshay will be away from coding for a couple of days (or weeks?), so I'm proposing this alternative API for contractor. This is based on Akshay's work.
Victor Martinez (victored) wrote : | # |
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Too bad I can't test it with testing scripts because the Granite build fails due to symbol changes.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Here are the symbol changes: http://
Looks like this branch breaks ABI.
Victor Martinez (victored) wrote : | # |
Indeed, this breaks the ABI, since it removes the constructors. I want to propose a solution that doesn't break the ABI:
1) Leave the previous Contractor class and it's DBus interface as they are, make their methods return empty hashmaps, and add the proper deprecation annotations. In other words, leave the previous contractor ABI untouched.
2) In addition to (1), Modify the class name for the new Contractor API. Instead of Granite.
Rico Tzschichholz (ricotz) wrote : | # |
"Removing" the constructor is fine since it is suppose to be a singleton which is a needed API break. And preserving ABI in this area shouldn't be a target anyway. So better break it for real if the consumers are fixable in no-time.
Rico Tzschichholz (ricotz) wrote : | # |
Please list/mention the current consumers of the contractor api
Victor Martinez (victored) wrote : | # |
The only ones I know are Scratch and Pantheon Files. Of course there might be others, but since the new API depends on a new daemon, those applications will have to migrate to the new API eventually.
I am handling the port of Pantheon Files to the new API on the branch mentioned above.
The ABI breakage should be gone now.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Here's a list of current Contractor users (From https:/
ContractorMenu widget in Granite
ContractorView widget in Granite
Context menu of Pantheon-Files
Maya, Scratch, Midori and elementary-flavored Simple Scan access Contractor via Granite convenience functions and rely on the fact that Contractor returns a string to be executed
Eidete uses ContractorView widget from Granite, needs to be updated due to API break
Victor Martinez (victored) wrote : | # |
ABI break fixed. Now we only have symbol additions and no removals.
Build log: http://
Victor Martinez (victored) wrote : | # |
The current merge stopper is bug #1171690 IMO.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Bug #1171690 debunked.
Victor Martinez (victored) : | # |
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
I've tested it with lp:~victored/pantheon-files/contractor-plugin and it seems to work fine.
- 574. By Victor Martinez
-
Contracts can specify either an icon name or an absolute path to an icon file. Make sure we support both of them properly.
- 575. By Victor Martinez
-
Avoid copying structs to avoid segmentation fault
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Files still exhibits a bug that's not present in raw D-bus API: https:/
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
After this is approved I'll land Contractor 0.3 to PPA. Everything is ready, we just have to enable the recipe: https:/
- 576. By Victor Martinez
-
Let's keep the references to the contracts around all the time.
Previously we were depending on references held by client code, but it's a source of bugs, so better keep our own references in addition to external references.
Victor Martinez (victored) wrote : | # |
> Files still exhibits a bug that's not present in raw D-bus API: https:/
This bug is only related to Files. The DBus API and this wrapper API are doing their job properly.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Works fine for me now. Thanks!
Preview Diff
1 | === modified file 'demo/main.vala' | |||
2 | --- demo/main.vala 2013-03-20 15:42:25 +0000 | |||
3 | +++ demo/main.vala 2013-04-24 17:07:27 +0000 | |||
4 | @@ -13,7 +13,7 @@ | |||
5 | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
6 | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
7 | 15 | Lesser General Public License for more details. | 15 | Lesser General Public License for more details. |
9 | 16 | 16 | ||
10 | 17 | You should have received a copy of the GNU Lesser General | 17 | You should have received a copy of the GNU Lesser General |
11 | 18 | Public License along with this library; if not, write to the | 18 | Public License along with this library; if not, write to the |
12 | 19 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 19 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
13 | @@ -276,32 +276,6 @@ | |||
14 | 276 | right_sep.set_expand (true); | 276 | right_sep.set_expand (true); |
15 | 277 | main_toolbar.insert (right_sep, -1); | 277 | main_toolbar.insert (right_sep, -1); |
16 | 278 | 278 | ||
17 | 279 | // Contractor | ||
18 | 280 | var contractor_tab = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); | ||
19 | 281 | var text_view = new Gtk.TextView (); | ||
20 | 282 | |||
21 | 283 | var hash_tables = Granite.Services.Contractor.get_contract ("/.zip", "application/zip"); | ||
22 | 284 | foreach (var hash_table in hash_tables) { | ||
23 | 285 | text_view.buffer.text += hash_table.lookup ("Name") | ||
24 | 286 | + ": " + hash_table.lookup ("Description") | ||
25 | 287 | + " icon: " + hash_table.lookup ("Exec") + "\n"; | ||
26 | 288 | } | ||
27 | 289 | |||
28 | 290 | contractor_tab.add (text_view); | ||
29 | 291 | contractor_tab.add (new Granite.Widgets.ContractorView ("file:///home/user/file.txt", "text/plain")); | ||
30 | 292 | var contractor_menu = new Granite.Widgets.ContractorMenu ("/home/user/file.txt", "text"); | ||
31 | 293 | var contractor_button_image = new Gtk.Image.from_icon_name ("document-export", | ||
32 | 294 | Gtk.IconSize.LARGE_TOOLBAR); | ||
33 | 295 | var contractor_tool_item = new Granite.Widgets.ToolButtonWithMenu (contractor_button_image, | ||
34 | 296 | "Share", contractor_menu); | ||
35 | 297 | main_toolbar.insert (contractor_tool_item, -1); | ||
36 | 298 | |||
37 | 299 | contractor_tool_item.halign = contractor_tool_item.valign = Gtk.Align.CENTER; | ||
38 | 300 | |||
39 | 301 | var contractor_item = new SourceListItem ("Contractor"); | ||
40 | 302 | contractor_item.page_num = page_switcher.append_page (contractor_tab, null); | ||
41 | 303 | services_category.add (contractor_item); | ||
42 | 304 | |||
43 | 305 | // Search Entry | 279 | // Search Entry |
44 | 306 | var search_entry = new Granite.Widgets.SearchBar ("Search"); | 280 | var search_entry = new Granite.Widgets.SearchBar ("Search"); |
45 | 307 | var search_item = new Gtk.ToolItem (); | 281 | var search_item = new Gtk.ToolItem (); |
46 | @@ -343,42 +317,42 @@ | |||
47 | 343 | 317 | ||
48 | 344 | private void show_light_window () { | 318 | private void show_light_window () { |
49 | 345 | var light_window = new Granite.Widgets.LightWindow (); | 319 | var light_window = new Granite.Widgets.LightWindow (); |
51 | 346 | 320 | ||
52 | 347 | var light_window_notebook = new Granite.Widgets.StaticNotebook (); | 321 | var light_window_notebook = new Granite.Widgets.StaticNotebook (); |
53 | 348 | var entry = new Gtk.Entry (); | 322 | var entry = new Gtk.Entry (); |
54 | 349 | var open_drop = new Gtk.ComboBoxText (); | 323 | var open_drop = new Gtk.ComboBoxText (); |
55 | 350 | var open_lbl = new LLabel ("Alwas Open Mpeg Video Files with Audience"); | 324 | var open_lbl = new LLabel ("Alwas Open Mpeg Video Files with Audience"); |
57 | 351 | 325 | ||
58 | 352 | var grid = new Gtk.Grid (); | 326 | var grid = new Gtk.Grid (); |
59 | 353 | grid.attach (new Gtk.Image.from_icon_name ("video-x-generic", Gtk.IconSize.DIALOG), 0, 0, 1, 2); | 327 | grid.attach (new Gtk.Image.from_icon_name ("video-x-generic", Gtk.IconSize.DIALOG), 0, 0, 1, 2); |
60 | 354 | grid.attach (entry, 1, 0, 1, 1); | 328 | grid.attach (entry, 1, 0, 1, 1); |
61 | 355 | grid.attach (new LLabel ("1.13 GB, Mpeg Video File"), 1, 1, 1, 1); | 329 | grid.attach (new LLabel ("1.13 GB, Mpeg Video File"), 1, 1, 1, 1); |
63 | 356 | 330 | ||
64 | 357 | grid.attach (light_window_notebook, 0, 2, 2, 1); | 331 | grid.attach (light_window_notebook, 0, 2, 2, 1); |
66 | 358 | 332 | ||
67 | 359 | var general = new Gtk.Grid (); | 333 | var general = new Gtk.Grid (); |
68 | 360 | general.attach (new LLabel.markup ("<b>Info:</b>"), 0, 0, 2, 1); | 334 | general.attach (new LLabel.markup ("<b>Info:</b>"), 0, 0, 2, 1); |
70 | 361 | 335 | ||
71 | 362 | general.attach (new LLabel.right ("Created:"), 0, 1, 1, 1); | 336 | general.attach (new LLabel.right ("Created:"), 0, 1, 1, 1); |
72 | 363 | general.attach (new LLabel.right ("Modified:"), 0, 2, 1, 1); | 337 | general.attach (new LLabel.right ("Modified:"), 0, 2, 1, 1); |
73 | 364 | general.attach (new LLabel.right ("Opened:"), 0, 3, 1, 1); | 338 | general.attach (new LLabel.right ("Opened:"), 0, 3, 1, 1); |
74 | 365 | general.attach (new LLabel.right ("Mimetype:"), 0, 4, 1, 1); | 339 | general.attach (new LLabel.right ("Mimetype:"), 0, 4, 1, 1); |
75 | 366 | general.attach (new LLabel.right ("Location:"), 0, 5, 1, 1); | 340 | general.attach (new LLabel.right ("Location:"), 0, 5, 1, 1); |
77 | 367 | 341 | ||
78 | 368 | general.attach (new LLabel ("Today at 9:50 PM"), 1, 1, 1, 1); | 342 | general.attach (new LLabel ("Today at 9:50 PM"), 1, 1, 1, 1); |
79 | 369 | general.attach (new LLabel ("Today at 9:50 PM"), 1, 2, 1, 1); | 343 | general.attach (new LLabel ("Today at 9:50 PM"), 1, 2, 1, 1); |
80 | 370 | general.attach (new LLabel ("Today at 10:00 PM"), 1, 3, 1, 1); | 344 | general.attach (new LLabel ("Today at 10:00 PM"), 1, 3, 1, 1); |
81 | 371 | general.attach (new LLabel ("video/mpeg"), 1, 4, 1, 1); | 345 | general.attach (new LLabel ("video/mpeg"), 1, 4, 1, 1); |
82 | 372 | general.attach (new LLabel ("/home/daniel/Downloads"), 1, 5, 1, 1); | 346 | general.attach (new LLabel ("/home/daniel/Downloads"), 1, 5, 1, 1); |
84 | 373 | 347 | ||
85 | 374 | general.attach (new LLabel.markup ("<b>Open with:</b>"), 0, 6, 2, 1); | 348 | general.attach (new LLabel.markup ("<b>Open with:</b>"), 0, 6, 2, 1); |
86 | 375 | general.attach (open_drop, 0, 7, 2, 1); | 349 | general.attach (open_drop, 0, 7, 2, 1); |
87 | 376 | general.attach (open_lbl, 0, 8, 2, 1); | 350 | general.attach (open_lbl, 0, 8, 2, 1); |
89 | 377 | 351 | ||
90 | 378 | light_window_notebook.append_page (general, new Gtk.Label ("General")); | 352 | light_window_notebook.append_page (general, new Gtk.Label ("General")); |
91 | 379 | light_window_notebook.append_page (new Gtk.Label ("More"), new Gtk.Label ("More")); | 353 | light_window_notebook.append_page (new Gtk.Label ("More"), new Gtk.Label ("More")); |
92 | 380 | light_window_notebook.append_page (new Gtk.Label ("Sharing"), new Gtk.Label ("Sharing")); | 354 | light_window_notebook.append_page (new Gtk.Label ("Sharing"), new Gtk.Label ("Sharing")); |
94 | 381 | 355 | ||
95 | 382 | open_lbl.margin_left = 24; | 356 | open_lbl.margin_left = 24; |
96 | 383 | open_drop.margin_left = 12; | 357 | open_drop.margin_left = 12; |
97 | 384 | open_drop.append ("audience", "Audience"); | 358 | open_drop.append ("audience", "Audience"); |
98 | @@ -389,7 +363,7 @@ | |||
99 | 389 | entry.text = "Cool Hand Luke"; | 363 | entry.text = "Cool Hand Luke"; |
100 | 390 | general.column_spacing = 6; | 364 | general.column_spacing = 6; |
101 | 391 | general.row_spacing = 6; | 365 | general.row_spacing = 6; |
103 | 392 | 366 | ||
104 | 393 | light_window.add (grid); | 367 | light_window.add (grid); |
105 | 394 | light_window.show_all (); | 368 | light_window.show_all (); |
106 | 395 | } | 369 | } |
107 | 396 | 370 | ||
108 | === modified file 'lib/CMakeLists.txt' | |||
109 | --- lib/CMakeLists.txt 2012-12-21 00:46:56 +0000 | |||
110 | +++ lib/CMakeLists.txt 2013-04-24 17:07:27 +0000 | |||
111 | @@ -16,6 +16,7 @@ | |||
112 | 16 | Services/Paths.vala | 16 | Services/Paths.vala |
113 | 17 | Services/System.vala | 17 | Services/System.vala |
114 | 18 | Services/Contractor.vala | 18 | Services/Contractor.vala |
115 | 19 | Services/ContractorProxy.vala | ||
116 | 19 | Services/IconFactory.vala | 20 | Services/IconFactory.vala |
117 | 20 | Services/SimpleCommand.vala | 21 | Services/SimpleCommand.vala |
118 | 21 | Widgets/Utils.vala | 22 | Widgets/Utils.vala |
119 | 22 | 23 | ||
120 | === added file 'lib/Services/Contractor.vala' | |||
121 | --- lib/Services/Contractor.vala 1970-01-01 00:00:00 +0000 | |||
122 | +++ lib/Services/Contractor.vala 2013-04-24 17:07:27 +0000 | |||
123 | @@ -0,0 +1,67 @@ | |||
124 | 1 | /*** | ||
125 | 2 | Copyright (C) 2011-2013 Lucas Baudin <xapantu@gmail.com> | ||
126 | 3 | |||
127 | 4 | This program or library is free software; you can redistribute it | ||
128 | 5 | and/or modify it under the terms of the GNU Lesser General Public | ||
129 | 6 | License as published by the Free Software Foundation; either | ||
130 | 7 | version 3 of the License, or (at your option) any later version. | ||
131 | 8 | |||
132 | 9 | This library is distributed in the hope that it will be useful, | ||
133 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
134 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
135 | 12 | Lesser General Public License for more details. | ||
136 | 13 | |||
137 | 14 | You should have received a copy of the GNU Lesser General | ||
138 | 15 | Public License along with this library; if not, write to the | ||
139 | 16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
140 | 17 | Boston, MA 02110-1301 USA. | ||
141 | 18 | ***/ | ||
142 | 19 | |||
143 | 20 | namespace Granite.Services { | ||
144 | 21 | [DBus (name = "org.elementary.Contractor")] | ||
145 | 22 | interface ContractorDBus : Object { | ||
146 | 23 | public abstract GLib.HashTable<string,string>[] GetServicesByLocation (string strlocation, string? file_mime = "") throws IOError; | ||
147 | 24 | public abstract GLib.HashTable<string,string>[] GetServicesByLocationsList (GLib.HashTable<string,string>[] locations) throws IOError; | ||
148 | 25 | } | ||
149 | 26 | |||
150 | 27 | /** | ||
151 | 28 | * A way to handle contractor, a way to communicate between apps. | ||
152 | 29 | * | ||
153 | 30 | * /!\ Highly unstable API | ||
154 | 31 | */ | ||
155 | 32 | [Deprecated (replacement = "Granite.Services.ContractorProxy", since = "0.2")] | ||
156 | 33 | public class Contractor : Object { | ||
157 | 34 | internal ContractorDBus contract; | ||
158 | 35 | internal static Contractor? contractor = null; | ||
159 | 36 | |||
160 | 37 | /** | ||
161 | 38 | * This creates a new Contractor | ||
162 | 39 | */ | ||
163 | 40 | public Contractor () { | ||
164 | 41 | } | ||
165 | 42 | |||
166 | 43 | internal static void ensure () { | ||
167 | 44 | } | ||
168 | 45 | |||
169 | 46 | /** | ||
170 | 47 | * This searches for available contracts of a particular file | ||
171 | 48 | * | ||
172 | 49 | * @param uri uri of file | ||
173 | 50 | * @param mime mime type of file | ||
174 | 51 | * @return Hashtable of available contracts | ||
175 | 52 | */ | ||
176 | 53 | public static GLib.HashTable<string,string>[] get_contract (string uri, string mime) { | ||
177 | 54 | return { new GLib.HashTable<string,string> (null, null) }; | ||
178 | 55 | } | ||
179 | 56 | |||
180 | 57 | /** | ||
181 | 58 | * generate contracts for arguments and filter them by common parent mimetype. | ||
182 | 59 | * | ||
183 | 60 | * @param locations Hashtable of locations | ||
184 | 61 | * @return Hashtable of available contracts | ||
185 | 62 | */ | ||
186 | 63 | public static GLib.HashTable<string,string>[] get_selection_contracts (GLib.HashTable<string, string>[] locations) { | ||
187 | 64 | return { new GLib.HashTable<string,string> (null, null) }; | ||
188 | 65 | } | ||
189 | 66 | } | ||
190 | 67 | } | ||
191 | 0 | 68 | ||
192 | === renamed file 'lib/Services/Contractor.vala' => 'lib/Services/ContractorProxy.vala' | |||
193 | --- lib/Services/Contractor.vala 2013-04-04 20:05:38 +0000 | |||
194 | +++ lib/Services/ContractorProxy.vala 2013-04-24 17:07:27 +0000 | |||
195 | @@ -1,5 +1,7 @@ | |||
196 | 1 | /*** | 1 | /*** |
198 | 2 | Copyright (C) 2011-2013 Lucas Baudin <xapantu@gmail.com> | 2 | Copyright (C) 2011-2013 Lucas Baudin <xapantu@gmail.com>, |
199 | 3 | Akshay Shekher <voldyman666@gmail.com>, | ||
200 | 4 | Victor Martinez <victoreduardm@gmail.com> | ||
201 | 3 | 5 | ||
202 | 4 | This program or library is free software; you can redistribute it | 6 | This program or library is free software; you can redistribute it |
203 | 5 | and/or modify it under the terms of the GNU Lesser General Public | 7 | and/or modify it under the terms of the GNU Lesser General Public |
204 | @@ -10,7 +12,7 @@ | |||
205 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
206 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
207 | 12 | Lesser General Public License for more details. | 14 | Lesser General Public License for more details. |
209 | 13 | 15 | ||
210 | 14 | You should have received a copy of the GNU Lesser General | 16 | You should have received a copy of the GNU Lesser General |
211 | 15 | Public License along with this library; if not, write to the | 17 | Public License along with this library; if not, write to the |
212 | 16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
213 | @@ -18,87 +20,190 @@ | |||
214 | 18 | ***/ | 20 | ***/ |
215 | 19 | 21 | ||
216 | 20 | namespace Granite.Services { | 22 | namespace Granite.Services { |
298 | 21 | 23 | public interface Contract : Object { | |
299 | 22 | [DBus (name = "org.elementary.contractor")] | 24 | public abstract string get_display_name (); |
300 | 23 | interface ContractorDBus : Object | 25 | public abstract string get_description (); |
301 | 24 | { | 26 | public abstract Icon get_icon (); |
302 | 25 | public abstract GLib.HashTable<string,string>[] GetServicesByLocation (string strlocation, string? file_mime="") throws IOError; | 27 | public abstract int execute_with_file (File file) throws Error; |
303 | 26 | public abstract GLib.HashTable<string,string>[] GetServicesByLocationsList (GLib.HashTable<string,string>[] locations) throws IOError; | 28 | public abstract int execute_with_files (File[] files) throws Error; |
304 | 27 | } | 29 | } |
305 | 28 | 30 | ||
306 | 29 | /** | 31 | public errordomain ContractorError { |
307 | 30 | * A way to handle contractor, a way to communicate between apps. | 32 | SERVICE_NOT_AVAILABLE |
308 | 31 | * | 33 | } |
309 | 32 | * /!\ Highly unstable API | 34 | |
310 | 33 | */ | 35 | internal struct ContractData { |
311 | 34 | public class Contractor : Object | 36 | string id; |
312 | 35 | { | 37 | string display_name; |
313 | 36 | 38 | string description; | |
314 | 37 | internal ContractorDBus contract; | 39 | string icon; |
315 | 38 | 40 | } | |
316 | 39 | internal static Contractor? contractor = null; | 41 | |
317 | 40 | 42 | [DBus (name = "org.elementary.Contractor")] | |
318 | 41 | /** | 43 | internal interface ContractorDBusAPI : Object { |
319 | 42 | * This creates a new Contractor | 44 | public abstract ContractData[] list_all_contracts () throws Error; |
320 | 43 | */ | 45 | public abstract ContractData[] get_contracts_by_mime (string mime_type) throws Error; |
321 | 44 | public Contractor() | 46 | public abstract ContractData[] get_contracts_by_mimelist (string[] mime_types) throws Error; |
322 | 45 | { | 47 | public abstract int execute_with_uri (string id, string uri) throws Error; |
323 | 46 | try | 48 | public abstract int execute_with_uri_list (string id, string[] uri) throws Error; |
324 | 47 | { | 49 | } |
325 | 48 | contract = Bus.get_proxy_sync (BusType.SESSION, | 50 | |
326 | 49 | "org.elementary.contractor", | 51 | public class ContractorProxy { |
327 | 50 | "/org/elementary/contractor"); | 52 | private class GenericContract : Object, Contract { |
328 | 51 | } | 53 | private string id; |
329 | 52 | catch (IOError e) | 54 | private string display_name; |
330 | 53 | { | 55 | private string description; |
331 | 54 | stderr.printf ("%s\n", e.message); | 56 | private string icon_key; |
332 | 55 | } | 57 | |
333 | 56 | } | 58 | private Icon icon; |
334 | 57 | 59 | ||
335 | 58 | internal static void ensure () | 60 | public GenericContract (ContractData data) { |
336 | 59 | { | 61 | icon_key = ""; |
337 | 60 | if(contractor == null) contractor = new Contractor (); | 62 | update_data (data); |
338 | 61 | } | 63 | } |
339 | 62 | 64 | ||
340 | 63 | /** | 65 | public void update_data (ContractData data) { |
341 | 64 | * This searches for available contracts of a particular file | 66 | id = data.id ?? ""; |
342 | 65 | * | 67 | display_name = data.display_name ?? ""; |
343 | 66 | * @param uri uri of file | 68 | description = data.description ?? ""; |
344 | 67 | * @param mime mime type of file | 69 | |
345 | 68 | * @return Hashtable of available contracts | 70 | if (icon_key != data.icon) { |
346 | 69 | */ | 71 | icon_key = data.icon ?? ""; |
347 | 70 | public static GLib.HashTable<string,string>[] get_contract(string uri, string mime) | 72 | icon = null; |
348 | 71 | { | 73 | } |
349 | 72 | ensure (); | 74 | } |
350 | 73 | GLib.HashTable<string,string>[] contracts = null; | 75 | |
351 | 74 | 76 | public string get_display_name () { | |
352 | 75 | try { | 77 | return display_name; |
353 | 76 | contracts = contractor.contract.GetServicesByLocation(uri, mime); | 78 | } |
354 | 77 | }catch (IOError e) { | 79 | |
355 | 78 | stderr.printf ("%s\n", e.message); | 80 | public string get_description () { |
356 | 79 | } | 81 | return description; |
357 | 80 | 82 | } | |
358 | 81 | return contracts; | 83 | |
359 | 82 | } | 84 | public Icon get_icon () { |
360 | 83 | 85 | if (icon == null) { | |
361 | 84 | /** | 86 | if (Path.is_absolute (icon_key)) |
362 | 85 | * generate contracts for rguments and filter them by common parent mimetype. | 87 | icon = new FileIcon (File.new_for_path (icon_key)); |
363 | 86 | * | 88 | else |
364 | 87 | * @param locations Hashtable of locations | 89 | icon = new ThemedIcon.with_default_fallbacks (icon_key); |
365 | 88 | * @return Hashtable of available contracts | 90 | } |
366 | 89 | */ | 91 | |
367 | 90 | public static GLib.HashTable<string,string>[] get_selection_contracts (GLib.HashTable<string, string>[] locations) | 92 | return icon; |
368 | 91 | { | 93 | } |
369 | 92 | ensure (); | 94 | |
370 | 93 | GLib.HashTable<string,string>[] contracts = null; | 95 | public int execute_with_file (File file) throws Error { |
371 | 94 | 96 | return ContractorProxy.execute_with_uri (id, file.get_uri ()); | |
372 | 95 | try { | 97 | } |
373 | 96 | contracts = contractor.contract.GetServicesByLocationsList (locations); | 98 | |
374 | 97 | }catch (IOError e) { | 99 | public int execute_with_files (File[] files) throws Error { |
375 | 98 | stderr.printf ("%s\n", e.message); | 100 | string[] uris = new string[files.length]; |
376 | 99 | } | 101 | |
377 | 100 | 102 | foreach (var file in files) | |
378 | 101 | return contracts; | 103 | uris += file.get_uri (); |
379 | 104 | |||
380 | 105 | return ContractorProxy.execute_with_uri_list (id, uris); | ||
381 | 106 | } | ||
382 | 107 | } | ||
383 | 108 | |||
384 | 109 | |||
385 | 110 | private static ContractorDBusAPI contractor_dbus; | ||
386 | 111 | private static Gee.HashMap<string, GenericContract> contracts; | ||
387 | 112 | |||
388 | 113 | private ContractorProxy () { } | ||
389 | 114 | |||
390 | 115 | private static void ensure () throws Error { | ||
391 | 116 | if (contractor_dbus == null) { | ||
392 | 117 | try { | ||
393 | 118 | contractor_dbus = Bus.get_proxy_sync (BusType.SESSION, | ||
394 | 119 | "org.elementary.Contractor", | ||
395 | 120 | "/org/elementary/contractor"); | ||
396 | 121 | } catch (IOError e) { | ||
397 | 122 | throw new ContractorError.SERVICE_NOT_AVAILABLE (e.message); | ||
398 | 123 | } | ||
399 | 124 | } | ||
400 | 125 | |||
401 | 126 | if (contracts == null) | ||
402 | 127 | contracts = new Gee.HashMap<string, GenericContract> (); | ||
403 | 128 | } | ||
404 | 129 | |||
405 | 130 | private static int execute_with_uri (string id, string uri) throws Error { | ||
406 | 131 | ensure (); | ||
407 | 132 | return contractor_dbus.execute_with_uri (id, uri); | ||
408 | 133 | } | ||
409 | 134 | |||
410 | 135 | private static int execute_with_uri_list (string id, string[] uris) throws Error { | ||
411 | 136 | ensure (); | ||
412 | 137 | return contractor_dbus.execute_with_uri_list (id, uris); | ||
413 | 138 | } | ||
414 | 139 | |||
415 | 140 | /** | ||
416 | 141 | * Provides all the contracts. | ||
417 | 142 | * | ||
418 | 143 | * @return List containing all the contracts available in the system. | ||
419 | 144 | */ | ||
420 | 145 | public static Gee.List<Contract> get_all_contracts () throws Error { | ||
421 | 146 | ensure (); | ||
422 | 147 | |||
423 | 148 | var data = contractor_dbus.list_all_contracts (); | ||
424 | 149 | |||
425 | 150 | return get_contracts_from_data (data); | ||
426 | 151 | } | ||
427 | 152 | |||
428 | 153 | /** | ||
429 | 154 | * This searches for available contracts of a particular file type. | ||
430 | 155 | * | ||
431 | 156 | * @param mime_type Mimetype of file. | ||
432 | 157 | * @return List of contracts that support the given mimetype. | ||
433 | 158 | */ | ||
434 | 159 | public static Gee.List<Contract> get_contracts_by_mime (string mime_type) throws Error { | ||
435 | 160 | ensure (); | ||
436 | 161 | |||
437 | 162 | var data = contractor_dbus.get_contracts_by_mime (mime_type); | ||
438 | 163 | |||
439 | 164 | return get_contracts_from_data (data); | ||
440 | 165 | } | ||
441 | 166 | |||
442 | 167 | /** | ||
443 | 168 | * Generate contracts for a list of mimetypes. | ||
444 | 169 | * | ||
445 | 170 | * Only the contracts that support all the mimetypes are returned. | ||
446 | 171 | * | ||
447 | 172 | * @param mime_types Array of mimetypes. | ||
448 | 173 | * @return List of contracts that support the given mimetypes. | ||
449 | 174 | */ | ||
450 | 175 | public static Gee.List<Contract> get_contracts_by_mimelist (string[] mime_types) throws Error { | ||
451 | 176 | ensure (); | ||
452 | 177 | |||
453 | 178 | var data = contractor_dbus.get_contracts_by_mimelist (mime_types); | ||
454 | 179 | |||
455 | 180 | return get_contracts_from_data (data); | ||
456 | 181 | } | ||
457 | 182 | |||
458 | 183 | private static Gee.List<Contract> get_contracts_from_data (ContractData[] data) { | ||
459 | 184 | var contract_list = new Gee.LinkedList<Contract> (); | ||
460 | 185 | |||
461 | 186 | if (data != null) { | ||
462 | 187 | foreach (var contract_data in data) { | ||
463 | 188 | string contract_id = contract_data.id; | ||
464 | 189 | |||
465 | 190 | // See if we have a contract already. Otherwise create a new one. | ||
466 | 191 | // We do this in order to be able to compare contracts by reference | ||
467 | 192 | // from client code. | ||
468 | 193 | var contract = contracts.get (contract_id); | ||
469 | 194 | |||
470 | 195 | if (contract == null) { | ||
471 | 196 | contract = new GenericContract (contract_data); | ||
472 | 197 | contracts.set (contract_id, contract); | ||
473 | 198 | } else { | ||
474 | 199 | contract.update_data (contract_data); | ||
475 | 200 | } | ||
476 | 201 | |||
477 | 202 | contract_list.add (contract); | ||
478 | 203 | } | ||
479 | 204 | } | ||
480 | 205 | |||
481 | 206 | return contract_list; | ||
482 | 102 | } | 207 | } |
483 | 103 | } | 208 | } |
484 | 104 | } | 209 | } |
485 | 105 | 210 | ||
486 | === modified file 'lib/Widgets/ContractorMenu.vala' | |||
487 | --- lib/Widgets/ContractorMenu.vala 2013-03-20 15:42:25 +0000 | |||
488 | +++ lib/Widgets/ContractorMenu.vala 2013-04-24 17:07:27 +0000 | |||
489 | @@ -20,6 +20,7 @@ | |||
490 | 20 | /** | 20 | /** |
491 | 21 | * This class provides a simple menu for managing Contractor. | 21 | * This class provides a simple menu for managing Contractor. |
492 | 22 | */ | 22 | */ |
493 | 23 | [Deprecated (since = "0.2")] | ||
494 | 23 | public class Granite.Widgets.ContractorMenu : Gtk.Menu { | 24 | public class Granite.Widgets.ContractorMenu : Gtk.Menu { |
495 | 24 | /** | 25 | /** |
496 | 25 | * The Hashtable of available contracts | 26 | * The Hashtable of available contracts |
497 | 26 | 27 | ||
498 | === modified file 'lib/Widgets/ContractorView.vala' | |||
499 | --- lib/Widgets/ContractorView.vala 2013-03-20 15:42:25 +0000 | |||
500 | +++ lib/Widgets/ContractorView.vala 2013-04-24 17:07:27 +0000 | |||
501 | @@ -22,6 +22,7 @@ | |||
502 | 22 | /** | 22 | /** |
503 | 23 | * This class provides a simple way to look at contracts from Contractor | 23 | * This class provides a simple way to look at contracts from Contractor |
504 | 24 | */ | 24 | */ |
505 | 25 | [Deprecated (since = "0.2")] | ||
506 | 25 | public class Granite.Widgets.ContractorView : TreeView { | 26 | public class Granite.Widgets.ContractorView : TreeView { |
507 | 26 | 27 | ||
508 | 27 | /** | 28 | /** |
After a long discussion about the API this seems to be the best option we could possibly get. Yay!
There are two things to do before this goes in:
1) Update Contractor daemon D-bus API to throw errors
2) Create a test client for this API