~ubuntu-branches/ubuntu/karmic/file-browser-applet/karmic

« back to all changes in this revision

Viewing changes to src/context-menu.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2009-04-11 17:15:39 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090411171539-jk4kgkvm4i39nv3c
Tags: 0.6.2-1
* New upstream release. (Closes: #504525)
 - Added context menu with a few actions (open-with, new folder here, 
   delete file/folder, create/extract archive, create CD/DVD from 
   file/folder, compile a tex file).
 - Added configuration option to make text vertical/horizontal when 
   the panel is vertical.
 - Added tooltips to configuration dialog.
 - Fixes upstream bugs #21, #30, #34, #37, #39, #43, #44, #45, #49, 
   #51, #56, #59, #60, and #62.
 - Added mnemonic keyboard shortcut to menus for 
   faster keyboard navigation.
 - Added recent documents' support.
 - Improved menu browser focus after context menu close.
 - Added preliminary DnD dragging out of applet. MOVE is the default 
   behaviour.
 - Some code cleanups and plugged memory leaks.
 - Slightly improved "New Folder" dialog.
 - Migrated to gtk+ builder from libglade.
* debian/control:
 - Add suggests on file-roller, brasero, and rubber 
   for new features.
 - Add Vcs-Bzr field.
 - Drop depricated libglade2-dev Build-Depend
 - Drop unneeded libpanel-applet2-0 Depend. Already picked up by 
   shlibs:Depends.
 - Add versionized Build-Depend on libgtk2.0-dev (>= 2.14)
 - Bump Standards-Version to 3.8.1
* debian/copyright:
 - Use /usr/share/common-licenses/GPL-2 rather than just GLP.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * File:                                context_menu.c
3
 
 * Created:                             April 2008
4
 
 * Created by:                  Axel von Bertoldi
5
 
 * Last Modified:               April 2008
6
 
 * Last Modified by:    Axel von Bertoldi
7
 
 * (C) 2005-2008                Axel von Bertoldi
 
2
 * File:                context_menu.c
 
3
 * Created:             April 2008
 
4
 * Created by:          Axel von Bertoldi
 
5
 * Last Modified:       April 2009
 
6
 * Last Modified by:    Axel von Bertoldi
 
7
 * (C) 2005-2008        Axel von Bertoldi
8
8
 *
9
9
 * This program is free software; you can redistribute it and/or modify it
10
10
 * under the terms of the GNU General Public License as published by the Free
23
23
 * Boston, MA 02110-1301, USA.
24
24
 */
25
25
 
26
 
#include <glade/glade-xml.h>
27
26
#include <glib/gprintf.h>
28
27
 
29
28
#include "context-menu.h"
31
30
#include "utils.h"
32
31
#include "config.h"
33
32
 
34
 
static Garbage garbage = NULL;
35
 
 
36
33
/******************************************************************************/
37
34
static char *archive_mime_types[] = {
38
 
        "application/x-ar",
39
 
        "application/x-arj",
40
 
        "application/x-bzip",
41
 
        "application/x-bzip-compressed-tar",
42
 
        "application/x-compress",
43
 
        "application/x-compressed-tar",
44
 
        "application/x-deb",
45
 
        "application/x-gtar",
46
 
        "application/x-gzip",
47
 
        "application/x-lha",
48
 
        "application/x-lhz",
49
 
        "application/x-rar",
50
 
        "application/x-rar-compressed",
51
 
        "application/x-tar",
52
 
        "application/x-zip",
53
 
        "application/x-zip-compressed",
54
 
        "application/zip",
55
 
        "multipart/x-zip",
56
 
        "application/x-rpm",
57
 
        "application/x-jar",
58
 
        "application/x-java-archive",
59
 
        "application/x-lzop",
60
 
        "application/x-zoo",
61
 
        "application/x-cd-image",
62
 
        "application/x-7z-compressed",
63
 
        "application/x-gzpostscript",
64
 
        "application/x-ms-dos-executable",
65
 
        NULL
 
35
    "application/x-ar",
 
36
    "application/x-arj",
 
37
    "application/x-bzip",
 
38
    "application/x-bzip-compressed-tar",
 
39
    "application/x-compress",
 
40
    "application/x-compressed-tar",
 
41
    "application/x-deb",
 
42
    "application/x-gtar",
 
43
    "application/x-gzip",
 
44
    "application/x-lha",
 
45
    "application/x-lhz",
 
46
    "application/x-rar",
 
47
    "application/x-rar-compressed",
 
48
    "application/x-tar",
 
49
    "application/x-zip",
 
50
    "application/x-zip-compressed",
 
51
    "application/zip",
 
52
    "multipart/x-zip",
 
53
    "application/x-rpm",
 
54
    "application/x-jar",
 
55
    "application/x-java-archive",
 
56
    "application/x-lzop",
 
57
    "application/x-zoo",
 
58
    "application/x-cd-image",
 
59
    "application/x-7z-compressed",
 
60
    "application/x-gzpostscript",
 
61
    "application/x-ms-dos-executable",
 
62
    NULL
66
63
};
67
64
/******************************************************************************/
68
65
static void
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;
76
 
        while (current) {
77
 
                gtk_widget_set_sensitive (current, sensitive);
78
 
 
79
 
                if (GTK_IS_MENU_BAR (current)) return;
80
 
 
81
 
                current = GTK_MENU_SHELL (current)->parent_menu_shell;
82
 
        }
 
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;
 
73
    while (current) {
 
74
        gtk_widget_set_sensitive (current, sensitive);
 
75
 
 
76
        if (GTK_IS_MENU_BAR (current)) return;
 
77
 
 
78
        current = GTK_MENU_SHELL (current)->parent_menu_shell;
 
79
    }
83
80
}
84
81
/******************************************************************************/
85
82
/* Stolen from menu.c from the gnome-panel */
86
83
static void
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__);
89
86
 
