1 /* EasyTAG - tag editor for audio files
2 * Copyright (C) 2014 Victor A. Santos <victoraur.santos@gmail.com>
3 * Copyright (C) 2014 David King <amigadave@amigadave.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "config.h"
20
21 #include <string.h>
22 #include <gio/gio.h>
23 #include <gio/gdesktopappinfo.h>
24 #include <glib/gi18n-lib.h>
25 #include <libnautilus-extension/nautilus-extension-types.h>
26 #include <libnautilus-extension/nautilus-file-info.h>
27 #include <libnautilus-extension/nautilus-menu-provider.h>
28
29 #define NAUTILUS_TYPE_EASYTAG (nautilus_easytag_get_type ())
30 #define NAUTILUS_EASYTAG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_EASYTAG, NautilusEasytag))
31 #define NAUTILUS_IS_EASYTAG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_EASYTAG))
32
33 typedef struct _NautilusEasytag NautilusEasytag;
34 typedef struct _NautilusEasytagClass NautilusEasytagClass;
35
36 struct _NautilusEasytag
37 {
38 GObject parent;
39 };
40
41 struct _NautilusEasytagClass
42 {
43 GObjectClass parent_class;
44 };
45
46 GType nautilus_easytag_get_type (void);
47
48 typedef struct
49 {
50 gboolean is_directory;
51 gboolean is_file;
52 } FileMimeInfo;
53
54 static struct
55 {
56 const gchar *mime_type;
57 gboolean is_directory;
58 gboolean is_file;
59 } easytag_mime_types[] =
60 {
61 { "inode/directory", TRUE, FALSE },
62 { "audio/x-mp3", FALSE, TRUE },
63 { "audio/x-mpeg", FALSE, TRUE },
64 { "audio/mpeg", FALSE, TRUE },
65 { "application/ogg", FALSE, TRUE },
66 { "audio/x-vorbis+ogg", FALSE, TRUE },
67 { "audio/x-flac", FALSE, TRUE },
68 { "audio/x-musepack", FALSE, TRUE },
69 { "audio/x-ape", FALSE, TRUE },
70 { "audio/x-speex+ogg", FALSE, TRUE },
71 { "audio/x-opus+ogg", FALSE, TRUE },
72 { NULL, FALSE }
73 };
74
75 static gboolean
unsupported_scheme(NautilusFileInfo * file)76 unsupported_scheme (NautilusFileInfo *file)
77 {
78 gboolean result = FALSE;
79 GFile *location;
80 gchar *scheme;
81
82 location = nautilus_file_info_get_location (file);
83 scheme = g_file_get_uri_scheme (location);
84
85 if (scheme != NULL)
86 {
87 const gchar *unsupported[] = { "trash", "computer", NULL };
88 gsize i;
89
90 for (i = 0; unsupported[i] != NULL; i++)
91 {
92 if (strcmp (scheme, unsupported[i]) == 0)
93 {
94 result = TRUE;
95 }
96 }
97 }
98
99 g_free (scheme);
100 g_object_unref (location);
101
102 return result;
103 }
104
105 static FileMimeInfo
get_file_mime_info(NautilusFileInfo * file)106 get_file_mime_info (NautilusFileInfo *file)
107 {
108 FileMimeInfo file_mime_info;
109 gsize i;
110
111 file_mime_info.is_directory = FALSE;
112 file_mime_info.is_file = FALSE;
113
114 for (i = 0; easytag_mime_types[i].mime_type != NULL; i++)
115 {
116 if (nautilus_file_info_is_mime_type (file,
117 easytag_mime_types[i].mime_type))
118 {
119 file_mime_info.is_directory = easytag_mime_types[i].is_directory;
120 file_mime_info.is_file = easytag_mime_types[i].is_file;
121
122 return file_mime_info;
123 }
124 }
125
126 return file_mime_info;
127 }
128
129 static void
on_open_in_easytag(NautilusMenuItem * item,gpointer data)130 on_open_in_easytag (NautilusMenuItem *item,
131 gpointer data)
132 {
133 NautilusFileInfo *dir;
134 GDesktopAppInfo *appinfo;
135
136 dir = g_object_get_data (G_OBJECT (item), "dir");
137
138 appinfo = g_desktop_app_info_new ("easytag.desktop");
139
140 if (appinfo)
141 {
142 GdkAppLaunchContext *context;
143 GList *uris = NULL;
144
145 uris = g_list_append (uris, nautilus_file_info_get_uri (dir));
146 context = gdk_display_get_app_launch_context (gdk_display_get_default ());
147
148 g_app_info_launch_uris (G_APP_INFO (appinfo), uris,
149 G_APP_LAUNCH_CONTEXT (context), NULL);
150 }
151 }
152
153 static void
on_open_with_easytag(NautilusMenuItem * item,gpointer data)154 on_open_with_easytag (NautilusMenuItem *item,
155 gpointer data)
156 {
157 GList *files;
158 GDesktopAppInfo *appinfo;
159
160 files = g_object_get_data (G_OBJECT (item), "files");
161
162 appinfo = g_desktop_app_info_new ("easytag.desktop");
163
164 if (appinfo)
165 {
166 GdkAppLaunchContext *context;
167 GList *l;
168 GList *uris = NULL;
169
170 for (l = files; l != NULL; l = g_list_next (l))
171 {
172 uris = g_list_append (uris,
173 nautilus_file_info_get_uri (l->data));
174 }
175
176 context = gdk_display_get_app_launch_context (gdk_display_get_default ());
177
178 g_app_info_launch_uris (G_APP_INFO (appinfo), uris,
179 G_APP_LAUNCH_CONTEXT (context), NULL);
180 }
181 }
182
183 static GList *
nautilus_easytag_get_file_items(NautilusMenuProvider * provider,GtkWidget * window,GList * files)184 nautilus_easytag_get_file_items (NautilusMenuProvider *provider,
185 GtkWidget *window,
186 GList *files)
187 {
188 GList *items = NULL;
189 GList *l;
190 gboolean one_item;
191 gboolean one_directory = TRUE;
192 gboolean all_files = TRUE;
193
194 if (files == NULL)
195 {
196 return NULL;
197 }
198
199 if (unsupported_scheme ((NautilusFileInfo *)files->data))
200 {
201 return NULL;
202 }
203
204 for (l = files; l != NULL; l = g_list_next (l))
205 {
206 FileMimeInfo file_mime_info;
207 NautilusFileInfo *file = l->data;
208
209 file_mime_info = get_file_mime_info (file);
210
211 if (all_files && !file_mime_info.is_file)
212 {
213 all_files = FALSE;
214 }
215
216 if (one_directory && !file_mime_info.is_directory)
217 {
218 one_directory = FALSE;
219 }
220 }
221
222 one_item = (files != NULL) && (files->next == NULL);
223
224 if (one_directory && one_item)
225 {
226 NautilusMenuItem *item;
227
228 item = nautilus_menu_item_new ("NautilusEasytag::open_directory",
229 _("Open in EasyTAG"),
230 _("Open the selected directory in EasyTAG"),
231 "easytag");
232 g_signal_connect (item,
233 "activate",
234 G_CALLBACK (on_open_in_easytag),
235 provider);
236 g_object_set_data (G_OBJECT (item),
237 "dir",
238 files->data);
239
240 items = g_list_append (items, item);
241 }
242 else if (all_files)
243 {
244 NautilusMenuItem *item;
245
246 item = nautilus_menu_item_new ("NautilusEasytag::open_files",
247 _("Open with EasyTAG"),
248 _("Open the selected files in EasyTAG"),
249 "easytag");
250 g_signal_connect (item,
251 "activate",
252 G_CALLBACK (on_open_with_easytag),
253 provider);
254 g_object_set_data_full (G_OBJECT (item),
255 "files",
256 nautilus_file_info_list_copy (files),
257 (GDestroyNotify) nautilus_file_info_list_free);
258
259 items = g_list_append (items, item);
260 }
261
262 return items;
263 }
264
265 static void
nautilus_easytag_menu_provider_iface_init(NautilusMenuProviderIface * iface)266 nautilus_easytag_menu_provider_iface_init (NautilusMenuProviderIface *iface)
267 {
268 iface->get_file_items = nautilus_easytag_get_file_items;
269 }
270
271 G_DEFINE_DYNAMIC_TYPE_EXTENDED (NautilusEasytag,
272 nautilus_easytag,
273 G_TYPE_OBJECT,
274 0,
275 G_IMPLEMENT_INTERFACE_DYNAMIC (NAUTILUS_TYPE_MENU_PROVIDER,
276 nautilus_easytag_menu_provider_iface_init));
277
278 static void
nautilus_easytag_init(NautilusEasytag * self)279 nautilus_easytag_init (NautilusEasytag *self)
280 {
281 }
282
283 static void
nautilus_easytag_class_init(NautilusEasytagClass * class)284 nautilus_easytag_class_init (NautilusEasytagClass *class)
285 {
286 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
287 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
288 }
289
290 static void
nautilus_easytag_class_finalize(NautilusEasytagClass * class)291 nautilus_easytag_class_finalize (NautilusEasytagClass *class)
292 {
293 }
294
295 /* Nautilus extension module. */
296 static GType type_list[1];
297
298 void
nautilus_module_initialize(GTypeModule * module)299 nautilus_module_initialize (GTypeModule *module)
300 {
301 nautilus_easytag_register_type (module);
302
303 type_list[0] = NAUTILUS_TYPE_EASYTAG;
304 }
305
306 void
nautilus_module_shutdown(void)307 nautilus_module_shutdown (void)
308 {
309 }
310
311 void
nautilus_module_list_types(const GType ** types,int * num_types)312 nautilus_module_list_types (const GType **types,
313 int *num_types)
314 {
315 *types = type_list;
316 *num_types = G_N_ELEMENTS (type_list);
317 }
318