~jan-hrdina/ubuntu/quantal/xfce4-places-plugin/1.4.0-upstream-import

« back to all changes in this revision

Viewing changes to panel-plugin/view.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc
  • Date: 2007-08-15 12:33:24 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070815123324-8snt7sp6zzj7vx1c
Tags: 1.0~beta1-0ubuntu1
* New upstream release.
* Upstream changes:
  - Adds mount/unmount options for volumes (removable media)
  - Adds Open Terminal Here option where applicable
  - Search for Files with an external application
  - The trash icon now shows whether there's anything in the trash
  - Large internal clean-up
  - Other minor bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include <libxfce4panel/xfce-panel-convenience.h>
39
39
#include <libxfcegui4/libxfcegui4.h>
40
40
 
 
41
#include <string.h>
 
42
 
41
43
#include "view.h"
42
44
#include "places.h"
43
45
#include "model.h"
 
46
#include "model_system.h"
 
47
#include "model_volumes.h"
 
48
#include "model_user.h"
44
49
#include "cfg.h"
45
50
 
46
51
// UI Helpers
63
68
                                             gboolean *push_in, 
64
69
                                             PlacesData*);
65
70
static void     places_view_cb_menu_deact(PlacesData*, GtkWidget *menu);
66
 
static void     places_view_cb_menu_item_open(GtkWidget *item, const gchar *uri);
67
71
 
68
72
//  - Button
69
73
static gboolean places_view_cb_button_pressed(PlacesData*, GdkEventButton *);
71
75
//  - Recent Documents
72
76
#if USE_RECENT_DOCUMENTS
73
77
static void     places_view_cb_recent_item_open(GtkRecentChooser*, PlacesData*);
74
 
static void     places_view_cb_recent_items_clear(GtkWidget *clear_item);
 
78
static gboolean places_view_cb_recent_items_clear(GtkWidget *clear_item);
75
79
#endif
76
80
 
77
81
// Model Visitor Callbacks
78
 
static void     places_view_add_menu_item(gpointer _places_data, 
79
 
                                   const gchar *label, const gchar *uri, const gchar *icon);
80
 
static void     places_view_add_menu_sep(gpointer _places_data);
81
 
 
 
82
static void     places_view_add_menu_item(PlacesData*, PlacesBookmark*);
82
83
 
83
84
/********** Initialization & Finalization **********/
84
 
 
85
85
void
86
86
places_view_init(PlacesData *pd)
87
87
{
89
89
    
90
90
    gpointer icon_theme_class;
91
91
 
92
 
    pd->view_just_separated = TRUE;
 
92
    pd->view_needs_separator = FALSE;
93
93
    pd->view_menu = NULL;
94
94
 
95
95
    pd->cfg = places_cfg_new(pd);
167
167
    if(pd->view_button_label != NULL)
168
168
        g_object_unref(pd->view_button_label);
169
169
    g_object_unref(pd->view_tooltips);
170
 
 
 
170
 
 
171
    if(pd->bookmark_groups != NULL){
 
172
        GList *bookmark_group = pd->bookmark_groups;
 
173
        while(bookmark_group != NULL){
 
174
            if(bookmark_group->data != NULL)
 
175
               places_bookmark_group_finalize((PlacesBookmarkGroup*) bookmark_group->data);
 
176
            bookmark_group = bookmark_group->next;
 
177
        }
 
178
        g_list_free(pd->bookmark_groups);
 
179
        pd->bookmark_groups = NULL;
 
180
    }
 
181
 
171
182
    places_cfg_finalize(pd);
172
183
}
173
184
 