90
87
    GtkWidget *menu_item = data;
91
88
    GtkMenu *menu = GTK_MENU(menu_item->parent); 
95
92
    tree_set_sensitive (menu_item, TRUE);
96
93
 
97
94
    /* Find the last viewable ancestor, and make an X grab on it */
98
 
        parent = GTK_WIDGET (menu);
99
 
        xgrab_shell = NULL;
100
 
        while (parent) {
101
 
                gboolean viewable = TRUE;
102
 
                GtkWidget *tmp = parent;
103
 
 
104
 
                while (tmp) {
105
 
                        if (!GTK_WIDGET_MAPPED (tmp)) {
106
 
                                viewable = FALSE;
107
 
                                break;
108
 
                        }
109
 
                        tmp = tmp->parent;
110
 
                }
111
 
 
112
 
                if (viewable)
113
 
                        xgrab_shell = parent;
114
 
 
115
 
                parent = GTK_MENU_SHELL (parent)->parent_menu_shell;
116
 
        }
117
 
 
118
 
        /*only grab if this HAD a grab before*/
119
 
        if (xgrab_shell && (GTK_MENU_SHELL (xgrab_shell)->have_xgrab)) {
120
 
            if (gdk_pointer_grab (xgrab_shell->window, TRUE,
121
 
                                              GDK_BUTTON_PRESS_MASK |
 
95
    parent = GTK_WIDGET (menu);
 
96
    xgrab_shell = NULL;
 
97
    while (parent) {
 
98
        gboolean viewable = TRUE;
 
99
        GtkWidget *tmp = parent;
 
100
 
 
101
        while (tmp) {
 
102
            if (!GTK_WIDGET_MAPPED (tmp)) {
 
103
                viewable = FALSE;
 
104
                break;
 
105
            }
 
106
            tmp = tmp->parent;
 
107
        }
 
108
 
 
109
        if (viewable)
 
110
            xgrab_shell = parent;
 
111
 
 
112
        parent = GTK_MENU_SHELL (parent)->parent_menu_shell;
 
113
    }
 
114
 
 
115
    /*only grab if this HAD a grab before*/
 
116
    if (xgrab_shell && (GTK_MENU_SHELL (xgrab_shell)->have_xgrab)) {
 
117
        if (gdk_pointer_grab (xgrab_shell->window, TRUE,
 
118
                              GDK_BUTTON_PRESS_MASK |
122
119
                              GDK_BUTTON_RELEASE_MASK |
123
120
                              GDK_ENTER_NOTIFY_MASK |
124
121
                              GDK_LEAVE_NOTIFY_MASK,
131
128
 
132
129
        }
133
130
    }
134
 
        gtk_grab_add (GTK_WIDGET (menu));
 
131
    gtk_grab_add (GTK_WIDGET (menu));
135
132
}
136
133
/******************************************************************************/
137
134
static void
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__);
140
137
 
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));
144
141
}
145
142
/******************************************************************************/
146
143
static void
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__);
149
146
 
150
147
    gtk_widget_destroy (menu);
151
 
    garbage_empty (&garbage, FALSE);
152
148
}
153
149
/******************************************************************************/
154
150
static void
156
152
                             const gchar* file,
