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

« back to all changes in this revision

Viewing changes to src/menu-browser.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2008-11-04 13:34:36 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081104133436-7kgxv6psv6mjnxh0
Tags: 0.6.0-0ubuntu1
* New upstream release.
 - 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.
 - Fixed bugs #21, #30, #34, #37, #39.
 - Plugged some memory leaks (thanks Silvio Ricardo Cordeiro).
 - Lots of code cleanup. 
* debian/control:
 - Add suggests on file-roller, brasero, and rubber 
   for new features.
 - Add Vcs-Bzr field.
 - Add versionized Build-Depend on libgtk2.0-dev (>= 2.14)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
#include <glib.h>
27
27
#include <glib/gprintf.h>
 
28
#include <gio/gio.h>
28
29
#include <gdk/gdkkeysyms.h>
29
30
#include <string.h>
30
31
 
39
40
#define G_OBJECT_DATA_NAME "item_path"
40
41
/******************************************************************************/
41
42
struct _MenuBrowserPrivate {
42
 
        GtkWidget               *menu;
43
43
        GtkWidget               *menu_item_label;
44
44
        GtkMenuShell    *parent_menu_shell;
45
 
        GPtrArray               *tmp_array;
 
45
        Garbage                 garbage;
46
46
};
47
47
#define MENU_BROWSER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_MENU_BROWSER, MenuBrowserPrivate))
48
48
enum  {
57
57
menu_browser_clear_menu (GtkWidget *menu_item) {
58
58
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
59
59
 
60
 
        GtkWidget *menu = NULL;
61
 
        if (1) {
62
 
                menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item));
63
 
                gtk_container_foreach (GTK_CONTAINER (menu),
64
 
                                                           (GtkCallback) gtk_widget_destroy,
65
 
                                                           NULL);
66
 
        }
67
 
        else {
68
 
                GtkWidget *old_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item));
69
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), NULL);
70
 
                menu = gtk_menu_new ();
71
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
72
 
                                                                   menu);
73
 
                gtk_widget_destroy (GTK_WIDGET (old_menu));
74
 
        }
 
60
        GtkWidget *menu = menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item));
 
61
        gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);
75
62
}
76
63
/******************************************************************************/
77
64
static void
80
67
 
81
68
        g_return_if_fail (IS_MENU_BROWSER (self));
82
69
 
83
 
        /* free the structure pointed to by each element */
84
 
        g_ptr_array_foreach (self->priv->tmp_array,
85
 
                                                 (GFunc)g_free,
86
 
                                                 NULL);
87
 
        /* delete and recreate the array */
88
 
        g_ptr_array_free (self->priv->tmp_array, TRUE);
89
 
        self->priv->tmp_array = g_ptr_array_new();
90
 
 
91
70
        menu_browser_clear_menu (GTK_WIDGET (self));
92
 
}
93
 
/******************************************************************************/
94
 
GtkWidget*
95
 
menu_browser_add_desktop_file (gchar *file_name, GtkWidget *menu, MenuBrowser *self) {
96
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
97
 
 
98
 
        if (!vfs_file_is_desktop (file_name)) {
99
 
                return NULL;
100
 
        }
101
 
 
102
 
        const gchar *app_name = NULL;
103
 
        GtkWidget       *icon = NULL;
104
 
        GtkWidget       *menu_item = NULL;
105
 
 
106
 
        app_name = vfs_get_desktop_app_name (file_name);
107
 
        icon = vfs_get_icon_for_file (file_name);
108
 
 
109
 
        if (app_name && icon) {
110
 
                menu_item = gtk_image_menu_item_new_with_label (app_name);
111
 
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
112
 
        }
113
 
        return menu_item;
114
 
}
115
 
/******************************************************************************/
116
 
GtkWidget*
117
 
menu_browser_add_default_file (gchar *file_name,
118
 
                                                           GtkWidget *menu,
119
 
                                                           MenuBrowser *self) {
120
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
121
 
 
122
 
        if (!IS_MENU_BROWSER (self)) return NULL;
123
 
 
124
 
        GtkWidget       *menu_item = NULL;
125
 
        GtkWidget       *menu_item_icon = NULL;
126
 
        gchar           *base_name = g_path_get_basename (file_name);
127
 
 
128
 
        /*make a menu item for this dir*/
129
 
        menu_item = gtk_image_menu_item_new_with_label (base_name);
130
 
        
131
 
        GtkWidget *label = gtk_bin_get_child (GTK_BIN (menu_item));
132
 
        if (GTK_IS_LABEL (label)) {
133
 
                gtk_label_set_max_width_chars (GTK_LABEL (label), MAX_FILE_NAME_LENGTH);        
134
 
                gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
135
 
        }
136
 
        if (strlen (base_name) > MAX_FILE_NAME_LENGTH) {
137
 
                gtk_widget_set_tooltip_text (menu_item, base_name);
138
 
        }
139
 
 
140
 
        /* bold executable files */
141
 
        if (vfs_file_is_executable (file_name)) {
142
 
                gchar *markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", base_name);
143
 
                gtk_label_set_markup (GTK_LABEL (label), markup);
144
 
                g_free (markup);
145
 
        }
146
 
        g_free (base_name);
147
 
 
148
 
        menu_item_icon = vfs_get_icon_for_file (file_name);
149
 
 
150
 
        /*stick the icon in the menu item, the menu item in the menu and show it all*/
151
 
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
152
 
                                                                        menu_item_icon);