174
185
void
175
186
places_view_reconfigure_model(PlacesData *pd)
176
187
{
177
 
    gint model_enable;
178
 
    model_enable = PLACES_BOOKMARKS_ENABLE_NONE;
 
188
    /* destroy first */
 
189
    if(pd->bookmark_groups != NULL){
 
190
        GList *bookmark_group = pd->bookmark_groups;
 
191
        while(bookmark_group != NULL){
 
192
            if(bookmark_group->data != NULL)
 
193
                places_bookmark_group_finalize((PlacesBookmarkGroup*) bookmark_group->data);
 
194
            bookmark_group = bookmark_group->next;
 
195
        }
 
196
        g_list_free(pd->bookmark_groups);
 
197
        pd->bookmark_groups = NULL;
 
198
    }
 
199
 
 
200
    /* now create */
 
201
    pd->bookmark_groups = g_list_append(pd->bookmark_groups, places_bookmarks_system_create());
 
202
 
179
203
    if(pd->cfg->show_volumes)
180
 
        model_enable |= PLACES_BOOKMARKS_ENABLE_VOLUMES;
181
 
    if(pd->cfg->show_bookmarks)
182
 
        model_enable |= PLACES_BOOKMARKS_ENABLE_USER;
183
 
    places_bookmarks_enable(pd->bookmarks, model_enable);
 
204
        pd->bookmark_groups = g_list_append(pd->bookmark_groups, places_bookmarks_volumes_create());
 
205
 
 
206
    if(pd->cfg->show_bookmarks){
 
207
        pd->bookmark_groups = g_list_append(pd->bookmark_groups, NULL); /* separator */
 
208
        pd->bookmark_groups = g_list_append(pd->bookmark_groups, places_bookmarks_user_create());
 
209
    }
184
210
}
185
211
 
186
212
/********** UI Helpers **********/
188
214
static void
189
215
places_view_update_menu(PlacesData *pd)
190
216
{
191
 
    BookmarksVisitor visitor;
192
217
#if USE_RECENT_DOCUMENTS
193
218
    GtkWidget *recent_menu;
194
219
    GtkWidget *clear_item;
205
230
    gtk_menu_set_screen (GTK_MENU (pd->view_menu),
206
231
                         gtk_widget_get_screen (GTK_WIDGET (pd->plugin)));
207
232
 
208
 
 
209
 
    // Add system, volumes, user bookmarks
210
 
    visitor.pass_thru  = pd;
211
 
    visitor.item       = places_view_add_menu_item;
212
 
    visitor.separator  = places_view_add_menu_sep;
213
 
    places_bookmarks_visit(pd->bookmarks, &visitor);
 
233
    GList *bookmark_group = pd->bookmark_groups;
 
234
    GList *bookmarks;
 
235
    PlacesBookmark *bookmark;
 
236
    while(bookmark_group != NULL){
 
237
        
 
238
        if(bookmark_group->data == NULL){ /* separator */
 
239
 
 
240
            pd->view_needs_separator = TRUE;
 
241
 
 
242
        }else{
 
243
 
 
244
            bookmarks = places_bookmark_group_get_bookmarks((PlacesBookmarkGroup*) bookmark_group->data);
 
245
    
 
246
            while(bookmarks != NULL){
 
247
                bookmark = (PlacesBookmark*) bookmarks->data;
 
248
                places_view_add_menu_item(pd, bookmark);
 
249
                bookmarks = bookmarks->next;
 
250
            }
 
251
 
 
252
            g_list_free(bookmarks);
 
253
 
 
254
        }
 
255
 
 
256
        bookmark_group = bookmark_group->next;
 
257
    }
214
258
 
215
259
    // Recent Documents
216
260
#if USE_RECENT_DOCUMENTS
 
261
    if(pd->cfg->show_recent || (pd->cfg->search_cmd != NULL && strlen(pd->cfg->search_cmd))){
 
262
#else
 
263
    if(pd->cfg->search_cmd != NULL && strlen(pd->cfg->search_cmd)){
 
264
#endif
 
265
        gtk_menu_shell_append(GTK_MENU_SHELL(pd->view_menu),
 
266
                              gtk_separator_menu_item_new());
 
267
    }
 
268
 
 
269
    if(pd->cfg->search_cmd != NULL && strlen(pd->cfg->search_cmd)){
 
270
        GtkWidget *search_item = gtk_image_menu_item_new_with_mnemonic(_("Search for Files"));
 
271
        if(pd->cfg->show_icons){
 
272
            GtkWidget *search_image = gtk_image_new_from_icon_name("system-search", GTK_ICON_SIZE_MENU);
 
273
            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(search_item), search_image);
 
274
        }
 
275
        gtk_menu_shell_append(GTK_MENU_SHELL(pd->view_menu), search_item);
 
276
        g_signal_connect_swapped(search_item, "activate",
 
277
                                 G_CALLBACK(places_gui_exec), pd->cfg->search_cmd);
 
278
 
 
279
    }
 
280
 
 
281
#if USE_RECENT_DOCUMENTS
217
282
    if(pd->cfg->show_recent){
218
 
        places_view_add_menu_sep(pd);
219
 
    
 
283
 
220
284
        recent_menu = gtk_recent_chooser_menu_new();
221
285
        gtk_recent_chooser_set_show_icons(GTK_RECENT_CHOOSER(recent_menu), pd->cfg->show_icons);
222
286
        gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(recent_menu), pd->cfg->show_recent_number);
236
300
                clear_item = gtk_menu_item_new_with_mnemonic(clear_stock_item.label);
237
301
            }
