81
68
g_return_if_fail (IS_MENU_BROWSER (self));
83
/* free the structure pointed to by each element */
84
g_ptr_array_foreach (self->priv->tmp_array,
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();
91
70
menu_browser_clear_menu (GTK_WIDGET (self));
93
/******************************************************************************/
95
menu_browser_add_desktop_file (gchar *file_name, GtkWidget *menu, MenuBrowser *self) {
96
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
98
if (!vfs_file_is_desktop (file_name)) {
102
const gchar *app_name = NULL;
103
GtkWidget *icon = NULL;
104
GtkWidget *menu_item = NULL;
106
app_name = vfs_get_desktop_app_name (file_name);
107
icon = vfs_get_icon_for_file (file_name);
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);
115
/******************************************************************************/
117
menu_browser_add_default_file (gchar *file_name,
120
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
122
if (!IS_MENU_BROWSER (self)) return NULL;
124
GtkWidget *menu_item = NULL;
125
GtkWidget *menu_item_icon = NULL;
126
gchar *base_name = g_path_get_basename (file_name);
128
/*make a menu item for this dir*/
129
menu_item = gtk_image_menu_item_new_with_label (base_name);
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);
136
if (strlen (base_name) > MAX_FILE_NAME_LENGTH) {
137
gtk_widget_set_tooltip_text (menu_item, base_name);
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);
148
menu_item_icon = vfs_get_icon_for_file (file_name);
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),
72
garbage_empty (&(self->priv->garbage), TRUE);
155
74
/******************************************************************************/
200
136
MenuBrowser *self) {
201
137
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
203
if (!IS_MENU_BROWSER (self)) return FALSE;
205
gchar *path = (gchar*)g_object_get_data (G_OBJECT (menu_item),
208
if (vfs_file_exists (path)) {
209
if (event->button == 1) {
210
menu_browser_on_file_left_click (path, self);
212
else if (event->button == 2) {
213
if (vfs_file_is_directory (path)) {
214
menu_browser_on_dir_middle_click (path, self);
217
menu_browser_on_file_middle_click (path, self);
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);
227
gchar *tmp = g_strdup_printf ("Error: \"%s\" does not exists.", path);
228
utils_show_dialog ("Error: File not found.",
139
g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
141
gchar *path = (gchar*)g_object_get_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME);
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);
150
if (event->button == 1) {
151
menu_browser_on_file_left_click (path, self);
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);
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);
233
164
gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
237
168
/******************************************************************************/
239
menu_browser_on_menu_key_press (GtkWidget *menu,
170
menu_browser_on_menu_key_press (GtkWidget *menu, GdkEventKey *event, MenuBrowser *self) {
242
171
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
173
g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
245
175
GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
246
176
GtkWidget *menu_item = menu_shell->active_menu_item;
248
if (!IS_MENU_BROWSER (self) ||
249
!self->priv->parent_menu_shell->active ||
179
if (!self->priv->parent_menu_shell->active || !menu_item) {
254
path = (gchar*)g_object_get_data (G_OBJECT (menu_item),
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) {
265
menu_browser_on_file_left_click (path, self);
266
gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
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);
274
menu_browser_on_file_middle_click (path, self);
276
gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
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);
287
gchar *tmp = g_strdup_printf ("Error: \"%s\" does not exists.", path);
288
utils_show_dialog ("Error: File not found.",
183
gchar *path = (gchar*)g_object_get_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME);
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);
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) {
199
menu_browser_on_file_left_click (path, self);
200
gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
202
else if (event->keyval == GDK_F4 ||
203
event->keyval == GDK_KP_F4) {
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);
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);
295
220
/******************************************************************************/
296
221
#ifdef NEW_MENU_SIGNAL
298
menu_browser_on_menu_button_press (GtkWidget *menu,
299
GdkEventButton *event,
223
menu_browser_on_menu_button_press (GtkWidget *menu, GdkEventButton *event, MenuBrowser *self) {
301
224
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
226
g_return_val_if_fail (IS_MENU_BROWSER (self), FALSE);
303
228
gchar *path = NULL;
304
229
GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
305
230
GtkWidget *menu_item = menu_shell->active_menu_item;
312
if (!IS_MENU_BROWSER (self) ||
313
!self->priv->parent_menu_shell->active ||
237
if (!self->priv->parent_menu_shell->active || !menu_item ||
315
238
!gtk_widget_intersect (menu, &area, NULL)) {
319
path = (gchar*)g_object_get_data (G_OBJECT (menu_item),
242
path = (gchar*)g_object_get_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME);
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);
327
else if (event->button == 2) {
328
if (vfs_file_is_directory (path)) {
329
menu_browser_on_dir_middle_click (path, self);
332
menu_browser_on_file_middle_click (path, self);
334
gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
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);
343
gchar *tmp = g_strdup_printf ("Error: \"%s\" does not exists.", path);
344
utils_show_dialog ("Error: File not found.",
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);
251
if (event->button == 1) {
252
menu_browser_on_file_left_click (path, self);
253
gtk_menu_shell_deactivate (self->priv->parent_menu_shell);
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);
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);
349
267
/*gtk_menu_shell_deactivate (self->priv->parent_menu_shell);*/
378
292
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
379
293
vfs_get_icon_for_file (path));
382
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
385
g_object_set_data (G_OBJECT (menu_item),
295
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
297
g_object_set_data (G_OBJECT (menu_item), G_OBJECT_DATA_NAME, path);
389
299
g_signal_connect (G_OBJECT (menu_item),
390
300
"button_press_event",
391
301
G_CALLBACK (menu_browser_on_item_button_press),
394
separator = gtk_separator_menu_item_new();
396
304
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
305
gtk_separator_menu_item_new());
400
308
/******************************************************************************/
402
menu_browser_add_folders (GtkWidget *menu,
310
menu_browser_add_folders (GtkWidget *menu, GPtrArray *dirs, MenuBrowser *self) {
406
311
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
408
313
g_return_if_fail (IS_MENU_BROWSER (self));
410
GtkWidget *menu_item = NULL;
411
GtkWidget *child_menu = NULL;
412
gchar *file_name_and_path = NULL;
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",
318
VfsFileInfo *vfs_file_info = (VfsFileInfo*)g_ptr_array_index (dirs, i);
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);
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);
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);
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);
439
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
337
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
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),
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 ());
342
garbage_add_item (self->priv->garbage, vfs_file_info->file_name);
343
garbage_add_item (self->priv->garbage, vfs_file_info->display_name);
448
345
g_object_set_data (G_OBJECT (menu_item),
449
346
G_OBJECT_DATA_NAME,
347
vfs_file_info->file_name);
452
349
g_signal_connect (GTK_MENU_ITEM (menu_item),
464
361
/******************************************************************************/
466
menu_browser_add_files (GtkWidget *menu,
363
menu_browser_add_files (GtkWidget *menu, GPtrArray *files, MenuBrowser *self) {
470
364
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
472
366
g_return_if_fail (IS_MENU_BROWSER (self));
474
GtkWidget *menu_item = NULL;
475
gchar *file_name_and_path = NULL;
478
370
for (i=0; i<files->len; i++) {
479
file_name_and_path = g_strdup_printf ("%s/%s",
481
(gchar *)g_ptr_array_index (files, i));
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);
371
VfsFileInfo *vfs_file_info = (VfsFileInfo*)g_ptr_array_index (files, i);
373
/*make a menu item for this dir*/
374
GtkWidget *menu_item = gtk_image_menu_item_new_with_label (vfs_file_info->display_name);
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);
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);
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);
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);
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);
400
garbage_add_item (self->priv->garbage, vfs_file_info->file_name);
401
garbage_add_item (self->priv->garbage, vfs_file_info->display_name);
491
403
g_object_set_data (G_OBJECT (menu_item),
492
404
G_OBJECT_DATA_NAME,
405
vfs_file_info->file_name);
494
406
#ifndef NEW_MENU_SIGNAL
495
407
g_signal_connect (menu_item,
496
408
"button_press_event",
517
428
/* empty the menu of its existing contents first */
518
429
menu_browser_clear_menu (parent_menu_item);
520
current_path = (gchar*)g_object_get_data (G_OBJECT (parent_menu_item),
431
current_path = (gchar*)g_object_get_data (G_OBJECT (parent_menu_item), G_OBJECT_DATA_NAME);
523
434
if (!self->priv->parent_menu_shell->active) return;
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),
533
439
g_signal_connect (current_menu,
534
440
"key_press_event",
535
441
G_CALLBACK (menu_browser_on_menu_key_press),
537
#ifndef NEW_MENU_SIGNAL
444
#ifdef NEW_MENU_SIGNAL
445
g_signal_connect (current_menu,
446
"button_press_event",
447
G_CALLBACK (menu_browser_on_menu_button_press),
538
450
/* add the dir name and events */
539
menu_browser_add_menu_header (current_menu,
451
menu_browser_add_menu_header (current_menu, current_path, self);
543
454
/* read the contents of the dir. */
544
455
error = vfs_get_dir_listings (files,
546
457
self->prefs->show_hidden,
548
460
/* add the folders*/
549
menu_browser_add_folders (current_menu,
461
menu_browser_add_folders (current_menu, dirs, self);
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),
466
gtk_separator_menu_item_new());
561
469
/* add the files */
562
menu_browser_add_files (current_menu,
470
menu_browser_add_files (current_menu, files, self);
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);
571
gtk_menu_shell_append (GTK_MENU_SHELL (current_menu),
573
gtk_widget_set_sensitive (GTK_WIDGET (menu_item),
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),
580
gtk_widget_set_sensitive (GTK_WIDGET (menu_item),
481
gtk_menu_shell_append (GTK_MENU_SHELL (current_menu), menu_item);
482
gtk_widget_set_sensitive (GTK_WIDGET (menu_item), FALSE);
584
484
gtk_widget_show_all (current_menu);
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);
620
514
/******************************************************************************/
622
menu_browser_init (MenuBrowser * self) {
516
menu_browser_init (MenuBrowser *self) {
518
g_return_if_fail (IS_MENU_BROWSER (self));
623
520
self->priv = MENU_BROWSER_GET_PRIVATE (self);
625
522
/******************************************************************************/
627
menu_browser_dispose (GObject * obj) {
524
menu_browser_dispose (GObject *obj) {
628
525
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
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));*/
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)));
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));
642
533
G_OBJECT_CLASS (menu_browser_parent_class)->dispose (obj);