153
 
        return menu_item;
 
71
 
 
72
        garbage_empty (&(self->priv->garbage), TRUE);
154
73
}
155
74
/******************************************************************************/
156
75
static void
158
77
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
159
78
 
160
79
        g_return_if_fail (IS_MENU_BROWSER (self));
161
 
        vfs_launch_terminal (path, self->prefs->terminal);
 
80
 
 
81
        LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
 
82
        launch_info->command = g_strdup (self->prefs->terminal);
 
83
        launch_info->file = g_strdup (path);
 
84
 
 
85
        vfs_launch_application (launch_info);
 
86
 
 
87
        g_free (launch_info->command);
 
88
        g_free (launch_info->file);
 
89
        g_free (launch_info);
162
90
}
163
91
/******************************************************************************/
164
92
static void
165
93
menu_browser_on_file_left_click (const gchar *file_name_and_path, MenuBrowser *self) {
166
94
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
167
95
 
168
 
        /* try launching the desktop file first */
169
 
        if (!vfs_launch_desktop_file (file_name_and_path)) {
170
 
                vfs_open_file (file_name_and_path, EXEC_OPEN);
171
 
        }
 
96
        g_return_if_fail (IS_MENU_BROWSER (self));
 
97
 
 
98
        vfs_file_do_default_action (file_name_and_path);
172
99
}
173
100
/******************************************************************************/
174
101
static void
176
103
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
177
104
 
178
105
        g_return_if_fail (IS_MENU_BROWSER (self));
179
 
        vfs_edit_file (file_name_and_path, self->prefs->editor);
 
106
 
 
107
        LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
 
108
        launch_info->command = g_strdup (self->prefs->editor);
 
109
        launch_info->file = g_strdup (file_name_and_path);
 
110
 
 
111
        vfs_launch_application (launch_info);
 
112
 
 
113
        g_free (launch_info->command);
 
114
        g_free (launch_info->file);
 
115
        g_free (launch_info);
180
116
}
181
117
/******************************************************************************/
182
118
static gboolean
185
121
#ifdef ENABLE_CONTEXT_MENU
186
122
        return context_menu_display (file_name_and_path, menu_item);
187
123
#else
188
 
        utils_show_dialog ("Error: Action not implemented.",
189
 
                                           "Right click on file action not yet implemented\n",
 
124
        utils_show_dialog ("Error",
 
125
                                           "Right-click on file action not yet implemented.",
190
126
                                           GTK_MESSAGE_INFO);
191
127
        return TRUE;
192
128
#endif
200
136
                                                                   MenuBrowser *self) {
201
137
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
202
138
 
203
 
        if (!IS_MENU_BROWSER (self)) return FALSE;
204
 
 
205
 
        gchar *path = (gchar*)g_object_get_data (G_OBJECT (menu_item),
206
 
                                                                                         G_OBJECT_DATA_NAME);
207
 
 
208
 
        if (vfs_file_exists (path)) {
209
 
                if (event->button == 1) {
210
 
                        menu_browser_on_file_left_click (path, self);
211
 
                }
212
 
                else if (event->button == 2) {
213
 
                        if (vfs_file_is_directory (path)) {
214
 
                                menu_browser_on_dir_middle_click (path, self);
215
 
                        }
216
 
                        else {
217
 
                                menu_browser_on_file_middle_click (path, self);
218
 
                        }
219
 
                }
220
 
                else if (event->button == 3) {
221
 
                        g_object_set_data (G_OBJECT (menu_item), "menu_browser", self);
222
 
                        g_object_set_data (G_OBJECT (menu_item), "button_event", event);
223
 
                        return menu_browser_on_file_right_click (path, menu_item);
224
 
                }
225
 
        }
226
 
        else {
227
 
                gchar *tmp = g_strdup_printf ("Error: \"%s\" does not exists.", path);
228
 
                utils_show_dialog ("Error: File not found.",
229
 
                                                   tmp,
230
 
                                                   GTK_MESSAGE_ERROR);
 
139
        g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
 
140
 
 
141
        gchar *path = (gchar*)g_object_get_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME);
 
142
 
 
143
        if (!vfs_file_exists (path)) {
 
144
                gchar *tmp = g_strdup_printf ("Error: The file \"%s\" does not exists.", path);
 
145
                utils_show_dialog ("Error", tmp, GTK_MESSAGE_ERROR);
231
146
                g_free (tmp);
232
 
        }
 
147
                return FALSE;
 
148
        }
 