238
302
            gtk_menu_shell_append(GTK_MENU_SHELL(recent_menu), clear_item);
 
303
            /* try button-release-event to catch mouse clicks and not hide the menu after */
 
304
            g_signal_connect(clear_item, "button-release-event",
 
305
                             G_CALLBACK(places_view_cb_recent_items_clear), NULL);
 
306
            /* use activate when button-release-event doesn't catch it (e.g., enter key pressed) */
239
307
            g_signal_connect(clear_item, "activate",
240
308
                             G_CALLBACK(places_view_cb_recent_items_clear), NULL);
241
309
    
262
330
    gtk_widget_realize(pd->view_menu);
263
331
}
264
332
 
 
333
static gboolean
 
334
places_view_bookmarks_changed(GList *bookmark_groups)
 
335
{
 
336
    gboolean ret = FALSE;
 
337
    GList *bookmark_group = bookmark_groups;
 
338
 
 
339
    while(bookmark_group != NULL){
 
340
 
 
341
        if(bookmark_group->data != NULL)
 
342
            ret = places_bookmark_group_changed((PlacesBookmarkGroup*) bookmark_group->data) || ret;
 
343
 
 
344
        bookmark_group = bookmark_group->next;
 
345
    }
 
346
 
 
347
    return ret;
 
348
}
265
349
 
266
350
void
267
351
places_view_open_menu(PlacesData *pd)
268
352
{
269
353
    /* check if menu is needed, or it needs an update */
270
 
    if(pd->view_menu == NULL || places_bookmarks_changed(pd->bookmarks))
 
354
    if(pd->view_menu == NULL || places_view_bookmarks_changed(pd->bookmark_groups))
271
355
        places_view_update_menu(pd);
272
356
 
273
357
    /* toggle the button */
291
375
        gtk_widget_destroy(pd->view_menu);
292
376
        pd->view_menu = NULL;
293
377
    }
 
378
    pd->view_needs_separator = FALSE;
294
379
}
295
380
 
296
381
void
479
564
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pd->view_button), FALSE);
480
565
}
481
566
 
482
 
static void
483
 
places_view_cb_menu_item_open(GtkWidget *widget, const gchar* uri)
484
 
{
485
 
    places_load_thunar(uri);
486
 
}
487
 
 
488
567
// Button
489
568
static gboolean
490
569
places_view_cb_button_pressed(PlacesData *pd, GdkEventButton *evt)
501
580
    return FALSE;
502
581
}
503
582
 
 
583
void
 
584
places_view_cb_menu_item_context_act(GtkWidget *item, PlacesData *pd)
 
585
{
 
586
    g_assert(pd != NULL);
 
587
    g_assert(pd->view_menu != NULL && GTK_IS_WIDGET(pd->view_menu));
 
588
 
 
589
    /* we want the menu gone - now - since it prevents mouse grabs */
 
590
    gtk_widget_hide(pd->view_menu);
 
591
    while(g_main_context_iteration(NULL, FALSE))
 
592
        /* no op */;
 
593
 
 
594
    PlacesBookmarkAction *action = (PlacesBookmarkAction*) g_object_get_data(G_OBJECT(item), "action");
 
595
    DBG("Calling action %s", action->label);
 
596
    places_bookmark_action_call(action);
 
597
    
 
598
}
 
599
 
 
600
gboolean
 
601
places_view_cb_menu_item_do_alt(PlacesData *pd, GtkWidget *menu_item)
 
