Merge lp:~victored/pantheon-files/contractor-plugin into lp:~elementary-apps/pantheon-files/trunk
- contractor-plugin
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1157 |
Proposed branch: | lp:~victored/pantheon-files/contractor-plugin |
Merge into: | lp:~elementary-apps/pantheon-files/trunk |
Diff against target: |
555 lines (+143/-311) 7 files modified
libcore/PluginManager.vala (+34/-2) plugins/CMakeLists.txt (+0/-1) plugins/contractor/CMakeLists.txt (+3/-1) plugins/contractor/plugin.vala (+106/-120) plugins/extended-actions/CMakeLists.txt (+0/-28) plugins/extended-actions/extended-actions.plug (+0/-3) plugins/extended-actions/plugin.vala (+0/-156) |
To merge this branch: | bzr merge lp:~victored/pantheon-files/contractor-plugin |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sergey "Shnatsel" Davidoff (community) | Approve | ||
Review via email: mp+160377@code.launchpad.net |
Commit message
Description of the change
- Rewrite contractor plugin to use new API. This talks to Contractor by using Granite's Proxy API.
- Drop extended-actions plugin. Same API as previous Contractor.
- 1160. By Victor Martinez
-
Destroy plugin menu items properly.
This implied some minor changes to the core library. Special care was taken to avoid breaking the existing plugin ABI.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Also, the right-click menu should list contract *names* and show descriptions only as tooltips on them.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
The old implementation showed descriptions only because names were purely technical, the only human-readable thing was description.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
And it gets worse! This is where it may end up: http://
- 1161. By Victor Martinez
-
Fix bug involving duplicate menu entries.
The code was assuming that the menu passed to the plugin was the same the plugins were added to initially, which is incorrect.
Victor Martinez (victored) wrote : | # |
Hey Sergey, thank you for testing!
I'm no longer able to reproduce the bug here.
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Works properly for me too.
Preview Diff
1 | === modified file 'libcore/PluginManager.vala' | |||
2 | --- libcore/PluginManager.vala 2012-11-06 19:52:04 +0000 | |||
3 | +++ libcore/PluginManager.vala 2013-04-24 17:03:26 +0000 | |||
4 | @@ -30,7 +30,11 @@ | |||
5 | 30 | string plugin_dir; | 30 | string plugin_dir; |
6 | 31 | Gee.List<string> names; | 31 | Gee.List<string> names; |
7 | 32 | bool in_available = false; | 32 | bool in_available = false; |
9 | 33 | public GLib.List<Gtk.Widget>? menus; | 33 | |
10 | 34 | [Deprecated (replacement = "Marlin.PluginManager.menuitem_references")] | ||
11 | 35 | public GLib.List<Gtk.Widget>? menus; // this doesn't manage GObject references properly | ||
12 | 36 | |||
13 | 37 | public Gee.List<Gtk.Widget> menuitem_references { get; private set; } | ||
14 | 34 | 38 | ||
15 | 35 | public PluginManager(Settings settings, string field, string plugin_dir) | 39 | public PluginManager(Settings settings, string field, string plugin_dir) |
16 | 36 | { | 40 | { |
17 | @@ -39,6 +43,8 @@ | |||
18 | 39 | this.plugin_dir = plugin_dir; | 43 | this.plugin_dir = plugin_dir; |
19 | 40 | plugin_hash = new Gee.HashMap<string,Plugins.Base>(); | 44 | plugin_hash = new Gee.HashMap<string,Plugins.Base>(); |
20 | 41 | names = new Gee.ArrayList<string>(); | 45 | names = new Gee.ArrayList<string>(); |
21 | 46 | |||
22 | 47 | menuitem_references = new Gee.LinkedList<Gtk.Widget> (); | ||
23 | 42 | } | 48 | } |
24 | 43 | 49 | ||
25 | 44 | public void load_plugins() | 50 | public void load_plugins() |
26 | @@ -147,10 +153,36 @@ | |||
27 | 147 | 153 | ||
28 | 148 | public void hook_context_menu(Gtk.Widget menu, List<GOF.File> files) | 154 | public void hook_context_menu(Gtk.Widget menu, List<GOF.File> files) |
29 | 149 | { | 155 | { |
30 | 156 | drop_menu_references (menu); | ||
31 | 157 | |||
32 | 158 | if (menu is Gtk.Menu) | ||
33 | 159 | drop_plugin_menuitems (menu as Gtk.Menu); | ||
34 | 160 | |||
35 | 161 | |||
36 | 162 | foreach (var plugin in plugin_hash.values) | ||
37 | 163 | plugin.context_menu (menu, files); | ||
38 | 164 | } | ||
39 | 165 | |||
40 | 166 | private void drop_plugin_menuitems (Gtk.Menu menu) { | ||
41 | 167 | var plugin_menu = menu as Gtk.Menu; | ||
42 | 168 | |||
43 | 169 | assert (plugin_menu != null); | ||
44 | 170 | |||
45 | 171 | foreach (var menu_item in menuitem_references) | ||
46 | 172 | menu_item.parent.remove (menu_item); | ||
47 | 173 | |||
48 | 174 | menuitem_references.clear (); | ||
49 | 175 | } | ||
50 | 176 | |||
51 | 177 | [Deprecated (replacement = "Marlin.PluginManager.drop_plugin_menuitems")] | ||
52 | 178 | private void drop_menu_references (Gtk.Widget menu) { | ||
53 | 179 | if (menus == null) | ||
54 | 180 | return; | ||
55 | 181 | |||
56 | 150 | foreach (var item in menus) | 182 | foreach (var item in menus) |
57 | 151 | item.destroy (); | 183 | item.destroy (); |
58 | 184 | |||
59 | 152 | menus = null; | 185 | menus = null; |
60 | 153 | foreach(var plugin in plugin_hash.values) plugin.context_menu (menu, files); | ||
61 | 154 | } | 186 | } |
62 | 155 | 187 | ||
63 | 156 | public void ui(Gtk.UIManager data) | 188 | public void ui(Gtk.UIManager data) |
64 | 157 | 189 | ||
65 | === modified file 'plugins/CMakeLists.txt' | |||
66 | --- plugins/CMakeLists.txt 2012-06-01 21:34:30 +0000 | |||
67 | +++ plugins/CMakeLists.txt 2013-04-24 17:03:26 +0000 | |||
68 | @@ -1,4 +1,3 @@ | |||
69 | 1 | add_subdirectory(extended-actions) | ||
70 | 2 | add_subdirectory(contractor) | 1 | add_subdirectory(contractor) |
71 | 3 | add_subdirectory(marlin-trash) | 2 | add_subdirectory(marlin-trash) |
72 | 4 | add_subdirectory(marlin-ctags) | 3 | add_subdirectory(marlin-ctags) |
73 | 5 | 4 | ||
74 | === modified file 'plugins/contractor/CMakeLists.txt' | |||
75 | --- plugins/contractor/CMakeLists.txt 2013-04-22 07:45:04 +0000 | |||
76 | +++ plugins/contractor/CMakeLists.txt 2013-04-24 17:03:26 +0000 | |||
77 | @@ -2,7 +2,8 @@ | |||
78 | 2 | pkg_check_modules(DEPS REQUIRED | 2 | pkg_check_modules(DEPS REQUIRED |
79 | 3 | gtk+-3.0 | 3 | gtk+-3.0 |
80 | 4 | gee-1.0 | 4 | gee-1.0 |
82 | 5 | glib-2.0) | 5 | glib-2.0 |
83 | 6 | granite) | ||
84 | 6 | set(CFLAGS | 7 | set(CFLAGS |
85 | 7 | ${DEPS_CFLAGS} ${DEPS_CFLAGS_OTHER} | 8 | ${DEPS_CFLAGS} ${DEPS_CFLAGS_OTHER} |
86 | 8 | ) | 9 | ) |
87 | @@ -19,6 +20,7 @@ | |||
88 | 19 | PACKAGES | 20 | PACKAGES |
89 | 20 | gtk+-3.0 | 21 | gtk+-3.0 |
90 | 21 | gee-1.0 | 22 | gee-1.0 |
91 | 23 | granite | ||
92 | 22 | OPTIONS | 24 | OPTIONS |
93 | 23 | --thread) | 25 | --thread) |
94 | 24 | add_library(marlin-contractor SHARED | 26 | add_library(marlin-contractor SHARED |
95 | 25 | 27 | ||
96 | === modified file 'plugins/contractor/plugin.vala' | |||
97 | --- plugins/contractor/plugin.vala 2012-06-02 15:49:15 +0000 | |||
98 | +++ plugins/contractor/plugin.vala 2013-04-24 17:03:26 +0000 | |||
99 | @@ -2,8 +2,10 @@ | |||
100 | 2 | * Authors: | 2 | * Authors: |
101 | 3 | * Lucas Baudin <xapantu@gmail.com> | 3 | * Lucas Baudin <xapantu@gmail.com> |
102 | 4 | * ammonkey <am.monkeyd@gmail.com> | 4 | * ammonkey <am.monkeyd@gmail.com> |
104 | 5 | * | 5 | * Victor Martinez <victoreduardm@gmail.com> |
105 | 6 | * | ||
106 | 6 | * Copyright (C) Lucas Baudin 2011 <xapantu@gmail.com> | 7 | * Copyright (C) Lucas Baudin 2011 <xapantu@gmail.com> |
107 | 8 | * Copyright (C) 2013 elementary | ||
108 | 7 | * | 9 | * |
109 | 8 | * Marlin is free software: you can redistribute it and/or modify it | 10 | * Marlin is free software: you can redistribute it and/or modify it |
110 | 9 | * under the terms of the GNU General Public License as published by the | 11 | * under the terms of the GNU General Public License as published by the |
111 | @@ -19,138 +21,122 @@ | |||
112 | 19 | * with this program. If not, see <http://www.gnu.org/licenses/>. | 21 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
113 | 20 | */ | 22 | */ |
114 | 21 | 23 | ||
124 | 22 | using Gtk; | 24 | public class Marlin.Plugins.ContractMenuItem : Gtk.MenuItem { |
125 | 23 | using Gee; | 25 | private Granite.Services.Contract contract; |
126 | 24 | 26 | private File[] files; | |
127 | 25 | [DBus (name = "org.elementary.contractor")] | 27 | |
128 | 26 | public interface ContractorService : Object | 28 | public ContractMenuItem (Granite.Services.Contract contract, File[] files) { |
129 | 27 | { | 29 | this.contract = contract; |
130 | 28 | //public abstract GLib.HashTable<string,string>[] GetServicesByMime (string mime) throws IOError; | 30 | this.files = files; |
131 | 29 | public abstract GLib.HashTable<string,string>[] GetServicesByLocation (string strlocation, string? file_mime="") throws IOError; | 31 | |
132 | 30 | public abstract GLib.HashTable<string,string>[] GetServicesByLocationsList (GLib.HashTable<string, string>[] locations) throws IOError; | 32 | label = contract.get_display_name (); |
133 | 33 | tooltip_text = contract.get_description (); | ||
134 | 34 | } | ||
135 | 35 | |||
136 | 36 | public override void activate () { | ||
137 | 37 | try { | ||
138 | 38 | if (files.length == 1) | ||
139 | 39 | contract.execute_with_file (files[0]); | ||
140 | 40 | else | ||
141 | 41 | contract.execute_with_files (files); | ||
142 | 42 | } catch (Error err) { | ||
143 | 43 | warning (err.message); | ||
144 | 44 | } | ||
145 | 45 | } | ||
146 | 31 | } | 46 | } |
147 | 32 | 47 | ||
226 | 33 | public class Marlin.Plugins.Contractor : Marlin.Plugins.Base | 48 | public class Marlin.Plugins.Contractor : Marlin.Plugins.Base { |
227 | 34 | { | 49 | private Gtk.UIManager ui_manager; |
228 | 35 | UIManager ui_manager; | 50 | private Gtk.Menu menu; |
229 | 36 | Gtk.Menu menu; | 51 | private GOF.File current_directory = null; |
230 | 37 | GOF.File current_directory = null; | 52 | |
231 | 38 | unowned GLib.List<GOF.File> selection; | 53 | public Contractor () { |
232 | 39 | GLib.HashTable<string,string>[] services = null; | 54 | } |
233 | 40 | 55 | ||
234 | 41 | private ContractorService service_eactions; | 56 | public override void context_menu (Gtk.Widget? widget, List<GOF.File> gof_files) { |
157 | 42 | |||
158 | 43 | public Contractor () | ||
159 | 44 | { | ||
160 | 45 | try { | ||
161 | 46 | service_eactions = Bus.get_proxy_sync (BusType.SESSION, | ||
162 | 47 | "org.elementary.contractor", | ||
163 | 48 | "/org/elementary/contractor"); | ||
164 | 49 | } catch (IOError e) { | ||
165 | 50 | stderr.printf ("%s\n", e.message); | ||
166 | 51 | } | ||
167 | 52 | } | ||
168 | 53 | |||
169 | 54 | private string get_app_display_name (GLib.HashTable<string,string> app__) | ||
170 | 55 | { | ||
171 | 56 | return app__.lookup ("Description"); | ||
172 | 57 | } | ||
173 | 58 | |||
174 | 59 | private GLib.HashTable<string,string> add_location_entry (GOF.File file) | ||
175 | 60 | { | ||
176 | 61 | GLib.HashTable<string,string> entry; | ||
177 | 62 | |||
178 | 63 | entry = new GLib.HashTable<string,string> (str_hash, str_equal); | ||
179 | 64 | entry.insert ("uri", file.uri); | ||
180 | 65 | var ftype = file.get_ftype (); | ||
181 | 66 | if (ftype == "application/octet-stream" || ftype == null) | ||
182 | 67 | entry.insert ("mimetype", ""); | ||
183 | 68 | else | ||
184 | 69 | entry.insert ("mimetype", ftype); | ||
185 | 70 | |||
186 | 71 | return entry; | ||
187 | 72 | } | ||
188 | 73 | |||
189 | 74 | private GLib.HashTable<string, string>[] build_hash_from_list_selection () | ||
190 | 75 | { | ||
191 | 76 | GLib.HashTable<string,string>[] locations = null; | ||
192 | 77 | |||
193 | 78 | foreach (GOF.File file in selection) { | ||
194 | 79 | if (file != null) | ||
195 | 80 | locations += add_location_entry (file); | ||
196 | 81 | //message ("file %s", file.name); | ||
197 | 82 | } | ||
198 | 83 | if (selection == null && current_directory != null) { | ||
199 | 84 | locations += add_location_entry (current_directory); | ||
200 | 85 | } | ||
201 | 86 | |||
202 | 87 | return locations; | ||
203 | 88 | } | ||
204 | 89 | |||
205 | 90 | public void action_activated () | ||
206 | 91 | { | ||
207 | 92 | Gtk.MenuItem menuitem; | ||
208 | 93 | GLib.HashTable<string,string> app__; | ||
209 | 94 | |||
210 | 95 | menuitem = (Gtk.MenuItem) menu.get_active (); | ||
211 | 96 | app__ = menuitem.get_data<GLib.HashTable<string,string>> ("app"); | ||
212 | 97 | |||
213 | 98 | if (app__ != null) { | ||
214 | 99 | var cmd = app__.lookup ("Exec"); | ||
215 | 100 | //message ("test exec %s", cmd); | ||
216 | 101 | try { | ||
217 | 102 | GLib.Process.spawn_command_line_async (cmd); | ||
218 | 103 | } catch (SpawnError e) { | ||
219 | 104 | stderr.printf ("error spawn command line %s: %s", cmd, e.message); | ||
220 | 105 | } | ||
221 | 106 | } | ||
222 | 107 | } | ||
223 | 108 | |||
224 | 109 | public override void context_menu (Gtk.Widget? widget, GLib.List<GOF.File> files) | ||
225 | 110 | { | ||
235 | 111 | menu = widget as Gtk.Menu; | 57 | menu = widget as Gtk.Menu; |
238 | 112 | 58 | return_if_fail (menu != null); | |
239 | 113 | selection = files; | 59 | |
240 | 60 | File[] files = null; | ||
241 | 61 | Gee.List<Granite.Services.Contract> contracts = null; | ||
242 | 62 | |||
243 | 114 | try { | 63 | try { |
250 | 115 | services = service_eactions.GetServicesByLocationsList (build_hash_from_list_selection ()); | 64 | if (gof_files == null) { |
251 | 116 | 65 | if (current_directory == null) | |
252 | 117 | uint i = 0; | 66 | return; |
253 | 118 | foreach(var app__ in services) | 67 | |
254 | 119 | { | 68 | files = new File[0]; |
255 | 120 | /* insert separator if we got at least 1 action */ | 69 | files += current_directory.location; |
256 | 70 | |||
257 | 71 | string? mimetype = current_directory.get_ftype (); | ||
258 | 72 | |||
259 | 73 | if (mimetype == null) | ||
260 | 74 | return; | ||
261 | 75 | |||
262 | 76 | contracts = Granite.Services.ContractorProxy.get_contracts_by_mime (mimetype); | ||
263 | 77 | } else { | ||
264 | 78 | files = get_file_array (gof_files); | ||
265 | 79 | var mimetypes = get_mimetypes (gof_files); | ||
266 | 80 | contracts = Granite.Services.ContractorProxy.get_contracts_by_mimelist (mimetypes); | ||
267 | 81 | } | ||
268 | 82 | |||
269 | 83 | assert (files != null); | ||
270 | 84 | assert (contracts != null); | ||
271 | 85 | |||
272 | 86 | for (int i = 0; i < contracts.size; i++) { | ||
273 | 87 | var contract = contracts.get (i); | ||
274 | 88 | Gtk.MenuItem menu_item; | ||
275 | 89 | |||
276 | 90 | // insert separator if we got at least 1 contract | ||
277 | 121 | if (i == 0) { | 91 | if (i == 0) { |
282 | 122 | var item = new Gtk.SeparatorMenuItem (); | 92 | menu_item = new Gtk.SeparatorMenuItem (); |
283 | 123 | menu.append (item); | 93 | add_menuitem (menu, menu_item); |
280 | 124 | item.show (); | ||
281 | 125 | plugins.menus.prepend (item); | ||
284 | 126 | } | 94 | } |
292 | 127 | var menuitem = new Gtk.MenuItem.with_label(get_app_display_name(app__)); | 95 | |
293 | 128 | menu.append (menuitem); | 96 | menu_item = new ContractMenuItem (contract, files); |
294 | 129 | menuitem.set_data<GLib.HashTable<string,string>> ("app", app__); | 97 | add_menuitem (menu, menu_item); |
288 | 130 | menuitem.show (); | ||
289 | 131 | menuitem.activate.connect (action_activated); | ||
290 | 132 | plugins.menus.prepend (menuitem); | ||
291 | 133 | i++; | ||
295 | 134 | } | 98 | } |
298 | 135 | } catch (IOError e) { | 99 | } catch (Error e) { |
299 | 136 | stderr.printf ("%s\n", e.message); | 100 | warning (e.message); |
300 | 137 | } | 101 | } |
301 | 138 | } | 102 | } |
302 | 139 | 103 | ||
305 | 140 | public override void ui (Gtk.UIManager? widget) | 104 | public override void ui (Gtk.UIManager? widget) { |
304 | 141 | { | ||
306 | 142 | ui_manager = widget; | 105 | ui_manager = widget; |
313 | 143 | menu = (Gtk.Menu)ui_manager.get_widget("/selection"); | 106 | menu = (Gtk.Menu) ui_manager.get_widget ("/selection"); |
314 | 144 | } | 107 | } |
315 | 145 | 108 | ||
316 | 146 | public override void directory_loaded (void* user_data) | 109 | public override void directory_loaded (void* user_data) { |
317 | 147 | { | 110 | current_directory = ((Object[]) user_data)[2] as GOF.File; |
318 | 148 | current_directory = ((Object[])user_data)[2] as GOF.File; | 111 | } |
319 | 112 | |||
320 | 113 | private void add_menuitem (Gtk.Menu menu, Gtk.MenuItem menu_item) { | ||
321 | 114 | menu.append (menu_item); | ||
322 | 115 | menu_item.show (); | ||
323 | 116 | plugins.menuitem_references.add (menu_item); | ||
324 | 117 | } | ||
325 | 118 | |||
326 | 119 | private static string[] get_mimetypes (List<GOF.File> files) { | ||
327 | 120 | string[] mimetypes = new string[files.length ()]; | ||
328 | 121 | |||
329 | 122 | foreach (var file in files) | ||
330 | 123 | mimetypes += file.get_ftype () ?? ""; | ||
331 | 124 | |||
332 | 125 | return mimetypes; | ||
333 | 126 | } | ||
334 | 127 | |||
335 | 128 | private static File[] get_file_array (List<GOF.File> files) { | ||
336 | 129 | File[] file_array = new File[0]; | ||
337 | 130 | |||
338 | 131 | foreach (var file in files) { | ||
339 | 132 | if (file.location != null) | ||
340 | 133 | file_array += file.location; | ||
341 | 134 | } | ||
342 | 135 | |||
343 | 136 | return file_array; | ||
344 | 149 | } | 137 | } |
345 | 150 | } | 138 | } |
346 | 151 | 139 | ||
349 | 152 | public Marlin.Plugins.Base module_init () | 140 | public Marlin.Plugins.Base module_init () { |
348 | 153 | { | ||
350 | 154 | return new Marlin.Plugins.Contractor (); | 141 | return new Marlin.Plugins.Contractor (); |
351 | 155 | } | 142 | } |
352 | 156 | |||
353 | 157 | 143 | ||
354 | === removed directory 'plugins/extended-actions' | |||
355 | === removed file 'plugins/extended-actions/CMakeLists.txt' | |||
356 | --- plugins/extended-actions/CMakeLists.txt 2013-04-22 07:45:04 +0000 | |||
357 | +++ plugins/extended-actions/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
358 | @@ -1,28 +0,0 @@ | |||
359 | 1 | find_package(PkgConfig) | ||
360 | 2 | pkg_check_modules(DEPS REQUIRED | ||
361 | 3 | gtk+-3.0 | ||
362 | 4 | gee-1.0 | ||
363 | 5 | glib-2.0) | ||
364 | 6 | set(CFLAGS | ||
365 | 7 | ${DEPS_CFLAGS} ${DEPS_CFLAGS_OTHER} | ||
366 | 8 | ) | ||
367 | 9 | include_directories(${CMAKE_BINARY_DIR}/libcore/) | ||
368 | 10 | include_directories(${CMAKE_SOURCE_DIR}/libcore/) | ||
369 | 11 | add_definitions(${CFLAGS}) | ||
370 | 12 | link_directories(${LIB_PATHS}) | ||
371 | 13 | vala_precompile(VALA_C marlin-extended-actions | ||
372 | 14 | plugin.vala | ||
373 | 15 | CUSTOM_VAPIS | ||
374 | 16 | ${CMAKE_BINARY_DIR}/libcore/marlincore.vapi | ||
375 | 17 | ${CMAKE_SOURCE_DIR}/libcore/marlincore-C.vapi | ||
376 | 18 | ${CMAKE_BINARY_DIR}/libwidgets/marlinwidgets.vapi | ||
377 | 19 | PACKAGES | ||
378 | 20 | gtk+-3.0 | ||
379 | 21 | gee-1.0 | ||
380 | 22 | OPTIONS | ||
381 | 23 | --thread) | ||
382 | 24 | add_library(marlin-extended-actions SHARED | ||
383 | 25 | ${VALA_C}) | ||
384 | 26 | target_link_libraries(marlin-extended-actions marlincore marlinwidgets) | ||
385 | 27 | install(TARGETS marlin-extended-actions DESTINATION lib/marlin/plugins/core/) | ||
386 | 28 | install(FILES extended-actions.plug DESTINATION lib/marlin/plugins/core/) | ||
387 | 29 | 0 | ||
388 | === removed file 'plugins/extended-actions/extended-actions.plug' | |||
389 | --- plugins/extended-actions/extended-actions.plug 2011-12-04 12:05:59 +0000 | |||
390 | +++ plugins/extended-actions/extended-actions.plug 1970-01-01 00:00:00 +0000 | |||
391 | @@ -1,3 +0,0 @@ | |||
392 | 1 | [Plugin] | ||
393 | 2 | Name=Extended Actions | ||
394 | 3 | File=libmarlin-extended-actions.so | ||
395 | 4 | 0 | ||
396 | === removed file 'plugins/extended-actions/plugin.vala' | |||
397 | --- plugins/extended-actions/plugin.vala 2012-06-01 21:34:30 +0000 | |||
398 | +++ plugins/extended-actions/plugin.vala 1970-01-01 00:00:00 +0000 | |||
399 | @@ -1,156 +0,0 @@ | |||
400 | 1 | /* | ||
401 | 2 | * Authors: | ||
402 | 3 | * Lucas Baudin <xapantu@gmail.com> | ||
403 | 4 | * ammonkey <am.monkeyd@gmail.com> | ||
404 | 5 | * | ||
405 | 6 | * Copyright (C) Lucas Baudin 2011 <xapantu@gmail.com> | ||
406 | 7 | * | ||
407 | 8 | * Marlin is free software: you can redistribute it and/or modify it | ||
408 | 9 | * under the terms of the GNU General Public License as published by the | ||
409 | 10 | * Free Software Foundation, either version 3 of the License, or | ||
410 | 11 | * (at your option) any later version. | ||
411 | 12 | * | ||
412 | 13 | * Marlin is distributed in the hope that it will be useful, but | ||
413 | 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
414 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
415 | 16 | * See the GNU General Public License for more details. | ||
416 | 17 | * | ||
417 | 18 | * You should have received a copy of the GNU General Public License along | ||
418 | 19 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
419 | 20 | */ | ||
420 | 21 | |||
421 | 22 | using Gtk; | ||
422 | 23 | using Gee; | ||
423 | 24 | |||
424 | 25 | [DBus (name = "org.magma.ExtendedActions")] | ||
425 | 26 | public interface ExtendedActionsService : Object | ||
426 | 27 | { | ||
427 | 28 | //public abstract GLib.HashTable<string,string>[] GetServicesByMime (string mime) throws IOError; | ||
428 | 29 | public abstract GLib.HashTable<string,string>[] GetServicesByLocation (string strlocation, string? file_mime="") throws IOError; | ||
429 | 30 | public abstract GLib.HashTable<string,string>[] GetServicesByLocationsList (GLib.HashTable<string, string>[] locations) throws IOError; | ||
430 | 31 | } | ||
431 | 32 | |||
432 | 33 | public class Marlin.Plugins.ExtendedActions : Marlin.Plugins.Base | ||
433 | 34 | { | ||
434 | 35 | UIManager ui_manager; | ||
435 | 36 | Gtk.Menu menu; | ||
436 | 37 | GOF.File current_directory = null; | ||
437 | 38 | unowned GLib.List<GOF.File> selection; | ||
438 | 39 | GLib.HashTable<string,string>[] services = null; | ||
439 | 40 | |||
440 | 41 | private ExtendedActionsService service_eactions; | ||
441 | 42 | |||
442 | 43 | public ExtendedActions () | ||
443 | 44 | { | ||
444 | 45 | try { | ||
445 | 46 | service_eactions = Bus.get_proxy_sync (BusType.SESSION, | ||
446 | 47 | "org.magma.ExtendedActions", | ||
447 | 48 | "/org/magma/ExtendedActions"); | ||
448 | 49 | } catch (IOError e) { | ||
449 | 50 | stderr.printf ("%s\n", e.message); | ||
450 | 51 | } | ||
451 | 52 | } | ||
452 | 53 | |||
453 | 54 | private string get_app_display_name (GLib.HashTable<string,string> app__) | ||
454 | 55 | { | ||
455 | 56 | return app__.lookup ("Description"); | ||
456 | 57 | } | ||
457 | 58 | |||
458 | 59 | private GLib.HashTable<string,string> add_location_entry (GOF.File file) | ||
459 | 60 | { | ||
460 | 61 | GLib.HashTable<string,string> entry; | ||
461 | 62 | |||
462 | 63 | entry = new GLib.HashTable<string,string> (str_hash, str_equal); | ||
463 | 64 | entry.insert ("uri", file.uri); | ||
464 | 65 | var ftype = file.get_ftype (); | ||
465 | 66 | if (ftype == "application/octet-stream" || ftype == null) | ||
466 | 67 | entry.insert ("mimetype", ""); | ||
467 | 68 | else | ||
468 | 69 | entry.insert ("mimetype", ftype); | ||
469 | 70 | |||
470 | 71 | return entry; | ||
471 | 72 | } | ||
472 | 73 | |||
473 | 74 | private GLib.HashTable<string, string>[] build_hash_from_list_selection () | ||
474 | 75 | { | ||
475 | 76 | GLib.HashTable<string,string>[] locations = null; | ||
476 | 77 | |||
477 | 78 | foreach (GOF.File file in selection) { | ||
478 | 79 | if (file != null) | ||
479 | 80 | locations += add_location_entry (file); | ||
480 | 81 | //message ("file %s", file.name); | ||
481 | 82 | } | ||
482 | 83 | if (selection == null && current_directory != null) { | ||
483 | 84 | locations += add_location_entry (current_directory); | ||
484 | 85 | } | ||
485 | 86 | |||
486 | 87 | return locations; | ||
487 | 88 | } | ||
488 | 89 | |||
489 | 90 | public void action_activated () | ||
490 | 91 | { | ||
491 | 92 | Gtk.MenuItem menuitem; | ||
492 | 93 | GLib.HashTable<string,string> app__; | ||
493 | 94 | |||
494 | 95 | menuitem = (Gtk.MenuItem) menu.get_active (); | ||
495 | 96 | app__ = menuitem.get_data<GLib.HashTable<string,string>> ("app"); | ||
496 | 97 | |||
497 | 98 | if (app__ != null) { | ||
498 | 99 | var cmd = app__.lookup ("Exec"); | ||
499 | 100 | //message ("test exec %s", cmd); | ||
500 | 101 | try { | ||
501 | 102 | GLib.Process.spawn_command_line_async (cmd); | ||
502 | 103 | } catch (SpawnError e) { | ||
503 | 104 | stderr.printf ("error spawn command line %s: %s", cmd, e.message); | ||
504 | 105 | } | ||
505 | 106 | } | ||
506 | 107 | } | ||
507 | 108 | |||
508 | 109 | public override void context_menu (Gtk.Widget? widget, GLib.List<GOF.File> files) | ||
509 | 110 | { | ||
510 | 111 | menu = widget as Gtk.Menu; | ||
511 | 112 | |||
512 | 113 | selection = files; | ||
513 | 114 | try { | ||
514 | 115 | services = service_eactions.GetServicesByLocationsList (build_hash_from_list_selection ()); | ||
515 | 116 | |||
516 | 117 | uint i = 0; | ||
517 | 118 | foreach(var app__ in services) | ||
518 | 119 | { | ||
519 | 120 | /* insert separator if we got at least 1 action */ | ||
520 | 121 | if (i == 0) { | ||
521 | 122 | var item = new Gtk.SeparatorMenuItem (); | ||
522 | 123 | menu.append (item); | ||
523 | 124 | item.show (); | ||
524 | 125 | plugins.menus.prepend (item); | ||
525 | 126 | } | ||
526 | 127 | var menuitem = new Gtk.MenuItem.with_label(get_app_display_name(app__)); | ||
527 | 128 | menu.append (menuitem); | ||
528 | 129 | menuitem.set_data<GLib.HashTable<string,string>> ("app", app__); | ||
529 | 130 | menuitem.show (); | ||
530 | 131 | menuitem.activate.connect (action_activated); | ||
531 | 132 | plugins.menus.prepend (menuitem); | ||
532 | 133 | i++; | ||
533 | 134 | } | ||
534 | 135 | } catch (IOError e) { | ||
535 | 136 | stderr.printf ("%s\n", e.message); | ||
536 | 137 | } | ||
537 | 138 | } | ||
538 | 139 | |||
539 | 140 | public override void ui (Gtk.UIManager? widget) | ||
540 | 141 | { | ||
541 | 142 | ui_manager = widget; | ||
542 | 143 | menu = (Gtk.Menu)ui_manager.get_widget("/selection"); | ||
543 | 144 | } | ||
544 | 145 | |||
545 | 146 | public override void directory_loaded (void* user_data) | ||
546 | 147 | { | ||
547 | 148 | current_directory = ((Object[])user_data)[2] as GOF.File; | ||
548 | 149 | } | ||
549 | 150 | } | ||
550 | 151 | |||
551 | 152 | public Marlin.Plugins.Base module_init () | ||
552 | 153 | { | ||
553 | 154 | return new Marlin.Plugins.ExtendedActions (); | ||
554 | 155 | } | ||
555 | 156 |
I'm afraid the recent commit didn't help resolve the bug mentioned in https:/ /code.launchpad .net/~victored/ granite/ contractor- wrapper/ +merge/ 159948/ comments/ 353537 at all