~ubuntu-branches/ubuntu/oneiric/gnome-panel/oneiric

« back to all changes in this revision

Viewing changes to .pc/01_layout.patch/gnome-panel/panel-menu-items.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher, Sebastien Bacher, Jeremy Bicha
  • Date: 2011-05-30 11:04:49 UTC
  • mfrom: (1.13.10 upstream) (2.2.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20110530110449-hinl17kxkcefjw6x
Tags: 1:3.0.2-0ubuntu1
[ Sebastien Bacher ]
* New upstream version
* debian/control.in:
  - the new libgweather version is in oneiric, use it
  - drop the python and python-gconf depends, 
    they were added for gnome-panel-add which is still using gconf and buggy
* debian/gnome-panel-data.install:
  - don't install the apport hook, it's only getting gconf datas which 
    doesn't work since gnome-panel uses gsettings
* debian/patches/90_build_fixes.patch:
  - restore build fix from git not applied in the new serie
* debian/patches/01_panel_submenus.patch:
  - don't take that Debian diff, the .menus use the upstream naming in Ubuntu
* debian/patches/06_no_resize_grip.patch:
  - dropped, the issue is fixed in the new version
* debian/patches/50_fix-potfiles.patch:
  - dropped, the issue is fixed in the new version
* debian/watch:
  - track unstable series as well

Drop those delta, since gnome-panel is not the default Ubuntu session now we
can go back to an experience closer to the upstream one: 
* debian/control.in:
  - drop the indicators recommends, unity-2d is the ubuntu fallback session
    so we can get back to use an upstream config for gnome-panel and reduce
    the delta we carry
* debian/patches/04_default_panel_config.patch:
  - don't modify the upstream layout
* debian/patches/05_no_session_delay.patch:
  - no need to tweak the upstream session to optimize it
* debian/patches/16_compiz_workspace_switcher.patch:
  - go back to the upstream switcher behaviour    
* debian/patches/25_dynamic_fusa_detection.patch:
  - not needed since we use the upstream layout, could be ported if someone
    is wanting to do the work though
* debian/patches/30_disable-initial-animation.patch, debian/rules:
  - drop the --disable-initial-animation, that was some login optimization
    but since it's not the default desktop you should go back to the 
    upstream behaviour

[ Jeremy Bicha ]   
* New upstream version
* Merge from Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Recommends gnome-settings-daemon which has the timezone polkit service
* debian/rules:
  - Update translations template.
* debian/gnome-panel-data.install:
  - Install apport hook
  - Install the "About Ubuntu" menu item.
* debian/patches/01_layout.patch:
  - Disabled, Help & About Ubuntu don't fit as well in Gnome Panel 3
* debian/patches/01_panel_submenus.patch.
  - Dropped
* debian/patches/03_dnd_places_link.patch:
  - Disabled, when using Drag'n'Drop from Places menu, install a link launcher
    (.desktop file) instead of copying the entire directory.
* debian/patches/17_about-ubuntu-translation.patch:
  - List ubuntu-about.desktop for translation.
* debian/patches/40_unset_menuproxy.patch:
  - Make sure gnome-panel and the applets don't pick up menu proxies.
* debian/patches/50_fix-potfiles.patch
  - Fix i18n
* debian/patches/85_disable_shutdown_on_ltsp.patch:
  - Suppress the shutdown option in the panel if LTSP_CLIENT is set.
* debian/patches/71_change_bookmark_submenu_limit_value.patch
  - Dropped, picked up by Debian
* debian/patches/18_lockdown_lock_editor.patch:
* debian/patches/90_git_wnck_show_realize.patch:
* debian/patches/90_fix_linking_DSO_link.patch:
* debian/patches/91_gir_annotations.patch
* debian/patches/92_git_calendar_day.patch
* debian/patches/92_git_fix_applets_in_multiscreen.patch:
  - Dropped, applied upstream
* debian/watch:
  - watch unstable versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2
 
 *
3
 
 * Copyright (C) 2005 Vincent Untz
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License as
7
 
 * published by the Free Software Foundation; either version 2 of the
8
 
 * License, or (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful, but
11
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
 * General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18
 
 * 02111-1307, USA.
19
 
 *
20
 
 * Authors:
21
 
 *      Vincent Untz <vincent@vuntz.net>
22
 
 *
23
 
 * Based on code from panel-menu-bar.c
24
 
 */
25
 
 
26
 
/*
27
 
 * TODO:
28
 
 *   + drag and drop loses icon for URIs
29
 
 *   + drag and drop of bookmarks/network places/removable media should create
30
 
 *     a menu button
31
 
 *   + if a menu is open and gets updated, it should reappear and not just
32
 
 *     disappear
33
 
 */
34
 
 
35
 
#include <config.h>
36
 
 
37
 
#include "panel-menu-items.h"
38
 
 
39
 
#include <string.h>
40
 
#include <glib/gi18n.h>
41
 
#include <gio/gio.h>
42
 
 
43
 
#include <libpanel-util/panel-error.h>
44
 
#include <libpanel-util/panel-glib.h>
45
 
#include <libpanel-util/panel-keyfile.h>
46
 
#include <libpanel-util/panel-launch.h>
47
 
#include <libpanel-util/panel-show.h>
48
 
 
49
 
#include "menu.h"
50
 
#include "panel-action-button.h"
51
 
#include "panel-globals.h"
52
 
#include "panel-icon-names.h"
53
 
#include "panel-lockdown.h"
54
 
#include "panel-recent.h"
55
 
#include "panel-stock-icons.h"
56
 
#include "panel-util.h"
57
 
 
58
 
#define BOOKMARKS_FILENAME      ".gtk-bookmarks"
59
 
#define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
60
 
#define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
61
 
#define NAMES_DIR               "/apps/nautilus/desktop"
62
 
#define HOME_NAME_KEY           "/apps/nautilus/desktop/home_icon_name"
63
 
#define COMPUTER_NAME_KEY       "/apps/nautilus/desktop/computer_icon_name"
64
 
#define MAX_ITEMS_OR_SUBMENU    5
65
 
#define MAX_BOOKMARK_ITEMS      100
66
 
 
67
 
G_DEFINE_TYPE (PanelPlaceMenuItem, panel_place_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
68
 
G_DEFINE_TYPE (PanelDesktopMenuItem, panel_desktop_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
69
 
 
70
 
#define PANEL_PLACE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemPrivate))
71
 
#define PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItemPrivate))
72
 
 
73
 
struct _PanelPlaceMenuItemPrivate {
74
 
        GtkWidget   *menu;
75
 
        PanelWidget *panel;
76
 
 
77
 
        GtkRecentManager *recent_manager;
78
 
 
79
 
        GFileMonitor *bookmarks_monitor;
80
 
 
81
 
        GVolumeMonitor *volume_monitor;
82
 
        gulong       drive_changed_id;
83
 
        gulong       drive_connected_id;
84
 
        gulong       drive_disconnected_id;
85
 
        gulong       volume_added_id;
86
 
        gulong       volume_changed_id;
87
 
        gulong       volume_removed_id;
88
 
        gulong       mount_added_id;
89
 
        gulong       mount_changed_id;
90
 
        gulong       mount_removed_id;
91
 
 
92
 
        guint        use_image : 1;
93
 
};
94
 
 
95
 
struct _PanelDesktopMenuItemPrivate {
96
 
        GtkWidget   *menu;
97
 
        PanelWidget *panel;
98
 
 
99
 
        guint        use_image : 1;
100
 
        guint        append_lock_logout : 1;
101
 
};
102
 
 
103
 
static void
104
 
activate_uri_on_screen (const char *uri,
105
 
                        GdkScreen  *screen)
106
 
{
107
 
        panel_show_uri (screen, uri, gtk_get_current_event_time (), NULL);
108
 
}
109
 
 
110
 
static void
111
 
activate_uri (GtkWidget  *menuitem,
112
 
              const char *uri)
113
 
{
114
 
        activate_uri_on_screen (uri, menuitem_to_screen (menuitem));
115
 
}
116
 
 
117
 
static void
118
 
activate_path (GtkWidget  *menuitem,
119
 
               const char *path)
120
 
{
121
 
        char *uri;
122
 
 
123
 
        uri = g_filename_to_uri (path, NULL, NULL);
124
 
        activate_uri_on_screen (uri, menuitem_to_screen (menuitem));
125
 
        g_free (uri);
126
 
}
127
 
 
128
 
static void
129
 
activate_home_uri (GtkWidget *menuitem,
130
 
                   gpointer   data)
131
 
{
132
 
        activate_path (menuitem, g_get_home_dir ());
133
 
}
134
 
 
135
 
static void
136
 
activate_desktop_uri (GtkWidget *menuitem,
137
 
                      gpointer   data)
138
 
{
139
 
        activate_path (menuitem,
140
 
                       g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
141
 
}
142
 
 
143
 
static void
144
 
panel_menu_items_append_from_desktop (GtkWidget *menu,
145
 
                                      char      *path,
146
 
                                      char      *force_name,
147
 
                                      gboolean   use_icon)
148
 
{
149
 
        GKeyFile  *key_file;
150
 
        gboolean   loaded;
151
 
        GtkWidget *item;
152
 
        char      *path_freeme;
153
 
        char      *full_path;
154
 
        char      *uri;
155
 
        char      *type;
156
 
        gboolean   is_application;
157
 
        char      *tryexec;
158
 
        char      *icon;
159
 
        char      *name;
160
 
        char      *comment;
161
 
 
162
 
        path_freeme = NULL;
163
 
 
164
 
        key_file = g_key_file_new ();
165
 
 
166
 
        if (g_path_is_absolute (path)) {
167
 
                loaded = g_key_file_load_from_file (key_file, path,
168
 
                                                    G_KEY_FILE_NONE, NULL);
169
 
                full_path = path;
170
 
        } else {
171
 
                char *lookup_file;
172
 
                char *desktop_path;
173
 
 
174
 
                if (!g_str_has_suffix (path, ".desktop")) {
175
 
                        desktop_path = g_strconcat (path, ".desktop", NULL);
176
 
                } else {
177
 
                        desktop_path = path;
178
 
                }
179
 
 
180
 
                lookup_file = g_strconcat ("applications", G_DIR_SEPARATOR_S,
181
 
                                           desktop_path, NULL);
182
 
                loaded = g_key_file_load_from_data_dirs (key_file, lookup_file,
183
 
                                                         &path_freeme,
184
 
                                                         G_KEY_FILE_NONE,
185
 
                                                         NULL);
186
 
                full_path = path_freeme;
187
 
                g_free (lookup_file);
188
 
 
189
 
                if (desktop_path != path)
190
 
                        g_free (desktop_path);
191
 
        }
192
 
 
193
 
        if (!loaded) {
194
 
                g_key_file_free (key_file);
195
 
                if (path_freeme)
196
 
                        g_free (path_freeme);
197
 
                return;
198
 
        }
199
 
 
200
 
        /* For Application desktop files, respect TryExec */
201
 
        type = panel_key_file_get_string (key_file, "Type");
202
 
        if (!type) {
203
 
                g_key_file_free (key_file);
204
 
                if (path_freeme)
205
 
                        g_free (path_freeme);
206
 
                return;
207
 
        }
208
 
        is_application = (strcmp (type, "Application") == 0);
209
 
        g_free (type);
210
 
 
211
 
        if (is_application) {
212
 
                tryexec = panel_key_file_get_string (key_file, "TryExec");
213
 
                if (tryexec) {
214
 
                        char *prog;
215
 
 
216
 
                        prog = g_find_program_in_path (tryexec);
217
 
                        g_free (tryexec);
218
 
 
219
 
                        if (!prog) {
220
 
                                /* FIXME: we could add some file monitor magic,
221
 
                                 * so that the menu items appears when the
222
 
                                 * program appears, but that's really complex
223
 
                                 * for not a huge benefit */
224
 
                                g_key_file_free (key_file);
225
 
                                if (path_freeme)
226
 
                                        g_free (path_freeme);
227
 
                                return;
228
 
                        }
229
 
 
230
 
                        g_free (prog);
231
 
                }
232
 
        }
233
 
 
234
 
        /* Now, simply build the menu item */
235
 
        icon    = panel_key_file_get_locale_string (key_file, "Icon");
236
 
        comment = panel_key_file_get_locale_string (key_file, "Comment");
237
 
 
238
 
        if (PANEL_GLIB_STR_EMPTY (force_name))
239
 
                name = panel_key_file_get_locale_string (key_file, "Name");
240
 
        else
241
 
                name = g_strdup (force_name);
242
 
 
243
 
        if (use_icon) {
244
 
                item = panel_image_menu_item_new ();
245
 
        } else {
246
 
                item = gtk_image_menu_item_new ();
247
 
        }
248
 
 
249
 
        setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
250
 
                                   icon, NULL, NULL, name);
251
 
 
252
 
        panel_util_set_tooltip_text (item, comment);
253
 
 
254
 
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
255
 
        g_signal_connect_data (item, "activate",
256
 
                               G_CALLBACK (panel_menu_item_activate_desktop_file),
257
 
                               g_strdup (full_path),
258
 
                               (GClosureNotify) g_free, 0);
259
 
        g_signal_connect (G_OBJECT (item), "button_press_event",
260
 
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
261
 
 
262
 
        uri = g_filename_to_uri (full_path, NULL, NULL);
263
 
 
264
 
        setup_uri_drag (item, uri, icon);
265
 
        g_free (uri);
266
 
 
267
 
        g_key_file_free (key_file);
268
 
 
269
 
        if (icon)
270
 
                g_free (icon);
271
 
 
272
 
        if (name)
273
 
                g_free (name);
274
 
 
275
 
        if (comment)
276
 
                g_free (comment);
277
 
 
278
 
        if (path_freeme)
279
 
                g_free (path_freeme);
280
 
}
281
 
 
282
 
static void
283
 
panel_menu_items_append_place_item (const char *icon_name,
284
 
                                    GIcon      *gicon,
285
 
                                    const char *title,
286
 
                                    const char *tooltip,
287
 
                                    GtkWidget  *menu,
288
 
                                    GCallback   callback,
289
 
                                    const char *uri)
290
 
{
291
 
        GtkWidget *item;
292
 
        char      *user_data;
293
 
 
294
 
        item = panel_image_menu_item_new ();
295
 
        setup_menu_item_with_icon (item,
296
 
                                   panel_menu_icon_get_size (),
297
 
                                   icon_name, NULL, gicon,
298
 
                                   title);
299
 
 
300
 
        panel_util_set_tooltip_text (item, tooltip);
301
 
 
302
 
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
303
 
 
304
 
        user_data = g_strdup (uri);
305
 
        g_signal_connect_data (item, "activate", callback, user_data,
306
 
                               (GClosureNotify) g_free, 0);
307
 
 
308
 
        g_signal_connect (G_OBJECT (item), "button_press_event",
309
 
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
310
 
 
311
 
        setup_uri_drag (item, uri, icon_name);
312
 
}
313
 
 
314
 
static GtkWidget *
315
 
panel_menu_items_create_action_item_full (PanelActionButtonType  action_type,
316
 
                                          const char            *label,
317
 
                                          const char            *tooltip)
318
 
{
319
 
        GtkWidget *item;
320
 
 
321
 
        if (panel_action_get_is_disabled (action_type))
322
 
                return NULL;
323
 
 
324
 
        item = gtk_image_menu_item_new ();
325
 
        setup_menu_item_with_icon (item,
326
 
                                   panel_menu_icon_get_size (),
327
 
                                   panel_action_get_icon_name (action_type),
328
 
                                   NULL, NULL,
329
 
                                   label ? label : panel_action_get_text (action_type));
330
 
 
331
 
        panel_util_set_tooltip_text (item,
332
 
                                     tooltip ?
333
 
                                        tooltip :
334
 
                                        panel_action_get_tooltip (action_type));
335
 
 
336
 
        g_signal_connect (item, "activate",
337
 
                          panel_action_get_invoke (action_type), NULL);
338
 
        g_signal_connect (G_OBJECT (item), "button_press_event",
339
 
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
340
 
        setup_internal_applet_drag (item, action_type);
341
 
 
342
 
        return item;
343
 
}
344
 
 
345
 
static GtkWidget *
346
 
panel_menu_items_create_action_item (PanelActionButtonType action_type)
347
 
{
348
 
        return panel_menu_items_create_action_item_full (action_type,
349
 
                                                         NULL, NULL);
350
 
}
351
 
 
352
 
static void
353
 
panel_place_menu_item_append_gtk_bookmarks (GtkWidget *menu)
354
 
{
355
 
        typedef struct {
356
 
                char *full_uri;
357
 
                char *label;
358
 
        } PanelBookmark;
359
 
 
360
 
        GtkWidget   *add_menu;
361
 
        char        *filename;
362
 
        GIOChannel  *io_channel;
363
 
        GHashTable  *table;
364
 
        int          i;
365
 
        GSList      *lines = NULL;
366
 
        GSList      *add_bookmarks, *l;
367
 
        PanelBookmark *bookmark;
368
 
 
369
 
        filename = g_build_filename (g_get_home_dir (),
370
 
                                     BOOKMARKS_FILENAME, NULL);
371
 
 
372
 
        io_channel = g_io_channel_new_file (filename, "r", NULL);
373
 
        g_free (filename);
374
 
 
375
 
        if (!io_channel)
376
 
                return;
377
 
 
378
 
        /* We use a hard limit to avoid having users shooting their
379
 
         * own feet, and to avoid crashing the system if a misbehaving
380
 
         * application creates a big bookmars file.
381
 
         */
382
 
        for (i = 0; i < MAX_BOOKMARK_ITEMS; i++) {
383
 
                char      *contents;
384
 
                gsize      length;
385
 
                gsize      terminator_pos;
386
 
                GIOStatus  status;
387
 
 
388
 
                status = g_io_channel_read_line (io_channel, &contents, &length, &terminator_pos, NULL);
389
 
 
390
 
                if (status != G_IO_STATUS_NORMAL)
391
 
                        break;
392
 
 
393
 
                if (length == 0)
394
 
                        break;
395
 
 
396
 
                /* Clear the line terminator (\n), if any */
397
 
                if (terminator_pos > 0)
398
 
                        contents[terminator_pos] = '\0';
399
 
 
400
 
                lines = g_slist_prepend (lines, contents);
401
 
        }
402
 
 
403
 
        g_io_channel_shutdown (io_channel, FALSE, NULL);
404
 
        g_io_channel_unref (io_channel);
405
 
 
406
 
        if (!lines)
407
 
                return;
408
 
 
409
 
        lines = g_slist_reverse (lines);
410
 
 
411
 
        table = g_hash_table_new (g_str_hash, g_str_equal);
412
 
        add_bookmarks = NULL;
413
 
 
414
 
        for (l = lines; l; l = l->next) {
415
 
                char *line = (char*) l->data;
416
 
 
417
 
                if (line[0] && !g_hash_table_lookup (table, line)) {
418
 
                        GFile    *file;
419
 
                        char     *space;
420
 
                        char     *label;
421
 
                        gboolean  keep;
422
 
 
423
 
                        g_hash_table_insert (table, line, line);
424
 
 
425
 
                        space = strchr (line, ' ');
426
 
                        if (space) {
427
 
                                *space = '\0';
428
 
                                label = g_strdup (space + 1);
429
 
                        } else {
430
 
                                label = NULL;
431
 
                        }
432
 
 
433
 
                        keep = FALSE;
434
 
 
435
 
                        if (g_str_has_prefix (line, "x-nautilus-search:"))
436
 
                                keep = TRUE;
437
 
 
438
 
                        if (!keep) {
439
 
                                file = g_file_new_for_uri (line);
440
 
                                keep = !g_file_is_native (file) ||
441
 
                                       g_file_query_exists (file, NULL);
442
 
                                g_object_unref (file);
443
 
                        }
444
 
 
445
 
                        if (!keep) {
446
 
                                if (label)
447
 
                                        g_free (label);
448
 
                                continue;
449
 
                        }
450
 
 
451
 
                        bookmark = g_malloc (sizeof (PanelBookmark));
452
 
                        bookmark->full_uri = g_strdup (line);
453
 
                        bookmark->label = label;
454
 
                        add_bookmarks = g_slist_prepend (add_bookmarks, bookmark);
455
 
                }
456
 
        }
457
 
 
458
 
        g_hash_table_destroy (table);
459
 
        g_slist_foreach (lines, (GFunc) g_free, NULL);
460
 
        g_slist_free (lines);
461
 
 
462
 
        add_bookmarks = g_slist_reverse (add_bookmarks);
463
 
 
464
 
        if (g_slist_length (add_bookmarks) <= MAX_ITEMS_OR_SUBMENU) {
465
 
                add_menu = menu;
466
 
        } else {
467
 
                GtkWidget *item;
468
 
 
469
 
                item = gtk_image_menu_item_new ();
470
 
                setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
471
 
                                           PANEL_ICON_BOOKMARKS, NULL, NULL,
472
 
                                           _("Bookmarks"));
473
 
 
474
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
475
 
                gtk_widget_show (item);
476
 
 
477
 
                add_menu = create_empty_menu ();
478
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
479
 
        }
480
 
 
481
 
        for (l = add_bookmarks; l; l = l->next) {
482
 
                char *display_name;
483
 
                char *tooltip;
484
 
                char *label;
485
 
                char *icon;
486
 
                GFile *file;
487
 
                GIcon *gicon;
488
 
 
489
 
                bookmark = l->data;
490
 
                
491
 
                file = g_file_new_for_uri (bookmark->full_uri);
492
 
                display_name = g_file_get_parse_name (file);
493
 
                g_object_unref (file);
494
 
                /* Translators: %s is a URI */
495
 
                tooltip = g_strdup_printf (_("Open '%s'"), display_name);
496
 
                g_free (display_name);
497
 
 
498
 
                label = NULL;
499
 
                if (bookmark->label) {
500
 
                        label = g_strdup (g_strstrip (bookmark->label));
501
 
                        if (!label [0]) {
502
 
                                g_free (label);
503
 
                                label = NULL;
504
 
                        }
505
 
                }
506
 
 
507
 
                if (!label) {
508
 
                        label = panel_util_get_label_for_uri (bookmark->full_uri);
509
 
 
510
 
                        if (!label) {
511
 
                                g_free (tooltip);
512
 
                                g_free (bookmark->full_uri);
513
 
                                if (bookmark->label)
514
 
                                        g_free (bookmark->label);
515
 
                                g_free (bookmark);
516
 
                                continue;
517
 
                        }
518
 
                }
519
 
 
520
 
                icon = panel_util_get_icon_for_uri (bookmark->full_uri);
521
 
                /*FIXME: we should probably get a GIcon if possible, so that we
522
 
                 * have customized icons for cd-rom, eg */
523
 
                if (!icon)
524
 
                        icon = g_strdup (PANEL_ICON_FOLDER);
525
 
 
526
 
                gicon = g_themed_icon_new_with_default_fallbacks (icon);
527
 
 
528
 
                //FIXME: drag and drop will be broken for x-nautilus-search uris
529
 
                panel_menu_items_append_place_item (icon, gicon,
530
 
                                                    label,
531
 
                                                    tooltip,
532
 
                                                    add_menu,
533
 
                                                    G_CALLBACK (activate_uri),
534
 
                                                    bookmark->full_uri);
535
 
 
536
 
                g_free (icon);
537
 
                g_object_unref (gicon);
538
 
                g_free (tooltip);
539
 
                g_free (label);
540
 
                g_free (bookmark->full_uri);
541
 
                if (bookmark->label)
542
 
                        g_free (bookmark->label);
543
 
                g_free (bookmark);
544
 
        }
545
 
 
546
 
        g_slist_free (add_bookmarks);
547
 
}
548
 
 
549
 
static void
550
 
drive_poll_for_media_cb (GObject      *source_object,
551
 
                         GAsyncResult *res,
552
 
                         gpointer      user_data)
553
 
{
554
 
        GdkScreen *screen;
555
 
        GError    *error;
556
 
        char      *primary;
557
 
        char      *name;
558
 
 
559
 
        error = NULL;
560
 
        if (!g_drive_poll_for_media_finish (G_DRIVE (source_object),
561
 
                                            res, &error)) {
562
 
                if (error->code != G_IO_ERROR_FAILED_HANDLED) {
563
 
                        screen = GDK_SCREEN (user_data);
564
 
 
565
 
                        name = g_drive_get_name (G_DRIVE (source_object));
566
 
                        primary = g_strdup_printf (_("Unable to scan %s for media changes"),
567
 
                                                   name);
568
 
                        g_free (name);
569
 
                        panel_error_dialog (NULL, screen,
570
 
                                            "cannot_scan_drive", TRUE,
571
 
                                            primary, error->message);
572
 
                        g_free (primary);
573
 
                }
574
 
                g_error_free (error);
575
 
        }
576
 
 
577
 
        //FIXME: should we mount the volume and activate the root of the new
578
 
        //mount?
579
 
}
580
 
 
581
 
static void
582
 
panel_menu_item_rescan_drive (GtkWidget *menuitem,
583
 
                              GDrive    *drive)
584
 
{
585
 
        g_drive_poll_for_media (drive, NULL,
586
 
                                drive_poll_for_media_cb,
587
 
                                menuitem_to_screen (menuitem));
588
 
}
589
 
 
590
 
static void
591
 
panel_menu_item_append_drive (GtkWidget *menu,
592
 
                              GDrive    *drive)
593
 
{
594
 
        GtkWidget *item;
595
 
        GIcon     *icon;
596
 
        char      *title;
597
 
        char      *tooltip;
598
 
 
599
 
        icon = g_drive_get_icon (drive);
600
 
        title = g_drive_get_name (drive);
601
 
 
602
 
        item = panel_image_menu_item_new ();
603
 
        setup_menu_item_with_icon (item,
604
 
                                   panel_menu_icon_get_size (),
605
 
                                   NULL, NULL, icon,
606
 
                                   title);
607
 
        g_object_unref (icon);
608
 
 
609
 
        tooltip = g_strdup_printf (_("Rescan %s"), title);
610
 
        panel_util_set_tooltip_text (item, tooltip);
611
 
        g_free (tooltip);
612
 
 
613
 
        g_free (title);
614
 
 
615
 
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
616
 
 
617
 
        g_signal_connect_data (item, "activate",
618
 
                               G_CALLBACK (panel_menu_item_rescan_drive),
619
 
                               g_object_ref (drive),
620
 
                               (GClosureNotify) g_object_unref, 0);
621
 
 
622
 
        g_signal_connect (G_OBJECT (item), "button_press_event",
623
 
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
624
 
}
625
 
 
626
 
typedef struct {
627
 
        GdkScreen       *screen;
628
 
        GMountOperation *mount_op;
629
 
} PanelVolumeMountData;
630
 
 
631
 
static void
632
 
volume_mount_cb (GObject      *source_object,
633
 
                 GAsyncResult *res,
634
 
                 gpointer      user_data)
635
 
{
636
 
        PanelVolumeMountData *mount_data = user_data;
637
 
        GError *error;
638
 
 
639
 
        error = NULL;
640
 
        if (!g_volume_mount_finish (G_VOLUME (source_object), res, &error)) {
641
 
                char *primary;
642
 
                char *name;
643
 
 
644
 
                if (error->code != G_IO_ERROR_FAILED_HANDLED) {
645
 
                        name = g_volume_get_name (G_VOLUME (source_object));
646
 
                        primary = g_strdup_printf (_("Unable to mount %s"),
647
 
                                                   name);
648
 
                        g_free (name);
649
 
 
650
 
                        panel_error_dialog (NULL, mount_data->screen,
651
 
                                            "cannot_mount_volume", TRUE,
652
 
                                            primary, error->message);
653
 
                        g_free (primary);
654
 
                }
655
 
                g_error_free (error);
656
 
        } else {
657
 
                GMount *mount;
658
 
                GFile  *root;
659
 
                char   *rooturi;
660
 
 
661
 
                mount = g_volume_get_mount (G_VOLUME (source_object));
662
 
                root = g_mount_get_root (mount);
663
 
                rooturi = g_file_get_uri (root);
664
 
                activate_uri_on_screen (rooturi, mount_data->screen);
665
 
                g_object_unref (mount);
666
 
                g_object_unref (root);
667
 
                g_free (rooturi);
668
 
        }
669
 
 
670
 
        g_object_unref (mount_data->mount_op);
671
 
        g_slice_free (PanelVolumeMountData, mount_data);
672
 
}
673
 
 
674
 
static void
675
 
panel_menu_item_mount_volume (GtkWidget *menuitem,
676
 
                              GVolume   *volume)
677
 
{
678
 
        PanelVolumeMountData *mount_data;
679
 
 
680
 
        mount_data = g_slice_new (PanelVolumeMountData);
681
 
        mount_data->screen = menuitem_to_screen (menuitem);
682
 
        mount_data->mount_op = gtk_mount_operation_new (NULL);
683
 
        gtk_mount_operation_set_screen (GTK_MOUNT_OPERATION (mount_data->mount_op),
684
 
                                        mount_data->screen);
685
 
 
686
 
        g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_data->mount_op, NULL,
687
 
                        volume_mount_cb, mount_data);
688
 
}
689
 
 
690
 
static void
691
 
panel_menu_item_append_volume (GtkWidget *menu,
692
 
                               GVolume   *volume)
693
 
{
694
 
        GtkWidget *item;
695
 
        GIcon     *icon;
696
 
        char      *title;
697
 
        char      *tooltip;
698
 
 
699
 
        icon = g_volume_get_icon (volume);
700
 
        title = g_volume_get_name (volume);
701
 
 
702
 
        item = panel_image_menu_item_new ();
703
 
        setup_menu_item_with_icon (item,
704
 
                                   panel_menu_icon_get_size (),
705
 
                                   NULL, NULL, icon,
706
 
                                   title);
707
 
        g_object_unref (icon);
708
 
 
709
 
        tooltip = g_strdup_printf (_("Mount %s"), title);
710
 
        panel_util_set_tooltip_text (item, tooltip);
711
 
        g_free (tooltip);
712
 
 
713
 
        g_free (title);
714
 
 
715
 
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
716
 
 
717
 
        g_signal_connect_data (item, "activate",
718
 
                               G_CALLBACK (panel_menu_item_mount_volume),
719
 
                               g_object_ref (volume),
720
 
                               (GClosureNotify) g_object_unref, 0);
721
 
 
722
 
        g_signal_connect (G_OBJECT (item), "button_press_event",
723
 
                          G_CALLBACK (menu_dummy_button_press_event), NULL);
724
 
}
725
 
 
726
 
static void
727
 
panel_menu_item_append_mount (GtkWidget *menu,
728
 
                              GMount    *mount)
729
 
{
730
 
        GFile  *root;
731
 
        GIcon  *icon;
732
 
        char   *display_name;
733
 
        char   *activation_uri;
734
 
 
735
 
        icon = g_mount_get_icon (mount);
736
 
        display_name = g_mount_get_name (mount);
737
 
 
738
 
        root = g_mount_get_root (mount);
739
 
        activation_uri = g_file_get_uri (root);
740
 
        g_object_unref (root);
741
 
 
742
 
        panel_menu_items_append_place_item (NULL, icon,
743
 
                                            display_name,
744
 
                                            display_name, //FIXME tooltip
745
 
                                            menu,
746
 
                                            G_CALLBACK (activate_uri),
747
 
                                            activation_uri);
748
 
 
749
 
        g_object_unref (icon);
750
 
        g_free (display_name);
751
 
        g_free (activation_uri);
752
 
}
753
 
 
754
 
typedef enum {
755
 
        PANEL_GIO_DRIVE,
756
 
        PANEL_GIO_VOLUME,
757
 
        PANEL_GIO_MOUNT
758
 
} PanelGioItemType;
759
 
 
760
 
typedef struct {
761
 
        PanelGioItemType type;
762
 
        union {
763
 
                GDrive *drive;
764
 
                GVolume *volume;
765
 
                GMount *mount;
766
 
        } u;
767
 
} PanelGioItem;
768
 
 
769
 
/* this is loosely based on update_places() from nautilus-places-sidebar.c */
770
 
static void
771
 
panel_place_menu_item_append_local_gio (PanelPlaceMenuItem *place_item,
772
 
                                        GtkWidget          *menu)
773
 
{
774
 
        GList   *l;
775
 
        GList   *ll;
776
 
        GList   *drives;
777
 
        GDrive  *drive;
778
 
        GList   *volumes;
779
 
        GVolume *volume;
780
 
        GList   *mounts;
781
 
        GMount  *mount;
782
 
        GSList       *items;
783
 
        GSList       *sl;
784
 
        PanelGioItem *item;
785
 
        GtkWidget *add_menu;
786
 
 
787
 
        items = NULL;
788
 
 
789
 
        /* first go through all connected drives */
790
 
        drives = g_volume_monitor_get_connected_drives (place_item->priv->volume_monitor);
791
 
        for (l = drives; l != NULL; l = l->next) {
792
 
                drive = l->data;
793
 
 
794
 
                volumes = g_drive_get_volumes (drive);
795
 
                if (volumes != NULL) {
796
 
                        for (ll = volumes; ll != NULL; ll = ll->next) {
797
 
                                volume = ll->data;
798
 
                                mount = g_volume_get_mount (volume);
799
 
                                item = g_slice_new (PanelGioItem);
800
 
                                if (mount != NULL) {
801
 
                                        item->type = PANEL_GIO_MOUNT;
802
 
                                        item->u.mount = mount;
803
 
                                } else {
804
 
                                        /* Do show the unmounted volumes; this
805
 
                                         * is so the user can mount it (in case
806
 
                                         * automounting is off).
807
 
                                         *
808
 
                                         * Also, even if automounting is
809
 
                                         * enabled, this gives a visual cue
810
 
                                         * that the user should remember to
811
 
                                         * yank out the media if he just
812
 
                                         * unmounted it.
813
 
                                         */
814
 
                                        item->type = PANEL_GIO_VOLUME;
815
 
                                        item->u.volume = g_object_ref (volume);
816
 
                                }
817
 
                                items = g_slist_prepend (items, item);
818
 
                                g_object_unref (volume);
819
 
                        }
820
 
                        g_list_free (volumes);
821
 
                } else {
822
 
                        if (g_drive_is_media_removable (drive) &&
823
 
                            !g_drive_is_media_check_automatic (drive)) {
824
 
                                /* If the drive has no mountable volumes and we
825
 
                                 * cannot detect media change.. we display the
826
 
                                 * drive so the user can manually poll the
827
 
                                 * drive by clicking on it..."
828
 
                                 *
829
 
                                 * This is mainly for drives like floppies
830
 
                                 * where media detection doesn't work.. but
831
 
                                 * it's also for human beings who like to turn
832
 
                                 * off media detection in the OS to save
833
 
                                 * battery juice.
834
 
                                 */
835
 
                                item = g_slice_new (PanelGioItem);
836
 
                                item->type = PANEL_GIO_DRIVE;
837
 
                                item->u.drive = g_object_ref (drive);
838
 
                                items = g_slist_prepend (items, item);
839
 
                        }
840
 
                }
841
 
                g_object_unref (drive);
842
 
        }
843
 
        g_list_free (drives);
844
 
 
845
 
        /* add all volumes that is not associated with a drive */
846
 
        volumes = g_volume_monitor_get_volumes (place_item->priv->volume_monitor);
847
 
        for (l = volumes; l != NULL; l = l->next) {
848
 
                volume = l->data;
849
 
                drive = g_volume_get_drive (volume);
850
 
                if (drive != NULL) {
851
 
                        g_object_unref (volume);
852
 
                        g_object_unref (drive);
853
 
                        continue;
854
 
                }
855
 
                mount = g_volume_get_mount (volume);
856
 
                item = g_slice_new (PanelGioItem);
857
 
                if (mount != NULL) {
858
 
                        item->type = PANEL_GIO_MOUNT;
859
 
                        item->u.mount = mount;
860
 
                } else {
861
 
                        /* see comment above in why we add an icon for an
862
 
                         * unmounted mountable volume */
863
 
                        item->type = PANEL_GIO_VOLUME;
864
 
                        item->u.volume = g_object_ref (volume);
865
 
                }
866
 
                items = g_slist_prepend (items, item);
867
 
                g_object_unref (volume);
868
 
        }
869
 
        g_list_free (volumes);
870
 
 
871
 
        /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
872
 
        mounts = g_volume_monitor_get_mounts (place_item->priv->volume_monitor);
873
 
        for (l = mounts; l != NULL; l = l->next) {
874
 
                GFile *root;
875
 
 
876
 
                mount = l->data;
877
 
 
878
 
                if (g_mount_is_shadowed (mount)) {
879
 
                        g_object_unref (mount);
880
 
                        continue;
881
 
                }
882
 
 
883
 
                volume = g_mount_get_volume (mount);
884
 
                if (volume != NULL) {
885
 
                        g_object_unref (volume);
886
 
                        g_object_unref (mount);
887
 
                        continue;
888
 
                }
889
 
 
890
 
                root = g_mount_get_root (mount);
891
 
                if (!g_file_is_native (root)) {
892
 
                        g_object_unref (root);
893
 
                        g_object_unref (mount);
894
 
                        continue;
895
 
                }
896
 
                g_object_unref (root);
897
 
 
898
 
                item = g_slice_new (PanelGioItem);
899
 
                item->type = PANEL_GIO_MOUNT;
900
 
                item->u.mount = mount;
901
 
                items = g_slist_prepend (items, item);
902
 
        }
903
 
        g_list_free (mounts);
904
 
 
905
 
        /* now that we have everything, add the items inline or in a submenu */
906
 
        items = g_slist_reverse (items);
907
 
 
908
 
        if (g_slist_length (items) <= MAX_ITEMS_OR_SUBMENU) {
909
 
                add_menu = menu;
910
 
        } else {
911
 
                GtkWidget  *item;
912
 
 
913
 
                item = gtk_image_menu_item_new ();
914
 
                setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
915
 
                                           PANEL_ICON_REMOVABLE_MEDIA,
916
 
                                           NULL, NULL,
917
 
                                           _("Removable Media"));
918
 
 
919
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
920
 
                gtk_widget_show (item);
921
 
 
922
 
                add_menu = create_empty_menu ();
923
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
924
 
        }
925
 
 
926
 
        for (sl = items; sl; sl = sl->next) {
927
 
                item = sl->data;
928
 
                switch (item->type) {
929
 
                case PANEL_GIO_DRIVE:
930
 
                        panel_menu_item_append_drive (add_menu, item->u.drive);
931
 
                        g_object_unref (item->u.drive);
932
 
                        break;
933
 
                case PANEL_GIO_VOLUME:
934
 
                        panel_menu_item_append_volume (add_menu, item->u.volume);
935
 
                        g_object_unref (item->u.volume);
936
 
                        break;
937
 
                case PANEL_GIO_MOUNT:
938
 
                        panel_menu_item_append_mount (add_menu, item->u.mount);
939
 
                        g_object_unref (item->u.mount);
940
 
                        break;
941
 
                default:
942
 
                        g_assert_not_reached ();
943
 
                }
944
 
                g_slice_free (PanelGioItem, item);
945
 
        }
946
 
 
947
 
        g_slist_free (items);
948
 
}
949
 
 
950
 
/* this is loosely based on update_places() from nautilus-places-sidebar.c */
951
 
static void
952
 
panel_place_menu_item_append_remote_gio (PanelPlaceMenuItem *place_item,
953
 
                                         GtkWidget          *menu)
954
 
{
955
 
        GtkWidget *add_menu;
956
 
        GList     *mounts, *l;
957
 
        GMount    *mount;
958
 
        GSList    *add_mounts, *sl;
959
 
 
960
 
        /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
961
 
        mounts = g_volume_monitor_get_mounts (place_item->priv->volume_monitor);
962
 
        add_mounts = NULL;
963
 
 
964
 
        for (l = mounts; l; l = l->next) {
965
 
                GVolume *volume;
966
 
                GFile   *root;
967
 
 
968
 
                mount = l->data;
969
 
 
970
 
                if (g_mount_is_shadowed (mount)) {
971
 
                        g_object_unref (mount);
972
 
                        continue;
973
 
                }
974
 
 
975
 
                volume = g_mount_get_volume (mount);
976
 
                if (volume != NULL) {
977
 
                        g_object_unref (volume);
978
 
                        g_object_unref (mount);
979
 
                        continue;
980
 
                }
981
 
 
982
 
                root = g_mount_get_root (mount);
983
 
                if (g_file_is_native (root)) {
984
 
                        g_object_unref (root);
985
 
                        g_object_unref (mount);
986
 
                        continue;
987
 
                }
988
 
                g_object_unref (root);
989
 
 
990
 
 
991
 
                add_mounts = g_slist_prepend (add_mounts, mount);
992
 
        }
993
 
        add_mounts = g_slist_reverse (add_mounts);
994
 
 
995
 
        if (g_slist_length (add_mounts) <= MAX_ITEMS_OR_SUBMENU) {
996
 
                add_menu = menu;
997
 
        } else {
998
 
                GtkWidget  *item;
999
 
 
1000
 
                item = panel_image_menu_item_new ();
1001
 
                setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
1002
 
                                           PANEL_ICON_NETWORK_SERVER,
1003
 
                                           NULL, NULL,
1004
 
                                           _("Network Places"));
1005
 
 
1006
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1007
 
                gtk_widget_show (item);
1008
 
 
1009
 
                add_menu = create_empty_menu ();
1010
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
1011
 
        }
1012
 
 
1013
 
        for (sl = add_mounts; sl; sl = sl->next) {
1014
 
                mount = sl->data;
1015
 
                panel_menu_item_append_mount (add_menu, mount);
1016
 
                g_object_unref (mount);
1017
 
        }
1018
 
 
1019
 
        g_slist_free (add_mounts);
1020
 
        g_list_free (mounts);
1021
 
}
1022
 
 
1023
 
 
1024
 
static GtkWidget *
1025
 
panel_place_menu_item_create_menu (PanelPlaceMenuItem *place_item)
1026
 
{
1027
 
        GtkWidget *places_menu;
1028
 
        GtkWidget *item;
1029
 
        char      *gconf_name;
1030
 
        char      *name;
1031
 
        char      *uri;
1032
 
        GFile     *file;
1033
 
 
1034
 
        places_menu = panel_create_menu ();
1035
 
 
1036
 
        file = g_file_new_for_path (g_get_home_dir ());
1037
 
        uri = g_file_get_uri (file);
1038
 
        name = panel_util_get_label_for_uri (uri);
1039
 
        g_object_unref (file);
1040
 
        
1041
 
        panel_menu_items_append_place_item (PANEL_ICON_HOME, NULL,
1042
 
                                            name,
1043
 
                                            _("Open your personal folder"),
1044
 
                                            places_menu,
1045
 
                                            G_CALLBACK (activate_home_uri),
1046
 
                                            uri);
1047
 
        g_free (name);
1048
 
        g_free (uri);
1049
 
 
1050
 
        if (!gconf_client_get_bool (panel_gconf_get_client (),
1051
 
                                    DESKTOP_IS_HOME_DIR_KEY,
1052
 
                                    NULL)) {
1053
 
                file = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
1054
 
                uri = g_file_get_uri (file);
1055
 
                g_object_unref (file);
1056
 
                
1057
 
                panel_menu_items_append_place_item (
1058
 
                                PANEL_ICON_DESKTOP, NULL,
1059
 
                                /* Translators: Desktop is used here as in
1060
 
                                 * "Desktop Folder" (this is not the Desktop
1061
 
                                 * environment). */
1062
 
                                C_("Desktop Folder", "Desktop"),
1063
 
                                _("Open the contents of your desktop in a folder"),
1064
 
                                places_menu,
1065
 
                                G_CALLBACK (activate_desktop_uri),
1066
 
                                /* FIXME: if the dir changes, we'd need to update the drag data since the uri is not the same */
1067
 
                                uri);
1068
 
                g_free (uri);
1069
 
        }
1070
 
 
1071
 
        panel_place_menu_item_append_gtk_bookmarks (places_menu);
1072
 
        add_menu_separator (places_menu);
1073
 
 
1074
 
        gconf_name = gconf_client_get_string (panel_gconf_get_client (),
1075
 
                                              COMPUTER_NAME_KEY,
1076
 
                                              NULL);
1077
 
        panel_menu_items_append_from_desktop (places_menu,
1078
 
                                              "nautilus-computer.desktop",
1079
 
                                              gconf_name,
1080
 
                                              TRUE);
1081
 
        if (gconf_name)
1082
 
                g_free (gconf_name);
1083
 
 
1084
 
        panel_place_menu_item_append_local_gio (place_item, places_menu);
1085
 
        add_menu_separator (places_menu);
1086
 
 
1087
 
        panel_menu_items_append_from_desktop (places_menu,
1088
 
                                              "network-scheme.desktop",
1089
 
                                              NULL,
1090
 
                                              TRUE);
1091
 
        panel_place_menu_item_append_remote_gio (place_item, places_menu);
1092
 
 
1093
 
        if (panel_is_program_in_path ("nautilus-connect-server")) {
1094
 
                item = panel_menu_items_create_action_item (PANEL_ACTION_CONNECT_SERVER);
1095
 
                if (item != NULL)
1096
 
                        gtk_menu_shell_append (GTK_MENU_SHELL (places_menu),
1097
 
                                               item);
1098
 
        }
1099
 
 
1100
 
        add_menu_separator (places_menu);
1101
 
 
1102
 
        panel_menu_items_append_from_desktop (places_menu,
1103
 
                                              "gnome-search-tool.desktop",
1104
 
                                              NULL,
1105
 
                                              FALSE);
1106
 
 
1107
 
        panel_recent_append_documents_menu (places_menu,
1108
 
                                            place_item->priv->recent_manager);
1109
 
 
1110
 
        return places_menu;
1111
 
}
1112
 
 
1113
 
static void
1114
 
panel_place_menu_item_recreate_menu (GtkWidget *widget)
1115
 
{
1116
 
        PanelPlaceMenuItem *place_item;
1117
 
 
1118
 
        place_item = PANEL_PLACE_MENU_ITEM (widget);
1119
 
 
1120
 
        if (place_item->priv->menu) {
1121
 
                gtk_widget_destroy (place_item->priv->menu);
1122
 
                place_item->priv->menu = panel_place_menu_item_create_menu (place_item);
1123
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (place_item),
1124
 
                                           place_item->priv->menu);
1125
 
                panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
1126
 
                                               "menu_panel",
1127
 
                                               place_item->priv->panel);
1128
 
        }
1129
 
}
1130
 
 
1131
 
static void
1132
 
panel_place_menu_item_key_changed (GConfClient *client,
1133
 
                                   guint        cnxn_id,
1134
 
                                   GConfEntry  *entry,
1135
 
                                   GtkWidget   *place_item)
1136
 
{
1137
 
        panel_place_menu_item_recreate_menu (place_item);
1138
 
}
1139
 
 
1140
 
static void
1141
 
panel_place_menu_item_gtk_bookmarks_changed (GFileMonitor *handle,
1142
 
                                             GFile        *file,
1143
 
                                             GFile        *other_file,
1144
 
                                             GFileMonitorEvent event,
1145
 
                                             gpointer      user_data)
1146
 
{
1147
 
        panel_place_menu_item_recreate_menu (GTK_WIDGET (user_data));
1148
 
}
1149
 
 
1150
 
static void
1151
 
panel_place_menu_item_drives_changed (GVolumeMonitor *monitor,
1152
 
                                      GDrive         *drive,
1153
 
                                      GtkWidget      *place_menu)
1154
 
{
1155
 
        panel_place_menu_item_recreate_menu (place_menu);
1156
 
}
1157
 
 
1158
 
static void
1159
 
panel_place_menu_item_volumes_changed (GVolumeMonitor *monitor,
1160
 
                                       GVolume        *volume,
1161
 
                                       GtkWidget      *place_menu)
1162
 
{
1163
 
        panel_place_menu_item_recreate_menu (place_menu);
1164
 
}
1165
 
 
1166
 
static void
1167
 
panel_place_menu_item_mounts_changed (GVolumeMonitor *monitor,
1168
 
                                      GMount         *mount,
1169
 
                                      GtkWidget      *place_menu)
1170
 
{
1171
 
        panel_place_menu_item_recreate_menu (place_menu);
1172
 
}
1173
 
 
1174
 
static void
1175
 
panel_desktop_menu_item_append_menu (GtkWidget *menu,
1176
 
                                     gpointer   data)
1177
 
{
1178
 
        PanelDesktopMenuItem *parent;
1179
 
        gboolean              add_separator;
1180
 
        GList                *children;
1181
 
        GList                *last;
1182
 
 
1183
 
        parent = PANEL_DESKTOP_MENU_ITEM (data);
1184
 
 
1185
 
        add_separator = FALSE;
1186
 
        children = gtk_container_get_children (GTK_CONTAINER (menu));
1187
 
        last = g_list_last (children);
1188
 
 
1189
 
        if (last != NULL)
1190
 
                add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
1191
 
 
1192
 
        g_list_free (children);
1193
 
 
1194
 
        if (add_separator)
1195
 
                add_menu_separator (menu);
1196
 
 
1197
 
        panel_menu_items_append_from_desktop (menu, "yelp.desktop", NULL, FALSE);
1198
 
        panel_menu_items_append_from_desktop (menu, "gnome-about.desktop", NULL, FALSE);
1199
 
 
1200
 
        if (parent->priv->append_lock_logout)
1201
 
                panel_menu_items_append_lock_logout (menu);
1202
 
}
1203
 
 
1204
 
static GtkWidget *
1205
 
panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item)
1206
 
{
1207
 
        GtkWidget *desktop_menu;
1208
 
 
1209
 
        desktop_menu = create_applications_menu ("settings.menu", NULL, FALSE);
1210
 
 
1211
 
        g_object_set_data (G_OBJECT (desktop_menu),
1212
 
                           "panel-menu-append-callback",
1213
 
                           panel_desktop_menu_item_append_menu);
1214
 
        g_object_set_data (G_OBJECT (desktop_menu),
1215
 
                           "panel-menu-append-callback-data",
1216
 
                           desktop_item);
1217
 
 
1218
 
        return desktop_menu;
1219
 
}
1220
 
 
1221
 
static void
1222
 
panel_desktop_menu_item_recreate_menu (PanelDesktopMenuItem *desktop_item)
1223
 
{
1224
 
        if (desktop_item->priv->menu) {
1225
 
                gtk_widget_destroy (desktop_item->priv->menu);
1226
 
                desktop_item->priv->menu = panel_desktop_menu_item_create_menu (desktop_item);
1227
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (desktop_item),
1228
 
                                           desktop_item->priv->menu);
1229
 
                panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
1230
 
                                               "menu_panel",
1231
 
                                               desktop_item->priv->panel);
1232
 
        }