157
153
                             GtkMenuItem *menu_item,
158
154
                             GtkMenu *menu) {
159
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
160
 
 
161
 
        gchar **args = g_strv_new (ARGS_SIZE);
162
 
        args[ARG_APP]  = g_strdup (app);
163
 
        args[ARG_FILE] = g_strdup (file);
164
 
 
165
 
        g_signal_connect_swapped (menu_item,
166
 
                                                          "activate",
167
 
                                                          G_CALLBACK (vfs_launch_application),
168
 
                                                          args);
 
155
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
156
 
 
157
    gchar **args = g_strv_new (ARGS_SIZE);
 
158
    args[ARG_APP]  = g_strdup (app);
 
159
    args[ARG_FILE] = g_strdup (file);
 
160
 
 
161
    g_signal_connect_data (GTK_MENU_ITEM (menu_item),
 
162
                           "activate",
 
163
                           G_CALLBACK (vfs_launch_application),
 
164
                           args,
 
165
                           (GClosureNotify)g_strfreev,
 
166
                           G_CONNECT_SWAPPED);
169
167
 
170
168
    g_signal_connect_swapped (menu_item,
171
169
                              "activate",
172
170
                              G_CALLBACK (close_menu_browser),
173
171
                              menu);
174
 
 
175
 
        garbage_add_item (garbage, args[ARG_APP]);
176
 
        garbage_add_item (garbage, args[ARG_FILE]);
177
 
        garbage_add_item (garbage, args);
178
172
}
179
173
/******************************************************************************/
180
174
static void
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__);
183
177
 
184
178
    GtkWidget *menu = gtk_widget_get_parent (menu_item);
185
 
 
186
179
    close_menu_browser (menu);
187
 
 
188
 
        GError *error = NULL;
189
 
 
190
 
        GladeXML* xml = glade_xml_new (GLADEUI_PATH, "new_dir_dialog", NULL);
191
 
        g_return_if_fail (xml != NULL);
192
 
 
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");
195
 
 
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);
199
 
 
200
 
                GFile *file = g_file_new_for_path (new_dir);
201
 
                g_file_make_directory (file, NULL, &error);
202
 
                g_object_unref (file);
203
 
 
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);
207
 
                }
208
 
        }
209
 
        gtk_widget_destroy (new_dir_dialog);
210
 
        g_free (file_name);
 
180
    GError *error = NULL;
 
181
 
 
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)) {
 
187
        return;
 
188
    }
 
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"));
 
192
    
 
193
    gtk_label_set_text (GTK_LABEL (current_path_label),
 
194
                        file_name);
 
195
 
 
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);
 
199
 
 
200
        GFile *file = g_file_new_for_path (new_dir);
 
201
        g_file_make_directory (file, NULL, &error);
 
202
        g_object_unref (file);
 
203
 
 
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);
 
207
        }
 
208
    }
 
209
    gtk_widget_destroy (new_dir_dialog);
211
210
}
212
211
/******************************************************************************/
213
212
static void
214
213
context_menu_add_new_dir (const gchar *file_name, GtkWidget *menu) {
215
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
216
 
 
217
 
        if (!vfs_file_is_directory (file_name)) return;
218
 
 
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);
224
 
 
225
 
        g_signal_connect (GTK_MENU_ITEM (menu_item),
226
 
                      "activate",
227
 
                      G_CALLBACK (context_menu_add_new_dir_callback),
228
 
                      g_strdup (file_name));
 
214
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
215
 
 
216
    if (!vfs_file_is_directory (file_name)) return;
 
217
 
 
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);
 
223
 
 
224
    g_signal_connect_data (GTK_MENU_ITEM (menu_item),
 
225
                           "activate",
 
226
                           G_CALLBACK (context_menu_add_new_dir_callback),
 
227
                           g_strdup (file_name),
 
228
                           (GClosureNotify)g_free,
 
229
                           0);
229
230
}
230
231
/******************************************************************************/
231
232
static void
232
233
context_menu_add_burn (const gchar *file_name, GtkWidget *menu) {
233
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
234
 
 
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);
240
 
 
241
 
        context_menu_setup_callback ("brasero",
 
234
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
235
 
 
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);
 
241
 
 
242
    context_menu_setup_callback ("brasero",
242
243
                                 file_name,
243
244
                                 GTK_MENU_ITEM (menu_item),
244
245
                                 GTK_MENU (menu));