602
{
 
603
    
 
604
    GList *actions = (GList*) g_object_get_data(G_OBJECT(menu_item), "actions");
 
605
    GtkWidget *context, *context_item;
 
606
    PlacesBookmarkAction *action;
 
607
 
 
608
 
 
609
    if(actions != NULL){
 
610
 
 
611
        context = gtk_menu_new();
 
612
        gtk_widget_show(context);
 
613
 
 
614
        while(actions != NULL){
 
615
            action = (PlacesBookmarkAction*) actions->data;
 
616
 
 
617
            context_item = gtk_menu_item_new_with_label(action->label);
 
618
            g_object_set_data(G_OBJECT(context_item), "action", action);
 
619
            gtk_widget_show(context_item);
 
620
            g_signal_connect(context_item, "activate",
 
621
                             G_CALLBACK(places_view_cb_menu_item_context_act), pd);
 
622
            gtk_menu_shell_append(GTK_MENU_SHELL(context), context_item);
 
623
 
 
624
            actions = actions->next;
 
625
        }
 
626
 
 
627
        gtk_menu_popup(GTK_MENU(context),
 
628
                       NULL, NULL,
 
629
                       NULL, NULL,
 
630
                       0, gtk_get_current_event_time());
 
631
 
 
632
        g_signal_connect_swapped(context, "deactivate", G_CALLBACK(places_view_open_menu), pd);
 
633
 
 
634
    }
 
635
 
 
636
    return TRUE;
 
637
}
 
638
 
 
639
gboolean
 
640
places_view_cb_menu_item_do_main(PlacesData *pd, GtkWidget *menu_item)
 
641
{
 
642
        const gchar *uri = (const gchar*) g_object_get_data(G_OBJECT(menu_item), "uri");
 
643
        if(uri != NULL){
 
644
            places_load_thunar(uri);
 
645
            return FALSE;
 
646
        }
 
647
        return TRUE;
 
648
}
 
649
 
 
650
 
 
651
gboolean
 
652
places_view_cb_menu_item_press(GtkWidget *menu_item, GdkEventButton *event, PlacesData *pd)
 
653
{
 
654
 
 
655
    gboolean ctrl =  (event->state & GDK_CONTROL_MASK) && 
 
656
                    !(event->state & (GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK));
 
657
    gboolean sensitive = GTK_WIDGET_IS_SENSITIVE(gtk_bin_get_child(GTK_BIN(menu_item)));
 
658
    if(event->button == 3 || (event->button == 1 && (ctrl || !sensitive)))
 
659
        return places_view_cb_menu_item_do_alt(pd, menu_item);
 
660
    else
 
661
        return FALSE;
 
662
}
 
663
 
504
664
// Recent Documents
505
665
 
506
666
#if USE_RECENT_DOCUMENTS
508
668
places_view_cb_recent_item_open(GtkRecentChooser *chooser, PlacesData *pd)
509
669
{
510
670
    gchar *uri = gtk_recent_chooser_get_current_uri(chooser);
511
 
    places_load_thunar(uri);
 
671
    places_load_file(uri);
512
672
    g_free(uri);
513
673
}
514
674
 
515
 
static void
 
675
static gboolean
516
676
places_view_cb_recent_items_clear(GtkWidget *clear_item)
517
677
{
518
678
    GtkRecentManager *manager = gtk_recent_manager_get_default();
519
679
    gint removed = gtk_recent_manager_purge_items(manager, NULL);
520
680
    DBG("Cleared %d recent items", removed);
 
681
    return TRUE;
521
682
}
522
683
#endif
523
684
 
524
685
/********** Model Visitor Callbacks **********/
525
686
 
526
687
static void
527
 
places_view_add_menu_item(gpointer _pd, const gchar *label, const gchar *uri, const gchar *icon)
528
 