1233
 
}
1234
 
 
1235
 
static void
1236
 
panel_place_menu_item_finalize (GObject *object)
1237
 
{
1238
 
        PanelPlaceMenuItem *menuitem = (PanelPlaceMenuItem *) object;
1239
 
 
1240
 
        gconf_client_remove_dir (panel_gconf_get_client (),
1241
 
                                 DESKTOP_IS_HOME_DIR_DIR,
1242
 
                                 NULL);
1243
 
        gconf_client_remove_dir (panel_gconf_get_client (),
1244
 
                                 NAMES_DIR,
1245
 
                                 NULL);
1246
 
 
1247
 
        if (menuitem->priv->bookmarks_monitor != NULL) {
1248
 
                g_file_monitor_cancel (menuitem->priv->bookmarks_monitor);
1249
 
                g_object_unref (menuitem->priv->bookmarks_monitor);
1250
 
        }
1251
 
        menuitem->priv->bookmarks_monitor = NULL;
1252
 
 
1253
 
        if (menuitem->priv->drive_changed_id)
1254
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1255
 
                                             menuitem->priv->drive_changed_id);
1256
 
        menuitem->priv->drive_changed_id = 0;
1257
 
 
1258
 
        if (menuitem->priv->drive_connected_id)
1259
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1260
 
                                             menuitem->priv->drive_connected_id);
