1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #include "eog-postr-plugin.h"
6
7 #include <gmodule.h>
8 #include <glib/gi18n-lib.h>
9
10 #include <eog/eog-debug.h>
11 #include <eog/eog-thumb-view.h>
12 #include <eog/eog-image.h>
13 #include <eog/eog-window-activatable.h>
14
15 #define EOG_POSTR_PLUGIN_MENU_ID "EogPluginPostr"
16 #define EOG_POSTR_PLUGIN_ACTION "upload-with-postr"
17
18 enum {
19 PROP_O,
20 PROP_WINDOW
21 };
22
23 static void
24 eog_window_activatable_iface_init (EogWindowActivatableInterface *iface);
25
26 G_DEFINE_DYNAMIC_TYPE_EXTENDED (EogPostrPlugin, eog_postr_plugin,
27 PEAS_TYPE_EXTENSION_BASE, 0,
28 G_IMPLEMENT_INTERFACE_DYNAMIC(EOG_TYPE_WINDOW_ACTIVATABLE,
29 eog_window_activatable_iface_init))
30
31 static void
postr_cb(GSimpleAction * simple,GVariant * parameter,gpointer user_data)32 postr_cb (GSimpleAction *simple,
33 GVariant *parameter,
34 gpointer user_data)
35 {
36 EogWindow *window;
37 GtkWidget *thumbview;
38 GList *images, *i;
39 gchar *cmd = g_strdup ("postr ");
40
41 eog_debug(DEBUG_PLUGINS);
42
43 g_return_if_fail (EOG_IS_WINDOW (user_data));
44
45 window = EOG_WINDOW (user_data);
46 thumbview = eog_window_get_thumb_view (window);
47 images = eog_thumb_view_get_selected_images (EOG_THUMB_VIEW (thumbview));
48
49 for (i = g_list_first (images); i; i = i->next) {
50 EogImage *image = (EogImage *) i->data;
51 GFile *imgfile;
52 gchar *imgpath;
53 gchar *oldcmd = cmd;
54
55 imgfile = eog_image_get_file (image);
56 imgpath = g_file_get_path (imgfile);
57
58 if (G_LIKELY (imgpath != NULL)) {
59 cmd = g_strconcat (oldcmd, "\"", imgpath, "\"", " ", NULL);
60 g_free (oldcmd);
61 }
62
63 g_free (imgpath);
64 g_object_unref (imgfile);
65 }
66
67 g_spawn_command_line_async (cmd, NULL);
68
69 g_list_free_full (images, g_object_unref);
70 g_free (cmd);
71 }
72
73 static void
eog_postr_plugin_update_action_state(EogPostrPlugin * plugin)74 eog_postr_plugin_update_action_state (EogPostrPlugin *plugin)
75 {
76 GAction *action;
77 EogThumbView *thumbview;
78 gboolean enable = FALSE;
79
80 thumbview = EOG_THUMB_VIEW (eog_window_get_thumb_view (plugin->window));
81
82 if (G_LIKELY (thumbview))
83 {
84 enable = (eog_thumb_view_get_n_selected (thumbview) != 0);
85 }
86
87 action = g_action_map_lookup_action (G_ACTION_MAP (plugin->window),
88 EOG_POSTR_PLUGIN_ACTION);
89 g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enable);
90 }
91
92 static void
_selection_changed_cb(EogThumbView * thumbview,gpointer user_data)93 _selection_changed_cb (EogThumbView *thumbview, gpointer user_data)
94 {
95 EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (user_data);
96
97 if (G_LIKELY (plugin))
98 eog_postr_plugin_update_action_state (plugin);
99 }
100
101 static void
eog_postr_plugin_init(EogPostrPlugin * plugin)102 eog_postr_plugin_init (EogPostrPlugin *plugin)
103 {
104 eog_debug_message (DEBUG_PLUGINS, "EogPostrPlugin initializing");
105 }
106
107
108 static void
eog_postr_plugin_dispose(GObject * object)109 eog_postr_plugin_dispose (GObject *object)
110 {
111 EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (object);
112
113 eog_debug_message (DEBUG_PLUGINS, "EogPostrPlugin disposing");
114
115 if (plugin->window != NULL) {
116 g_object_unref (plugin->window);
117 plugin->window = NULL;
118 }
119
120 G_OBJECT_CLASS (eog_postr_plugin_parent_class)->dispose (object);
121 }
122
123 static void
impl_activate(EogWindowActivatable * activatable)124 impl_activate (EogWindowActivatable *activatable)
125 {
126 EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (activatable);
127 GMenu *model, *menu;
128 GMenuItem *item;
129 GSimpleAction *action;
130
131 eog_debug (DEBUG_PLUGINS);
132
133 g_return_if_fail (plugin->window != NULL);
134
135 model= eog_window_get_gear_menu_section (plugin->window,
136 "plugins-section");
137
138 g_return_if_fail (G_IS_MENU (model));
139
140 /* Setup and inject action */
141 action = g_simple_action_new (EOG_POSTR_PLUGIN_ACTION, NULL);
142 g_signal_connect(action, "activate",
143 G_CALLBACK (postr_cb), plugin->window);
144 g_action_map_add_action (G_ACTION_MAP (plugin->window),
145 G_ACTION (action));
146 g_object_unref (action);
147
148 g_signal_connect (G_OBJECT (eog_window_get_thumb_view (plugin->window)),
149 "selection-changed",
150 G_CALLBACK (_selection_changed_cb),
151 plugin);
152 eog_postr_plugin_update_action_state (plugin);
153
154 /* Append entry to the window's gear menu */
155 menu = g_menu_new ();
156 g_menu_append (menu, _("Upload to Flickr"),
157 "win." EOG_POSTR_PLUGIN_ACTION);
158
159 item = g_menu_item_new_section (NULL, G_MENU_MODEL (menu));
160 g_menu_item_set_attribute (item, "id",
161 "s", EOG_POSTR_PLUGIN_MENU_ID);
162 g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_ICON,
163 "s", "postr");
164 g_menu_append_item (model, item);
165 g_object_unref (item);
166
167 g_object_unref (menu);
168
169 }
170
171 static void
impl_deactivate(EogWindowActivatable * activatable)172 impl_deactivate (EogWindowActivatable *activatable)
173 {
174 EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (activatable);
175 GMenu *menu;
176 GMenuModel *model;
177 gint i;
178
179 eog_debug (DEBUG_PLUGINS);
180
181 menu = eog_window_get_gear_menu_section (plugin->window,
182 "plugins-section");
183
184 g_return_if_fail (G_IS_MENU (menu));
185
186 /* Remove menu entry */
187 model = G_MENU_MODEL (menu);
188 for (i = 0; i < g_menu_model_get_n_items (model); i++) {
189 gchar *id;
190 if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) {
191 const gboolean found =
192 (g_strcmp0 (id, EOG_POSTR_PLUGIN_MENU_ID) == 0);
193 g_free (id);
194
195 if (found) {
196 g_menu_remove (menu, i);
197 break;
198 }
199 }
200 }
201
202 g_signal_handlers_disconnect_by_func (eog_window_get_thumb_view (plugin->window),
203 _selection_changed_cb, plugin);
204
205
206 /* Finally remove action */
207 g_action_map_remove_action (G_ACTION_MAP (plugin->window),
208 EOG_POSTR_PLUGIN_ACTION);
209 }
210
211 static void
eog_postr_plugin_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)212 eog_postr_plugin_get_property (GObject *object,
213 guint prop_id,
214 GValue *value,
215 GParamSpec *pspec)
216 {
217 EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (object);
218
219 switch (prop_id)
220 {
221 case PROP_WINDOW:
222 g_value_set_object (value, plugin->window);
223 break;
224
225 default:
226 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
227 break;
228 }
229 }
230
231 static void
eog_postr_plugin_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)232 eog_postr_plugin_set_property (GObject *object,
233 guint prop_id,
234 const GValue *value,
235 GParamSpec *pspec)
236 {
237 EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (object);
238
239 switch (prop_id)
240 {
241 case PROP_WINDOW:
242 plugin->window = EOG_WINDOW (g_value_dup_object (value));
243 break;
244
245 default:
246 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
247 break;
248 }
249 }
250
251 static void
eog_postr_plugin_class_init(EogPostrPluginClass * klass)252 eog_postr_plugin_class_init (EogPostrPluginClass *klass)
253 {
254 GObjectClass *object_class = G_OBJECT_CLASS (klass);
255
256 object_class->finalize = eog_postr_plugin_dispose;
257 object_class->set_property = eog_postr_plugin_set_property;
258 object_class->get_property = eog_postr_plugin_get_property;
259
260 g_object_class_override_property (object_class, PROP_WINDOW, "window");
261 }
262
263 static void
eog_postr_plugin_class_finalize(EogPostrPluginClass * klass)264 eog_postr_plugin_class_finalize (EogPostrPluginClass *klass)
265 {
266 /* Dummy needed for G_DEFINE_DYNAMIC_TYPE_EXTENDED */
267 }
268
269 static void
eog_window_activatable_iface_init(EogWindowActivatableInterface * iface)270 eog_window_activatable_iface_init (EogWindowActivatableInterface *iface)
271 {
272 iface->activate = impl_activate;
273 iface->deactivate = impl_deactivate;
274 }
275
276 G_MODULE_EXPORT void
peas_register_types(PeasObjectModule * module)277 peas_register_types (PeasObjectModule *module)
278 {
279 eog_postr_plugin_register_type (G_TYPE_MODULE (module));
280 peas_object_module_register_extension_type (module,
281 EOG_TYPE_WINDOW_ACTIVATABLE,
282 EOG_TYPE_POSTR_PLUGIN);
283 }
284