{
529
 
    g_assert(_pd != NULL);
530
 
    g_return_if_fail(label != NULL && label != "");
531
 
    g_return_if_fail(uri != NULL && uri != "");
532
 
 
533
 
    PlacesData *pd = (PlacesData*) _pd;
534
 
    GtkWidget *item = gtk_image_menu_item_new_with_label(label);
535
 
 
536
 
    if(pd->cfg->show_icons && icon != NULL){
537
 
        GdkPixbuf *pb = xfce_themed_icon_load(icon, 16);
 
688
places_view_load_thunar_wrapper(PlacesBookmarkAction *act)
 
689
{
 
690
    g_assert(act != NULL);
 
691
    places_load_terminal((gchar*) act->priv);
 
692
}
 
693
 
 
694
 
 
695
 
 
696
static void
 
697
places_view_load_terminal_wrapper(PlacesBookmarkAction *act)
 
698
{
 
699
    g_assert(act != NULL);
 
700
    places_load_terminal((gchar*) act->priv);
 
701
}
 
702
 
 
703
 
 
704
static void
 
705
places_view_add_menu_item(PlacesData *pd, PlacesBookmark *bookmark)
 
706
{
 
707
    g_assert(pd != NULL);
 
708
    g_assert(bookmark != NULL);
 
709
 
 
710
    GtkWidget *item;
 
711
 
 
712
    if(pd->view_needs_separator){
 
713
        gtk_menu_shell_append(GTK_MENU_SHELL(pd->view_menu),
 
714
                              gtk_separator_menu_item_new());
 
715
        pd->view_needs_separator = FALSE;
 
716
    }
 
717
 
 
718
    item = gtk_image_menu_item_new_with_label(bookmark->label);
 
719
 
 
720
    if(pd->cfg->show_icons && bookmark->icon != NULL){
 
721
        GdkPixbuf *pb = xfce_themed_icon_load(bookmark->icon, 16);
538
722
        
539
723
        if(G_LIKELY(pb != NULL)){
540
724
            GtkWidget *image = gtk_image_new_from_pixbuf(pb);
543
727
        }
544
728
    }
545
729
 
546
 
    g_signal_connect(item, "activate",
547
 
                     G_CALLBACK(places_view_cb_menu_item_open), (gchar*) uri);
 
730
    if(bookmark->uri != NULL){
 
731
        
 
732
        g_object_set_data(G_OBJECT(item), "uri", (gchar*) bookmark->uri);
 
733
 
 
734
        if(bookmark->uri_scheme != PLACES_URI_SCHEME_TRASH){
 
735
            PlacesBookmarkAction *terminal  = g_new0(PlacesBookmarkAction, 1);
 
736
            terminal->label                 = _("Open Terminal Here");
 
737
            terminal->priv                  = bookmark->uri;
 
738
            terminal->action                = places_view_load_terminal_wrapper;
 
739
            bookmark->actions = g_list_prepend(bookmark->actions, terminal);
 
740
        }
 
741
 
 
742
        PlacesBookmarkAction *open  = g_new0(PlacesBookmarkAction, 1);
 
743
        open->label                 = _("Open");
 
744
        open->priv                  = bookmark->uri;
 
745
        open->action                = places_view_load_thunar_wrapper;
 
746
        bookmark->actions = g_list_prepend(bookmark->actions, open);
 
747
 
 
748
    }else{
 
749
        /* Probably an unmounted volume. Gray it out. */
 
750
        gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(item)), FALSE);
 
751
    }
 
752
 
 
753
    if(bookmark->actions != NULL)
 
754
        g_object_set_data(G_OBJECT(item), "actions", bookmark->actions);
 
755
 
 
756
 
 
757
    g_signal_connect(item, "button-release-event",
 
758
                     G_CALLBACK(places_view_cb_menu_item_press), pd);
 
759
    g_signal_connect_swapped(item, "activate",
 
760
                     G_CALLBACK(places_view_cb_menu_item_do_main), pd);
 
761
    g_signal_connect_swapped(item, "destroy",
 
762
                     G_CALLBACK(places_bookmark_free), bookmark);
 
763
 
548
764
    gtk_menu_shell_append(GTK_MENU_SHELL(pd->view_menu), item);
549
765
 
550
 
    pd->view_just_separated = FALSE;
551
 
}
552
 
 
553
 
static void
554
 
places_view_add_menu_sep(gpointer _pd)
555
 
{
556
 
    g_assert(_pd != NULL);
557
 
    PlacesData *pd = (PlacesData*) _pd;
558
 
 
559
 
    if(!pd->view_just_separated){
560
 
        gtk_menu_shell_append(GTK_MENU_SHELL(pd->view_menu),
561
 
                              gtk_separator_menu_item_new());
562
 
        pd->view_just_separated = TRUE;
563
 
    }
564
766
}
565
767
 
566
768
// vim: ai et tabstop=4