1261
 
        menuitem->priv->drive_connected_id = 0;
1262
 
 
1263
 
        if (menuitem->priv->drive_disconnected_id)
1264
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1265
 
                                             menuitem->priv->drive_disconnected_id);
1266
 
        menuitem->priv->drive_disconnected_id = 0;
1267
 
 
1268
 
        if (menuitem->priv->volume_added_id)
1269
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1270
 
                                             menuitem->priv->volume_added_id);
1271
 
        menuitem->priv->volume_added_id = 0;
1272
 
 
1273
 
        if (menuitem->priv->volume_changed_id)
1274
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1275
 
                                             menuitem->priv->volume_changed_id);
1276
 
        menuitem->priv->volume_changed_id = 0;
1277
 
 
1278
 
        if (menuitem->priv->volume_removed_id)
1279
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1280
 
                                             menuitem->priv->volume_removed_id);
1281
 
        menuitem->priv->volume_removed_id = 0;
1282
 
 
1283
 
        if (menuitem->priv->mount_added_id)
1284
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1285
 
                                             menuitem->priv->mount_added_id);
1286
 
        menuitem->priv->mount_added_id = 0;
1287
 
 
1288
 
        if (menuitem->priv->mount_changed_id)
1289
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1290
 
                                             menuitem->priv->mount_changed_id);
