1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License as
8
* published by the Free Software Foundation; either version 2 of the
9
* License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this library; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
* Authors : Mr Jamie McCracken (jamiemcc at blueyonder dot co dot uk)
21
* Cosimo Cecchi <cosimoc@gnome.org>
27
#include <gdk/gdkkeysyms.h>
30
#include <glib/gi18n.h>
32
#include <gio/gdesktopappinfo.h>
34
#include <libnautilus-private/nautilus-dnd.h>
35
#include <libnautilus-private/nautilus-bookmark.h>
36
#include <libnautilus-private/nautilus-global-preferences.h>
37
#include <libnautilus-private/nautilus-file.h>
38
#include <libnautilus-private/nautilus-file-utilities.h>
39
#include <libnautilus-private/nautilus-file-operations.h>
40
#include <libnautilus-private/nautilus-trash-monitor.h>
41
#include <libnautilus-private/nautilus-icon-names.h>
43
#include <eel/eel-debug.h>
44
#include <eel/eel-gtk-extensions.h>
45
#include <eel/eel-glib-extensions.h>
46
#include <eel/eel-graphic-effects.h>
47
#include <eel/eel-string.h>
48
#include <eel/eel-stock-dialogs.h>
50
#include "nautilus-application.h"
51
#include "nautilus-bookmark-list.h"
52
#include "nautilus-places-sidebar.h"
53
#include "nautilus-properties-window.h"
54
#include "nautilus-window.h"
55
#include "nautilus-window-slot.h"
57
#define DEBUG_FLAG NAUTILUS_DEBUG_PLACES
58
#include <libnautilus-private/nautilus-debug.h>
60
#define EJECT_BUTTON_XPAD 6
61
#define ICON_CELL_XPAD 6
64
GtkScrolledWindow parent;
65
GtkTreeView *tree_view;
66
GtkCellRenderer *eject_icon_cell_renderer;
69
NautilusWindow *window;
70
NautilusBookmarkList *bookmarks;
71
GVolumeMonitor *volume_monitor;
73
gboolean devices_header_added;
74
gboolean bookmarks_header_added;
78
gboolean drag_data_received;
80
gboolean drop_occured;
83
GtkWidget *popup_menu;
84
GtkWidget *popup_menu_open_in_new_tab_item;
85
GtkWidget *popup_menu_add_shortcut_item;
86
GtkWidget *popup_menu_remove_item;
87
GtkWidget *popup_menu_rename_item;
88
GtkWidget *popup_menu_separator_item;
89
GtkWidget *popup_menu_mount_item;
90
GtkWidget *popup_menu_unmount_item;
91
GtkWidget *popup_menu_eject_item;
92
GtkWidget *popup_menu_rescan_item;
93
GtkWidget *popup_menu_empty_trash_item;
94
GtkWidget *popup_menu_start_item;
95
GtkWidget *popup_menu_stop_item;
96
GtkWidget *popup_menu_properties_separator_item;
97
GtkWidget *popup_menu_properties_item;
98
GtkWidget *popup_menu_format_item;
100
/* volume mounting - delayed open process */
102
NautilusWindowSlot *go_to_after_mount_slot;
103
NautilusWindowOpenFlags go_to_after_mount_flags;
105
GDBusProxy *hostnamed_proxy;
106
GCancellable *hostnamed_cancellable;
109
guint bookmarks_changed_id;
110
guint switch_location_timer;
111
} NautilusPlacesSidebar;
114
GtkScrolledWindowClass parent;
115
} NautilusPlacesSidebarClass;
119
} NautilusPlacesSidebarProvider;
123
} NautilusPlacesSidebarProviderClass;
126
PLACES_SIDEBAR_COLUMN_ROW_TYPE,
127
PLACES_SIDEBAR_COLUMN_URI,
128
PLACES_SIDEBAR_COLUMN_DRIVE,
129
PLACES_SIDEBAR_COLUMN_VOLUME,
130
PLACES_SIDEBAR_COLUMN_MOUNT,
131
PLACES_SIDEBAR_COLUMN_NAME,
132
PLACES_SIDEBAR_COLUMN_GICON,
133
PLACES_SIDEBAR_COLUMN_INDEX,
134
PLACES_SIDEBAR_COLUMN_EJECT,
135
PLACES_SIDEBAR_COLUMN_NO_EJECT,
136
PLACES_SIDEBAR_COLUMN_BOOKMARK,
137
PLACES_SIDEBAR_COLUMN_TOOLTIP,
138
PLACES_SIDEBAR_COLUMN_SECTION_TYPE,
139
PLACES_SIDEBAR_COLUMN_HEADING_TEXT,
141
PLACES_SIDEBAR_COLUMN_COUNT
147
PLACES_MOUNTED_VOLUME,
150
PLACES_CONNECT_SERVER
160
static void open_selected_bookmark (NautilusPlacesSidebar *sidebar,
163
NautilusWindowOpenFlags flags);
164
static void nautilus_places_sidebar_style_set (GtkWidget *widget,
165
GtkStyle *previous_style);
166
static gboolean eject_or_unmount_bookmark (NautilusPlacesSidebar *sidebar,
168
static gboolean eject_or_unmount_selection (NautilusPlacesSidebar *sidebar);
169
static void check_unmount_and_eject (GMount *mount,
172
gboolean *show_unmount,
173
gboolean *show_eject);
175
static void bookmarks_check_popup_sensitivity (NautilusPlacesSidebar *sidebar);
177
/* Identifiers for target types */
183
/* Target types for dragging from the shortcuts list */
184
static const GtkTargetEntry nautilus_shortcuts_source_targets[] = {
185
{ "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW }
188
/* Target types for dropping into the shortcuts list */
189
static const GtkTargetEntry nautilus_shortcuts_drop_targets [] = {
190
{ "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW },
191
{ "text/uri-list", 0, TEXT_URI_LIST }
194
/* Drag and drop interface declarations */
198
NautilusPlacesSidebar *sidebar;
199
} NautilusShortcutsModel;
202
GtkListStoreClass parent_class;
203
} NautilusShortcutsModelClass;
205
GType _nautilus_shortcuts_model_get_type (void);
206
static void _nautilus_shortcuts_model_drag_source_init (GtkTreeDragSourceIface *iface);
207
G_DEFINE_TYPE_WITH_CODE (NautilusShortcutsModel, _nautilus_shortcuts_model, GTK_TYPE_LIST_STORE,
208
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
209
_nautilus_shortcuts_model_drag_source_init));
210
static GtkListStore *nautilus_shortcuts_model_new (NautilusPlacesSidebar *sidebar);
212
G_DEFINE_TYPE (NautilusPlacesSidebar, nautilus_places_sidebar, GTK_TYPE_SCROLLED_WINDOW);
215
add_heading (NautilusPlacesSidebar *sidebar,
216
SectionType section_type,
221
gtk_list_store_append (sidebar->store, &iter);
222
gtk_list_store_set (sidebar->store, &iter,
223
PLACES_SIDEBAR_COLUMN_ROW_TYPE, PLACES_HEADING,
224
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, section_type,
225
PLACES_SIDEBAR_COLUMN_HEADING_TEXT, title,
226
PLACES_SIDEBAR_COLUMN_EJECT, FALSE,
227
PLACES_SIDEBAR_COLUMN_NO_EJECT, TRUE,
234
check_heading_for_section (NautilusPlacesSidebar *sidebar,
235
SectionType section_type)
237
switch (section_type) {
238
case SECTION_DEVICES:
239
if (!sidebar->devices_header_added) {
240
add_heading (sidebar, SECTION_DEVICES,
242
sidebar->devices_header_added = TRUE;
246
case SECTION_BOOKMARKS:
247
if (!sidebar->bookmarks_header_added) {
248
add_heading (sidebar, SECTION_BOOKMARKS,
250
sidebar->bookmarks_header_added = TRUE;
260
add_place (NautilusPlacesSidebar *sidebar,
261
PlaceType place_type,
262
SectionType section_type,
273
gboolean show_eject, show_unmount;
274
gboolean show_eject_button;
276
check_heading_for_section (sidebar, section_type);
278
check_unmount_and_eject (mount, volume, drive,
279
&show_unmount, &show_eject);
281
if (show_unmount || show_eject) {
282
g_assert (place_type != PLACES_BOOKMARK);
286
show_eject_button = FALSE;
288
show_eject_button = (show_unmount || show_eject);
291
gtk_list_store_append (sidebar->store, &iter);
292
gtk_list_store_set (sidebar->store, &iter,
293
PLACES_SIDEBAR_COLUMN_GICON, icon,
294
PLACES_SIDEBAR_COLUMN_NAME, name,
295
PLACES_SIDEBAR_COLUMN_URI, uri,
296
PLACES_SIDEBAR_COLUMN_DRIVE, drive,
297
PLACES_SIDEBAR_COLUMN_VOLUME, volume,
298
PLACES_SIDEBAR_COLUMN_MOUNT, mount,
299
PLACES_SIDEBAR_COLUMN_ROW_TYPE, place_type,
300
PLACES_SIDEBAR_COLUMN_INDEX, index,
301
PLACES_SIDEBAR_COLUMN_EJECT, show_eject_button,
302
PLACES_SIDEBAR_COLUMN_NO_EJECT, !show_eject_button,
303
PLACES_SIDEBAR_COLUMN_BOOKMARK, place_type != PLACES_BOOKMARK,
304
PLACES_SIDEBAR_COLUMN_TOOLTIP, tooltip,
305
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, section_type,
310
const gchar *location;
311
const gchar *last_uri;
312
NautilusPlacesSidebar *sidebar;
314
} RestoreLocationData;
317
restore_selection_foreach (GtkTreeModel *model,
322
RestoreLocationData *data = user_data;
325
gtk_tree_model_get (model, iter,
326
PLACES_SIDEBAR_COLUMN_URI, &uri,
329
if (g_strcmp0 (uri, data->last_uri) == 0 ||
330
g_strcmp0 (uri, data->location) == 0) {
331
data->path = gtk_tree_path_copy (path);
336
return (data->path != NULL);
340
sidebar_update_restore_selection (NautilusPlacesSidebar *sidebar,
341
const gchar *location,
342
const gchar *last_uri)
344
RestoreLocationData data;
345
GtkTreeSelection *selection;
347
data.location = location;
348
data.last_uri = last_uri;
349
data.sidebar = sidebar;
352
gtk_tree_model_foreach (GTK_TREE_MODEL (sidebar->store),
353
restore_selection_foreach, &data);
355
if (data.path != NULL) {
356
selection = gtk_tree_view_get_selection (sidebar->tree_view);
357
gtk_tree_selection_select_path (selection, data.path);
358
gtk_tree_path_free (data.path);
363
recent_is_supported (void)
365
const char * const *supported;
369
enabled = g_settings_get_boolean (gnome_privacy_preferences,
370
NAUTILUS_PREFERENCES_RECENT_FILES_ENABLED);
376
supported = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
381
for (i = 0; supported[i] != NULL; i++) {
382
if (strcmp ("recent", supported[i]) == 0) {
390
add_special_dirs (NautilusPlacesSidebar *sidebar)
396
for (index = 0; index < G_USER_N_DIRECTORIES; index++) {
402
NautilusBookmark *bookmark;
405
if (index == G_USER_DIRECTORY_DESKTOP ||
406
index == G_USER_DIRECTORY_TEMPLATES ||
407
index == G_USER_DIRECTORY_PUBLIC_SHARE) {
411
path = g_get_user_special_dir (index);
413
/* xdg resets special dirs to the home directory in case
414
* it's not finiding what it expects. We don't want the home
415
* to be added multiple times in that weird configuration.
418
|| g_strcmp0 (path, g_get_home_dir ()) == 0
419
|| g_list_find_custom (dirs, path, (GCompareFunc) g_strcmp0) != NULL) {
423
root = g_file_new_for_path (path);
425
/* Don't add the bookmark to the sidebar if it was removed from
426
* the user dir list, or if its location doesn't exist.
428
bookmark = nautilus_bookmark_list_item_with_location (sidebar->bookmarks, root, &idx);
429
if (bookmark && !nautilus_bookmark_get_exists (bookmark)) {
430
g_object_unref (root);
435
name = g_strdup (nautilus_bookmark_get_name (bookmark));
436
icon = nautilus_bookmark_get_symbolic_icon (bookmark);
438
name = g_file_get_basename (root);
439
icon = nautilus_special_directory_get_symbolic_icon (index);
443
mount_uri = g_file_get_uri (root);
445
add_place (sidebar, PLACES_XDG_DIR,
447
name, icon, mount_uri,
448
NULL, NULL, NULL, idx,
451
g_object_unref (root);
452
g_object_unref (icon);
456
dirs = g_list_prepend (dirs, (char *)path);
463
update_places (NautilusPlacesSidebar *sidebar)
465
NautilusBookmark *bookmark;
466
GtkTreeSelection *selection;
467
GtkTreeIter last_iter;
469
GVolumeMonitor *volume_monitor;
470
GList *mounts, *l, *ll;
476
int bookmark_count, index;
477
char *location, *mount_uri, *name, *last_uri, *identifier;
478
const gchar *bookmark_name;
481
NautilusWindowSlot *slot;
483
GList *network_mounts, *network_volumes;
485
DEBUG ("Updating places sidebar");
490
selection = gtk_tree_view_get_selection (sidebar->tree_view);
491
if (gtk_tree_selection_get_selected (selection, &model, &last_iter)) {
492
gtk_tree_model_get (model,
494
PLACES_SIDEBAR_COLUMN_URI, &last_uri, -1);
496
gtk_list_store_clear (sidebar->store);
498
sidebar->devices_header_added = FALSE;
499
sidebar->bookmarks_header_added = FALSE;
501
slot = nautilus_window_get_active_slot (sidebar->window);
502
location = nautilus_window_slot_get_current_uri (slot);
504
network_mounts = network_volumes = NULL;
505
volume_monitor = sidebar->volume_monitor;
507
/* add built in bookmarks */
509
add_heading (sidebar, SECTION_COMPUTER,
512
if (recent_is_supported ()) {
513
mount_uri = "recent:///"; /* No need to strdup */
514
icon = g_themed_icon_new ("document-open-recent-symbolic");
515
add_place (sidebar, PLACES_BUILT_IN,
517
_("Recent"), icon, mount_uri,
520
g_object_unref (icon);
524
mount_uri = nautilus_get_home_directory_uri ();
525
icon = g_themed_icon_new (NAUTILUS_ICON_HOME);
526
add_place (sidebar, PLACES_BUILT_IN,
528
_("Home"), icon, mount_uri,
530
_("Open your personal folder"));
531
g_object_unref (icon);
534
if (g_settings_get_boolean (gnome_background_preferences, NAUTILUS_PREFERENCES_SHOW_DESKTOP)) {
536
mount_uri = nautilus_get_desktop_directory_uri ();
537
icon = g_themed_icon_new (NAUTILUS_ICON_FOLDER);
538
add_place (sidebar, PLACES_BUILT_IN,
540
_("Desktop"), icon, mount_uri,
542
_("Open the contents of your desktop in a folder"));
543
g_object_unref (icon);
547
/* XDG directories */
548
add_special_dirs (sidebar);
550
mount_uri = "trash:///"; /* No need to strdup */
551
icon = nautilus_trash_monitor_get_icon ();
552
add_place (sidebar, PLACES_BUILT_IN,
554
_("Trash"), icon, mount_uri,
556
_("Open the trash"));
557
g_object_unref (icon);
559
/* go through all connected drives */
560
drives = g_volume_monitor_get_connected_drives (volume_monitor);
562
for (l = drives; l != NULL; l = l->next) {
565
volumes = g_drive_get_volumes (drive);
566
if (volumes != NULL) {
567
for (ll = volumes; ll != NULL; ll = ll->next) {
569
identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS);
571
if (g_strcmp0 (identifier, "network") == 0) {
573
network_volumes = g_list_prepend (network_volumes, volume);
578
mount = g_volume_get_mount (volume);
580
/* Show mounted volume in the sidebar */
581
icon = g_mount_get_symbolic_icon (mount);
582
root = g_mount_get_default_location (mount);
583
mount_uri = g_file_get_uri (root);
584
name = g_mount_get_name (mount);
585
tooltip = g_file_get_parse_name (root);
587
add_place (sidebar, PLACES_MOUNTED_VOLUME,
589
name, icon, mount_uri,
590
drive, volume, mount, 0, tooltip);
591
g_object_unref (root);
592
g_object_unref (mount);
593
g_object_unref (icon);
598
/* Do show the unmounted volumes in the sidebar;
599
* this is so the user can mount it (in case automounting
602
* Also, even if automounting is enabled, this gives a visual
603
* cue that the user should remember to yank out the media if
604
* he just unmounted it.
606
icon = g_volume_get_symbolic_icon (volume);
607
name = g_volume_get_name (volume);
608
tooltip = g_strdup_printf (_("Mount and open %s"), name);
610
add_place (sidebar, PLACES_MOUNTED_VOLUME,
613
drive, volume, NULL, 0, tooltip);
614
g_object_unref (icon);
618
g_object_unref (volume);
620
g_list_free (volumes);
622
if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive)) {
623
/* If the drive has no mountable volumes and we cannot detect media change.. we
624
* display the drive in the sidebar so the user can manually poll the drive by
625
* right clicking and selecting "Rescan..."
627
* This is mainly for drives like floppies where media detection doesn't
628
* work.. but it's also for human beings who like to turn off media detection
629
* in the OS to save battery juice.
631
icon = g_drive_get_symbolic_icon (drive);
632
name = g_drive_get_name (drive);
633
tooltip = g_strdup_printf (_("Mount and open %s"), name);
635
add_place (sidebar, PLACES_BUILT_IN,
638
drive, NULL, NULL, 0, tooltip);
639
g_object_unref (icon);
644
g_object_unref (drive);
646
g_list_free (drives);
648
/* add all volumes that is not associated with a drive */
649
volumes = g_volume_monitor_get_volumes (volume_monitor);
650
for (l = volumes; l != NULL; l = l->next) {
652
drive = g_volume_get_drive (volume);
654
g_object_unref (volume);
655
g_object_unref (drive);
659
identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS);
661
if (g_strcmp0 (identifier, "network") == 0) {
663
network_volumes = g_list_prepend (network_volumes, volume);
668
mount = g_volume_get_mount (volume);
670
icon = g_mount_get_symbolic_icon (mount);
671
root = g_mount_get_default_location (mount);
672
mount_uri = g_file_get_uri (root);
673
tooltip = g_file_get_parse_name (root);
674
g_object_unref (root);
675
name = g_mount_get_name (mount);
676
add_place (sidebar, PLACES_MOUNTED_VOLUME,
678
name, icon, mount_uri,
679
NULL, volume, mount, 0, tooltip);
680
g_object_unref (mount);
681
g_object_unref (icon);
686
/* see comment above in why we add an icon for an unmounted mountable volume */
687
icon = g_volume_get_symbolic_icon (volume);
688
name = g_volume_get_name (volume);
689
add_place (sidebar, PLACES_MOUNTED_VOLUME,
692
NULL, volume, NULL, 0, name);
693
g_object_unref (icon);
696
g_object_unref (volume);
698
g_list_free (volumes);
700
/* file system root */
702
mount_uri = "file:///"; /* No need to strdup */
703
icon = g_themed_icon_new (NAUTILUS_ICON_FILESYSTEM);
704
add_place (sidebar, PLACES_BUILT_IN,
706
sidebar->hostname, icon, mount_uri,
708
_("Open the contents of the File System"));
709
g_object_unref (icon);
711
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
712
mounts = g_volume_monitor_get_mounts (volume_monitor);
714
for (l = mounts; l != NULL; l = l->next) {
716
if (g_mount_is_shadowed (mount)) {
717
g_object_unref (mount);
720
volume = g_mount_get_volume (mount);
721
if (volume != NULL) {
722
g_object_unref (volume);
723
g_object_unref (mount);
726
root = g_mount_get_default_location (mount);
728
if (!g_file_is_native (root)) {
729
network_mounts = g_list_prepend (network_mounts, mount);
730
g_object_unref (root);
734
icon = g_mount_get_symbolic_icon (mount);
735
mount_uri = g_file_get_uri (root);
736
name = g_mount_get_name (mount);
737
tooltip = g_file_get_parse_name (root);
738
add_place (sidebar, PLACES_MOUNTED_VOLUME,
740
name, icon, mount_uri,
741
NULL, NULL, mount, 0, tooltip);
742
g_object_unref (root);
743
g_object_unref (mount);
744
g_object_unref (icon);
749
g_list_free (mounts);
752
bookmark_count = nautilus_bookmark_list_length (sidebar->bookmarks);
754
for (index = 0; index < bookmark_count; ++index) {
755
bookmark = nautilus_bookmark_list_item_at (sidebar->bookmarks, index);
756
root = nautilus_bookmark_get_location (bookmark);
758
if (!nautilus_bookmark_get_exists (bookmark) && g_file_is_native (root)) {
759
g_object_unref (root);
763
if (nautilus_bookmark_get_is_builtin (bookmark)) {
764
g_object_unref (root);
768
bookmark_name = nautilus_bookmark_get_name (bookmark);
769
icon = nautilus_bookmark_get_symbolic_icon (bookmark);
770
mount_uri = nautilus_bookmark_get_uri (bookmark);
771
tooltip = g_file_get_parse_name (root);
773
add_place (sidebar, PLACES_BOOKMARK,
775
bookmark_name, icon, mount_uri,
776
NULL, NULL, NULL, index,
778
g_object_unref (root);
779
g_object_unref (icon);
785
add_heading (sidebar, SECTION_NETWORK,
788
mount_uri = "network:///"; /* No need to strdup */
789
icon = g_themed_icon_new (NAUTILUS_ICON_NETWORK);
790
add_place (sidebar, PLACES_BUILT_IN,
792
_("Browse Network"), icon, mount_uri,
794
_("Browse the contents of the network"));
795
g_object_unref (icon);
797
icon = g_themed_icon_new (NAUTILUS_ICON_NETWORK_SERVER);
798
add_place (sidebar, PLACES_CONNECT_SERVER,
800
_("Connect to Server"), icon, NULL,
802
_("Connect to a network server address"));
803
g_object_unref (icon);
805
network_volumes = g_list_reverse (network_volumes);
806
for (l = network_volumes; l != NULL; l = l->next) {
808
mount = g_volume_get_mount (volume);
811
network_mounts = g_list_prepend (network_mounts, mount);
814
icon = g_volume_get_symbolic_icon (volume);
815
name = g_volume_get_name (volume);
816
tooltip = g_strdup_printf (_("Mount and open %s"), name);
818
add_place (sidebar, PLACES_MOUNTED_VOLUME,
821
NULL, volume, NULL, 0, tooltip);
822
g_object_unref (icon);
828
g_list_free_full (network_volumes, g_object_unref);
830
network_mounts = g_list_reverse (network_mounts);
831
for (l = network_mounts; l != NULL; l = l->next) {
833
root = g_mount_get_default_location (mount);
834
icon = g_mount_get_symbolic_icon (mount);
835
mount_uri = g_file_get_uri (root);
836
name = g_mount_get_name (mount);
837
tooltip = g_file_get_parse_name (root);
838
add_place (sidebar, PLACES_MOUNTED_VOLUME,
840
name, icon, mount_uri,
841
NULL, NULL, mount, 0, tooltip);
842
g_object_unref (root);
843
g_object_unref (icon);
849
g_list_free_full (network_mounts, g_object_unref);
851
/* restore selection */
852
sidebar_update_restore_selection (sidebar, location, last_uri);
859
mount_added_callback (GVolumeMonitor *volume_monitor,
861
NautilusPlacesSidebar *sidebar)
863
update_places (sidebar);
867
mount_removed_callback (GVolumeMonitor *volume_monitor,
869
NautilusPlacesSidebar *sidebar)
871
update_places (sidebar);
875
mount_changed_callback (GVolumeMonitor *volume_monitor,
877
NautilusPlacesSidebar *sidebar)
879
update_places (sidebar);
883
volume_added_callback (GVolumeMonitor *volume_monitor,
885
NautilusPlacesSidebar *sidebar)
887
update_places (sidebar);
891
volume_removed_callback (GVolumeMonitor *volume_monitor,
893
NautilusPlacesSidebar *sidebar)
895
update_places (sidebar);
899
volume_changed_callback (GVolumeMonitor *volume_monitor,
901
NautilusPlacesSidebar *sidebar)
903
update_places (sidebar);
907
drive_disconnected_callback (GVolumeMonitor *volume_monitor,
909
NautilusPlacesSidebar *sidebar)
911
update_places (sidebar);
915
drive_connected_callback (GVolumeMonitor *volume_monitor,
917
NautilusPlacesSidebar *sidebar)
919
update_places (sidebar);
923
drive_changed_callback (GVolumeMonitor *volume_monitor,
925
NautilusPlacesSidebar *sidebar)
927
update_places (sidebar);
931
over_eject_button (NautilusPlacesSidebar *sidebar,
936
GtkTreeViewColumn *column;
937
int width, x_offset, hseparator;
938
int eject_button_size;
944
model = gtk_tree_view_get_model (sidebar->tree_view);
946
if (gtk_tree_view_get_path_at_pos (sidebar->tree_view,
948
path, &column, NULL, NULL)) {
950
gtk_tree_model_get_iter (model, &iter, *path);
951
gtk_tree_model_get (model, &iter,
952
PLACES_SIDEBAR_COLUMN_EJECT, &show_eject,
960
gtk_widget_style_get (GTK_WIDGET (sidebar->tree_view),
961
"horizontal-separator", &hseparator,
964
/* Reload cell attributes for this particular row */
965
gtk_tree_view_column_cell_set_cell_data (column,
966
model, &iter, FALSE, FALSE);
968
gtk_tree_view_column_cell_get_position (column,
969
sidebar->eject_icon_cell_renderer,
972
eject_button_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
974
/* This is kinda weird, but we have to do it to workaround gtk+ expanding
975
* the eject cell renderer (even thought we told it not to) and we then
976
* had to set it right-aligned */
977
x_offset += width - hseparator - EJECT_BUTTON_XPAD - eject_button_size;
979
if (x - x_offset >= 0 &&
980
x - x_offset <= eject_button_size) {
987
gtk_tree_path_free (*path);
995
clicked_eject_button (NautilusPlacesSidebar *sidebar,
998
GdkEvent *event = gtk_get_current_event ();
999
GdkEventButton *button_event = (GdkEventButton *) event;
1001
if ((event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) &&
1002
over_eject_button (sidebar, button_event->x, button_event->y, path)) {
1010
update_current_uri (NautilusPlacesSidebar *sidebar)
1012
GtkTreeSelection *selection;
1017
if (sidebar->uri == NULL) {
1021
/* set selection if any place matches location */
1022
selection = gtk_tree_view_get_selection (sidebar->tree_view);
1023
gtk_tree_selection_unselect_all (selection);
1024
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (sidebar->store),
1028
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
1029
PLACES_SIDEBAR_COLUMN_URI, &uri,
1033
if (strcmp (uri, sidebar->uri) == 0) {
1035
gtk_tree_selection_select_iter (selection, &iter);
1040
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (sidebar->store),
1046
loading_uri_callback (NautilusWindow *window,
1048
NautilusPlacesSidebar *sidebar)
1050
if (g_strcmp0 (sidebar->uri, location) != 0) {
1051
g_free (sidebar->uri);
1052
sidebar->uri = g_strdup (location);
1054
update_current_uri (sidebar);
1058
/* Computes the appropriate row and position for dropping */
1060
compute_drop_position (GtkTreeView *tree_view,
1064
GtkTreeViewDropPosition *pos,
1065
NautilusPlacesSidebar *sidebar)
1067
GtkTreeModel *model;
1069
PlaceType place_type;
1070
SectionType section_type;
1072
if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
1078
model = gtk_tree_view_get_model (tree_view);
1080
gtk_tree_model_get_iter (model, &iter, *path);
1081
gtk_tree_model_get (model, &iter,
1082
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
1083
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, §ion_type,
1086
if (section_type != SECTION_BOOKMARKS &&
1087
place_type == PLACES_HEADING) {
1088
/* never drop on headings, but special case the bookmarks heading,
1089
* so we can drop bookmarks in between it and the first item when
1092
gtk_tree_path_free (*path);
1098
if (section_type != SECTION_BOOKMARKS &&
1099
sidebar->drag_data_received &&
1100
sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
1101
/* don't allow dropping bookmarks into non-bookmark areas */
1102
gtk_tree_path_free (*path);
1108
if (sidebar->drag_data_received &&
1109
sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
1110
/* bookmark rows can only be reordered */
1111
*pos = GTK_TREE_VIEW_DROP_AFTER;
1113
*pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
1120
get_drag_data (GtkTreeView *tree_view,
1121
GdkDragContext *context,
1126
target = gtk_drag_dest_find_target (GTK_WIDGET (tree_view),
1130
if (target == GDK_NONE) {
1134
gtk_drag_get_data (GTK_WIDGET (tree_view),
1135
context, target, time);
1141
remove_switch_location_timer (NautilusPlacesSidebar *sidebar)
1143
if (sidebar->switch_location_timer != 0) {
1144
g_source_remove (sidebar->switch_location_timer);
1145
sidebar->switch_location_timer = 0;
1150
free_drag_data (NautilusPlacesSidebar *sidebar)
1152
sidebar->drag_data_received = FALSE;
1154
if (sidebar->drag_list) {
1155
nautilus_drag_destroy_selection_list (sidebar->drag_list);
1156
sidebar->drag_list = NULL;
1159
remove_switch_location_timer (sidebar);
1161
g_free (sidebar->target_uri);
1162
sidebar->target_uri = NULL;
1166
switch_location_timer (gpointer user_data)
1168
NautilusPlacesSidebar *sidebar = user_data;
1170
NautilusWindowSlot *target_slot;
1172
sidebar->switch_location_timer = 0;
1174
target_slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (sidebar->window));
1176
location = g_file_new_for_uri (sidebar->target_uri);
1177
nautilus_window_slot_open_location (target_slot, location, 0);
1178
g_object_unref (location);
1184
check_switch_location_timer (NautilusPlacesSidebar *sidebar,
1187
GtkSettings *settings;
1190
if (g_strcmp0 (uri, sidebar->target_uri) == 0) {
1193
remove_switch_location_timer (sidebar);
1195
settings = gtk_widget_get_settings (GTK_WIDGET (sidebar));
1196
g_object_get (settings, "gtk-timeout-expand", &timeout, NULL);
1198
g_free (sidebar->target_uri);
1199
sidebar->target_uri = NULL;
1202
sidebar->target_uri = g_strdup (uri);
1203
sidebar->switch_location_timer =
1204
gdk_threads_add_timeout (timeout,
1205
switch_location_timer,
1211
drag_motion_callback (GtkTreeView *tree_view,
1212
GdkDragContext *context,
1216
NautilusPlacesSidebar *sidebar)
1219
GtkTreeViewDropPosition pos;
1222
char *target_uri = NULL;
1225
if (!sidebar->drag_data_received) {
1226
if (!get_drag_data (tree_view, context, time)) {
1232
res = compute_drop_position (tree_view, x, y, &path, &pos, sidebar);
1238
if (pos == GTK_TREE_VIEW_DROP_AFTER ) {
1239
if (sidebar->drag_data_received &&
1240
sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
1241
action = GDK_ACTION_MOVE;
1246
if (sidebar->drag_list == NULL) {
1249
gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store),
1251
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store),
1253
PLACES_SIDEBAR_COLUMN_URI, &target_uri,
1255
nautilus_drag_default_drop_action_for_icons (context, target_uri,
1262
gtk_tree_view_set_drag_dest_row (tree_view, path, pos);
1266
gtk_tree_path_free (path);
1270
g_signal_stop_emission_by_name (tree_view, "drag-motion");
1273
check_switch_location_timer (sidebar, target_uri);
1274
gdk_drag_status (context, action, time);
1276
remove_switch_location_timer (sidebar);
1277
gdk_drag_status (context, 0, time);
1280
g_free (target_uri);
1286
drag_leave_callback (GtkTreeView *tree_view,
1287
GdkDragContext *context,
1289
NautilusPlacesSidebar *sidebar)
1291
free_drag_data (sidebar);
1292
gtk_tree_view_set_drag_dest_row (tree_view, NULL, 0);
1293
g_signal_stop_emission_by_name (tree_view, "drag-leave");
1297
uri_list_from_selection (GList *selection)
1299
NautilusDragSelectionItem *item;
1304
for (l = selection; l != NULL; l = l->next) {
1306
ret = g_list_prepend (ret, item->uri);
1309
return g_list_reverse (ret);
1313
build_selection_list (const char *data)
1315
NautilusDragSelectionItem *item;
1321
uris = g_uri_list_extract_uris (data);
1323
for (i = 0; uris[i]; i++) {
1325
item = nautilus_drag_selection_item_new ();
1326
item->uri = g_strdup (uri);
1327
item->file = nautilus_file_get_existing_by_uri (uri);
1328
item->got_icon_position = FALSE;
1329
result = g_list_prepend (result, item);
1334
return g_list_reverse (result);
1338
get_selected_iter (NautilusPlacesSidebar *sidebar,
1341
GtkTreeSelection *selection;
1343
selection = gtk_tree_view_get_selection (sidebar->tree_view);
1345
return gtk_tree_selection_get_selected (selection, NULL, iter);
1348
/* Reorders the selected bookmark to the specified position */
1350
reorder_bookmarks (NautilusPlacesSidebar *sidebar,
1357
/* Get the selected path */
1358
if (!get_selected_iter (sidebar, &iter)) {
1362
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
1363
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
1364
PLACES_SIDEBAR_COLUMN_INDEX, &old_position,
1367
if (type != PLACES_BOOKMARK ||
1369
old_position >= nautilus_bookmark_list_length (sidebar->bookmarks)) {
1373
nautilus_bookmark_list_move_item (sidebar->bookmarks, old_position,
1378
drag_data_received_callback (GtkWidget *widget,
1379
GdkDragContext *context,
1382
GtkSelectionData *selection_data,
1385
NautilusPlacesSidebar *sidebar)
1387
GtkTreeView *tree_view;
1388
GtkTreePath *tree_path;
1389
GtkTreeViewDropPosition tree_pos;
1392
GtkTreeModel *model;
1394
GList *selection_list, *uris;
1395
PlaceType place_type;
1396
SectionType section_type;
1399
tree_view = GTK_TREE_VIEW (widget);
1401
if (!sidebar->drag_data_received) {
1402
if (gtk_selection_data_get_target (selection_data) != GDK_NONE &&
1403
info == TEXT_URI_LIST) {
1404
sidebar->drag_list = build_selection_list ((const gchar *) gtk_selection_data_get_data (selection_data));
1406
sidebar->drag_list = NULL;
1408
sidebar->drag_data_received = TRUE;
1409
sidebar->drag_data_info = info;
1412
g_signal_stop_emission_by_name (widget, "drag-data-received");
1414
if (!sidebar->drop_occured) {
1418
/* Compute position */
1419
success = compute_drop_position (tree_view, x, y, &tree_path, &tree_pos, sidebar);
1426
if (tree_pos == GTK_TREE_VIEW_DROP_AFTER) {
1427
model = gtk_tree_view_get_model (tree_view);
1429
if (!gtk_tree_model_get_iter (model, &iter, tree_path)) {
1433
gtk_tree_model_get (model, &iter,
1434
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, §ion_type,
1435
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
1436
PLACES_SIDEBAR_COLUMN_INDEX, &position,
1439
if (section_type != SECTION_BOOKMARKS) {
1443
if (tree_pos == GTK_TREE_VIEW_DROP_AFTER && place_type != PLACES_HEADING) {
1444
/* heading already has position 0 */
1449
case GTK_TREE_MODEL_ROW:
1450
reorder_bookmarks (sidebar, position);
1454
g_assert_not_reached ();
1458
GdkDragAction real_action;
1460
/* file transfer requested */
1461
real_action = gdk_drag_context_get_selected_action (context);
1463
if (real_action == GDK_ACTION_ASK) {
1465
nautilus_drag_drop_action_ask (GTK_WIDGET (tree_view),
1466
gdk_drag_context_get_actions (context));
1469
if (real_action > 0) {
1470
model = gtk_tree_view_get_model (tree_view);
1472
gtk_tree_model_get_iter (model, &iter, tree_path);
1473
gtk_tree_model_get (model, &iter,
1474
PLACES_SIDEBAR_COLUMN_URI, &drop_uri,
1479
selection_list = build_selection_list ((const gchar *) gtk_selection_data_get_data (selection_data));
1480
g_assert (selection_list);
1481
uris = uri_list_from_selection (selection_list);
1483
nautilus_file_operations_copy_move (uris, NULL, drop_uri,
1484
real_action, GTK_WIDGET (tree_view),
1486
nautilus_drag_destroy_selection_list (selection_list);
1490
case GTK_TREE_MODEL_ROW:
1494
g_assert_not_reached ();
1503
sidebar->drop_occured = FALSE;
1504
free_drag_data (sidebar);
1505
gtk_drag_finish (context, success, FALSE, time);
1507
gtk_tree_path_free (tree_path);
1511
drag_drop_callback (GtkTreeView *tree_view,
1512
GdkDragContext *context,
1516
NautilusPlacesSidebar *sidebar)
1518
gboolean retval = FALSE;
1519
sidebar->drop_occured = TRUE;
1520
retval = get_drag_data (tree_view, context, time);
1521
g_signal_stop_emission_by_name (tree_view, "drag-drop");
1525
/* Callback used when the file list's popup menu is detached */
1527
bookmarks_popup_menu_detach_cb (GtkWidget *attach_widget,
1530
NautilusPlacesSidebar *sidebar;
1532
sidebar = NAUTILUS_PLACES_SIDEBAR (attach_widget);
1533
g_assert (NAUTILUS_IS_PLACES_SIDEBAR (sidebar));
1535
sidebar->popup_menu = NULL;
1536
sidebar->popup_menu_add_shortcut_item = NULL;
1537
sidebar->popup_menu_remove_item = NULL;
1538
sidebar->popup_menu_rename_item = NULL;
1539
sidebar->popup_menu_separator_item = NULL;
1540
sidebar->popup_menu_mount_item = NULL;
1541
sidebar->popup_menu_unmount_item = NULL;
1542
sidebar->popup_menu_eject_item = NULL;
1543
sidebar->popup_menu_rescan_item = NULL;
1544
sidebar->popup_menu_start_item = NULL;
1545
sidebar->popup_menu_stop_item = NULL;
1546
sidebar->popup_menu_empty_trash_item = NULL;
1547
sidebar->popup_menu_properties_separator_item = NULL;
1548
sidebar->popup_menu_properties_item = NULL;
1549
sidebar->popup_menu_format_item = NULL;
1553
check_have_gnome_disks (void)
1558
disks_path = g_find_program_in_path ("gnome-disks");
1559
res = (disks_path != NULL);
1560
g_free (disks_path);
1566
check_unmount_and_eject (GMount *mount,
1569
gboolean *show_unmount,
1570
gboolean *show_eject)
1572
*show_unmount = FALSE;
1573
*show_eject = FALSE;
1575
if (drive != NULL) {
1576
*show_eject = g_drive_can_eject (drive);
1579
if (volume != NULL) {
1580
*show_eject |= g_volume_can_eject (volume);
1582
if (mount != NULL) {
1583
*show_eject |= g_mount_can_eject (mount);
1584
*show_unmount = g_mount_can_unmount (mount) && !*show_eject;
1589
check_visibility (GMount *mount,
1592
gboolean *show_mount,
1593
gboolean *show_unmount,
1594
gboolean *show_eject,
1595
gboolean *show_rescan,
1596
gboolean *show_start,
1597
gboolean *show_stop,
1598
gboolean *show_format)
1600
gchar *unix_device_id;
1602
*show_mount = FALSE;
1603
*show_rescan = FALSE;
1604
*show_start = FALSE;
1606
*show_format = FALSE;
1608
check_unmount_and_eject (mount, volume, drive, show_unmount, show_eject);
1610
if (drive != NULL) {
1611
if (g_drive_is_media_removable (drive) &&
1612
!g_drive_is_media_check_automatic (drive) &&
1613
g_drive_can_poll_for_media (drive))
1614
*show_rescan = TRUE;
1616
*show_start = g_drive_can_start (drive) || g_drive_can_start_degraded (drive);
1617
*show_stop = g_drive_can_stop (drive);
1620
*show_unmount = FALSE;
1623
if (volume != NULL) {
1625
*show_mount = g_volume_can_mount (volume);
1627
unix_device_id = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
1628
*show_format = (unix_device_id != NULL) && check_have_gnome_disks ();
1629
g_free (unix_device_id);
1634
bookmarks_check_popup_sensitivity (NautilusPlacesSidebar *sidebar)
1638
GDrive *drive = NULL;
1639
GVolume *volume = NULL;
1640
GMount *mount = NULL;
1642
NautilusDirectory *directory;
1643
gboolean show_mount;
1644
gboolean show_unmount;
1645
gboolean show_eject;
1646
gboolean show_rescan;
1647
gboolean show_start;
1649
gboolean show_empty_trash;
1650
gboolean show_properties;
1651
gboolean show_format;
1654
type = PLACES_BUILT_IN;
1656
if (sidebar->popup_menu == NULL) {
1660
if (get_selected_iter (sidebar, &iter)) {
1661
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
1662
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
1663
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
1664
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
1665
PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
1666
PLACES_SIDEBAR_COLUMN_URI, &uri,
1670
gtk_widget_set_visible (sidebar->popup_menu_add_shortcut_item, (type == PLACES_MOUNTED_VOLUME));
1672
gtk_widget_set_sensitive (sidebar->popup_menu_remove_item, (type == PLACES_BOOKMARK));
1673
gtk_widget_set_sensitive (sidebar->popup_menu_rename_item, (type == PLACES_BOOKMARK || type == PLACES_XDG_DIR));
1674
gtk_widget_set_sensitive (sidebar->popup_menu_empty_trash_item, !nautilus_trash_monitor_is_empty ());
1676
check_visibility (mount, volume, drive,
1677
&show_mount, &show_unmount, &show_eject, &show_rescan, &show_start, &show_stop, &show_format);
1679
/* We actually want both eject and unmount since eject will unmount all volumes.
1680
* TODO: hide unmount if the drive only has a single mountable volume
1683
show_empty_trash = (uri != NULL) &&
1684
(!strcmp (uri, "trash:///"));
1686
/* Only show properties for local mounts */
1687
show_properties = (mount != NULL);
1688
if (mount != NULL) {
1689
location = g_mount_get_default_location (mount);
1690
directory = nautilus_directory_get (location);
1692
show_properties = nautilus_directory_is_local (directory);
1694
nautilus_directory_unref (directory);
1695
g_object_unref (location);
1698
gtk_widget_set_visible (sidebar->popup_menu_separator_item,
1699
show_mount || show_unmount || show_eject || show_empty_trash);
1700
gtk_widget_set_visible (sidebar->popup_menu_mount_item, show_mount);
1701
gtk_widget_set_visible (sidebar->popup_menu_unmount_item, show_unmount);
1702
gtk_widget_set_visible (sidebar->popup_menu_eject_item, show_eject);
1703
gtk_widget_set_visible (sidebar->popup_menu_rescan_item, show_rescan);
1704
gtk_widget_set_visible (sidebar->popup_menu_start_item, show_start);
1705
gtk_widget_set_visible (sidebar->popup_menu_stop_item, show_stop);
1706
gtk_widget_set_visible (sidebar->popup_menu_empty_trash_item, show_empty_trash);
1707
gtk_widget_set_visible (sidebar->popup_menu_properties_separator_item, show_properties);
1708
gtk_widget_set_visible (sidebar->popup_menu_properties_item, show_properties);
1709
gtk_widget_set_visible (sidebar->popup_menu_format_item, show_format);
1711
/* Adjust start/stop items to reflect the type of the drive */
1712
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_start_item), _("_Start"));
1713
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_stop_item), _("_Stop"));
1714
if ((show_start || show_stop) && drive != NULL) {
1715
switch (g_drive_get_start_stop_type (drive)) {
1716
case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
1717
/* start() for type G_DRIVE_START_STOP_TYPE_SHUTDOWN is normally not used */
1718
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_start_item), _("_Power On"));
1719
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_stop_item), _("_Safely Remove Drive"));
1721
case G_DRIVE_START_STOP_TYPE_NETWORK:
1722
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_start_item), _("_Connect Drive"));
1723
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_stop_item), _("_Disconnect Drive"));
1725
case G_DRIVE_START_STOP_TYPE_MULTIDISK:
1726
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_start_item), _("_Start Multi-disk Device"));
1727
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_stop_item), _("_Stop Multi-disk Device"));
1729
case G_DRIVE_START_STOP_TYPE_PASSWORD:
1730
/* stop() for type G_DRIVE_START_STOP_TYPE_PASSWORD is normally not used */
1731
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_start_item), _("_Unlock Drive"));
1732
gtk_menu_item_set_label (GTK_MENU_ITEM (sidebar->popup_menu_stop_item), _("_Lock Drive"));
1736
case G_DRIVE_START_STOP_TYPE_UNKNOWN:
1737
/* uses defaults set above */
1746
/* Callback used when the selection in the shortcuts tree changes */
1748
bookmarks_selection_changed_cb (GtkTreeSelection *selection,
1749
NautilusPlacesSidebar *sidebar)
1751
bookmarks_check_popup_sensitivity (sidebar);
1755
volume_mounted_cb (GVolume *volume,
1760
NautilusPlacesSidebar *sidebar;
1763
sidebar = NAUTILUS_PLACES_SIDEBAR (user_data);
1765
sidebar->mounting = FALSE;
1767
mount = g_volume_get_mount (volume);
1768
if (mount != NULL) {
1769
location = g_mount_get_default_location (mount);
1771
if (sidebar->go_to_after_mount_slot != NULL) {
1772
if ((sidebar->go_to_after_mount_flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) == 0) {
1773
nautilus_window_slot_open_location (sidebar->go_to_after_mount_slot, location,
1774
sidebar->go_to_after_mount_flags);
1776
NautilusWindow *new, *cur;
1778
cur = NAUTILUS_WINDOW (sidebar->window);
1779
new = nautilus_application_create_window (NAUTILUS_APPLICATION (g_application_get_default ()),
1780
gtk_window_get_screen (GTK_WINDOW (cur)));
1781
nautilus_window_go_to (new, location);
1785
g_object_unref (G_OBJECT (location));
1786
g_object_unref (G_OBJECT (mount));
1789
if (sidebar->go_to_after_mount_slot) {
1790
g_object_remove_weak_pointer (G_OBJECT (sidebar->go_to_after_mount_slot),
1791
(gpointer *) &sidebar->go_to_after_mount_slot);
1792
sidebar->go_to_after_mount_slot = NULL;
1797
drive_start_from_bookmark_cb (GObject *source_object,
1806
if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) {
1807
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
1808
name = g_drive_get_name (G_DRIVE (source_object));
1809
primary = g_strdup_printf (_("Unable to start %s"), name);
1811
eel_show_error_dialog (primary,
1816
g_error_free (error);
1821
open_selected_volume (NautilusPlacesSidebar *sidebar,
1822
GtkTreeModel *model,
1824
NautilusWindowOpenFlags flags)
1828
NautilusWindowSlot *slot;
1830
gtk_tree_model_get (model, iter,
1831
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
1832
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
1835
if (volume != NULL && !sidebar->mounting) {
1836
sidebar->mounting = TRUE;
1838
g_assert (sidebar->go_to_after_mount_slot == NULL);
1840
slot = nautilus_window_get_active_slot (sidebar->window);
1841
sidebar->go_to_after_mount_slot = slot;
1842
g_object_add_weak_pointer (G_OBJECT (sidebar->go_to_after_mount_slot),
1843
(gpointer *) &sidebar->go_to_after_mount_slot);
1845
sidebar->go_to_after_mount_flags = flags;
1847
nautilus_file_operations_mount_volume_full (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))),
1850
G_OBJECT (sidebar));
1851
} else if (volume == NULL && drive != NULL &&
1852
(g_drive_can_start (drive) || g_drive_can_start_degraded (drive))) {
1853
GMountOperation *mount_op;
1855
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
1856
g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, NULL);
1857
g_object_unref (mount_op);
1861
g_object_unref (drive);
1863
g_object_unref (volume);
1867
open_selected_uri (NautilusPlacesSidebar *sidebar,
1869
NautilusWindowOpenFlags flags)
1871
NautilusWindowSlot *slot;
1874
DEBUG ("Activating bookmark %s", uri);
1876
location = g_file_new_for_uri (uri);
1878
/* Navigate to the clicked location */
1879
if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) == 0) {
1880
slot = nautilus_window_get_active_slot (sidebar->window);
1881
nautilus_window_slot_open_location (slot, location, flags);
1883
NautilusWindow *cur, *new;
1885
cur = NAUTILUS_WINDOW (sidebar->window);
1886
new = nautilus_application_create_window (NAUTILUS_APPLICATION (g_application_get_default ()),
1887
gtk_window_get_screen (GTK_WINDOW (cur)));
1888
nautilus_window_go_to (new, location);
1891
g_object_unref (location);
1895
open_connect_to_server (NautilusPlacesSidebar *sidebar)
1897
NautilusApplication *application = NAUTILUS_APPLICATION (g_application_get_default ());
1900
dialog = nautilus_application_connect_server (application, sidebar->window);
1901
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1905
open_selected_bookmark (NautilusPlacesSidebar *sidebar,
1906
GtkTreeModel *model,
1908
NautilusWindowOpenFlags flags)
1917
gtk_tree_model_get (model, iter,
1918
PLACES_SIDEBAR_COLUMN_URI, &uri,
1919
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &row_type,
1923
open_selected_uri (sidebar, uri, flags);
1925
} else if (row_type == PLACES_CONNECT_SERVER) {
1926
open_connect_to_server (sidebar);
1928
open_selected_volume (sidebar, model, iter, flags);
1933
open_shortcut_from_menu (NautilusPlacesSidebar *sidebar,
1934
NautilusWindowOpenFlags flags)
1936
GtkTreeModel *model;
1938
GtkTreePath *path = NULL;
1940
model = gtk_tree_view_get_model (sidebar->tree_view);
1941
gtk_tree_view_get_cursor (sidebar->tree_view, &path, NULL);
1943
if (path != NULL && gtk_tree_model_get_iter (model, &iter, path)) {
1944
open_selected_bookmark (sidebar, model, &iter, flags);
1947
gtk_tree_path_free (path);
1951
open_shortcut_cb (GtkMenuItem *item,
1952
NautilusPlacesSidebar *sidebar)
1954
open_shortcut_from_menu (sidebar, 0);
1958
open_shortcut_in_new_window_cb (GtkMenuItem *item,
1959
NautilusPlacesSidebar *sidebar)
1961
open_shortcut_from_menu (sidebar, NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
1965
open_shortcut_in_new_tab_cb (GtkMenuItem *item,
1966
NautilusPlacesSidebar *sidebar)
1968
open_shortcut_from_menu (sidebar, NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
1971
/* Add bookmark for the selected item */
1973
add_bookmark (NautilusPlacesSidebar *sidebar)
1975
GtkTreeModel *model;
1980
NautilusBookmark *bookmark;
1982
model = gtk_tree_view_get_model (sidebar->tree_view);
1984
if (get_selected_iter (sidebar, &iter)) {
1985
gtk_tree_model_get (model, &iter,
1986
PLACES_SIDEBAR_COLUMN_URI, &uri,
1987
PLACES_SIDEBAR_COLUMN_NAME, &name,
1994
location = g_file_new_for_uri (uri);
1995
bookmark = nautilus_bookmark_new (location, name);
1996
nautilus_bookmark_list_append (sidebar->bookmarks, bookmark);
1998
g_object_unref (location);
1999
g_object_unref (bookmark);
2006
add_shortcut_cb (GtkMenuItem *item,
2007
NautilusPlacesSidebar *sidebar)
2009
add_bookmark (sidebar);
2012
/* Rename the selected bookmark */
2014
rename_selected_bookmark (NautilusPlacesSidebar *sidebar)
2018
GtkTreeViewColumn *column;
2019
GtkCellRenderer *cell;
2023
if (get_selected_iter (sidebar, &iter)) {
2024
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2025
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
2028
if (type != PLACES_BOOKMARK && type != PLACES_XDG_DIR) {
2032
path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
2033
column = gtk_tree_view_get_column (GTK_TREE_VIEW (sidebar->tree_view), 0);
2034
renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
2035
cell = g_list_nth_data (renderers, 6);
2036
g_list_free (renderers);
2037
g_object_set (cell, "editable", TRUE, NULL);
2038
gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (sidebar->tree_view),
2039
path, column, cell, TRUE);
2040
gtk_tree_path_free (path);
2045
rename_shortcut_cb (GtkMenuItem *item,
2046
NautilusPlacesSidebar *sidebar)
2048
rename_selected_bookmark (sidebar);
2051
/* Removes the selected bookmarks */
2053
remove_selected_bookmarks (NautilusPlacesSidebar *sidebar)
2059
if (!get_selected_iter (sidebar, &iter)) {
2063
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2064
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
2067
if (type != PLACES_BOOKMARK) {
2071
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2072
PLACES_SIDEBAR_COLUMN_INDEX, &index,
2075
nautilus_bookmark_list_delete_item_at (sidebar->bookmarks, index);
2079
remove_shortcut_cb (GtkMenuItem *item,
2080
NautilusPlacesSidebar *sidebar)
2082
remove_selected_bookmarks (sidebar);
2086
mount_shortcut_cb (GtkMenuItem *item,
2087
NautilusPlacesSidebar *sidebar)
2092
if (!get_selected_iter (sidebar, &iter)) {
2096
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2097
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
2100
if (volume != NULL) {
2101
nautilus_file_operations_mount_volume (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))), volume);
2102
g_object_unref (volume);
2107
unmount_done (gpointer data)
2109
NautilusWindow *window;
2112
g_object_unref (window);
2116
show_unmount_progress_cb (GMountOperation *op,
2117
const gchar *message,
2122
NautilusApplication *app = NAUTILUS_APPLICATION (g_application_get_default ());
2124
if (bytes_left == 0) {
2125
nautilus_application_notify_unmount_done (app, message);
2127
nautilus_application_notify_unmount_show (app, message);
2132
show_unmount_progress_aborted_cb (GMountOperation *op,
2135
NautilusApplication *app = NAUTILUS_APPLICATION (g_application_get_default ());
2136
nautilus_application_notify_unmount_done (app, NULL);
2139
static GMountOperation *
2140
get_unmount_operation (NautilusPlacesSidebar *sidebar)
2142
GMountOperation *mount_op;
2144
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
2145
g_signal_connect (mount_op, "show-unmount-progress",
2146
G_CALLBACK (show_unmount_progress_cb), sidebar);
2147
g_signal_connect (mount_op, "aborted",
2148
G_CALLBACK (show_unmount_progress_aborted_cb), sidebar);
2154
do_unmount (GMount *mount,
2155
NautilusPlacesSidebar *sidebar)
2157
GMountOperation *mount_op;
2159
if (mount != NULL) {
2160
mount_op = get_unmount_operation (sidebar);
2161
nautilus_file_operations_unmount_mount_full (NULL, mount, mount_op, FALSE, TRUE,
2163
g_object_ref (sidebar->window));
2164
g_object_unref (mount_op);
2169
do_unmount_selection (NautilusPlacesSidebar *sidebar)
2174
if (!get_selected_iter (sidebar, &iter)) {
2178
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2179
PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
2182
if (mount != NULL) {
2183
do_unmount (mount, sidebar);
2184
g_object_unref (mount);
2189
unmount_shortcut_cb (GtkMenuItem *item,
2190
NautilusPlacesSidebar *sidebar)
2192
do_unmount_selection (sidebar);
2196
drive_eject_cb (GObject *source_object,
2200
NautilusWindow *window;
2206
g_object_unref (window);
2209
if (!g_drive_eject_with_operation_finish (G_DRIVE (source_object), res, &error)) {
2210
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
2211
name = g_drive_get_name (G_DRIVE (source_object));
2212
primary = g_strdup_printf (_("Unable to eject %s"), name);
2214
eel_show_error_dialog (primary,
2219
g_error_free (error);
2224
volume_eject_cb (GObject *source_object,
2228
NautilusWindow *window;
2234
g_object_unref (window);
2237
if (!g_volume_eject_with_operation_finish (G_VOLUME (source_object), res, &error)) {
2238
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
2239
name = g_volume_get_name (G_VOLUME (source_object));
2240
primary = g_strdup_printf (_("Unable to eject %s"), name);
2242
eel_show_error_dialog (primary,
2247
g_error_free (error);
2252
mount_eject_cb (GObject *source_object,
2256
NautilusWindow *window;
2262
g_object_unref (window);
2265
if (!g_mount_eject_with_operation_finish (G_MOUNT (source_object), res, &error)) {
2266
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
2267
name = g_mount_get_name (G_MOUNT (source_object));
2268
primary = g_strdup_printf (_("Unable to eject %s"), name);
2270
eel_show_error_dialog (primary,
2275
g_error_free (error);
2280
do_eject (GMount *mount,
2283
NautilusPlacesSidebar *sidebar)
2285
GMountOperation *mount_op = get_unmount_operation (sidebar);
2287
if (mount != NULL) {
2288
g_mount_eject_with_operation (mount, 0, mount_op, NULL, mount_eject_cb,
2289
g_object_ref (sidebar->window));
2290
} else if (volume != NULL) {
2291
g_volume_eject_with_operation (volume, 0, mount_op, NULL, volume_eject_cb,
2292
g_object_ref (sidebar->window));
2293
} else if (drive != NULL) {
2294
g_drive_eject_with_operation (drive, 0, mount_op, NULL, drive_eject_cb,
2295
g_object_ref (sidebar->window));
2298
g_object_unref (mount_op);
2302
eject_shortcut_cb (GtkMenuItem *item,
2303
NautilusPlacesSidebar *sidebar)
2310
if (!get_selected_iter (sidebar, &iter)) {
2314
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2315
PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
2316
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
2317
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
2320
do_eject (mount, volume, drive, sidebar);
2324
eject_or_unmount_bookmark (NautilusPlacesSidebar *sidebar,
2327
GtkTreeModel *model;
2329
gboolean can_unmount, can_eject;
2335
model = GTK_TREE_MODEL (sidebar->store);
2340
if (!gtk_tree_model_get_iter (model, &iter, path)) {
2344
gtk_tree_model_get (model, &iter,
2345
PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
2346
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
2347
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
2352
check_unmount_and_eject (mount, volume, drive, &can_unmount, &can_eject);
2353
/* if we can eject, it has priority over unmount */
2355
do_eject (mount, volume, drive, sidebar);
2357
} else if (can_unmount) {
2358
do_unmount (mount, sidebar);
2363
g_object_unref (mount);
2365
g_object_unref (volume);
2367
g_object_unref (drive);
2373
eject_or_unmount_selection (NautilusPlacesSidebar *sidebar)
2379
if (!get_selected_iter (sidebar, &iter)) {
2383
path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
2388
ret = eject_or_unmount_bookmark (sidebar, path);
2390
gtk_tree_path_free (path);
2396
drive_poll_for_media_cb (GObject *source_object,
2405
if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) {
2406
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
2407
name = g_drive_get_name (G_DRIVE (source_object));
2408
primary = g_strdup_printf (_("Unable to poll %s for media changes"), name);
2410
eel_show_error_dialog (primary,
2415
g_error_free (error);
2420
rescan_shortcut_cb (GtkMenuItem *item,
2421
NautilusPlacesSidebar *sidebar)
2426
if (!get_selected_iter (sidebar, &iter)) {
2430
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2431
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
2434
if (drive != NULL) {
2435
g_drive_poll_for_media (drive, NULL, drive_poll_for_media_cb, NULL);
2437
g_object_unref (drive);
2441
drive_start_cb (GObject *source_object,
2450
if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) {
2451
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
2452
name = g_drive_get_name (G_DRIVE (source_object));
2453
primary = g_strdup_printf (_("Unable to start %s"), name);
2455
eel_show_error_dialog (primary,
2460
g_error_free (error);
2465
start_shortcut_cb (GtkMenuItem *item,
2466
NautilusPlacesSidebar *sidebar)
2471
if (!get_selected_iter (sidebar, &iter)) {
2475
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2476
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
2479
if (drive != NULL) {
2480
GMountOperation *mount_op;
2482
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
2484
g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_cb, NULL);
2486
g_object_unref (mount_op);
2488
g_object_unref (drive);
2492
drive_stop_cb (GObject *source_object,
2496
NautilusWindow *window;
2502
g_object_unref (window);
2505
if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) {
2506
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
2507
name = g_drive_get_name (G_DRIVE (source_object));
2508
primary = g_strdup_printf (_("Unable to stop %s"), name);
2510
eel_show_error_dialog (primary,
2515
g_error_free (error);
2520
stop_shortcut_cb (GtkMenuItem *item,
2521
NautilusPlacesSidebar *sidebar)
2526
if (!get_selected_iter (sidebar, &iter)) {
2530
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2531
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
2534
if (drive != NULL) {
2535
GMountOperation *mount_op = get_unmount_operation (sidebar);
2536
g_drive_stop (drive, G_MOUNT_UNMOUNT_NONE, mount_op, NULL, drive_stop_cb,
2537
g_object_ref (sidebar->window));
2538
g_object_unref (mount_op);
2540
g_object_unref (drive);
2544
format_shortcut_cb (GtkMenuItem *item,
2545
NautilusPlacesSidebar *sidebar)
2548
gchar *cmdline, *device_identifier, *xid_string;
2553
if (!get_selected_iter (sidebar, &iter)) {
2557
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
2558
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
2565
device_identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
2566
xid = (gint) gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (sidebar->window)));
2567
xid_string = g_strdup_printf ("%d", xid);
2569
cmdline = g_strconcat ("gnome-disks ",
2570
"--block-device ", device_identifier, " ",
2572
"--xid ", xid_string,
2574
app_info = g_app_info_create_from_commandline (cmdline, NULL, 0, NULL);
2575
g_app_info_launch (app_info, NULL, NULL, NULL);
2578
g_free (device_identifier);
2579
g_free (xid_string);
2580
g_clear_object (&volume);
2581
g_clear_object (&app_info);
2585
empty_trash_cb (GtkMenuItem *item,
2586
NautilusPlacesSidebar *sidebar)
2588
nautilus_file_operations_empty_trash (GTK_WIDGET (sidebar->window));
2592
find_prev_or_next_row (NautilusPlacesSidebar *sidebar,
2596
GtkTreeModel *model = GTK_TREE_MODEL (sidebar->store);
2601
res = gtk_tree_model_iter_previous (model, iter);
2603
res = gtk_tree_model_iter_next (model, iter);
2607
gtk_tree_model_get (model, iter,
2608
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
2610
if (place_type == PLACES_HEADING) {
2612
res = gtk_tree_model_iter_previous (model, iter);
2614
res = gtk_tree_model_iter_next (model, iter);
2623
find_prev_row (NautilusPlacesSidebar *sidebar, GtkTreeIter *iter)
2625
return find_prev_or_next_row (sidebar, iter, TRUE);
2629
find_next_row (NautilusPlacesSidebar *sidebar, GtkTreeIter *iter)
2631
return find_prev_or_next_row (sidebar, iter, FALSE);
2635
properties_cb (GtkMenuItem *item,
2636
NautilusPlacesSidebar *sidebar)
2638
GtkTreeModel *model;
2639
GtkTreePath *path = NULL;
2645
model = gtk_tree_view_get_model (sidebar->tree_view);
2646
gtk_tree_view_get_cursor (sidebar->tree_view, &path, NULL);
2648
if (path == NULL || !gtk_tree_model_get_iter (model, &iter, path)) {
2649
gtk_tree_path_free (path);
2653
gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
2657
file = nautilus_file_get_by_uri (uri);
2658
list = g_list_prepend (NULL, nautilus_file_ref (file));
2660
nautilus_properties_window_present (list, GTK_WIDGET (sidebar), NULL);
2662
nautilus_file_list_free (list);
2666
gtk_tree_path_free (path);
2670
nautilus_places_sidebar_focus (GtkWidget *widget,
2671
GtkDirectionType direction)
2673
NautilusPlacesSidebar *sidebar = NAUTILUS_PLACES_SIDEBAR (widget);
2678
res = get_selected_iter (sidebar, &iter);
2681
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (sidebar->store), &iter);
2682
res = find_next_row (sidebar, &iter);
2684
path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
2685
gtk_tree_view_set_cursor (sidebar->tree_view, path, NULL, FALSE);
2686
gtk_tree_path_free (path);
2690
return GTK_WIDGET_CLASS (nautilus_places_sidebar_parent_class)->focus (widget, direction);
2693
/* Handler for GtkWidget::key-press-event on the shortcuts list */
2695
bookmarks_key_press_event_cb (GtkWidget *widget,
2697
NautilusPlacesSidebar *sidebar)
2700
GtkTreeIter selected_iter;
2703
if (!get_selected_iter (sidebar, &selected_iter)) {
2707
modifiers = gtk_accelerator_get_default_mod_mask ();
2709
if ((event->keyval == GDK_KEY_Return ||
2710
event->keyval == GDK_KEY_KP_Enter ||
2711
event->keyval == GDK_KEY_ISO_Enter ||
2712
event->keyval == GDK_KEY_space)) {
2713
NautilusWindowOpenFlags flags = 0;
2715
if ((event->state & modifiers) == GDK_SHIFT_MASK) {
2716
flags = NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
2717
} else if ((event->state & modifiers) == GDK_CONTROL_MASK) {
2718
flags = NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
2721
open_selected_bookmark (sidebar, GTK_TREE_MODEL (sidebar->store),
2722
&selected_iter, flags);
2726
if (event->keyval == GDK_KEY_Down &&
2727
(event->state & modifiers) == GDK_MOD1_MASK) {
2728
return eject_or_unmount_selection (sidebar);
2731
if (event->keyval == GDK_KEY_Up) {
2732
if (find_prev_row (sidebar, &selected_iter)) {
2733
path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &selected_iter);
2734
gtk_tree_view_set_cursor (sidebar->tree_view, path, NULL, FALSE);
2735
gtk_tree_path_free (path);
2740
if (event->keyval == GDK_KEY_Down) {
2741
if (find_next_row (sidebar, &selected_iter)) {
2742
path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &selected_iter);
2743
gtk_tree_view_set_cursor (sidebar->tree_view, path, NULL, FALSE);
2744
gtk_tree_path_free (path);
2749
if ((event->keyval == GDK_KEY_Delete
2750
|| event->keyval == GDK_KEY_KP_Delete)
2751
&& (event->state & modifiers) == 0) {
2752
remove_selected_bookmarks (sidebar);
2756
if ((event->keyval == GDK_KEY_F2)
2757
&& (event->state & modifiers) == 0) {
2758
rename_selected_bookmark (sidebar);
2765
/* Constructs the popup menu for the file list if needed */
2767
bookmarks_build_popup_menu (NautilusPlacesSidebar *sidebar)
2771
if (sidebar->popup_menu) {
2775
sidebar->popup_menu = gtk_menu_new ();
2776
gtk_menu_attach_to_widget (GTK_MENU (sidebar->popup_menu),
2777
GTK_WIDGET (sidebar),
2778
bookmarks_popup_menu_detach_cb);
2780
item = gtk_image_menu_item_new_with_mnemonic (_("_Open"));
2781
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
2782
gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU));
2783
g_signal_connect (item, "activate",
2784
G_CALLBACK (open_shortcut_cb), sidebar);
2785
gtk_widget_show (item);
2786
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2788
item = gtk_menu_item_new_with_mnemonic (_("Open in New _Tab"));
2789
sidebar->popup_menu_open_in_new_tab_item = item;
2790
g_signal_connect (item, "activate",
2791
G_CALLBACK (open_shortcut_in_new_tab_cb), sidebar);
2792
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2793
gtk_widget_show (item);
2795
item = gtk_menu_item_new_with_mnemonic (_("Open in New _Window"));
2796
g_signal_connect (item, "activate",
2797
G_CALLBACK (open_shortcut_in_new_window_cb), sidebar);
2798
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2799
gtk_widget_show (item);
2801
eel_gtk_menu_append_separator (GTK_MENU (sidebar->popup_menu));
2803
item = gtk_menu_item_new_with_mnemonic (_("_Add Bookmark"));
2804
sidebar->popup_menu_add_shortcut_item = item;
2805
g_signal_connect (item, "activate",
2806
G_CALLBACK (add_shortcut_cb), sidebar);
2807
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2809
item = gtk_image_menu_item_new_with_label (_("Remove"));
2810
sidebar->popup_menu_remove_item = item;
2811
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
2812
gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));
2813
g_signal_connect (item, "activate",
2814
G_CALLBACK (remove_shortcut_cb), sidebar);
2815
gtk_widget_show (item);
2816
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2818
item = gtk_menu_item_new_with_label (_("Renameā¦"));
2819
sidebar->popup_menu_rename_item = item;
2820
g_signal_connect (item, "activate",
2821
G_CALLBACK (rename_shortcut_cb), sidebar);
2822
gtk_widget_show (item);
2823
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2825
/* Mount/Unmount/Eject menu items */
2827
sidebar->popup_menu_separator_item =
2828
GTK_WIDGET (eel_gtk_menu_append_separator (GTK_MENU (sidebar->popup_menu)));
2830
item = gtk_menu_item_new_with_mnemonic (_("_Mount"));
2831
sidebar->popup_menu_mount_item = item;
2832
g_signal_connect (item, "activate",
2833
G_CALLBACK (mount_shortcut_cb), sidebar);
2834
gtk_widget_show (item);
2835
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2837
item = gtk_menu_item_new_with_mnemonic (_("_Unmount"));
2838
sidebar->popup_menu_unmount_item = item;
2839
g_signal_connect (item, "activate",
2840
G_CALLBACK (unmount_shortcut_cb), sidebar);
2841
gtk_widget_show (item);
2842
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2844
item = gtk_menu_item_new_with_mnemonic (_("_Eject"));
2845
sidebar->popup_menu_eject_item = item;
2846
g_signal_connect (item, "activate",
2847
G_CALLBACK (eject_shortcut_cb), sidebar);
2848
gtk_widget_show (item);
2849
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2851
item = gtk_menu_item_new_with_mnemonic (_("_Detect Media"));
2852
sidebar->popup_menu_rescan_item = item;
2853
g_signal_connect (item, "activate",
2854
G_CALLBACK (rescan_shortcut_cb), sidebar);
2855
gtk_widget_show (item);
2856
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2858
item = gtk_menu_item_new_with_mnemonic (_("_Start"));
2859
sidebar->popup_menu_start_item = item;
2860
g_signal_connect (item, "activate",
2861
G_CALLBACK (start_shortcut_cb), sidebar);
2862
gtk_widget_show (item);
2863
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2865
item = gtk_menu_item_new_with_mnemonic (_("_Stop"));
2866
sidebar->popup_menu_stop_item = item;
2867
g_signal_connect (item, "activate",
2868
G_CALLBACK (stop_shortcut_cb), sidebar);
2869
gtk_widget_show (item);
2870
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2872
item = gtk_menu_item_new_with_mnemonic (_("_Formatā¦"));
2873
sidebar->popup_menu_format_item = item;
2874
g_signal_connect (item, "activate",
2875
G_CALLBACK (format_shortcut_cb), sidebar);
2876
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2878
/* Empty Trash menu item */
2880
item = gtk_menu_item_new_with_mnemonic (_("Empty _Trash"));
2881
sidebar->popup_menu_empty_trash_item = item;
2882
g_signal_connect (item, "activate",
2883
G_CALLBACK (empty_trash_cb), sidebar);
2884
gtk_widget_show (item);
2885
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2887
/* Properties menu item */
2889
sidebar->popup_menu_properties_separator_item =
2890
GTK_WIDGET (eel_gtk_menu_append_separator (GTK_MENU (sidebar->popup_menu)));
2892
item = gtk_menu_item_new_with_mnemonic (_("_Properties"));
2893
sidebar->popup_menu_properties_item = item;
2894
g_signal_connect (item, "activate",
2895
G_CALLBACK (properties_cb), sidebar);
2896
gtk_widget_show (item);
2897
gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
2899
bookmarks_check_popup_sensitivity (sidebar);
2903
bookmarks_popup_menu (NautilusPlacesSidebar *sidebar,
2904
GdkEventButton *event)
2906
bookmarks_build_popup_menu (sidebar);
2907
eel_pop_up_context_menu (GTK_MENU(sidebar->popup_menu),
2911
/* Callback used for the GtkWidget::popup-menu signal of the shortcuts list */
2913
bookmarks_popup_menu_cb (GtkWidget *widget,
2914
NautilusPlacesSidebar *sidebar)
2916
bookmarks_popup_menu (sidebar, NULL);
2921
bookmarks_row_activated_cb (GtkWidget *widget,
2923
GtkTreeViewColumn *column,
2924
NautilusPlacesSidebar *sidebar)
2927
GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
2929
if (!gtk_tree_model_get_iter (model, &iter, path)) {
2933
open_selected_bookmark (sidebar, model, &iter, 0);
2937
bookmarks_button_release_event_cb (GtkWidget *widget,
2938
GdkEventButton *event,
2939
NautilusPlacesSidebar *sidebar)
2943
GtkTreeModel *model;
2944
GtkTreeView *tree_view;
2945
gboolean ret = FALSE;
2950
if (event->type != GDK_BUTTON_RELEASE) {
2954
if (clicked_eject_button (sidebar, &path)) {
2955
eject_or_unmount_bookmark (sidebar, path);
2956
gtk_tree_path_free (path);
2961
if (event->button == 1) {
2965
tree_view = GTK_TREE_VIEW (widget);
2966
model = gtk_tree_view_get_model (tree_view);
2968
if (event->window != gtk_tree_view_get_bin_window (tree_view)) {
2972
res = gtk_tree_view_get_path_at_pos (tree_view, (int) event->x, (int) event->y,
2973
&path, NULL, NULL, NULL);
2975
if (!res || path == NULL) {
2979
res = gtk_tree_model_get_iter (model, &iter, path);
2981
gtk_tree_path_free (path);
2985
if (event->button == 2) {
2986
NautilusWindowOpenFlags flags = 0;
2988
flags = (event->state & GDK_CONTROL_MASK) ?
2989
NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW :
2990
NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
2992
open_selected_bookmark (sidebar, model, &iter, flags);
2994
} else if (event->button == 3) {
2997
gtk_tree_model_get (model, &iter,
2998
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &row_type,
3001
if (row_type != PLACES_HEADING &&
3002
row_type != PLACES_CONNECT_SERVER) {
3003
bookmarks_popup_menu (sidebar, event);
3007
gtk_tree_path_free (path);
3013
bookmarks_edited (GtkCellRenderer *cell,
3016
NautilusPlacesSidebar *sidebar)
3022
NautilusBookmark *bookmark;
3025
g_object_set (cell, "editable", FALSE, NULL);
3027
path = gtk_tree_path_new_from_string (path_string);
3028
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store), &iter, path)) {
3033
gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
3034
PLACES_SIDEBAR_COLUMN_URI, &uri,
3035
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
3041
location = g_file_new_for_uri (uri);
3042
bookmark = nautilus_bookmark_list_item_with_location (sidebar->bookmarks, location, NULL);
3044
if (bookmark != NULL) {
3045
nautilus_bookmark_set_custom_name (bookmark, new_text);
3046
} else if (type == PLACES_XDG_DIR) {
3047
/* In case we're renaming a built-in bookmark, and it's not in the
3048
* list, add it with a custom name.
3050
bookmark = nautilus_bookmark_new (location, new_text);
3051
nautilus_bookmark_list_append (sidebar->bookmarks, bookmark);
3052
g_object_unref (bookmark);
3055
g_object_unref (location);
3059
gtk_tree_path_free (path);
3063
bookmarks_editing_canceled (GtkCellRenderer *cell,
3064
NautilusPlacesSidebar *sidebar)
3066
g_object_set (cell, "editable", FALSE, NULL);
3070
trash_state_changed_cb (NautilusTrashMonitor *trash_monitor,
3074
NautilusPlacesSidebar *sidebar;
3076
sidebar = NAUTILUS_PLACES_SIDEBAR (data);
3078
/* The trash icon changed, update the sidebar */
3079
update_places (sidebar);
3081
bookmarks_check_popup_sensitivity (sidebar);
3085
tree_selection_func (GtkTreeSelection *selection,
3086
GtkTreeModel *model,
3088
gboolean path_currently_selected,
3094
gtk_tree_model_get_iter (model, &iter, path);
3095
gtk_tree_model_get (model, &iter,
3096
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &row_type,
3099
if (row_type == PLACES_HEADING) {
3107
icon_cell_renderer_func (GtkTreeViewColumn *column,
3108
GtkCellRenderer *cell,
3109
GtkTreeModel *model,
3115
gtk_tree_model_get (model, iter,
3116
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
3119
if (type == PLACES_HEADING) {
3131
padding_cell_renderer_func (GtkTreeViewColumn *column,
3132
GtkCellRenderer *cell,
3133
GtkTreeModel *model,
3139
gtk_tree_model_get (model, iter,
3140
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
3143
if (type == PLACES_HEADING) {
3159
heading_cell_renderer_func (GtkTreeViewColumn *column,
3160
GtkCellRenderer *cell,
3161
GtkTreeModel *model,
3167
gtk_tree_model_get (model, iter,
3168
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
3171
if (type == PLACES_HEADING) {
3183
places_sidebar_sort_func (GtkTreeModel *model,
3184
GtkTreeIter *iter_a,
3185
GtkTreeIter *iter_b,
3188
SectionType section_type_a, section_type_b;
3189
PlaceType place_type_a, place_type_b;
3192
gtk_tree_model_get (model, iter_a,
3193
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, §ion_type_a,
3194
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type_a,
3196
gtk_tree_model_get (model, iter_b,
3197
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, §ion_type_b,
3198
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type_b,
3201
/* fall back to the default order if we're not in the
3202
* XDG part of the computer section.
3204
if ((section_type_a == section_type_b) &&
3205
(section_type_a == SECTION_COMPUTER) &&
3206
(place_type_a == place_type_b) &&
3207
(place_type_a == PLACES_XDG_DIR)) {
3208
gchar *name_a, *name_b;
3210
gtk_tree_model_get (model, iter_a,
3211
PLACES_SIDEBAR_COLUMN_NAME, &name_a,
3213
gtk_tree_model_get (model, iter_b,
3214
PLACES_SIDEBAR_COLUMN_NAME, &name_b,
3217
retval = g_utf8_collate (name_a, name_b);
3221
} else if (place_type_a == PLACES_CONNECT_SERVER) {
3229
update_hostname (NautilusPlacesSidebar *sidebar)
3233
const gchar *hostname;
3235
if (sidebar->hostnamed_proxy == NULL)
3238
variant = g_dbus_proxy_get_cached_property (sidebar->hostnamed_proxy,
3240
if (variant == NULL) {
3244
hostname = g_variant_get_string (variant, &len);
3246
g_strcmp0 (sidebar->hostname, hostname) != 0) {
3247
g_free (sidebar->hostname);
3248
sidebar->hostname = g_strdup (hostname);
3249
update_places (sidebar);
3252
g_variant_unref (variant);
3256
hostname_proxy_new_cb (GObject *source_object,
3260
NautilusPlacesSidebar *sidebar = user_data;
3261
GError *error = NULL;
3263
sidebar->hostnamed_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
3264
g_clear_object (&sidebar->hostnamed_cancellable);
3266
if (error != NULL) {
3267
g_debug ("Failed to create D-Bus proxy: %s", error->message);
3268
g_error_free (error);
3272
g_signal_connect_swapped (sidebar->hostnamed_proxy,
3273
"g-properties-changed",
3274
G_CALLBACK (update_hostname),
3276
update_hostname (sidebar);
3280
nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
3282
GtkTreeView *tree_view;
3283
GtkTreeViewColumn *col;
3284
GtkCellRenderer *cell;
3285
GtkTreeSelection *selection;
3288
sidebar->volume_monitor = g_volume_monitor_get ();
3290
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sidebar),
3292
GTK_POLICY_AUTOMATIC);
3293
gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (sidebar), NULL);
3294
gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (sidebar), NULL);
3295
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sidebar), GTK_SHADOW_IN);
3297
gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (sidebar)),
3298
GTK_JUNCTION_RIGHT | GTK_JUNCTION_LEFT);
3301
tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
3302
gtk_tree_view_set_headers_visible (tree_view, FALSE);
3304
col = GTK_TREE_VIEW_COLUMN (gtk_tree_view_column_new ());
3306
/* initial padding */
3307
cell = gtk_cell_renderer_text_new ();
3308
gtk_tree_view_column_pack_start (col, cell, FALSE);
3314
cell = gtk_cell_renderer_text_new ();
3315
gtk_tree_view_column_pack_start (col, cell, FALSE);
3316
gtk_tree_view_column_set_attributes (col, cell,
3317
"text", PLACES_SIDEBAR_COLUMN_HEADING_TEXT,
3320
"weight", PANGO_WEIGHT_BOLD,
3325
gtk_tree_view_column_set_cell_data_func (col, cell,
3326
heading_cell_renderer_func,
3330
cell = gtk_cell_renderer_text_new ();
3331
gtk_tree_view_column_pack_start (col, cell, FALSE);
3332
gtk_tree_view_column_set_cell_data_func (col, cell,
3333
padding_cell_renderer_func,
3337
cell = gtk_cell_renderer_pixbuf_new ();
3338
g_object_set (cell, "follow-state", TRUE, NULL);
3339
gtk_tree_view_column_pack_start (col, cell, FALSE);
3340
gtk_tree_view_column_set_attributes (col, cell,
3341
"gicon", PLACES_SIDEBAR_COLUMN_GICON,
3343
gtk_tree_view_column_set_cell_data_func (col, cell,
3344
icon_cell_renderer_func,
3347
/* eject text renderer */
3348
cell = gtk_cell_renderer_text_new ();
3349
gtk_tree_view_column_pack_start (col, cell, TRUE);
3350
gtk_tree_view_column_set_attributes (col, cell,
3351
"text", PLACES_SIDEBAR_COLUMN_NAME,
3352
"visible", PLACES_SIDEBAR_COLUMN_EJECT,
3355
"ellipsize", PANGO_ELLIPSIZE_END,
3356
"ellipsize-set", TRUE,
3359
/* eject icon renderer */
3360
cell = gtk_cell_renderer_pixbuf_new ();
3361
sidebar->eject_icon_cell_renderer = cell;
3362
eject = g_themed_icon_new_with_default_fallbacks ("media-eject-symbolic");
3364
"mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
3365
"stock-size", GTK_ICON_SIZE_MENU,
3366
"xpad", EJECT_BUTTON_XPAD,
3367
/* align right, because for some reason gtk+ expands
3368
this even though we tell it not to. */
3370
"follow-state", TRUE,
3373
gtk_tree_view_column_pack_start (col, cell, FALSE);
3374
gtk_tree_view_column_set_attributes (col, cell,
3375
"visible", PLACES_SIDEBAR_COLUMN_EJECT,
3377
g_object_unref (eject);
3379
/* normal text renderer */
3380
cell = gtk_cell_renderer_text_new ();
3381
gtk_tree_view_column_pack_start (col, cell, TRUE);
3382
g_object_set (G_OBJECT (cell), "editable", FALSE, NULL);
3383
gtk_tree_view_column_set_attributes (col, cell,
3384
"text", PLACES_SIDEBAR_COLUMN_NAME,
3385
"visible", PLACES_SIDEBAR_COLUMN_NO_EJECT,
3386
"editable-set", PLACES_SIDEBAR_COLUMN_BOOKMARK,
3389
"ellipsize", PANGO_ELLIPSIZE_END,
3390
"ellipsize-set", TRUE,
3393
g_signal_connect (cell, "edited",
3394
G_CALLBACK (bookmarks_edited), sidebar);
3395
g_signal_connect (cell, "editing-canceled",
3396
G_CALLBACK (bookmarks_editing_canceled), sidebar);
3398
/* this is required to align the eject buttons to the right */
3399
gtk_tree_view_column_set_max_width (GTK_TREE_VIEW_COLUMN (col), NAUTILUS_ICON_SIZE_SMALLER);
3400
gtk_tree_view_append_column (tree_view, col);
3402
sidebar->store = nautilus_shortcuts_model_new (sidebar);
3403
gtk_tree_view_set_tooltip_column (tree_view, PLACES_SIDEBAR_COLUMN_TOOLTIP);
3404
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sidebar->store),
3405
PLACES_SIDEBAR_COLUMN_NAME,
3406
GTK_SORT_ASCENDING);
3407
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sidebar->store),
3408
PLACES_SIDEBAR_COLUMN_NAME,
3409
places_sidebar_sort_func,
3412
gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (sidebar->store));
3413
gtk_container_add (GTK_CONTAINER (sidebar), GTK_WIDGET (tree_view));
3414
gtk_widget_show (GTK_WIDGET (tree_view));
3415
gtk_tree_view_set_enable_search (tree_view, FALSE);
3417
gtk_widget_show (GTK_WIDGET (sidebar));
3418
sidebar->tree_view = tree_view;
3420
gtk_tree_view_set_search_column (tree_view, PLACES_SIDEBAR_COLUMN_NAME);
3421
selection = gtk_tree_view_get_selection (tree_view);
3422
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
3424
gtk_tree_selection_set_select_function (selection,
3425
tree_selection_func,
3429
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tree_view),
3431
nautilus_shortcuts_source_targets,
3432
G_N_ELEMENTS (nautilus_shortcuts_source_targets),
3434
gtk_drag_dest_set (GTK_WIDGET (tree_view),
3436
nautilus_shortcuts_drop_targets, G_N_ELEMENTS (nautilus_shortcuts_drop_targets),
3437
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
3439
g_signal_connect (tree_view, "key-press-event",
3440
G_CALLBACK (bookmarks_key_press_event_cb), sidebar);
3442
g_signal_connect (tree_view, "drag-motion",
3443
G_CALLBACK (drag_motion_callback), sidebar);
3444
g_signal_connect (tree_view, "drag-leave",
3445
G_CALLBACK (drag_leave_callback), sidebar);
3446
g_signal_connect (tree_view, "drag-data-received",
3447
G_CALLBACK (drag_data_received_callback), sidebar);
3448
g_signal_connect (tree_view, "drag-drop",
3449
G_CALLBACK (drag_drop_callback), sidebar);
3451
g_signal_connect (selection, "changed",
3452
G_CALLBACK (bookmarks_selection_changed_cb), sidebar);
3453
g_signal_connect (tree_view, "popup-menu",
3454
G_CALLBACK (bookmarks_popup_menu_cb), sidebar);
3455
g_signal_connect (tree_view, "button-release-event",
3456
G_CALLBACK (bookmarks_button_release_event_cb), sidebar);
3457
g_signal_connect (tree_view, "row-activated",
3458
G_CALLBACK (bookmarks_row_activated_cb), sidebar);
3460
gtk_tree_view_set_activate_on_single_click (sidebar->tree_view, TRUE);
3462
g_signal_connect_swapped (gnome_background_preferences, "changed::" NAUTILUS_PREFERENCES_SHOW_DESKTOP,
3463
G_CALLBACK (update_places),
3465
g_signal_connect_swapped (gnome_privacy_preferences, "changed::" NAUTILUS_PREFERENCES_RECENT_FILES_ENABLED,
3466
G_CALLBACK (update_places),
3469
sidebar->hostname = g_strdup (_("Computer"));
3470
sidebar->hostnamed_cancellable = g_cancellable_new ();
3471
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
3472
G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
3474
"org.freedesktop.hostname1",
3475
"/org/freedesktop/hostname1",
3476
"org.freedesktop.hostname1",
3477
sidebar->hostnamed_cancellable,
3478
hostname_proxy_new_cb,
3481
g_signal_connect_object (nautilus_trash_monitor_get (),
3482
"trash-state-changed",
3483
G_CALLBACK (trash_state_changed_cb),
3488
nautilus_places_sidebar_dispose (GObject *object)
3490
NautilusPlacesSidebar *sidebar;
3492
sidebar = NAUTILUS_PLACES_SIDEBAR (object);
3494
sidebar->window = NULL;
3495
sidebar->tree_view = NULL;
3497
g_free (sidebar->uri);
3498
sidebar->uri = NULL;
3500
free_drag_data (sidebar);
3502
if (sidebar->bookmarks_changed_id != 0) {
3503
g_signal_handler_disconnect (sidebar->bookmarks,
3504
sidebar->bookmarks_changed_id);
3505
sidebar->bookmarks_changed_id = 0;
3508
g_clear_object (&sidebar->store);
3510
if (sidebar->go_to_after_mount_slot) {
3511
g_object_remove_weak_pointer (G_OBJECT (sidebar->go_to_after_mount_slot),
3512
(gpointer *) &sidebar->go_to_after_mount_slot);
3513
sidebar->go_to_after_mount_slot = NULL;
3516
g_signal_handlers_disconnect_by_func (nautilus_preferences,
3517
bookmarks_popup_menu_detach_cb,
3520
g_signal_handlers_disconnect_by_func (gnome_background_preferences,
3524
g_signal_handlers_disconnect_by_func (gnome_privacy_preferences,
3528
if (sidebar->volume_monitor != NULL) {
3529
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3530
volume_added_callback, sidebar);
3531
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3532
volume_removed_callback, sidebar);
3533
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3534
volume_changed_callback, sidebar);
3535
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3536
mount_added_callback, sidebar);
3537
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3538
mount_removed_callback, sidebar);
3539
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3540
mount_changed_callback, sidebar);
3541
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3542
drive_disconnected_callback, sidebar);
3543
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3544
drive_connected_callback, sidebar);
3545
g_signal_handlers_disconnect_by_func (sidebar->volume_monitor,
3546
drive_changed_callback, sidebar);
3548
g_clear_object (&sidebar->volume_monitor);
3551
if (sidebar->hostnamed_cancellable != NULL) {
3552
g_cancellable_cancel (sidebar->hostnamed_cancellable);
3553
g_clear_object (&sidebar->hostnamed_cancellable);
3556
g_clear_object (&sidebar->hostnamed_proxy);
3557
g_free (sidebar->hostname);
3558
sidebar->hostname = NULL;
3560
G_OBJECT_CLASS (nautilus_places_sidebar_parent_class)->dispose (object);
3564
nautilus_places_sidebar_class_init (NautilusPlacesSidebarClass *class)
3566
G_OBJECT_CLASS (class)->dispose = nautilus_places_sidebar_dispose;
3568
GTK_WIDGET_CLASS (class)->style_set = nautilus_places_sidebar_style_set;
3569
GTK_WIDGET_CLASS (class)->focus = nautilus_places_sidebar_focus;
3573
nautilus_places_sidebar_set_parent_window (NautilusPlacesSidebar *sidebar,
3574
NautilusWindow *window)
3576
NautilusWindowSlot *slot;
3577
NautilusApplication *app = NAUTILUS_APPLICATION (g_application_get_default ());
3579
sidebar->window = window;
3581
slot = nautilus_window_get_active_slot (window);
3583
sidebar->bookmarks = nautilus_application_get_bookmarks (app);
3584
sidebar->bookmarks_changed_id =
3585
g_signal_connect_swapped (sidebar->bookmarks, "changed",
3586
G_CALLBACK (update_places),
3589
g_signal_connect_object (sidebar->volume_monitor, "volume-added",
3590
G_CALLBACK (volume_added_callback), sidebar, 0);
3591
g_signal_connect_object (sidebar->volume_monitor, "volume-removed",
3592
G_CALLBACK (volume_removed_callback), sidebar, 0);
3593
g_signal_connect_object (sidebar->volume_monitor, "volume-changed",
3594
G_CALLBACK (volume_changed_callback), sidebar, 0);
3595
g_signal_connect_object (sidebar->volume_monitor, "mount-added",
3596
G_CALLBACK (mount_added_callback), sidebar, 0);
3597
g_signal_connect_object (sidebar->volume_monitor, "mount-removed",
3598
G_CALLBACK (mount_removed_callback), sidebar, 0);
3599
g_signal_connect_object (sidebar->volume_monitor, "mount-changed",
3600
G_CALLBACK (mount_changed_callback), sidebar, 0);
3601
g_signal_connect_object (sidebar->volume_monitor, "drive-disconnected",
3602
G_CALLBACK (drive_disconnected_callback), sidebar, 0);
3603
g_signal_connect_object (sidebar->volume_monitor, "drive-connected",
3604
G_CALLBACK (drive_connected_callback), sidebar, 0);
3605
g_signal_connect_object (sidebar->volume_monitor, "drive-changed",
3606
G_CALLBACK (drive_changed_callback), sidebar, 0);
3608
update_places (sidebar);
3610
g_signal_connect_object (window, "loading-uri",
3611
G_CALLBACK (loading_uri_callback),
3613
sidebar->uri = nautilus_window_slot_get_current_uri (slot);
3614
update_current_uri (sidebar);
3618
nautilus_places_sidebar_style_set (GtkWidget *widget,
3619
GtkStyle *previous_style)
3621
NautilusPlacesSidebar *sidebar;
3623
sidebar = NAUTILUS_PLACES_SIDEBAR (widget);
3625
update_places (sidebar);
3629
nautilus_places_sidebar_new (NautilusWindow *window)
3631
NautilusPlacesSidebar *sidebar;
3633
sidebar = g_object_new (nautilus_places_sidebar_get_type (), NULL);
3634
nautilus_places_sidebar_set_parent_window (sidebar, window);
3636
return GTK_WIDGET (sidebar);
3640
/* Drag and drop interfaces */
3642
/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */
3645
nautilus_shortcuts_model_row_draggable (GtkTreeDragSource *drag_source,
3648
GtkTreeModel *model;
3650
PlaceType place_type;
3651
SectionType section_type;
3653
model = GTK_TREE_MODEL (drag_source);
3655
gtk_tree_model_get_iter (model, &iter, path);
3656
gtk_tree_model_get (model, &iter,
3657
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
3658
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, §ion_type,
3661
if (place_type != PLACES_HEADING && section_type == SECTION_BOOKMARKS)
3668
_nautilus_shortcuts_model_class_init (NautilusShortcutsModelClass *klass)
3674
_nautilus_shortcuts_model_init (NautilusShortcutsModel *model)
3676
model->sidebar = NULL;
3680
_nautilus_shortcuts_model_drag_source_init (GtkTreeDragSourceIface *iface)
3682
iface->row_draggable = nautilus_shortcuts_model_row_draggable;
3685
static GtkListStore *
3686
nautilus_shortcuts_model_new (NautilusPlacesSidebar *sidebar)
3688
NautilusShortcutsModel *model;
3689
GType model_types[PLACES_SIDEBAR_COLUMN_COUNT] = {
3706
model = g_object_new (_nautilus_shortcuts_model_get_type (), NULL);
3707
model->sidebar = sidebar;
3709
gtk_list_store_set_column_types (GTK_LIST_STORE (model),
3710
PLACES_SIDEBAR_COLUMN_COUNT,
3713
return GTK_LIST_STORE (model);