149
 
 
150
        if (event->button == 1) {
 
151
                menu_browser_on_file_left_click (path, self);
 
152
        }
 
153
        else if (event->button == 2) {
 
154
                vfs_file_is_directory (path) ?
 
155
                        menu_browser_on_dir_middle_click (path, self) :
 
156
                        menu_browser_on_file_middle_click (path, self);
 
157
        }
 
158
        else if (event->button == 3) {
 
159
                g_object_set_data (G_OBJECT (menu_item), "menu_browser", self);
 
160
                g_object_set_data (G_OBJECT (menu_item), "button_event", event);
 
161
                return menu_browser_on_file_right_click (path, menu_item);
 
162
        }
 
163
 
233
164
        gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
234
165
        return FALSE;
235
166
}
236
167
#endif
237
168
/******************************************************************************/
238
169
static gboolean
239
 
menu_browser_on_menu_key_press (GtkWidget *menu,
240
 
                                                                GdkEventKey *event,
241
 
                                                                MenuBrowser *self) {
 
170
menu_browser_on_menu_key_press (GtkWidget *menu, GdkEventKey *event, MenuBrowser *self) {
242
171
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
243
172
 
244
 
        gchar *path = NULL ;
 
173
        g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
 
174
 
245
175
        GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
246
176
        GtkWidget *menu_item = menu_shell->active_menu_item;
247
177
 
248
 
        if (!IS_MENU_BROWSER (self) ||
249
 
                !self->priv->parent_menu_shell->active ||
250
 
                !menu_item) {
 
178
        /* huh!? */
 
179
        if (!self->priv->parent_menu_shell->active || !menu_item) {
251
180
                return FALSE;
252
181
        }
253
182
 
254
 
        path = (gchar*)g_object_get_data (G_OBJECT (menu_item),
255
 
                                                                          G_OBJECT_DATA_NAME);
256
 
 
257
 
        if (vfs_file_exists (path)) {
258
 
                if (event->keyval == GDK_KP_Space ||
259
 
                        event->keyval == GDK_space ||
260
 
                        event->keyval == GDK_Return ||
261
 
                        event->keyval == GDK_KP_Enter ||
262
 
                        event->keyval == GDK_ISO_Enter ||
263
 
                        event->keyval == GDK_3270_Enter) {
264
 
 
265
 
                        menu_browser_on_file_left_click (path, self);
266
 
                        gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
267
 
                }
268
 
                else if (event->keyval == GDK_F4 ||
269
 
                                 event->keyval == GDK_KP_F4) {
270
 
                        if (vfs_file_is_directory (path)) {
271
 
                                menu_browser_on_dir_middle_click (path, self);
272
 
                        }
273
 
                        else {
274
 
                                menu_browser_on_file_middle_click (path, self);
275
 
                        }
276
 
                        gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
277
 
                }
278
 
                else if ((event->keyval == GDK_Menu) ||
279
 
                                 (event->keyval == GDK_F10 &&
280
 
                                 (event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK)){
281
 
                        g_object_set_data (G_OBJECT (menu_item), "menu_browser", self);
282
 
                        g_object_set_data (G_OBJECT (menu_item), "button_event", event);
283
 
                        return menu_browser_on_file_right_click (path, menu_item);
284
 
                }
285
 
        }
286
 
        else {
287
 
                gchar *tmp = g_strdup_printf ("Error: \"%s\" does not exists.", path);
288
 
                utils_show_dialog ("Error: File not found.",
289
 
                                                   tmp,
290
 
                                                   GTK_MESSAGE_ERROR);
 
183
        gchar *path = (gchar*)g_object_get_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME);
 
184
 
 
185
        if (!vfs_file_exists (path)) {
 
186
                gchar *tmp = g_strdup_printf ("Error: The file \"%s\" does not exists.", path);
 
187
                utils_show_dialog ("Error", tmp, GTK_MESSAGE_ERROR);
291
188
                g_free (tmp);
292
 
        }
 
189
                return FALSE;
 
190
        }
 
191
 
 
192
        if (event->keyval == GDK_KP_Space ||
 
193
                event->keyval == GDK_space ||
 
194
                event->keyval == GDK_Return ||
 
195
                event->keyval == GDK_KP_Enter ||
 
196
                event->keyval == GDK_ISO_Enter ||
 
197
                event->keyval == GDK_3270_Enter) {
 
198
 
 
199
                menu_browser_on_file_left_click (path, self);
 
200
                gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
 
201
        }
 
202
        else if (event->keyval == GDK_F4 ||
 
203
                         event->keyval == GDK_KP_F4) {
 
204
 
 
205
                vfs_file_is_directory (path) ?
 
206
                        menu_browser_on_dir_middle_click (path, self) :
 
207
                        menu_browser_on_file_middle_click (path, self);
 
208
                gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
 
209
        }
 
210
        else if ((event->keyval == GDK_Menu) ||
 
211
                         (event->keyval == GDK_F10 &&
 
212
                         (event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK)){
 
213
                g_object_set_data (G_OBJECT (menu_item), "menu_browser", self);
 
214
                g_object_set_data (G_OBJECT (menu_item), "button_event", event);
 
215
                return menu_browser_on_file_right_click (path, menu_item);
 
216
        }
 
217
 
293
218
        return FALSE;
294
219
}
295
220
/******************************************************************************/
296
221
#ifdef NEW_MENU_SIGNAL
297
222
static gboolean
298
 
menu_browser_on_menu_button_press (GtkWidget *menu,
299
 
                                                                   GdkEventButton *event,
300
 
                                                                   MenuBrowser *self) {
 
223
menu_browser_on_menu_button_press (GtkWidget *menu, GdkEventButton *event, MenuBrowser *self) {
301
224
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
302
225
 
 
226
        g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
 
227
 
303
228
        gchar *path = NULL;
304
229
        GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
305
230
        GtkWidget *menu_item = menu_shell->active_menu_item;
309
234
        area.width = 1;
310
235
        area.height = 1; 
311
236
        
312
 
        if (!IS_MENU_BROWSER (self) ||
313
 
                !self->priv->parent_menu_shell->active ||
314
 
                !menu_item ||
 
237
        if (!self->priv->parent_menu_shell->active || !menu_item ||
315
238
                !gtk_widget_intersect (menu, &area, NULL)) {
316
239
                return FALSE;
317
240
        }
318
241
 
319
 
        path = (gchar*)g_object_get_data (G_OBJECT (menu_item),
320
 
                                                                          G_OBJECT_DATA_NAME);
 
242
        path = (gchar*)g_object_get_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME);
321
243
 
322
 
        if (vfs_file_exists (path)) {
323
 
                if (event->button == 1) {
324
 
                        menu_browser_on_file_left_click (path, self);
325
 
                        gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
326
 
                }
327
 
                else if (event->button == 2) {
328
 
                        if (vfs_file_is_directory (path)) {
329
 
                                menu_browser_on_dir_middle_click (path, self);
330
 
                        }
331
 
                        else {
332
 
                                menu_browser_on_file_middle_click (path, self);
333
 
                        }
334
 
                        gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
335
 
                }
336
 
                else if (event->button == 3) {
337
 
                        g_object_set_data (G_OBJECT (menu_item), "menu_browser", self);
338
 
                        g_object_set_data (G_OBJECT (menu_item), "button_event", event);
339
 
                        return menu_browser_on_file_right_click (path, menu_item);
340
 
                }
341
 
        }
342
 
        else {
343
 
                gchar *tmp = g_strdup_printf ("Error: \"%s\" does not exists.", path);
344
 
                utils_show_dialog ("Error: File not found.",
345
 
                                                   tmp,
346
 
                                                   GTK_MESSAGE_ERROR);
 
244
        if (!vfs_file_exists (path)) {
 
245
                gchar *tmp = g_strdup_printf ("Error: The file \"%s\" does not exists.", path);
 
246
                utils_show_dialog ("Error", tmp, GTK_MESSAGE_ERROR);
347
247
                g_free (tmp);
348
 
        }
 
248
                return FALSE;
 
249
        }
 
250
 
 
251
        if (event->button == 1) {
 
252
                menu_browser_on_file_left_click (path, self);
 
253
                gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
 
254
        }
 
255
        else if (event->button == 2) {
 
256
                vfs_file_is_directory (path) ?
 
257
                        menu_browser_on_dir_middle_click (path, self) :
 
258
                        menu_browser_on_file_middle_click (path, self);
 
259
                gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
 
260
        }
 
261
        else if (event->button == 3) {
 
262
                g_object_set_data (G_OBJECT (menu_item), "menu_browser", self);
 
263
                g_object_set_data (G_OBJECT (menu_item), "button_event", event);
 
264
                return menu_browser_on_file_right_click (path, menu_item);
 
265
        }
 
266
 
349
267
        /*gtk_menu_shell_deactivate (self->priv->parent_menu_shell);*/
350
268
        return FALSE;
351
269
}
353
271
/******************************************************************************/
354
272
#ifndef NEW_MENU_SIGNAL
355
273
static void
356
 
menu_browser_add_menu_header (GtkWidget *menu,
357
 
                                                          gchar *path,
358
 
                                                          MenuBrowser *self) {
 
274
menu_browser_add_menu_header (GtkWidget *menu, gchar *path, MenuBrowser *self) {
359
275
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
360
276
 
361
277
        g_return_if_fail (IS_MENU_BROWSER (self));
362
 
        GtkWidget *menu_item = NULL;
363
 
        GtkWidget *separator = NULL;
 
278
 
364
279
        gchar *dir = g_path_get_basename (path);
365
 
 
366
 
        menu_item = gtk_image_menu_item_new_with_label (dir);
 
280
        GtkWidget *menu_item = gtk_image_menu_item_new_with_label (dir);
367
281
 
368
282
        GtkWidget *label = gtk_bin_get_child (GTK_BIN (menu_item));
369
283
        if (GTK_IS_LABEL (label)) {
378
292
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
379
293
                                                                   vfs_get_icon_for_file (path));
380
294
 
381
 
 
382
 
        gtk_menu_shell_append (GTK_MENU_SHELL (menu),
383
 
                                                   menu_item);
384
 
 
385
 
        g_object_set_data (G_OBJECT (menu_item),
386
 
                                           G_OBJECT_DATA_NAME,
387
 
                                           path);
 
295
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 
296
 
 
297
        g_object_set_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME, path);
388
298
 
389
299
        g_signal_connect (G_OBJECT (menu_item),
390
300
                                          "button_press_event",
391
301
                                          G_CALLBACK (menu_browser_on_item_button_press),
392
302
                                          self);
393
303
 
394
 
        separator = gtk_separator_menu_item_new();
395
 
 
396
304
        gtk_menu_shell_append (GTK_MENU_SHELL (menu),
397
 
                                                   separator);
 
305
                                                   gtk_separator_menu_item_new());
398
306
}
399
307
#endif
400
308
/******************************************************************************/
401
309
static void
402
 
menu_browser_add_folders (GtkWidget             *menu,
403
 
                                                  gchar                 *path,
404
 
                                                  GPtrArray             *dirs,
405
 
                                                  MenuBrowser   *self) {
 
310
menu_browser_add_folders (GtkWidget *menu, GPtrArray *dirs, MenuBrowser *self) {
406
311
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
407
312
 
408
313
        g_return_if_fail (IS_MENU_BROWSER (self));
409
314
 
410
 
        GtkWidget       *menu_item = NULL;
411
 
        GtkWidget       *child_menu = NULL;
412
 
        gchar           *file_name_and_path = NULL;
413
 
        gchar           *dir = NULL;
414
315
        int i;
415
316
 
416
317
        for (i=0; i<dirs->len; i++) {
417
 
                dir = (gchar *)g_ptr_array_index (dirs, i);
418
 
                file_name_and_path = g_strdup_printf ("%s/%s",
419
 
                                                                                          path,
420
 
                                                                                          dir);
 
318
                VfsFileInfo *vfs_file_info = (VfsFileInfo*)g_ptr_array_index (dirs, i);
421
319
 
422
320
                /*make a menu item for this dir, limit the length of the text in the menu*/
423
 
                menu_item = gtk_image_menu_item_new_with_label (dir);
 
321
                GtkWidget *menu_item = gtk_image_menu_item_new_with_label (vfs_file_info->display_name);
424
322
 
425
323
                GtkWidget *label = gtk_bin_get_child (GTK_BIN (menu_item));
426
324
                if (GTK_IS_LABEL (label)) {
427
325
                        gtk_label_set_max_width_chars (GTK_LABEL (label), MAX_FILE_NAME_LENGTH);        
428
326
                        gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
429
327
                }
430
 
                if (strlen (dir) > MAX_FILE_NAME_LENGTH) {
431
 
                        gtk_widget_set_tooltip_text (menu_item, dir);
 
328
                if (strlen (vfs_file_info->display_name) > MAX_FILE_NAME_LENGTH) {
 
329
                        gtk_widget_set_tooltip_text (menu_item, vfs_file_info->display_name);
432
330
                }
433
331
 
434
332
                /*get the icon widget based on the returned icon name (always the same icon, can speed up here)*/
435
333
                /*stick the icon in the menu item, the menu item in the menu and show it all*/
436
334
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
437
 
                                                                           vfs_get_icon_for_file (file_name_and_path));
 
335
                                                                           vfs_file_info->icon);
438
336
 
439
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu),
440
 
                                                           menu_item);
 
337
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
441
338
 
442
339
                /*make the sub menu to show all the files in this dir*/
443
 
                child_menu = gtk_menu_new ();
444
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
445
 
                                                                   child_menu);
446
 
 
447
 
                g_ptr_array_add (self->priv->tmp_array, file_name_and_path);
 
340
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), gtk_menu_new ());
 