1291
 
        menuitem->priv->mount_changed_id = 0;
1292
 
 
1293
 
        if (menuitem->priv->mount_removed_id)
1294
 
                g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1295
 
                                             menuitem->priv->mount_removed_id);
1296
 
        menuitem->priv->mount_removed_id = 0;
1297
 
 
1298
 
        if (menuitem->priv->volume_monitor != NULL)
1299
 
                g_object_unref (menuitem->priv->volume_monitor);
1300
 
        menuitem->priv->volume_monitor = NULL;
1301
 
 
1302
 
        G_OBJECT_CLASS (panel_place_menu_item_parent_class)->finalize (object);
1303
 
}
1304
 
 
1305
 
static void
1306
 
panel_desktop_menu_item_finalize (GObject *object)
1307
 
{
1308
 
        PanelDesktopMenuItem *menuitem = (PanelDesktopMenuItem *) object;
1309
 
 
1310
 
        if (menuitem->priv->append_lock_logout)
1311
 
                panel_lockdown_notify_remove (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
1312
 
                                              menuitem);
1313
 
        G_OBJECT_CLASS (panel_desktop_menu_item_parent_class)->finalize (object);
1314
 
}
1315
 
 
1316
 
static void
1317
 
panel_place_menu_item_init (PanelPlaceMenuItem *menuitem)
1318
 
