32
31
#include "config.h"
34
static Garbage garbage = NULL;
36
33
/******************************************************************************/
37
34
static char *archive_mime_types[] = {
41
"application/x-bzip-compressed-tar",
42
"application/x-compress",
43
"application/x-compressed-tar",
50
"application/x-rar-compressed",
53
"application/x-zip-compressed",
58
"application/x-java-archive",
61
"application/x-cd-image",
62
"application/x-7z-compressed",
63
"application/x-gzpostscript",
64
"application/x-ms-dos-executable",
38
"application/x-bzip-compressed-tar",
39
"application/x-compress",
40
"application/x-compressed-tar",
47
"application/x-rar-compressed",
50
"application/x-zip-compressed",
55
"application/x-java-archive",
58
"application/x-cd-image",
59
"application/x-7z-compressed",
60
"application/x-gzpostscript",
61
"application/x-ms-dos-executable",
67
64
/******************************************************************************/
69
66
tree_set_sensitive (GtkWidget *menu_item, gboolean sensitive) {
70
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
71
/* walk up the menu browser tree from the menu item that causes the popup
72
* menu and disable all the menu shells, stopping at the menu bar. Need to
73
* do this to get around the focus bug. Would be nicer if we could do this
74
* w/o changing the appearance of the widgets */
75
GtkWidget *current = menu_item->parent;
77
gtk_widget_set_sensitive (current, sensitive);
79
if (GTK_IS_MENU_BAR (current)) return;
81
current = GTK_MENU_SHELL (current)->parent_menu_shell;
67
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
68
/* walk up the menu browser tree from the menu item that causes the popup
69
* menu and disable all the menu shells, stopping at the menu bar. Need to
70
* do this to get around the focus bug. Would be nicer if we could do this
71
* w/o changing the appearance of the widgets */
72
GtkWidget *current = menu_item->parent;
74
gtk_widget_set_sensitive (current, sensitive);
76
if (GTK_IS_MENU_BAR (current)) return;
78
current = GTK_MENU_SHELL (current)->parent_menu_shell;
84
81
/******************************************************************************/
85
82
/* Stolen from menu.c from the gnome-panel */
87
84
restore_grabs (GtkWidget *w, gpointer data) {
88
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
85
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
90
87
GtkWidget *menu_item = data;
91
88
GtkMenu *menu = GTK_MENU(menu_item->parent);
134
gtk_grab_add (GTK_WIDGET (menu));
131
gtk_grab_add (GTK_WIDGET (menu));
136
133
/******************************************************************************/
138
135
close_menu_browser (GtkWidget *menu) {
139
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
136
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
141
GtkWidget *browser = g_object_get_data (G_OBJECT (menu), "menu_browser");
142
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (browser));
138
GtkWidget *browser = g_object_get_data (G_OBJECT (menu), "menu_browser");
139
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (browser));
143
140
gtk_menu_shell_deactivate (GTK_MENU_SHELL (parent));
145
142
/******************************************************************************/
147
144
context_menu_clean_up (GtkWidget *menu) {
148
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
145
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
150
147
gtk_widget_destroy (menu);
151
garbage_empty (&garbage, FALSE);
153
149
/******************************************************************************/
156
152
const gchar* file,
157
153
GtkMenuItem *menu_item,
159
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
161
gchar **args = g_strv_new (ARGS_SIZE);
162
args[ARG_APP] = g_strdup (app);
163
args[ARG_FILE] = g_strdup (file);
165
g_signal_connect_swapped (menu_item,
167
G_CALLBACK (vfs_launch_application),
155
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
157
gchar **args = g_strv_new (ARGS_SIZE);
158
args[ARG_APP] = g_strdup (app);
159
args[ARG_FILE] = g_strdup (file);
161
g_signal_connect_data (GTK_MENU_ITEM (menu_item),
163
G_CALLBACK (vfs_launch_application),
165
(GClosureNotify)g_strfreev,
170
168
g_signal_connect_swapped (menu_item,
172
170
G_CALLBACK (close_menu_browser),
175
garbage_add_item (garbage, args[ARG_APP]);
176
garbage_add_item (garbage, args[ARG_FILE]);
177
garbage_add_item (garbage, args);
179
173
/******************************************************************************/
181
175
context_menu_add_new_dir_callback (GtkWidget *menu_item, gchar *file_name) {
182
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
176
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
184
178
GtkWidget *menu = gtk_widget_get_parent (menu_item);
186
179
close_menu_browser (menu);
188
GError *error = NULL;
190
GladeXML* xml = glade_xml_new (GLADEUI_PATH, "new_dir_dialog", NULL);
191
g_return_if_fail (xml != NULL);
193
GtkWidget *new_dir_dialog = glade_xml_get_widget (xml, "new_dir_dialog");
194
GtkWidget *new_dir_entry = glade_xml_get_widget (xml, "new_dir_entry");
196
if (gtk_dialog_run (GTK_DIALOG (new_dir_dialog)) == GTK_RESPONSE_ACCEPT) {
197
const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (new_dir_entry));
198
gchar *new_dir = g_strdup_printf ("%s/%s", file_name, entry_text);
200
GFile *file = g_file_new_for_path (new_dir);
201
g_file_make_directory (file, NULL, &error);
202
g_object_unref (file);
204
/* open the dir if we succeeded in creating it */
205
if (utils_gerror_ok (&error, TRUE)) {
206
vfs_file_do_default_action (new_dir);
209
gtk_widget_destroy (new_dir_dialog);
180
GError *error = NULL;
182
GtkBuilder* builder = gtk_builder_new();
183
/*gtk_builder_add_from_file (builder, BUILDER_UI_PATH, &error);*/
184
gchar *toplevel = "new_dir_dialog";
185
gtk_builder_add_objects_from_file (builder, BUILDER_UI_PATH, &toplevel, &error);
186
if (!utils_gerror_ok(&error, TRUE)) {
189
GtkWidget *new_dir_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "new_dir_dialog"));
190
GtkWidget *new_dir_entry = GTK_WIDGET (gtk_builder_get_object (builder, "new_dir_entry"));
191
GtkWidget *current_path_label = GTK_WIDGET (gtk_builder_get_object (builder, "current_path_label"));
193
gtk_label_set_text (GTK_LABEL (current_path_label),
196
if (gtk_dialog_run (GTK_DIALOG (new_dir_dialog)) == GTK_RESPONSE_ACCEPT) {
197
const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (new_dir_entry));
198
gchar *new_dir = g_strdup_printf ("%s/%s", file_name, entry_text);
200
GFile *file = g_file_new_for_path (new_dir);
201
g_file_make_directory (file, NULL, &error);
202
g_object_unref (file);
204
/* open the dir if we succeeded in creating it */
205
if (utils_gerror_ok (&error, TRUE)) {
206
vfs_file_do_default_action (new_dir);
209
gtk_widget_destroy (new_dir_dialog);
212
211
/******************************************************************************/
214
213
context_menu_add_new_dir (const gchar *file_name, GtkWidget *menu) {
215
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
217
if (!vfs_file_is_directory (file_name)) return;
219
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_New Folder Here"));
220
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
221
gtk_image_new_from_stock (GTK_STOCK_NEW,
222
GTK_ICON_SIZE_MENU));
223
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
225
g_signal_connect (GTK_MENU_ITEM (menu_item),
227
G_CALLBACK (context_menu_add_new_dir_callback),
228
g_strdup (file_name));
214
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
216
if (!vfs_file_is_directory (file_name)) return;
218
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_New Folder Here"));
219
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
220
gtk_image_new_from_stock (GTK_STOCK_NEW,
221
GTK_ICON_SIZE_MENU));
222
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
224
g_signal_connect_data (GTK_MENU_ITEM (menu_item),
226
G_CALLBACK (context_menu_add_new_dir_callback),
227
g_strdup (file_name),
228
(GClosureNotify)g_free,
230
231
/******************************************************************************/
232
233
context_menu_add_burn (const gchar *file_name, GtkWidget *menu) {
233
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
235
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Create CD/DVD"));
236
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
237
gtk_image_new_from_icon_name ("nautilus-cd-burner",
238
GTK_ICON_SIZE_MENU));
239
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
241
context_menu_setup_callback ("brasero",
234
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
236
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Create CD/DVD"));
237
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
238
gtk_image_new_from_icon_name ("nautilus-cd-burner",
239
GTK_ICON_SIZE_MENU));
240
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
242
context_menu_setup_callback ("brasero",
243
244
GTK_MENU_ITEM (menu_item),
244
245
GTK_MENU (menu));
246
247
/******************************************************************************/
248
249
context_menu_add_compile_tex (const gchar *file_name, GtkWidget *menu) {
249
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
251
if (!g_str_has_suffix (file_name, "tex")) return;
253
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Build Latex Document"));
254
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
255
gtk_image_new_from_icon_name ("build",
256
GTK_ICON_SIZE_MENU));
257
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
259
context_menu_setup_callback ("rubber -f --inplace -d",
250
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
252
if (!g_str_has_suffix (file_name, "tex")) return;
254
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Build Latex Document"));
255
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
256
gtk_image_new_from_icon_name ("build",
257
GTK_ICON_SIZE_MENU));
258
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
260
context_menu_setup_callback ("rubber -f --inplace -d",
261
262
GTK_MENU_ITEM (menu_item),
262
263
GTK_MENU (menu));
264
265
/******************************************************************************/
266
267
is_archive (const gchar *file_name) {
267
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
269
gboolean ret = FALSE;
270
GFile* file = g_file_new_for_path (file_name);
271
GFileInfo* file_info = g_file_query_info (file,
272
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
277
const gchar* content_type = g_file_info_get_content_type (file_info);
280
for (i = 0; archive_mime_types[i] != NULL; i++) {
281
if (g_strcmp0 (content_type, archive_mime_types[i]) == 0) {
286
g_object_unref (file_info);
287
g_object_unref (file);
268
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
270
gboolean ret = FALSE;
271
GFile* file = g_file_new_for_path (file_name);
272
GFileInfo* file_info = g_file_query_info (file,
273
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
278
const gchar* content_type = g_file_info_get_content_type (file_info);
281
for (i = 0; archive_mime_types[i] != NULL; i++) {
282
if (g_strcmp0 (content_type, archive_mime_types[i]) == 0) {
287
g_object_unref (file_info);
288
g_object_unref (file);
291
292
/******************************************************************************/
293
294
context_menu_add_archive_action (const gchar *file_name, GtkWidget *menu) {
294
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
296
gchar *archive_label = NULL;
297
gchar *archive_action = NULL;
299
if (is_archive (file_name)) {
300
archive_label = _("_Extract Here");
301
archive_action = "file-roller -h";
304
archive_label = _("Create _Archive");
305
archive_action = "file-roller -d";
308
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (archive_label);
309
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
310
gtk_image_new_from_icon_name ("package",
311
GTK_ICON_SIZE_MENU));
312
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
314
context_menu_setup_callback (archive_action,
295
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
297
gchar *archive_label = NULL;
298
gchar *archive_action = NULL;
300
if (is_archive (file_name)) {
301
archive_label = _("_Extract Here");
302
archive_action = "file-roller -h";
305
archive_label = _("Create _Archive");
306
archive_action = "file-roller -d";
309
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (archive_label);
310
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
311
gtk_image_new_from_icon_name ("package",
312
GTK_ICON_SIZE_MENU));
313
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
315
context_menu_setup_callback (archive_action,
316
317
GTK_MENU_ITEM (menu_item),
317
318
GTK_MENU (menu));
319
320
/******************************************************************************/
321
322
context_menu_add_open_with_item (const gchar *file_name, GtkWidget *menu) {
322
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
324
GList *root = vfs_get_all_mime_applications (file_name);
327
g_return_if_fail (root != NULL);
329
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Open With"));
330
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
331
gtk_image_new_from_stock (GTK_STOCK_OPEN,
332
GTK_ICON_SIZE_MENU));
333
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
335
GtkWidget *sub_menu = gtk_menu_new ();
337
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
339
while (apps != NULL) {
340
menu_item = gtk_image_menu_item_new_with_label (g_app_info_get_name (apps->data));
341
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
342
gtk_image_new_from_gicon (g_app_info_get_icon (apps->data),
343
GTK_ICON_SIZE_MENU));
345
gtk_menu_shell_append (GTK_MENU_SHELL (sub_menu), menu_item);
347
context_menu_setup_callback (g_app_info_get_executable (apps->data),
323
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
325
GList *root = vfs_get_all_mime_applications (file_name);
328
g_return_if_fail (root != NULL);
330
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Open With"));
331
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
332
gtk_image_new_from_stock (GTK_STOCK_OPEN,
333
GTK_ICON_SIZE_MENU));
334
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
336
GtkWidget *sub_menu = gtk_menu_new ();
338
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
340
while (apps != NULL) {
341
menu_item = gtk_image_menu_item_new_with_label (g_app_info_get_name (apps->data));
342
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
343
gtk_image_new_from_gicon (g_app_info_get_icon (apps->data),
344
GTK_ICON_SIZE_MENU));
346
gtk_menu_shell_append (GTK_MENU_SHELL (sub_menu), menu_item);
348
context_menu_setup_callback (g_app_info_get_executable (apps->data),
349
350
GTK_MENU_ITEM (menu_item),
350
351
GTK_MENU (menu));
352
g_object_unref (apps->data);
353
g_object_unref (apps->data);
357
358
/******************************************************************************/
359
360
context_menu_add_trash_item (const gchar *file_name, GtkWidget *menu) {
360
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
362
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Move to Trash"));
363
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
364
gtk_image_new_from_stock (GTK_STOCK_DELETE,
365
GTK_ICON_SIZE_MENU));
366
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
368
g_signal_connect_swapped (G_OBJECT (menu_item),
370
G_CALLBACK (vfs_file_trash),
371
(gpointer) g_strdup (file_name));
361
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
363
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Move to Trash"));
364
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
365
gtk_image_new_from_icon_name ("user-trash-full",
366
GTK_ICON_SIZE_MENU));
367
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
369
g_signal_connect_data (GTK_MENU_ITEM (menu_item),
371
G_CALLBACK (vfs_file_trash),
372
g_strdup (file_name),
373
(GClosureNotify)g_free,
373
376
g_signal_connect_swapped (menu_item,
378
381
/******************************************************************************/
380
383
context_menu_populate (const gchar *file_name, GtkWidget *menu) {
381
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
383
context_menu_add_open_with_item (file_name, menu);
384
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
385
context_menu_add_new_dir (file_name, menu);
386
context_menu_add_trash_item (file_name, menu);
387
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
388
context_menu_add_archive_action (file_name, menu);
389
context_menu_add_compile_tex (file_name, menu);
390
context_menu_add_burn (file_name, menu);
392
gtk_widget_show_all (menu);
384
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
386
context_menu_add_open_with_item (file_name, menu);
387
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
388
context_menu_add_new_dir (file_name, menu);
389
context_menu_add_trash_item (file_name, menu);
390
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
391
context_menu_add_archive_action (file_name, menu);
392
context_menu_add_compile_tex (file_name, menu);
393
context_menu_add_burn (file_name, menu);
395
gtk_widget_show_all (menu);
394
397
/******************************************************************************/
396
399
context_menu_display (const gchar *file_name, GtkWidget *menu_item) {
397
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
402
GdkEventButton *event = g_object_get_data (G_OBJECT (menu_item), "button_event");
404
event_button = event->button;
405
event_time = event->time;
409
event_time = gtk_get_current_event_time();
412
garbage_init (&garbage);
414
GtkWidget *menu = gtk_menu_new ();
416
/* add some data to the popup menu so we can get to it later */
417
GtkWidget *menu_browser = g_object_get_data (G_OBJECT (menu_item), "menu_browser");
418
g_object_set_data (G_OBJECT (menu), "menu_browser", menu_browser);
419
g_object_set_data (G_OBJECT (menu), "menu_item", menu_item);
400
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
405
GdkEventButton *event = g_object_get_data (G_OBJECT (menu_item), "button_event");
407
event_button = event->button;
408
event_time = event->time;
412
event_time = gtk_get_current_event_time();
415
GtkWidget *menu = gtk_menu_new ();
417
/* add some data to the popup menu so we can get to it later */
418
GtkWidget *menu_browser = g_object_get_data (G_OBJECT (menu_item), "menu_browser");
419
g_object_set_data (G_OBJECT (menu), "menu_browser", menu_browser);
420
g_object_set_data (G_OBJECT (menu), "menu_item", menu_item);
421
422
g_signal_connect_swapped (menu_item,
423
424
G_CALLBACK (context_menu_clean_up),
426
g_signal_connect (GTK_MENU_SHELL (menu),
427
g_signal_connect (GTK_MENU_SHELL (menu),
428
429
G_CALLBACK (restore_grabs),
431
context_menu_populate (file_name, menu);
432
context_menu_populate (file_name, menu);
433
/* disable the menu browser to get around the focus bug */
434
/* disable the menu browser to get around the focus bug */
434
435
tree_set_sensitive (menu_item, FALSE);
436
gtk_menu_popup (GTK_MENU (menu),
437
gtk_menu_popup (GTK_MENU (menu),
445
446
/******************************************************************************/