246
247
/******************************************************************************/
247
248
static void
248
249
context_menu_add_compile_tex (const gchar *file_name, GtkWidget *menu) {
249
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
250
 
 
251
 
        if (!g_str_has_suffix (file_name, "tex")) return;
252
 
 
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);
258
 
 
259
 
        context_menu_setup_callback ("rubber -f --inplace -d",
 
250
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
251
 
 
252
    if (!g_str_has_suffix (file_name, "tex")) return;
 
253
 
 
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);
 
259
 
 
260
    context_menu_setup_callback ("rubber -f --inplace -d",
260
261
                                 file_name,
261
262
                                 GTK_MENU_ITEM (menu_item),
262
263
                                 GTK_MENU (menu));
264
265
/******************************************************************************/
265
266
static gboolean
266
267
is_archive (const gchar *file_name) {
267
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
268
 
 
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,
273
 
                                                                                           0,
274
 
                                                                                           NULL,                                                                                           
275
 
                                                                                           NULL);
276
 
 
277
 
        const gchar* content_type = g_file_info_get_content_type (file_info);
278
 
 
279
 
        int i;
280
 
        for (i = 0; archive_mime_types[i] != NULL; i++) {
281
 
                if (g_strcmp0 (content_type, archive_mime_types[i]) == 0) {
282
 
                        ret = TRUE;
283
 
                        break;
284
 
                }
285
 
        }
286
 
        g_object_unref (file_info);
287
 
        g_object_unref (file);
288
 
 
289
 
        return ret;
 
268
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
269
 
 
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,
 
274
                                               0,
 
275
                                               NULL,                                               
 
276
                                               NULL);
 
277
 
 
278
    const gchar* content_type = g_file_info_get_content_type (file_info);
 
279
 
 
280
    int i;
 
281
    for (i = 0; archive_mime_types[i] != NULL; i++) {
 
282
        if (g_strcmp0 (content_type, archive_mime_types[i]) == 0) {
 
283
            ret = TRUE;
 
284
            break;
 
285
        }
 
286
    }
 
287
    g_object_unref (file_info);
 
288
    g_object_unref (file);
 
289
 
 
290
    return ret;
290
291
}
291
292
/******************************************************************************/
292
293
static void
293
294
context_menu_add_archive_action (const gchar *file_name, GtkWidget *menu) {
294
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
295
 
 
296
 
        gchar *archive_label = NULL;
297
 
        gchar *archive_action = NULL;
298
 
 
299
 
        if (is_archive (file_name)) {
300
 
                archive_label = _("_Extract Here");
301
 
                archive_action = "file-roller -h";
302
 
        }
303
 
        else {
304
 
                archive_label = _("Create _Archive");
305
 
                archive_action = "file-roller -d";
306
 
        }
307
 
 
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);
313
 
 
314
 
        context_menu_setup_callback (archive_action,
 
295
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
296
 
 
297
    gchar *archive_label = NULL;
 
298
    gchar *archive_action = NULL;
 
299
 
 
300
    if (is_archive (file_name)) {
 
301
        archive_label = _("_Extract Here");
 
302
        archive_action = "file-roller -h";
 
303
    }
 
304
    else {
 
305
        archive_label = _("Create _Archive");
 
306
        archive_action = "file-roller -d";
 
307
    }
 
308
 
 
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);
 
314
 
 
315
    context_menu_setup_callback (archive_action,
315
316
                                 file_name,
316
317
                                 GTK_MENU_ITEM (menu_item),
317
318
                                 GTK_MENU (menu));
319
320
/******************************************************************************/
320
321
static void
321
322
context_menu_add_open_with_item (const gchar *file_name, GtkWidget *menu) {
322
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
323
 
 
324
 
        GList *root = vfs_get_all_mime_applications (file_name);
325
 
        GList *apps = root;
326
 
        
327
 
        g_return_if_fail (root != NULL);
328
 
 
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);
334
 
 
335
 
        GtkWidget *sub_menu = gtk_menu_new ();
336
 
 
337
 
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
338
 
 
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));
344
 
 
345
 
                gtk_menu_shell_append (GTK_MENU_SHELL (sub_menu), menu_item);
346
 
 
347
 
                context_menu_setup_callback (g_app_info_get_executable (apps->data),
348
 
                                                                         file_name,
 
323
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
324
 
 
325
    GList *root = vfs_get_all_mime_applications (file_name);
 
326
    GList *apps = root;
 
327
    
 
328
    g_return_if_fail (root != NULL);
 
329
 
 
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);
 
335
 
 
336
    GtkWidget *sub_menu = gtk_menu_new ();
 