{
1319
 
        GFile *bookmark;
1320
 
        char  *bookmarks_filename;
1321
 
        GError *error;
1322
 
 
1323
 
        menuitem->priv = PANEL_PLACE_MENU_ITEM_GET_PRIVATE (menuitem);
1324
 
 
1325
 
        gconf_client_add_dir (panel_gconf_get_client (),
1326
 
                              DESKTOP_IS_HOME_DIR_DIR,
1327
 
                              GCONF_CLIENT_PRELOAD_NONE,
1328
 
                              NULL);
1329
 
        gconf_client_add_dir (panel_gconf_get_client (),
1330
 
                              NAMES_DIR,
1331
 
                              GCONF_CLIENT_PRELOAD_NONE,
1332
 
                              NULL);
1333
 
 
1334
 
        panel_gconf_notify_add_while_alive (HOME_NAME_KEY,
1335
 
                                            (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
1336
 
                                            G_OBJECT (menuitem));
1337
 
        panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
1338
 
                                            (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
1339
 
                                            G_OBJECT (menuitem));
1340
 
        panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
1341
 
                                            (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
1342
 
                                            G_OBJECT (menuitem));
1343
 
 
1344
 
        menuitem->priv->recent_manager = gtk_recent_manager_get_default ();
1345
 
 
1346
 
        bookmarks_filename = g_build_filename (g_get_home_dir (),
1347
 
                                               BOOKMARKS_FILENAME, NULL);
1348
 
        bookmark = g_file_new_for_path (bookmarks_filename);
1349
 
 
1350
 
        error = NULL;
1351
 
        menuitem->priv->bookmarks_monitor = g_file_monitor_file 
1352
 
                                                        (bookmark,
1353
 
                                                        G_FILE_MONITOR_NONE,
1354
 
                                                        NULL,
1355
 
                                                        &error);
1356
 
        if (error) {
1357
 
                g_warning ("Failed to add file monitor for %s: %s\n",
1358
 
                           bookmarks_filename, error->message);
1359
 
                g_error_free (error);
1360
 
        } else {
1361
 
                g_signal_connect (G_OBJECT (menuitem->priv->bookmarks_monitor), 
1362
 
                                  "changed", 
1363
 
                                  (GCallback) panel_place_menu_item_gtk_bookmarks_changed,
1364
 
                                  menuitem);
1365
 
        }
1366
 
 
1367
 
        g_object_unref (bookmark);
1368
 
        g_free (bookmarks_filename);
1369
 
 
1370
 
        menuitem->priv->volume_monitor = g_volume_monitor_get ();
1371
 
 
1372
 
        menuitem->priv->drive_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
1373
 
                                                           "drive-changed",
1374
 
                                                           G_CALLBACK (panel_place_menu_item_drives_changed),
1375
 
                                                           menuitem);
1376
 
        menuitem->priv->drive_connected_id = g_signal_connect (menuitem->priv->volume_monitor,
1377
 
                                                             "drive-connected",
1378
 
                                                             G_CALLBACK (panel_place_menu_item_drives_changed),
1379
 
                                                             menuitem);
1380
 
        menuitem->priv->drive_disconnected_id = g_signal_connect (menuitem->priv->volume_monitor,
1381
 
                                                             "drive-disconnected",
1382
 
                                                             G_CALLBACK (panel_place_menu_item_drives_changed),
1383
 
                                                             menuitem);
1384
 
        menuitem->priv->volume_added_id = g_signal_connect (menuitem->priv->volume_monitor,
1385
 
                                                           "volume-added",
1386
 
                                                           G_CALLBACK (panel_place_menu_item_volumes_changed),
1387
 
                                                           menuitem);
1388
 
        menuitem->priv->volume_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
1389
 
                                                             "volume-changed",
1390
 
                                                             G_CALLBACK (panel_place_menu_item_volumes_changed),
1391
 
                                                             menuitem);