341
 
 
342
                garbage_add_item (self->priv->garbage, vfs_file_info->file_name);
 
343
                garbage_add_item (self->priv->garbage, vfs_file_info->display_name);
 
344
 
448
345
                g_object_set_data (G_OBJECT (menu_item),
449
346
                                                   G_OBJECT_DATA_NAME,
450
 
                                                   file_name_and_path);
 
347
                                                   vfs_file_info->file_name);
451
348
 
452
349
                g_signal_connect (GTK_MENU_ITEM (menu_item),
453
350
                                                  "activate",
463
360
}
464
361
/******************************************************************************/
465
362
static void
466
 
menu_browser_add_files (GtkWidget       *menu,
467
 
                                                gchar           *path,
468
 
                                                GPtrArray       *files,
469
 
                                                MenuBrowser     *self) {
 
363
menu_browser_add_files (GtkWidget *menu, GPtrArray *files, MenuBrowser *self) {
470
364
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
471
365
 
472
366
        g_return_if_fail (IS_MENU_BROWSER (self));
473
367
 
474
 
        GtkWidget       *menu_item = NULL;
475
 
        gchar           *file_name_and_path = NULL;
476
368
        int i;
477
369
 
478
370
        for (i=0; i<files->len; i++) {
479
 
                file_name_and_path = g_strdup_printf ("%s/%s",
480
 
                                                                                          path,
481
 
                                                                                          (gchar *)g_ptr_array_index (files, i));
482
 
 
483
 
                /* desktop files */
484
 
                menu_item = menu_browser_add_desktop_file (file_name_and_path, menu, self);
485
 
                if (menu_item == NULL) {
486
 
                        menu_item = menu_browser_add_default_file (file_name_and_path, menu, self);
487
 
                }
 
371
                VfsFileInfo *vfs_file_info = (VfsFileInfo*)g_ptr_array_index (files, i);
 
372
 
 
373
                /*make a menu item for this dir*/
 
374
                GtkWidget *menu_item = gtk_image_menu_item_new_with_label (vfs_file_info->display_name);
 
375
        
 
376
                /* set the ellipsizig and tooltip */
 
377
                GtkWidget *label = gtk_bin_get_child (GTK_BIN (menu_item));
 
378
                if (GTK_IS_LABEL (label)) {
 
379
                        gtk_label_set_max_width_chars (GTK_LABEL (label), MAX_FILE_NAME_LENGTH);        
 
380
                        gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
 
381
                }
 
382
                if (strlen (vfs_file_info->display_name) > MAX_FILE_NAME_LENGTH) {
 
383
                        gtk_widget_set_tooltip_text (menu_item, vfs_file_info->display_name);
 
384
                }
 
385
 
 
386
                /* bold executable files */
 
387
                if (vfs_file_info->is_executable) {
 
388
                        gchar *markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
 
389
                                                                                                         vfs_file_info->display_name);
 
390
                        gtk_label_set_markup (GTK_LABEL (label), markup);
 
391
                        g_free (markup);
 
392
                }
 
393
 
 
394
                /*stick the icon in the menu item, the menu item in the menu and show it all*/
 
395
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
 
396
                                                                           vfs_file_info->icon);
488
397
 
489
398
                gtk_menu_shell_append (GTK_MENU_SHELL(menu), menu_item);
490
 
                g_ptr_array_add (self->priv->tmp_array, file_name_and_path);
 
399
 
 
400
                garbage_add_item (self->priv->garbage, vfs_file_info->file_name);
 
401
                garbage_add_item (self->priv->garbage, vfs_file_info->display_name);
 
402
 
491
403
                g_object_set_data (G_OBJECT (menu_item),
492
404
                                                   G_OBJECT_DATA_NAME,
493
 
                                                   file_name_and_path);
 
405
                                                   vfs_file_info->file_name);