337
 
 
338
    gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
 
339
 
 
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));
 
345
 
 
346
        gtk_menu_shell_append (GTK_MENU_SHELL (sub_menu), menu_item);
 
347
 
 
348
        context_menu_setup_callback (g_app_info_get_executable (apps->data),
 
349
                                     file_name,
349
350
                                     GTK_MENU_ITEM (menu_item),
350
351
                                     GTK_MENU (menu));
351
352
 
352
 
                g_object_unref (apps->data);
353
 
                apps = apps->next;
354
 
        }
355
 
        g_list_free (root);
 
353
        g_object_unref (apps->data);
 
354
        apps = apps->next;
 
355
    }
 
356
    g_list_free (root);
356
357
}
357
358
/******************************************************************************/
358
359
static void
359
360
context_menu_add_trash_item (const gchar *file_name, GtkWidget *menu) {
360
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
361
 
                                                  
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);
367
 
        
368
 
        g_signal_connect_swapped (G_OBJECT (menu_item),
369
 
                                                          "activate",
370
 
                                                          G_CALLBACK (vfs_file_trash),
371
 
                                                          (gpointer) g_strdup (file_name));
 
361
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
362
                          
 
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);
 
368
 
 
369
    g_signal_connect_data (GTK_MENU_ITEM (menu_item),
 
370
                           "activate",
 
371
                           G_CALLBACK (vfs_file_trash),
 
372
                           g_strdup (file_name),
 
373
                           (GClosureNotify)g_free,
 
374
                           G_CONNECT_SWAPPED);
372
375
 
373
376
    g_signal_connect_swapped (menu_item,
374
377
                              "activate",
378
381
/******************************************************************************/
379
382
static void
380
383
context_menu_populate (const gchar *file_name, GtkWidget *menu) {
381
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
382
 
 
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);
391
 
 
392
 
        gtk_widget_show_all (menu);
 
384
    if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
 
385
 
 
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);
 
394
 
 
395
    gtk_widget_show_all (menu);
393
396
}
394
397
/******************************************************************************/
395
398
gboolean
396
399
context_menu_display (const gchar *file_name, GtkWidget *menu_item) {
397
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
398
 
 
399
 
        int event_button;
400
 
        int event_time;
401
 
 
402
 
        GdkEventButton *event = g_object_get_data (G_OBJECT (menu_item), "button_event");
403
 
        if (event) {
404
 
                event_button = event->button;
405
 
                event_time = event->time;
406
 
        }
407
 
        else {
408
 
                event_button = 3;
409
 
                event_time = gtk_get_current_event_time();
410
 
        }
411
 
 
412
 
        garbage_init (&garbage);
413
 
 
414
 
        GtkWidget *menu = gtk_menu_new ();
415
 
 
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__);
 
401
 
 
402
    int event_button;
 
403
    int event_time;
 
404
 
 
405
    GdkEventButton *event = g_object_get_data (G_OBJECT (menu_item), "button_event");
 
406
    if (event) {
 
407
        event_button = event->button;
 
408
        event_time = event->time;
 
409
    }
 
410
    else {
 
411
        event_button = 3;
 
412
        event_time = gtk_get_current_event_time();
 
413
    }
 
414
 
 
415
    GtkWidget *menu = gtk_menu_new ();
 
416
 
 
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);
420
421
 
421
422
    g_signal_connect_swapped (menu_item,
422
423
                              "destroy",
423
424
                              G_CALLBACK (context_menu_clean_up),
424
425
                              menu);
425
426
 
426
 
        g_signal_connect (GTK_MENU_SHELL (menu),
 
427
    g_signal_connect (GTK_MENU_SHELL (menu),
427
428
                      "deactivate",
428
429
                      G_CALLBACK (restore_grabs),
429
430
                      menu_item);
430
431
 
431
 
        context_menu_populate (file_name, menu);
 
432
    context_menu_populate (file_name, menu);
432
433
 
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);
435
436
 
436
 
        gtk_menu_popup (GTK_MENU (menu),
437
 
                                        NULL,
438
 
                                        NULL,
439
 
                                        NULL,
440
 
                                        NULL,
441
 
                                        event_button,
442
 
                                        event_time);
443
 
        return TRUE;
 
437
    gtk_menu_popup (GTK_MENU (menu),
 
438
                    NULL,
 
439
                    NULL,
 
440
                    NULL,
 
441
                    NULL,
 
442
                    event_button,
 
443
                    event_time);
 
444
    return TRUE;
444
445
}
445
446
/******************************************************************************/