1392
 
        menuitem->priv->volume_removed_id = g_signal_connect (menuitem->priv->volume_monitor,
1393
 
                                                             "volume-removed",
1394
 
                                                             G_CALLBACK (panel_place_menu_item_volumes_changed),
1395
 
                                                             menuitem);
1396
 
        menuitem->priv->mount_added_id = g_signal_connect (menuitem->priv->volume_monitor,
1397
 
                                                           "mount-added",
1398
 
                                                           G_CALLBACK (panel_place_menu_item_mounts_changed),
1399
 
                                                           menuitem);
1400
 
        menuitem->priv->mount_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
1401
 
                                                             "mount-changed",
1402
 
                                                             G_CALLBACK (panel_place_menu_item_mounts_changed),
1403
 
                                                             menuitem);
1404
 
        menuitem->priv->mount_removed_id = g_signal_connect (menuitem->priv->volume_monitor,
1405
 
                                                             "mount-removed",
1406
 
                                                             G_CALLBACK (panel_place_menu_item_mounts_changed),
1407
 
                                                             menuitem);
1408
 
 
1409
 
}
1410
 
 
1411
 
static void
1412
 
panel_desktop_menu_item_init (PanelDesktopMenuItem *menuitem)
1413
 
{
1414
 
        menuitem->priv = PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE (menuitem);
1415
 
}
1416
 
 
1417
 