494
406
#ifndef NEW_MENU_SIGNAL
495
407
                g_signal_connect (menu_item,
496
408
                                                  "button_press_event",
501
413
}
502
414
/******************************************************************************/
503
415
static void
504
 
menu_browser_populate_menu (GtkWidget   *parent_menu_item,
505
 
                                                        MenuBrowser *self) {
 
416
menu_browser_populate_menu (GtkWidget *parent_menu_item, MenuBrowser *self) {
506
417
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
507
418
 
508
419
        g_return_if_fail (IS_MENU_BROWSER (self));
517
428
        /* empty the menu of its existing contents first */
518
429
        menu_browser_clear_menu (parent_menu_item);
519
430
 
520
 
        current_path = (gchar*)g_object_get_data (G_OBJECT (parent_menu_item),
521
 
                                                                                          G_OBJECT_DATA_NAME);
 
431
        current_path = (gchar*)g_object_get_data (G_OBJECT (parent_menu_item), G_OBJECT_DATA_NAME);
522
432
 
 
433
        /* huh!? */
523
434
        if (!self->priv->parent_menu_shell->active) return;
524
435
 
525
436
        /* get the menu widget to pack all the menu items for this dir into */
526
437
        current_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (parent_menu_item));
527
 
#ifdef NEW_MENU_SIGNAL
528
 
        g_signal_connect (current_menu,
529
 
                                          "button_press_event",
530
 
                                          G_CALLBACK (menu_browser_on_menu_button_press),
531
 
                                          self),
532
 
#endif
 
438
 
533
439
        g_signal_connect (current_menu,
534
440
                                          "key_press_event",
535
441
                                          G_CALLBACK (menu_browser_on_menu_key_press),
536
442
                                          self),
537
 
#ifndef NEW_MENU_SIGNAL
 
443
 
 
444
#ifdef NEW_MENU_SIGNAL
 
445
        g_signal_connect (current_menu,
 
446
                                          "button_press_event",
 
447
                                          G_CALLBACK (menu_browser_on_menu_button_press),
 
448
                                          self),
 
449
#else 
538
450
        /* add the dir name and events */
539
 
        menu_browser_add_menu_header (current_menu,
540
 
                                                                  current_path,
541
 
                                                                  self);
 
451
        menu_browser_add_menu_header (current_menu, current_path, self);
542
452
#endif
 
453
 
543
454
        /* read the contents of the dir. */
544
455
        error = vfs_get_dir_listings (files,
545
456
                                                                  dirs,
546
457
                                                                  self->prefs->show_hidden,
547
458
                                                                  current_path);
 
459
 
548
460
        /* add the folders*/
549
 
        menu_browser_add_folders (current_menu,
550
 
                                                          current_path,
551
 
                                                          dirs,
552
 
                                                          self);
 
461
        menu_browser_add_folders (current_menu, dirs, self);
553
462
 
554
463
        if ((dirs->len > 0) & (files->len > 0)) {
555
464
                /*add a separator between dirs and files*/
556
 
                menu_item = gtk_separator_menu_item_new();
557
465
                gtk_menu_shell_append (GTK_MENU_SHELL (current_menu),
558
 
                                                           menu_item);
 
466
                                                           gtk_separator_menu_item_new());
559
467
        }
