23
23
* Boston, MA 02110-1301, USA.
26
#include <glade/glade-xml.h>
27
#include <panel-applet.h>
26
28
#include <glib/gprintf.h>
29
31
#include "context-menu.h"
32
/******************************************************************************/
34
context_menu_add_delete_item (const gchar *file_name,
36
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
38
GtkWidget *menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_DELETE, NULL);
39
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
41
GtkWidget *item_label = GTK_BIN (menu_item)->child;
42
gtk_label_set_text (GTK_LABEL (item_label), "Move to Trash");
44
g_signal_connect_swapped (G_OBJECT (menu_item),
46
G_CALLBACK (vfs_trash_file),
47
(gpointer) file_name);
49
/******************************************************************************/
51
context_menu_add_fake_items (const gchar *file_name,
53
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
57
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_ABOUT, NULL);
58
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
60
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_ADD, NULL);
61
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
63
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_APPLY, NULL);
64
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
66
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_BOLD, NULL);
67
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
69
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CDROM, NULL);
70
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
72
/******************************************************************************/
75
context_menu_populate (const gchar *file_name,
77
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
79
context_menu_add_delete_item (file_name, menu);
80
context_menu_add_fake_items (file_name, menu);
82
/******************************************************************************/
84
context_menu_clean_up (GtkMenuShell *menu,
86
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
34
Garbage garbage = NULL;
36
/******************************************************************************/
37
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",
67
/******************************************************************************/
69
tree_set_sensitive (GtkWidget *menu_item, gboolean sensitive) {
70
/* walk up the menu browser tree from the menu item that causes the popup
71
* menu and disable all the menu shells, stopping at the menu bar. Need to
72
* do this to get around the focus bug. Would be nicer if we couls do this
73
* w/o changing the appearance of the widgets */
74
GtkWidget *current = menu_item->parent;
76
gtk_widget_set_sensitive (current, sensitive);
78
if (GTK_IS_MENU_BAR (current)) return;
80
current = GTK_MENU_SHELL (current)->parent_menu_shell;
83
/******************************************************************************/
85
context_menu_clean_up (GtkMenuShell *menu) {
86
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
88
g_return_if_fail (GTK_IS_MENU_SHELL (menu));
90
/* re-enable the menu browser */
91
GtkWidget *tree_menu_item = g_object_get_data (G_OBJECT (menu), "menu_item");
93
tree_set_sensitive (tree_menu_item, TRUE);
95
/* close the menu browser tree */
96
GtkWidget *browser = g_object_get_data (G_OBJECT (menu), "menu_browser");
88
97
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (browser));
89
98
gtk_menu_shell_deactivate (GTK_MENU_SHELL (parent));
91
/* gtk_grab_remove (GTK_WIDGET (menu));*/
92
/* gdk_pointer_ungrab (GDK_CURRENT_TIME);*/
100
/* delete the popup menu and empty the garbage */
94
101
gtk_widget_destroy (GTK_WIDGET (menu));
102
garbage_empty (&garbage, FALSE);
104
/******************************************************************************/
105
/* originally wanted to use nautilus burn for this, but it doesn't seem
106
* possible to programmatically add files to burn:/// */
109
context_menu_add_burn_callback (const gchar *file_name) {
110
GFile *source = g_file_new_for_path (file_name);
111
GFile *destination = g_file_new_for_uri ("burn:///");
113
GError *error = NULL;
117
G_FILE_COPY_OVERWRITE,
123
utils_gerror_ok (&error, TRUE);
126
/******************************************************************************/
128
context_menu_add_new_dir_callback (gchar *file_name) {
129
GError *error = NULL;
131
GladeXML* xml = glade_xml_new (GLADEUI_PATH, "new_dir_dialog", NULL);
132
g_return_if_fail (xml != NULL);
134
GtkWidget *new_dir_dialog = glade_xml_get_widget (xml, "new_dir_dialog");
135
GtkWidget *new_dir_entry = glade_xml_get_widget (xml, "new_dir_entry");
137
if (gtk_dialog_run (GTK_DIALOG (new_dir_dialog)) == GTK_RESPONSE_ACCEPT) {
138
const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (new_dir_entry));
139
gchar *new_dir = g_strdup_printf ("%s/%s", file_name, entry_text);
141
GFile *file = g_file_new_for_path (new_dir);
142
g_file_make_directory (file, NULL, &error);
143
g_object_unref (file);
145
/* open the dir if we succeeded in creating it */
146
if (utils_gerror_ok (&error, TRUE)) {
147
vfs_file_do_default_action (new_dir);
150
gtk_widget_destroy (new_dir_dialog);
153
/******************************************************************************/
155
context_menu_add_new_dir (const gchar *file_name, GtkWidget *menu) {
157
if (!vfs_file_is_directory (file_name)) return;
159
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic ("_New Folder Here");
160
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
161
gtk_image_new_from_stock (GTK_STOCK_NEW,
162
GTK_ICON_SIZE_MENU));
163
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
165
g_signal_connect_swapped (G_OBJECT (menu_item),
167
G_CALLBACK (context_menu_add_new_dir_callback),
168
(gpointer) g_strdup (file_name));
170
/******************************************************************************/
172
context_menu_add_burn (const gchar *file_name, GtkWidget *menu) {
173
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic ("_Create CD/DVD");
174
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
175
gtk_image_new_from_icon_name ("nautilus-cd-burner",
176
GTK_ICON_SIZE_MENU));
177
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
179
LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
180
launch_info->command = g_strdup ("brasero");
181
launch_info->file = g_strdup (file_name);
183
g_signal_connect_swapped (G_OBJECT (menu_item),
185
G_CALLBACK (vfs_launch_application),
186
(gpointer) launch_info);
188
garbage_add_item (garbage, launch_info);
189
garbage_add_item (garbage, launch_info->command);
190
garbage_add_item (garbage, launch_info->file);
192
/******************************************************************************/
194
context_menu_add_compile_tex (const gchar *file_name, GtkWidget *menu) {
196
if (!g_str_has_suffix (file_name, "tex")) return;
198
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic ("_Build Latex Document");
199
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
200
gtk_image_new_from_icon_name ("build",
201
GTK_ICON_SIZE_MENU));
202
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
204
LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
205
launch_info->command = g_strdup ("rubber -f --inplace -d");
206
launch_info->file = g_strdup (file_name);
208
g_signal_connect_swapped (G_OBJECT (menu_item),
210
G_CALLBACK (vfs_launch_application),
211
(gpointer) launch_info);
213
garbage_add_item (garbage, launch_info);
214
garbage_add_item (garbage, launch_info->command);
215
garbage_add_item (garbage, launch_info->file);
217
/******************************************************************************/
219
is_archive (const gchar *file_name) {
220
gboolean ret = FALSE;
221
GFile* file = g_file_new_for_path (file_name);
222
GFileInfo* file_info = g_file_query_info (file,
223
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
228
const gchar* content_type = g_file_info_get_content_type (file_info);
231
for (i = 0; archive_mime_types[i] != NULL; i++) {
232
if (g_strcmp0 (content_type, archive_mime_types[i]) == 0) {
237
g_object_unref (file_info);
238
g_object_unref (file);
242
/******************************************************************************/
244
context_menu_add_archive_action (const gchar *file_name, GtkWidget *menu) {
245
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
247
gchar *archive_label = NULL;
248
gchar *archive_action = NULL;
250
if (is_archive (file_name)) {
251
archive_label = "_Extract Here";
252
archive_action = "file-roller -h";
255
archive_label = "Create _Archive";
256
archive_action = "file-roller -d";
259
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic (archive_label);
260
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
261
gtk_image_new_from_icon_name ("package",
262
GTK_ICON_SIZE_MENU));
263
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
265
LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
266
launch_info->command = g_strdup (archive_action);
267
launch_info->file = g_strdup (file_name);
269
g_signal_connect_swapped (G_OBJECT (menu_item),
271
G_CALLBACK (vfs_launch_application),
272
(gpointer) launch_info);
274
garbage_add_item (garbage, launch_info);
275
garbage_add_item (garbage, launch_info->command);
276
garbage_add_item (garbage, launch_info->file);
278
/******************************************************************************/
280
context_menu_add_open_with_item (const gchar *file_name, GtkWidget *menu) {
281
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
283
GList *root = vfs_get_all_mime_applications (file_name);
286
if (root == NULL) return;
288
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic ("_Open With");
289
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
290
gtk_image_new_from_stock (GTK_STOCK_OPEN,
291
GTK_ICON_SIZE_MENU));
292
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
294
GtkWidget *sub_menu = gtk_menu_new ();
295
/* sigh! The browser menu does not close properly if the popup menu is
296
* cancelled from a submenu in the popup menu*/
297
g_signal_connect_swapped (GTK_MENU_SHELL (sub_menu),
299
G_CALLBACK (context_menu_clean_up),
302
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
305
while (apps != NULL) {
306
menu_item = gtk_image_menu_item_new_with_label (g_app_info_get_name (apps->data));
307
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
308
gtk_image_new_from_gicon (g_app_info_get_icon (apps->data),
309
GTK_ICON_SIZE_MENU));
311
LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
312
launch_info->command = g_strdup (g_app_info_get_executable (apps->data));
313
launch_info->file = g_strdup (file_name);
315
g_signal_connect_swapped (GTK_MENU_ITEM (menu_item),
317
G_CALLBACK (vfs_launch_application),
318
(gpointer) launch_info);
320
gtk_menu_shell_append (GTK_MENU_SHELL (sub_menu), menu_item);
322
garbage_add_item (garbage, launch_info);
323
garbage_add_item (garbage, launch_info->command);
324
garbage_add_item (garbage, launch_info->file);
326
g_object_unref (apps->data);
331
/******************************************************************************/
333
context_menu_add_trash_item (const gchar *file_name, GtkWidget *menu) {
334
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
336
GtkWidget *menu_item = gtk_image_menu_item_new_with_mnemonic ("_Move to Trash");
337
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
338
gtk_image_new_from_stock (GTK_STOCK_DELETE,
339
GTK_ICON_SIZE_MENU));
340
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
342
g_signal_connect_swapped (G_OBJECT (menu_item),
344
G_CALLBACK (vfs_file_trash),
345
(gpointer) g_strdup (file_name));
347
/******************************************************************************/
350
context_menu_add_close_item (GtkWidget *menu) {
351
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
353
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
354
gtk_separator_menu_item_new());
356
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
357
gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, NULL));
360
/******************************************************************************/
362
context_menu_populate (const gchar *file_name, GtkWidget *menu) {
363
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
365
context_menu_add_open_with_item (file_name, menu);
366
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
367
context_menu_add_new_dir (file_name, menu);
368
context_menu_add_trash_item (file_name, menu);
369
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
370
context_menu_add_archive_action (file_name, menu);
371
context_menu_add_compile_tex (file_name, menu);
372
context_menu_add_burn (file_name, menu);
373
/*context_menu_add_close_item (menu);*/
375
gtk_widget_show_all (menu);
96
377
/******************************************************************************/
98
context_menu_display (const gchar *file_name,
99
GtkWidget *menu_item) {
379
context_menu_display (const gchar *file_name, GtkWidget *menu_item) {
100
380
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
102
382
int event_button;
105
GdkEventButton *event = g_object_get_data (G_OBJECT (menu_item),
385
GdkEventButton *event = g_object_get_data (G_OBJECT (menu_item), "button_event");
108
387
event_button = event->button;
109
388
event_time = event->time;