static void
1418
 
panel_place_menu_item_class_init (PanelPlaceMenuItemClass *klass)
1419
 
{
1420
 
        GObjectClass *gobject_class = (GObjectClass   *) klass;
1421
 
 
1422
 
        gobject_class->finalize  = panel_place_menu_item_finalize;
1423
 
 
1424
 
        g_type_class_add_private (klass, sizeof (PanelPlaceMenuItemPrivate));
1425
 
}
1426
 
 
1427
 
static void
1428
 
panel_desktop_menu_item_class_init (PanelDesktopMenuItemClass *klass)
1429
 
{
1430
 
        GObjectClass *gobject_class = (GObjectClass   *) klass;
1431
 
 
1432
 
        gobject_class->finalize  = panel_desktop_menu_item_finalize;
1433
 
 
1434
 
        g_type_class_add_private (klass, sizeof (PanelDesktopMenuItemPrivate));
1435
 
}
1436
 
 
1437
 
GtkWidget *
1438
 
panel_place_menu_item_new (gboolean use_image)
1439
 
{
1440
 
        PanelPlaceMenuItem *menuitem;
1441
 
        GtkWidget          *image;
1442
 
 
1443
 
        menuitem = g_object_new (PANEL_TYPE_PLACE_MENU_ITEM, NULL);
1444
 
 
1445
 
        if (use_image)
1446
 
                image = gtk_image_new_from_icon_name (PANEL_ICON_FOLDER,
1447
 
                                                      panel_menu_icon_get_size ());
1448
 
        else
1449
 
                image = NULL;
1450
 
 
1451
 
        setup_menuitem (GTK_WIDGET (menuitem),
1452
 
                        image ? panel_menu_icon_get_size () : GTK_ICON_SIZE_INVALID,
1453
 
                        image,
1454
 
                        _("Places"));
1455
 
 
1456
 
        menuitem->priv->use_image = use_image;
1457
 
 
1458
 
        menuitem->priv->menu = panel_place_menu_item_create_menu (menuitem);
1459
 
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
1460
 
                                   menuitem->priv->menu);