560
468
 
561
469
        /* add the files */
562
 
        menu_browser_add_files (current_menu,
563
 
                                                        current_path,
564
 
                                                        files,
565
 
                                                        self);
 
470
        menu_browser_add_files (current_menu, files, self);
566
471
 
567
 
        /* add any error or other messages*/
 
472
        /* add any error or other messages */
568
473
        if (error != NULL) {
569
474
                menu_item = gtk_menu_item_new_with_label (error);
570
475
                g_free (error);
571
 
                gtk_menu_shell_append (GTK_MENU_SHELL (current_menu),
572
 
                                                           menu_item);
573
 
                gtk_widget_set_sensitive (GTK_WIDGET (menu_item),
574
 
                                                                  FALSE);
 
476
                gtk_menu_shell_append (GTK_MENU_SHELL (current_menu), menu_item);
 
477
                gtk_widget_set_sensitive (GTK_WIDGET (menu_item), FALSE);
575
478
        } /* the folder was empty */
576
479
        else if ((dirs->len == 0) & (files->len == 0)) {
577
480
                menu_item = gtk_menu_item_new_with_label ("(Empty)");
578
 
                gtk_menu_shell_append (GTK_MENU_SHELL (current_menu),
579
 
                                                           menu_item);
580
 
                gtk_widget_set_sensitive (GTK_WIDGET (menu_item),
581
 
                                                                  FALSE);
 
481
                gtk_menu_shell_append (GTK_MENU_SHELL (current_menu), menu_item);
 
482
                gtk_widget_set_sensitive (GTK_WIDGET (menu_item), FALSE);
582
483
        }
583
 
 
584
484
        gtk_widget_show_all (current_menu);
585
485
 
586
 
        /*clean up*/
 
486
        /* clean up */
587
487
        g_ptr_array_foreach (dirs, (GFunc)g_free, NULL);
588
488
        g_ptr_array_foreach (files, (GFunc)g_free, NULL);
589
489
        g_ptr_array_free (dirs, TRUE);
591
491
}
592
492
/******************************************************************************/
593
493
void
594
 
menu_browser_update (MenuBrowser *self,
595
 
                                         gchar* path,
596
 
                                         gchar* label) {
 
494
menu_browser_update (MenuBrowser *self, const gchar *path, const gchar *label) {
597
495
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
598
496
 
599
497
        g_return_if_fail (IS_MENU_BROWSER (self));
600
498
 
601
 
        g_return_if_fail (IS_MENU_BROWSER (self));
602
 
 
603
499
        GtkWidget *item_label = GTK_BIN (self)->child;
604
 
 
605
500
        gtk_label_set_text (GTK_LABEL (item_label), label);
606
501
 
607
 
        g_object_set_data (G_OBJECT (self),
608
 
                                           G_OBJECT_DATA_NAME,
609
 
                                           g_strdup (path));
 
502
        g_free (g_object_get_data (G_OBJECT (self), G_OBJECT_DATA_NAME));
 
503
        g_object_set_data (G_OBJECT (self), G_OBJECT_DATA_NAME, g_strdup (path));
610
504
}
611
505
/******************************************************************************/
612
506
static void
613
 
menu_browser_class_init (MenuBrowserClass * klass) {
 
507
menu_browser_class_init (MenuBrowserClass *klass) {
614
508
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
615
509
 
616
510
        menu_browser_parent_class = g_type_class_peek_parent (klass);
619
513
}
620
514
/******************************************************************************/
621
515
static void
622
 
menu_browser_init (MenuBrowser * self) {
 
516
menu_browser_init (MenuBrowser *self) {
 
517
        
 
518
        g_return_if_fail (IS_MENU_BROWSER (self));
 
519
 
623
520
        self->priv = MENU_BROWSER_GET_PRIVATE (self);
624
521
}
625
522
/******************************************************************************/
626
523
static void
627
 
menu_browser_dispose (GObject * obj) {
 
524
menu_browser_dispose (GObject *obj) {
628
525
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
629
526
 
630
 
        MenuBrowser *self;
631
 
        MenuBrowserClass *klass;
632
 
        self = MENU_BROWSER (obj);
633
 
        klass = MENU_BROWSER_CLASS (g_type_class_peek (TYPE_MENU_BROWSER));
 
527
        MenuBrowser *self = MENU_BROWSER (obj);
 
528
/*      MenuBrowserClass *klass = MENU_BROWSER_CLASS (g_type_class_peek (TYPE_MENU_BROWSER));*/
634
529
 
635
 
        (self->priv->menu == NULL ? NULL : (self->priv->menu = (gtk_widget_destroy (self->priv->menu), NULL)));
636
530
        (self->priv->menu_item_label == NULL ? NULL : (self->priv->menu_item_label = (gtk_widget_destroy (self->priv->menu_item_label), NULL)));
637
 
        (self->priv->tmp_array == NULL ? NULL : (self->priv->tmp_array = (g_ptr_array_free (self->priv->tmp_array, TRUE), NULL)));
638
 
 
639
 
        /* do NOT enable this. Ever! */
640
 
        /*(self->priv->icon_theme == NULL ? NULL : (self->priv->icon_theme = (g_object_unref (self->priv->icon_theme), NULL)));*/
 
531
        (self->priv->garbage == NULL ? NULL : garbage_empty (&(self->priv->garbage), FALSE));
641
532
 
642
533
        G_OBJECT_CLASS (menu_browser_parent_class)->dispose (obj);
643
534
}
667
558
/******************************************************************************/
668
559
#ifdef NEW_MENU_SIGNAL
669
560
static void
670
 
menu_browser_add_main_menu_header (GtkWidget *menu,
671
 
                                                                   gchar *path,
672
 
                                                                   MenuBrowser *self) {
 
561
menu_browser_add_main_menu_header (GtkWidget *menu, gchar *path, MenuBrowser *self) {
673
562
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
674
563
 
675
 
 
676
564
        g_return_if_fail (IS_MENU_BROWSER (self));
677
565
 
678
566
        GtkWidget *menu_item = NULL;
712
600
menu_browser_activate_main_menu (MenuBrowser *self) {
713
601
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
714
602
 
715
 
        if (!IS_MENU_BROWSER (self)) return FALSE;
 
603
        g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
716
604
 
717
605
        self->priv->parent_menu_shell =
718
606
                        GTK_MENU_SHELL (gtk_widget_get_parent (GTK_WIDGET (self)));
719
607
 
720
608
        GtkWidget *menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (self));
 
609
 
 
610
        /* this is here because of the solution to the focus problem caused by the
 
611
         * popped context menu */
 
612
        gtk_widget_set_sensitive (GTK_WIDGET (menu), TRUE);
 
613
 
721
614
        menu_browser_populate_menu (GTK_WIDGET (self), self);
 
615
 
722
616
#ifdef NEW_MENU_SIGNAL
723
 
        gchar *path = g_object_get_data (G_OBJECT (self),
724
 
                                                                         G_OBJECT_DATA_NAME);
725
 
        menu_browser_add_main_menu_header (menu,
726
 
                                                                           path,
727
 
                                                                           self);
 
617
        gchar *path = g_object_get_data (G_OBJECT (self), G_OBJECT_DATA_NAME);
 
618
        menu_browser_add_main_menu_header (menu, path, self);
728
619
#endif
729
620
        gtk_menu_reposition (GTK_MENU (menu));
730
621
        return TRUE;
736
627
                                  BrowserPrefs *prefs) {
737
628
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
738
629
 
739
 
        MenuBrowser *self;
740
 
        self = g_object_newv (TYPE_MENU_BROWSER, 0, NULL);
 
630
        MenuBrowser *self = g_object_newv (TYPE_MENU_BROWSER, 0, NULL);
741
631
 
742
632
        self->priv->parent_menu_shell = NULL;
743
633
 
747
637
        }
748
638
        self->prefs = prefs;
749
639
 
750
 
        self->priv->tmp_array = g_ptr_array_new();
 
640
        garbage_init(&(self->priv->garbage));
751
641
 
752
642
        GtkWidget *item_label = gtk_label_new (label);
753
643
        gtk_misc_set_alignment (GTK_MISC (item_label), 0.0, 0.5);
755
645
        self->priv->menu_item_label = item_label;
756
646
 
757
647
        /*make the main menu*/
758
 
        self->priv->menu = gtk_menu_new();
759
 
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (self),
760
 
                                                           self->priv->menu);
 
648
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (self), gtk_menu_new());
761
649
 
762
 
        g_object_set_data (G_OBJECT (self), G_OBJECT_DATA_NAME, (char *)path);
 
650
        g_object_set_data (G_OBJECT (self), G_OBJECT_DATA_NAME, g_strdup (path));
763
651
 
764
652
        g_signal_connect (G_OBJECT (self),
765
653
                                          "activate",