1461
 
 
1462
 
        return GTK_WIDGET (menuitem);
1463
 
}
1464
 
 
1465
 
GtkWidget *
1466
 
panel_desktop_menu_item_new (gboolean use_image,
1467
 
                             gboolean append_lock_logout)
1468
 
{
1469
 
        PanelDesktopMenuItem *menuitem;
1470
 
        GtkWidget            *image;
1471
 
 
1472
 
        menuitem = g_object_new (PANEL_TYPE_DESKTOP_MENU_ITEM, NULL);
1473
 
 
1474
 
        if (use_image)
1475
 
                image = gtk_image_new_from_icon_name ("computer",
1476
 
                                                      panel_menu_icon_get_size ());
1477
 
        else
1478
 
                image = NULL;
1479
 
 
1480
 
        setup_menuitem (GTK_WIDGET (menuitem),
1481
 
                        image ? panel_menu_icon_get_size () : GTK_ICON_SIZE_INVALID,
1482
 
                        image,
1483
 
                        _("System"));
1484
 
 
1485
 
        menuitem->priv->use_image = use_image;
1486
 
 
1487
 
        menuitem->priv->append_lock_logout = append_lock_logout;
1488
 
        if (append_lock_logout)
1489
 
                panel_lockdown_notify_add (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
1490
 
                                           menuitem);
1491
 
 
1492
 
        menuitem->priv->menu = panel_desktop_menu_item_create_menu (menuitem);
1493
 
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
1494
 
                                   menuitem->priv->menu);
1495
 
 
1496
 
        return GTK_WIDGET (menuitem);
1497
 
}
1498
 
 
1499
 
void
1500
 
panel_place_menu_item_set_panel (GtkWidget   *item,
1501
 
                                 PanelWidget *panel)
1502
 
{
1503
 
        PanelPlaceMenuItem *place_item;
1504
 
 
1505
 
        place_item = PANEL_PLACE_MENU_ITEM (item);
1506
 
 
1507
 
        place_item->priv->panel = panel;
1508
 
        panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
1509
 
                                       "menu_panel", panel);
1510
 
}
1511
 
 
1512
 
void
1513
 
panel_desktop_menu_item_set_panel (GtkWidget   *item,
1514
 
                                   PanelWidget *panel)
1515
 
{
1516
 
        PanelDesktopMenuItem *desktop_item;
1517
 
 
1518
 
        desktop_item = PANEL_DESKTOP_MENU_ITEM (item);
1519
 
 
1520
 
        desktop_item->priv->panel = panel;
1521
 
        panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
1522
 
                                       "menu_panel", panel);
1523
 
}
1524
 
 
1525
 
void
1526
 
panel_menu_items_append_lock_logout (GtkWidget *menu)
1527
 
{
1528
 
        gboolean    separator_inserted;
1529
 
        GList      *children;
1530
 
        GList      *last;
1531
 
        GtkWidget  *item;
1532
 
        const char *translate;
1533
 
        char       *label;
1534
 
        char       *tooltip;
1535
 
 
1536
 
        separator_inserted = FALSE;
1537
 
        children = gtk_container_get_children (GTK_CONTAINER (menu));
1538
 
        last = g_list_last (children);
1539
 
        if (last != NULL) {
1540
 
                separator_inserted = GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
1541
 
        }
1542
 
        g_list_free (children);
1543
 
 
1544
 
        if (panel_lock_screen_action_available ("lock")) {
1545
 
                item = panel_menu_items_create_action_item (PANEL_ACTION_LOCK);
1546
 
                if (item != NULL) {
1547
 
                        if (!separator_inserted) {
1548
 
                                add_menu_separator (menu);
1549
 
                                separator_inserted = TRUE;
1550
 
                        }
1551
 
 
1552
 
                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1553
 
                }
1554
 
        }
1555
 
 
1556
 
        if (panel_lockdown_get_disable_log_out ())
1557
 
                return;
1558
 
        /* Below this, we only have log out/shutdown items */
1559
 
 
1560
 
        /* Translators: translate "1" (msgctxt: "panel:showusername") to anything
1561
 
         * but "1" if "Log Out %s" doesn't make any sense in your
1562
 
         * language (where %s is a username).
1563
 
         */
1564
 
        translate = C_("panel:showusername", "1");
1565
 
        if (strcmp (translate, "1") == 0) {
1566
 
                const char *user_name;
1567
 
 
1568
 
                user_name = g_get_real_name ();
1569
 
                if (!user_name || !user_name [0])
1570
 
                        user_name = g_get_user_name ();
1571
 
 
1572
 
                /* keep those strings in sync with the ones in
1573
 
                 * panel-action-button.c */
1574
 
                /* Translators: this string is used ONLY if you translated
1575
 
                 * "1" (msgctxt: "panel:showusername") to "1" */
1576
 
                label = g_strdup_printf (_("Log Out %s..."),
1577
 
                                         g_get_user_name ());
1578
 
                /* Translators: this string is used ONLY if you translated
1579
 
                 * "1" (msgctxt: "panel:showusername") to "1" */
1580
 
                tooltip = g_strdup_printf (_("Log out %s of this session to "
1581
 
                                             "log in as a different user"),
1582
 
                                           user_name);
1583
 
        } else {
1584
 
                label   = NULL;
1585
 
                tooltip = NULL;
1586
 
        }
1587
 
 
1588
 
        item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
1589
 
                                                         label, tooltip);
1590
 
        g_free (label);
1591
 
        g_free (tooltip);
1592
 
 
1593
 
        if (item != NULL) {
1594
 
                if (!separator_inserted) {
1595
 
                        add_menu_separator (menu);
1596
 
                        separator_inserted = TRUE;
1597
 
                }
1598
 
 
1599
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1600
 
        }
1601
 
 
1602
 
        item = panel_menu_items_create_action_item (PANEL_ACTION_SHUTDOWN);
1603
 
        if (item != NULL) {
1604
 
                if (!separator_inserted)
1605
 
                        add_menu_separator (menu);
1606
 
 
1607
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1608
 
        }
1609
 
}
1610
 
 
1611
 
void
1612
 
panel_menu_item_activate_desktop_file (GtkWidget  *menuitem,
1613
 
                                       const char *path)
1614
 
{
1615
 
        panel_launch_desktop_file (path, menuitem_to_screen (menuitem), NULL);
1616
 
}