diff options
-rw-r--r-- | po/POTFILES.in | 3 | ||||
-rwxr-xr-x | src/gtk/gtk-code-generator.sh | 106 | ||||
-rw-r--r-- | src/gtk/nautilusgtkbookmarksmanager.c | 594 | ||||
-rw-r--r-- | src/gtk/nautilusgtkbookmarksmanager.h | 90 | ||||
-rw-r--r-- | src/gtk/nautilusgtkplacessidebar.c | 5633 | ||||
-rw-r--r-- | src/gtk/nautilusgtkplacessidebar.h | 159 | ||||
-rw-r--r-- | src/gtk/nautilusgtkplacessidebarprivate.h | 60 | ||||
-rw-r--r-- | src/gtk/nautilusgtkplacesview.c | 46 | ||||
-rw-r--r-- | src/gtk/nautilusgtkplacesviewprivate.h | 9 | ||||
-rw-r--r-- | src/gtk/nautilusgtkplacesviewrow.c | 8 | ||||
-rw-r--r-- | src/gtk/nautilusgtksidebarrow.c | 667 | ||||
-rw-r--r-- | src/gtk/nautilusgtksidebarrow.ui | 92 | ||||
-rw-r--r-- | src/gtk/nautilusgtksidebarrowprivate.h | 61 | ||||
-rw-r--r-- | src/meson.build | 7 | ||||
-rw-r--r-- | src/nautilus-places-view.c | 6 | ||||
-rw-r--r-- | src/nautilus-window.c | 115 | ||||
-rw-r--r-- | src/resources/nautilus.gresource.xml | 1 | ||||
-rw-r--r-- | src/resources/ui/nautilus-window.ui | 11 |
18 files changed, 136 insertions, 7532 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in index 20c36be67..7c1b6a31b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -98,6 +98,3 @@ src/gtk/nautilusgtkplacesview.c src/gtk/nautilusgtkplacesviewrow.c src/gtk/nautilusgtkplacesviewrow.ui src/gtk/nautilusgtkplacesview.ui -src/gtk/nautilusgtkbookmarksmanager.c -src/gtk/nautilusgtkplacessidebar.c -src/gtk/nautilusgtksidebarrow.ui diff --git a/src/gtk/gtk-code-generator.sh b/src/gtk/gtk-code-generator.sh index e6f2ac0d0..147efb3bd 100755 --- a/src/gtk/gtk-code-generator.sh +++ b/src/gtk/gtk-code-generator.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Fetch the GtkPlaces* files but rename the symbols to avoid symbol clashes +# Fetch the GtkPlacesView files but rename the symbols to avoid symbol clashes # when using the file chooser inside nautilus i.e. when activating the "move to" # action. # Also remove/add the neccesary bits to make it work inside nautilus @@ -13,7 +13,6 @@ SUFIX=?h=gtk-3-24 # by order: # type substitution # remove marshalers -# replace GtkTrashMonitor API with NautilusTrashMonitor API # add external localization library after the always there config.h # and remove the gtk internal P_ and I_ localization, we don't actually # want localization of this in nautilus @@ -21,9 +20,6 @@ SUFIX=?h=gtk-3-24 # and remove all the other types that get included by the general gtk.h # remove the error when including gtk.h # load nautilus resources, not gtk resources -# use local sidebar header instead of private gtk one -# in-line replace private gtkfilesystem.h helper function -# ignore shadowed variable which we would treat as compile error update_file () { _source="$1" @@ -36,86 +32,62 @@ update_file () { -e 's/GTK_PLACES_VIEW/NAUTILUS_GTK_PLACES_VIEW/g' \ -e 's/GTK_TYPE_PLACES_VIEW/NAUTILUS_TYPE_GTK_PLACES_VIEW/g' \ -e 's/GTK_IS_PLACES_VIEW/NAUTILUS_IS_GTK_PLACES_VIEW/g' \ - -e 's/G_DECLARE_FINAL_TYPE (NautilusGtkPlacesViewRow, nautilus_gtk_places_view_row, GTK, PLACES_VIEW_ROW, GtkListBoxRow/ G_DECLARE_FINAL_TYPE (NautilusGtkPlacesViewRow, nautilus_gtk_places_view_row, NAUTILUS, GTK_PLACES_VIEW_ROW, GtkListBoxRow/g' \ - -e 's/gtkplacessidebar/nautilusgtkplacessidebar/g' \ - -e 's/gtk_places_sidebar/nautilus_gtk_places_sidebar/g' \ - -e 's/GtkPlacesSidebar/NautilusGtkPlacesSidebar/g' \ - -e 's/GTK_PLACES_SIDEBAR/NAUTILUS_GTK_PLACES_SIDEBAR/g' \ - -e 's/GTK_TYPE_PLACES_SIDEBAR/NAUTILUS_TYPE_GTK_PLACES_SIDEBAR/g' \ - -e 's/GTK_IS_PLACES_SIDEBAR/NAUTILUS_IS_GTK_PLACES_SIDEBAR/g' \ - -e 's/GtkPlacesOpen/NautilusGtkPlacesOpen/g' \ - -e 's/GTK_PLACES_OPEN/NAUTILUS_GTK_PLACES_OPEN/g' \ - -e 's/gtkbookmarksmanager/nautilusgtkbookmarksmanager/g' \ - -e 's/gtk_bookmarks_manager/nautilus_gtk_bookmarks_manager/g' \ - -e 's/GtkBookmarksManager/NautilusGtkBookmarksManager/g' \ - -e 's/GTK_BOOKMARKS_MANAGER/NAUTILUS_GTK_BOOKMARKS_MANAGER/g' \ - -e 's/GTK_TYPE_BOOKMARKS_MANAGER/NAUTILUS_TYPE_GTK_BOOKMARKS_MANAGER/g' \ - -e 's/GTK_IS_BOOKMARKS_MANAGER/NAUTILUS_IS_GTK_BOOKMARKS_MANAGER/g' \ - -e 's/gtksidebarrow/nautilusgtksidebarrow/g' \ - -e 's/gtk_sidebar_row/nautilus_gtk_sidebar_row/g' \ - -e 's/GtkSidebarRow/NautilusGtkSidebarRow/g' \ - -e 's/GTK_SIDEBAR_ROW/NAUTILUS_GTK_SIDEBAR_ROW/g' \ - -e 's/GTK_TYPE_SIDEBAR_ROW/NAUTILUS_TYPE_GTK_SIDEBAR_ROW/g' \ - -e 's/GTK_IS_SIDEBAR_ROW/NAUTILUS_IS_GTK_SIDEBAR_ROW/g' \ - -e 's/G_DECLARE_FINAL_TYPE (NautilusGtkSidebarRow, nautilus_gtk_sidebar_row, GTK, SIDEBAR_ROW, GtkListBoxRow/ G_DECLARE_FINAL_TYPE (NautilusGtkSidebarRow, nautilus_gtk_sidebar_row, NAUTILUS, GTK_SIDEBAR_ROW, GtkListBoxRow/g' \ -e 's/_gtk_marshal_VOID__STRING_STRING/NULL/g' \ -e '/gtkmarshalers.h/d' \ -e '/g_signal_set_va_marshaller/,+2d' \ -e 's/_gtk_marshal_VOID__OBJECT_FLAGS/NULL/g' \ - -e 's/_gtk_marshal_VOID__OBJECT_POINTER_INT/NULL/g' \ - -e 's/_gtk_marshal_VOID__OBJECT_OBJECT_OBJECT/NULL/g' \ - -e 's/_gtk_marshal_INT__OBJECT_OBJECT_POINTER/NULL/g' \ - -e 's/_gtk_marshal_INT__INT/NULL/g' \ - -e 's/gtktrashmonitor.h/nautilus-trash-monitor.h/g' \ - -e 's/GtkTrashMonitor/NautilusTrashMonitor/g' \ - -e "s/_gtk_trash_monitor_get_icon (\(.*\))/nautilus_trash_monitor_get_symbolic_icon ()/g" \ - -e "s/_gtk_trash_monitor_get_has_trash (\(.*\))/!nautilus_trash_monitor_is_empty ()/g" \ - -e 's/_gtk_trash_monitor_get/nautilus_trash_monitor_get/g' \ -e '/"config.h"/a #include <glib\/gi18n.h>' \ -e "s/P_(\(.*\))/\1/" \ -e "s/I_(\(.*\))/\1/" \ -e '/"config.h"/a #include <gtk\/gtk.h>' \ -e '/gtktypebuiltins.h/d' \ + -e '/gtkplacessidebar.h/d' \ -e '/gtkintl.h/d' \ - -e '/<gtk\/gtkbox.h>/d' \ - -e '/"gtkbox\(.*\).h"/d' \ - -e '/"gtkbu\(.*\).h"/d' \ - -e '/"gtkc\(.*\).h"/d' \ - -e '/"gtkd\(.*\).h"/d' \ - -e '/"gtke\(.*\).h"/d' \ - -e '/"gtkf\(.*\).h"/d' \ - -e '/"gtkg\(.*\).h"/d' \ - -e '/"gtki\(.*\).h"/d' \ - -e '/"gtkl\(.*\).h"/d' \ - -e '/"gtkm\(.*\).h"/d' \ - -e '/"gtkpo\(.*\).h"/d' \ - -e '/"gtkr\(.*\).h"/d' \ - -e '/"gtksc\(.*\).h"/d' \ - -e '/"gtkse\(.*\).h"/d' \ - -e '/"gtksi\(.*\).h"/d' \ - -e '/"gtksp\(.*\).h"/d' \ - -e '/"gtkst\(.*\).h"/d' \ - -e '/"gtkt\(.*\).h"/d' \ - -e '/"gtkw\(.*\).h"/d' \ + -e '/gtkbox.h/d' \ -e '/#error/d' \ -e 's/gtk\/libgtk/gnome\/nautilus\/gtk/g' \ - -e 's/<gtk\/nautilusgtkplacessidebar.h>/"nautilusgtkplacessidebar.h"'/g \ - -e 's/_gtk_file_info_consider_as_directory (info)/(g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY || g_file_info_get_file_type (info) == G_FILE_TYPE_MOUNTABLE || g_file_info_get_file_type (info) == G_FILE_TYPE_SHORTCUT)/g' \ - -e '/#include "nautilus-trash-monitor.h"/a #pragma GCC diagnostic ignored "-Wshadow"' \ > "${_dest}" } update_file "${URL}/gtkplacesview.c${SUFIX}" "nautilusgtkplacesview.c" update_file "${URL}/gtkplacesviewprivate.h${SUFIX}" "nautilusgtkplacesviewprivate.h" update_file "${URLUI}/gtkplacesview.ui${SUFIX}" "nautilusgtkplacesview.ui" -update_file "${URL}/gtkplacessidebar.c${SUFIX}" "nautilusgtkplacessidebar.c" -update_file "${URL}/gtkplacessidebarprivate.h${SUFIX}" "nautilusgtkplacessidebarprivate.h" -update_file "${URL}/gtkplacessidebar.h${SUFIX}" "nautilusgtkplacessidebar.h" -update_file "${URL}/gtkbookmarksmanager.c${SUFIX}" "nautilusgtkbookmarksmanager.c" -update_file "${URL}/gtkbookmarksmanager.h${SUFIX}" "nautilusgtkbookmarksmanager.h" + +# Since comments are not allowed inside the sed line, this is what it will do +# by order: +# type substitution +# use the correct prefixes for type definition +# add external localization library after the always there config.h +# and remove the gtk internal P_ and I_ localization, we don't actually +# want localization of this in nautilus +# include gtk.h library after the always there config.h +# and remove all the other types that get included by the general gtk.h +# remove the error when including gtk.h +# load nautilus resources, not gtk resources +update_file () { + _source="$1" + _dest="$2" + + curl "${_source}" | sed \ + -e 's/gtkplacesviewrow/nautilusgtkplacesviewrow/g' \ + -e 's/gtk_places_view_row/nautilus_gtk_places_view_row/g' \ + -e 's/GtkPlacesViewRow/NautilusGtkPlacesViewRow/g' \ + -e 's/GTK_PLACES_VIEW_ROW/NAUTILUS_GTK_PLACES_VIEW_ROW/g' \ + -e 's/GTK_TYPE_PLACES_VIEW_ROW/NAUTILUS_TYPE_GTK_PLACES_VIEW_ROW/g' \ + -e 's/GTK_IS_PLACES_VIEW_ROW/NAUTILUS_IS_GTK_PLACES_VIEW_ROW/g' \ + -e 's/G_DECLARE_FINAL_TYPE (NautilusGtkPlacesViewRow, nautilus_gtk_places_view_row, GTK, PLACES_VIEW_ROW, GtkListBoxRow/ G_DECLARE_FINAL_TYPE (NautilusGtkPlacesViewRow, nautilus_gtk_places_view_row, NAUTILUS, GTK_PLACES_VIEW_ROW, GtkListBoxRow/g' \ + -e '/"config.h"/a #include <glib\/gi18n.h>' \ + -e "s/P_(\(.*\))/\1/" \ + -e "s/I_(\(.*\))/\1/" \ + -e '/"config.h"/a #include <gtk\/gtk.h>' \ + -e '/gtksizegroup.h/d' \ + -e '/gtkwidget.h/d' \ + -e '/gtklistbox.h/d' \ + -e '/#error /d' \ + -e 's/gtk\/libgtk/gnome\/nautilus\/gtk/g' \ + > "${_dest}" +} + update_file "${URL}/gtkplacesviewrow.c${SUFIX}" "nautilusgtkplacesviewrow.c" update_file "${URL}/gtkplacesviewrowprivate.h${SUFIX}" "nautilusgtkplacesviewrowprivate.h" update_file "${URLUI}/gtkplacesviewrow.ui${SUFIX}" "nautilusgtkplacesviewrow.ui" -update_file "${URL}/gtksidebarrow.c${SUFIX}" "nautilusgtksidebarrow.c" -update_file "${URL}/gtksidebarrowprivate.h${SUFIX}" "nautilusgtksidebarrowprivate.h" -update_file "${URLUI}/gtksidebarrow.ui${SUFIX}" "nautilusgtksidebarrow.ui" diff --git a/src/gtk/nautilusgtkbookmarksmanager.c b/src/gtk/nautilusgtkbookmarksmanager.c deleted file mode 100644 index 385d58635..000000000 --- a/src/gtk/nautilusgtkbookmarksmanager.c +++ /dev/null @@ -1,594 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */ -/* GTK - The GIMP Toolkit - * nautilusgtkbookmarksmanager.c: Utilities to manage and monitor ~/.gtk-bookmarks - * Copyright (C) 2003, Red Hat, Inc. - * Copyright (C) 2007-2008 Carlos Garnacho - * Copyright (C) 2011 Suse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - * - * Authors: Federico Mena Quintero <federico@gnome.org> - */ - -#include "config.h" -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#include <string.h> - -#include <glib/gi18n-lib.h> - -#include "nautilusgtkbookmarksmanager.h" - -static void -_gtk_bookmark_free (gpointer data) -{ - GtkBookmark *bookmark = data; - - g_object_unref (bookmark->file); - g_free (bookmark->label); - g_slice_free (GtkBookmark, bookmark); -} - -static void -set_error_bookmark_doesnt_exist (GFile *file, GError **error) -{ - gchar *uri = g_file_get_uri (file); - - g_set_error (error, - GTK_FILE_CHOOSER_ERROR, - GTK_FILE_CHOOSER_ERROR_NONEXISTENT, - _("%s does not exist in the bookmarks list"), - uri); - - g_free (uri); -} - -static GFile * -get_legacy_bookmarks_file (void) -{ - GFile *file; - gchar *filename; - - filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL); - file = g_file_new_for_path (filename); - g_free (filename); - - return file; -} - -static GFile * -get_bookmarks_file (void) -{ - GFile *file; - gchar *filename; - - filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL); - file = g_file_new_for_path (filename); - g_free (filename); - - return file; -} - -static GSList * -read_bookmarks (GFile *file) -{ - gchar *contents; - gchar **lines, *space; - GSList *bookmarks = NULL; - gint i; - - if (!g_file_load_contents (file, NULL, &contents, - NULL, NULL, NULL)) - return NULL; - - lines = g_strsplit (contents, "\n", -1); - - for (i = 0; lines[i]; i++) - { - GtkBookmark *bookmark; - - if (!*lines[i]) - continue; - - if (!g_utf8_validate (lines[i], -1, NULL)) - continue; - - bookmark = g_slice_new0 (GtkBookmark); - - if ((space = strchr (lines[i], ' ')) != NULL) - { - space[0] = '\0'; - bookmark->label = g_strdup (space + 1); - } - - bookmark->file = g_file_new_for_uri (lines[i]); - bookmarks = g_slist_prepend (bookmarks, bookmark); - } - - bookmarks = g_slist_reverse (bookmarks); - g_strfreev (lines); - g_free (contents); - - return bookmarks; -} - -static void -save_bookmarks (GFile *bookmarks_file, - GSList *bookmarks) -{ - GError *error = NULL; - GString *contents; - GSList *l; - GFile *parent = NULL; - - contents = g_string_new (""); - - for (l = bookmarks; l; l = l->next) - { - GtkBookmark *bookmark = l->data; - gchar *uri; - - uri = g_file_get_uri (bookmark->file); - if (!uri) - continue; - - g_string_append (contents, uri); - - if (bookmark->label && g_utf8_validate (bookmark->label, -1, NULL)) - g_string_append_printf (contents, " %s", bookmark->label); - - g_string_append_c (contents, '\n'); - g_free (uri); - } - - parent = g_file_get_parent (bookmarks_file); - if (!g_file_make_directory_with_parents (parent, NULL, &error)) - { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) - g_clear_error (&error); - else - goto out; - } - if (!g_file_replace_contents (bookmarks_file, - contents->str, - contents->len, - NULL, FALSE, 0, NULL, - NULL, &error)) - goto out; - - out: - if (error) - { - g_critical ("%s", error->message); - g_error_free (error); - } - g_clear_object (&parent); - g_string_free (contents, TRUE); -} - -static void -notify_changed (NautilusGtkBookmarksManager *manager) -{ - if (manager->changed_func) - manager->changed_func (manager->changed_func_data); -} - -static void -bookmarks_file_changed (GFileMonitor *monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event, - gpointer data) -{ - NautilusGtkBookmarksManager *manager = data; - - switch (event) - { - case G_FILE_MONITOR_EVENT_CHANGED: - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - case G_FILE_MONITOR_EVENT_CREATED: - case G_FILE_MONITOR_EVENT_DELETED: - g_slist_free_full (manager->bookmarks, _gtk_bookmark_free); - manager->bookmarks = read_bookmarks (file); - - gdk_threads_enter (); - notify_changed (manager); - gdk_threads_leave (); - break; - - default: - /* ignore at the moment */ - break; - } -} - -NautilusGtkBookmarksManager * -_nautilus_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func, gpointer changed_func_data) -{ - NautilusGtkBookmarksManager *manager; - GFile *bookmarks_file; - GError *error; - - manager = g_new0 (NautilusGtkBookmarksManager, 1); - - manager->changed_func = changed_func; - manager->changed_func_data = changed_func_data; - - bookmarks_file = get_bookmarks_file (); - manager->bookmarks = read_bookmarks (bookmarks_file); - if (!manager->bookmarks) - { - GFile *legacy_bookmarks_file; - - /* Read the legacy one and write it to the new one */ - legacy_bookmarks_file = get_legacy_bookmarks_file (); - manager->bookmarks = read_bookmarks (legacy_bookmarks_file); - if (manager->bookmarks) - save_bookmarks (bookmarks_file, manager->bookmarks); - - g_object_unref (legacy_bookmarks_file); - } - - error = NULL; - manager->bookmarks_monitor = g_file_monitor_file (bookmarks_file, - G_FILE_MONITOR_NONE, - NULL, &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } - else - manager->bookmarks_monitor_changed_id = g_signal_connect (manager->bookmarks_monitor, "changed", - G_CALLBACK (bookmarks_file_changed), manager); - - g_object_unref (bookmarks_file); - - return manager; -} - -void -_nautilus_gtk_bookmarks_manager_free (NautilusGtkBookmarksManager *manager) -{ - g_return_if_fail (manager != NULL); - - if (manager->bookmarks_monitor) - { - g_file_monitor_cancel (manager->bookmarks_monitor); - g_signal_handler_disconnect (manager->bookmarks_monitor, manager->bookmarks_monitor_changed_id); - manager->bookmarks_monitor_changed_id = 0; - g_object_unref (manager->bookmarks_monitor); - } - - g_slist_free_full (manager->bookmarks, _gtk_bookmark_free); - - g_free (manager); -} - -GSList * -_nautilus_gtk_bookmarks_manager_list_bookmarks (NautilusGtkBookmarksManager *manager) -{ - GSList *bookmarks, *files = NULL; - - g_return_val_if_fail (manager != NULL, NULL); - - bookmarks = manager->bookmarks; - - while (bookmarks) - { - GtkBookmark *bookmark; - - bookmark = bookmarks->data; - bookmarks = bookmarks->next; - - files = g_slist_prepend (files, g_object_ref (bookmark->file)); - } - - return g_slist_reverse (files); -} - -static GSList * -find_bookmark_link_for_file (GSList *bookmarks, GFile *file, int *position_ret) -{ - int pos; - - pos = 0; - for (; bookmarks; bookmarks = bookmarks->next) - { - GtkBookmark *bookmark = bookmarks->data; - - if (g_file_equal (file, bookmark->file)) - { - if (position_ret) - *position_ret = pos; - - return bookmarks; - } - - pos++; - } - - if (position_ret) - *position_ret = -1; - - return NULL; -} - -gboolean -_nautilus_gtk_bookmarks_manager_has_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file) -{ - GSList *link; - - link = find_bookmark_link_for_file (manager->bookmarks, file, NULL); - return (link != NULL); -} - -gboolean -_nautilus_gtk_bookmarks_manager_insert_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file, - gint position, - GError **error) -{ - GSList *link; - GtkBookmark *bookmark; - GFile *bookmarks_file; - - g_return_val_if_fail (manager != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - link = find_bookmark_link_for_file (manager->bookmarks, file, NULL); - - if (link) - { - gchar *uri; - bookmark = link->data; - uri = g_file_get_uri (bookmark->file); - - g_set_error (error, - GTK_FILE_CHOOSER_ERROR, - GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS, - _("%s already exists in the bookmarks list"), - uri); - - g_free (uri); - - return FALSE; - } - - bookmark = g_slice_new0 (GtkBookmark); - bookmark->file = g_object_ref (file); - - manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, position); - - bookmarks_file = get_bookmarks_file (); - save_bookmarks (bookmarks_file, manager->bookmarks); - g_object_unref (bookmarks_file); - - notify_changed (manager); - - return TRUE; -} - -gboolean -_nautilus_gtk_bookmarks_manager_remove_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file, - GError **error) -{ - GSList *link; - GFile *bookmarks_file; - - g_return_val_if_fail (manager != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (!manager->bookmarks) - return FALSE; - - link = find_bookmark_link_for_file (manager->bookmarks, file, NULL); - if (link) - { - GtkBookmark *bookmark = link->data; - - manager->bookmarks = g_slist_remove_link (manager->bookmarks, link); - _gtk_bookmark_free (bookmark); - g_slist_free_1 (link); - } - else - { - set_error_bookmark_doesnt_exist (file, error); - return FALSE; - } - - bookmarks_file = get_bookmarks_file (); - save_bookmarks (bookmarks_file, manager->bookmarks); - g_object_unref (bookmarks_file); - - notify_changed (manager); - - return TRUE; -} - -gboolean -_nautilus_gtk_bookmarks_manager_reorder_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file, - gint new_position, - GError **error) -{ - GSList *link; - GFile *bookmarks_file; - int old_position; - - g_return_val_if_fail (manager != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (new_position >= 0, FALSE); - - if (!manager->bookmarks) - return FALSE; - - link = find_bookmark_link_for_file (manager->bookmarks, file, &old_position); - if (new_position == old_position) - return TRUE; - - if (link) - { - GtkBookmark *bookmark = link->data; - - manager->bookmarks = g_slist_remove_link (manager->bookmarks, link); - g_slist_free_1 (link); - - if (new_position > old_position) - new_position--; - - manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, new_position); - } - else - { - set_error_bookmark_doesnt_exist (file, error); - return FALSE; - } - - bookmarks_file = get_bookmarks_file (); - save_bookmarks (bookmarks_file, manager->bookmarks); - g_object_unref (bookmarks_file); - - notify_changed (manager); - - return TRUE; -} - -gchar * -_nautilus_gtk_bookmarks_manager_get_bookmark_label (NautilusGtkBookmarksManager *manager, - GFile *file) -{ - GSList *bookmarks; - gchar *label = NULL; - - g_return_val_if_fail (manager != NULL, NULL); - g_return_val_if_fail (file != NULL, NULL); - - bookmarks = manager->bookmarks; - - while (bookmarks) - { - GtkBookmark *bookmark; - - bookmark = bookmarks->data; - bookmarks = bookmarks->next; - - if (g_file_equal (file, bookmark->file)) - { - label = g_strdup (bookmark->label); - break; - } - } - - return label; -} - -gboolean -_nautilus_gtk_bookmarks_manager_set_bookmark_label (NautilusGtkBookmarksManager *manager, - GFile *file, - const gchar *label, - GError **error) -{ - GFile *bookmarks_file; - GSList *link; - - g_return_val_if_fail (manager != NULL, FALSE); - g_return_val_if_fail (file != NULL, FALSE); - - link = find_bookmark_link_for_file (manager->bookmarks, file, NULL); - if (link) - { - GtkBookmark *bookmark = link->data; - - g_free (bookmark->label); - bookmark->label = g_strdup (label); - } - else - { - set_error_bookmark_doesnt_exist (file, error); - return FALSE; - } - - bookmarks_file = get_bookmarks_file (); - save_bookmarks (bookmarks_file, manager->bookmarks); - g_object_unref (bookmarks_file); - - notify_changed (manager); - - return TRUE; -} - -gboolean -_nautilus_gtk_bookmarks_manager_get_xdg_type (NautilusGtkBookmarksManager *manager, - GFile *file, - GUserDirectory *directory) -{ - GSList *link; - gboolean match; - GFile *location; - const gchar *path; - GUserDirectory dir; - GtkBookmark *bookmark; - - link = find_bookmark_link_for_file (manager->bookmarks, file, NULL); - if (!link) - return FALSE; - - match = FALSE; - bookmark = link->data; - - for (dir = 0; dir < G_USER_N_DIRECTORIES; dir++) - { - path = g_get_user_special_dir (dir); - if (!path) - continue; - - location = g_file_new_for_path (path); - match = g_file_equal (location, bookmark->file); - g_object_unref (location); - - if (match) - break; - } - - if (match && directory != NULL) - *directory = dir; - - return match; -} - -gboolean -_nautilus_gtk_bookmarks_manager_get_is_builtin (NautilusGtkBookmarksManager *manager, - GFile *file) -{ - GUserDirectory xdg_type; - - /* if this is not an XDG dir, it's never builtin */ - if (!_nautilus_gtk_bookmarks_manager_get_xdg_type (manager, file, &xdg_type)) - return FALSE; - - /* exclude XDG locations we don't display by default */ - return _nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (xdg_type); -} - -gboolean -_nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type) -{ - return (xdg_type != G_USER_DIRECTORY_DESKTOP) && - (xdg_type != G_USER_DIRECTORY_TEMPLATES) && - (xdg_type != G_USER_DIRECTORY_PUBLIC_SHARE); -} diff --git a/src/gtk/nautilusgtkbookmarksmanager.h b/src/gtk/nautilusgtkbookmarksmanager.h deleted file mode 100644 index 229c61370..000000000 --- a/src/gtk/nautilusgtkbookmarksmanager.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */ -/* GTK - The GIMP Toolkit - * nautilusgtkbookmarksmanager.h: Utilities to manage and monitor ~/.gtk-bookmarks - * Copyright (C) 2003, Red Hat, Inc. - * Copyright (C) 2007-2008 Carlos Garnacho - * Copyright (C) 2011 Suse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - * - * Authors: Federico Mena Quintero <federico@gnome.org> - */ - -#ifndef __NAUTILUS_GTK_BOOKMARKS_MANAGER_H__ -#define __NAUTILUS_GTK_BOOKMARKS_MANAGER_H__ - -#include <gio/gio.h> - -typedef void (* GtkBookmarksChangedFunc) (gpointer data); - -typedef struct -{ - /* This list contains GtkBookmark structs */ - GSList *bookmarks; - - GFileMonitor *bookmarks_monitor; - gulong bookmarks_monitor_changed_id; - - gpointer changed_func_data; - GtkBookmarksChangedFunc changed_func; -} NautilusGtkBookmarksManager; - -typedef struct -{ - GFile *file; - gchar *label; -} GtkBookmark; - -NautilusGtkBookmarksManager *_nautilus_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func, - gpointer changed_func_data); - - -void _nautilus_gtk_bookmarks_manager_free (NautilusGtkBookmarksManager *manager); - -GSList *_nautilus_gtk_bookmarks_manager_list_bookmarks (NautilusGtkBookmarksManager *manager); - -gboolean _nautilus_gtk_bookmarks_manager_insert_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file, - gint position, - GError **error); - -gboolean _nautilus_gtk_bookmarks_manager_remove_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file, - GError **error); - -gboolean _nautilus_gtk_bookmarks_manager_reorder_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file, - gint new_position, - GError **error); - -gboolean _nautilus_gtk_bookmarks_manager_has_bookmark (NautilusGtkBookmarksManager *manager, - GFile *file); - -gchar * _nautilus_gtk_bookmarks_manager_get_bookmark_label (NautilusGtkBookmarksManager *manager, - GFile *file); - -gboolean _nautilus_gtk_bookmarks_manager_set_bookmark_label (NautilusGtkBookmarksManager *manager, - GFile *file, - const gchar *label, - GError **error); - -gboolean _nautilus_gtk_bookmarks_manager_get_xdg_type (NautilusGtkBookmarksManager *manager, - GFile *file, - GUserDirectory *directory); -gboolean _nautilus_gtk_bookmarks_manager_get_is_builtin (NautilusGtkBookmarksManager *manager, - GFile *file); - -gboolean _nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type); - -#endif /* __NAUTILUS_GTK_BOOKMARKS_MANAGER_H__ */ diff --git a/src/gtk/nautilusgtkplacessidebar.c b/src/gtk/nautilusgtkplacessidebar.c deleted file mode 100644 index 71c320d7d..000000000 --- a/src/gtk/nautilusgtkplacessidebar.c +++ /dev/null @@ -1,5633 +0,0 @@ -/* NautilusGtkPlacesSidebar - sidebar widget for places in the filesystem - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - * This code is originally from Nautilus. - * - * Authors : Mr Jamie McCracken (jamiemcc at blueyonder dot co dot uk) - * Cosimo Cecchi <cosimoc@gnome.org> - * Federico Mena Quintero <federico@gnome.org> - * Carlos Soriano <csoriano@gnome.org> - */ - -#include "config.h" -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#include <gio/gio.h> -#ifdef HAVE_CLOUDPROVIDERS -#include <cloudproviders/cloudproviderscollector.h> -#include <cloudproviders/cloudprovidersaccount.h> -#include <cloudproviders/cloudprovidersprovider.h> -#endif - -#include "nautilusgtkplacessidebarprivate.h" -#include "nautilusgtksidebarrowprivate.h" -#include "gdk/gdkkeysyms.h" -#include "nautilusgtkbookmarksmanager.h" -#include "nautilusgtkplacessidebar.h" -#include "nautilus-trash-monitor.h" -#pragma GCC diagnostic ignored "-Wshadow" - -/** - * SECTION:nautilusgtkplacessidebar - * @Short_description: Sidebar that displays frequently-used places in the file system - * @Title: NautilusGtkPlacesSidebar - * @See_also: #GtkFileChooser - * - * #NautilusGtkPlacesSidebar is a widget that displays a list of frequently-used places in the - * file system: the user’s home directory, the user’s bookmarks, and volumes and drives. - * This widget is used as a sidebar in #GtkFileChooser and may be used by file managers - * and similar programs. - * - * The places sidebar displays drives and volumes, and will automatically mount - * or unmount them when the user selects them. - * - * Applications can hook to various signals in the places sidebar to customize - * its behavior. For example, they can add extra commands to the context menu - * of the sidebar. - * - * While bookmarks are completely in control of the user, the places sidebar also - * allows individual applications to provide extra shortcut folders that are unique - * to each application. For example, a Paint program may want to add a shortcut - * for a Clipart folder. You can do this with nautilus_gtk_places_sidebar_add_shortcut(). - * - * To make use of the places sidebar, an application at least needs to connect - * to the #NautilusGtkPlacesSidebar::open-location signal. This is emitted when the - * user selects in the sidebar a location to open. The application should also - * call nautilus_gtk_places_sidebar_set_location() when it changes the currently-viewed - * location. - * - * # CSS nodes - * - * NautilusGtkPlacesSidebar uses a single CSS node with name placessidebar and style - * class .sidebar. - * - * Among the children of the places sidebar, the following style classes can - * be used: - * - .sidebar-new-bookmark-row for the 'Add new bookmark' row - * - .sidebar-placeholder-row for a row that is a placeholder - * - .has-open-popup when a popup is open for a row - */ - -/* These are used when a destination-side DND operation is taking place. - * Normally, when a common drag action is taking place, the state will be - * DROP_STATE_NEW_BOOKMARK_ARMED, however, if the client of NautilusGtkPlacesSidebar - * wants to show hints about the valid targets, we sill set it as - * DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT, so the sidebar will show drop hints - * until the client says otherwise - */ -typedef enum { - DROP_STATE_NORMAL, - DROP_STATE_NEW_BOOKMARK_ARMED, - DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT, -} DropState; - -struct _NautilusGtkPlacesSidebar { - GtkScrolledWindow parent; - - GtkWidget *list_box; - GtkWidget *new_bookmark_row; - - NautilusGtkBookmarksManager *bookmarks_manager; - -#ifdef HAVE_CLOUDPROVIDERS - CloudProvidersCollector *cloud_manager; - GList *unready_accounts; -#endif - - GVolumeMonitor *volume_monitor; - NautilusTrashMonitor *trash_monitor; - GtkSettings *gtk_settings; - GFile *current_location; - - GtkWidget *rename_popover; - GtkWidget *rename_entry; - GtkWidget *rename_button; - GtkWidget *rename_error; - gchar *rename_uri; - - gulong trash_monitor_changed_id; - GtkWidget *trash_row; - - /* DND */ - GList *drag_list; /* list of GFile */ - gint drag_data_info; - gboolean dragging_over; - GtkTargetList *source_targets; - GtkWidget *drag_row; - gint drag_row_height; - gint drag_row_x; - gint drag_row_y; - gint drag_root_x; - gint drag_root_y; - GtkWidget *row_placeholder; - DropState drop_state; - GtkGesture *long_press_gesture; - - /* volume mounting - delayed open process */ - NautilusGtkPlacesOpenFlags go_to_after_mount_open_flags; - GCancellable *cancellable; - - GtkWidget *popover; - NautilusGtkSidebarRow *context_row; - GSList *shortcuts; - - GDBusProxy *hostnamed_proxy; - GCancellable *hostnamed_cancellable; - gchar *hostname; - - NautilusGtkPlacesOpenFlags open_flags; - - GActionGroup *action_group; - - guint mounting : 1; - guint drag_data_received : 1; - guint drop_occurred : 1; - guint show_recent_set : 1; - guint show_recent : 1; - guint show_desktop_set : 1; - guint show_desktop : 1; - guint show_connect_to_server : 1; - guint show_enter_location : 1; - guint show_other_locations : 1; - guint show_trash : 1; - guint show_starred_location : 1; - guint local_only : 1; - guint populate_all : 1; -}; - -struct _NautilusGtkPlacesSidebarClass { - GtkScrolledWindowClass parent; - - void (* open_location) (NautilusGtkPlacesSidebar *sidebar, - GFile *location, - NautilusGtkPlacesOpenFlags open_flags); - void (* populate_popup) (NautilusGtkPlacesSidebar *sidebar, - GtkMenu *menu, - GFile *selected_item, - GVolume *selected_volume); - void (* show_error_message) (NautilusGtkPlacesSidebar *sidebar, - const gchar *primary, - const gchar *secondary); - void (* show_connect_to_server) (NautilusGtkPlacesSidebar *sidebar); - GdkDragAction (* drag_action_requested) (NautilusGtkPlacesSidebar *sidebar, - GdkDragContext *context, - GFile *dest_file, - GList *source_file_list); - GdkDragAction (* drag_action_ask) (NautilusGtkPlacesSidebar *sidebar, - GdkDragAction actions); - void (* drag_perform_drop) (NautilusGtkPlacesSidebar *sidebar, - GFile *dest_file, - GList *source_file_list, - GdkDragAction action); - void (* show_enter_location) (NautilusGtkPlacesSidebar *sidebar); - - void (* show_other_locations) (NautilusGtkPlacesSidebar *sidebar); - - void (* show_other_locations_with_flags) (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkPlacesOpenFlags open_flags); - - void (* show_starred_location) (NautilusGtkPlacesSidebar *sidebar); - - void (* mount) (NautilusGtkPlacesSidebar *sidebar, - GMountOperation *mount_operation); - void (* unmount) (NautilusGtkPlacesSidebar *sidebar, - GMountOperation *unmount_operation); -}; - -enum { - OPEN_LOCATION, - POPULATE_POPUP, - SHOW_ERROR_MESSAGE, - SHOW_CONNECT_TO_SERVER, - SHOW_ENTER_LOCATION, - DRAG_ACTION_REQUESTED, - DRAG_ACTION_ASK, - DRAG_PERFORM_DROP, - SHOW_OTHER_LOCATIONS, - SHOW_OTHER_LOCATIONS_WITH_FLAGS, - SHOW_STARRED_LOCATION, - MOUNT, - UNMOUNT, - LAST_SIGNAL -}; - -enum { - PROP_LOCATION = 1, - PROP_OPEN_FLAGS, - PROP_SHOW_RECENT, - PROP_SHOW_DESKTOP, - PROP_SHOW_CONNECT_TO_SERVER, - PROP_SHOW_ENTER_LOCATION, - PROP_SHOW_TRASH, - PROP_SHOW_STARRED_LOCATION, - PROP_LOCAL_ONLY, - PROP_SHOW_OTHER_LOCATIONS, - PROP_POPULATE_ALL, - NUM_PROPERTIES -}; - -/* Names for themed icons */ -#define ICON_NAME_HOME "user-home-symbolic" -#define ICON_NAME_DESKTOP "user-desktop-symbolic" -#define ICON_NAME_FILESYSTEM "drive-harddisk-symbolic" -#define ICON_NAME_EJECT "media-eject-symbolic" -#define ICON_NAME_NETWORK "network-workgroup-symbolic" -#define ICON_NAME_NETWORK_SERVER "network-server-symbolic" -#define ICON_NAME_FOLDER_NETWORK "folder-remote-symbolic" -#define ICON_NAME_OTHER_LOCATIONS "list-add-symbolic" - -#define ICON_NAME_FOLDER "folder-symbolic" -#define ICON_NAME_FOLDER_DESKTOP "user-desktop-symbolic" -#define ICON_NAME_FOLDER_DOCUMENTS "folder-documents-symbolic" -#define ICON_NAME_FOLDER_DOWNLOAD "folder-download-symbolic" -#define ICON_NAME_FOLDER_MUSIC "folder-music-symbolic" -#define ICON_NAME_FOLDER_PICTURES "folder-pictures-symbolic" -#define ICON_NAME_FOLDER_PUBLIC_SHARE "folder-publicshare-symbolic" -#define ICON_NAME_FOLDER_TEMPLATES "folder-templates-symbolic" -#define ICON_NAME_FOLDER_VIDEOS "folder-videos-symbolic" -#define ICON_NAME_FOLDER_SAVED_SEARCH "folder-saved-search-symbolic" - -static guint places_sidebar_signals [LAST_SIGNAL] = { 0 }; -static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; - -static gboolean eject_or_unmount_bookmark (NautilusGtkSidebarRow *row); -static gboolean eject_or_unmount_selection (NautilusGtkPlacesSidebar *sidebar); -static void check_unmount_and_eject (GMount *mount, - GVolume *volume, - GDrive *drive, - gboolean *show_unmount, - gboolean *show_eject); -static gboolean on_button_press_event (GtkWidget *widget, - GdkEventButton *event, - NautilusGtkSidebarRow *sidebar); -static gboolean on_button_release_event (GtkWidget *widget, - GdkEventButton *event, - NautilusGtkSidebarRow *sidebar); -static void popup_menu_cb (NautilusGtkSidebarRow *row); -static void long_press_cb (GtkGesture *gesture, - gdouble x, - gdouble y, - NautilusGtkPlacesSidebar *sidebar); -static void stop_drop_feedback (NautilusGtkPlacesSidebar *sidebar); -static GMountOperation * get_mount_operation (NautilusGtkPlacesSidebar *sidebar); -static GMountOperation * get_unmount_operation (NautilusGtkPlacesSidebar *sidebar); - - -/* Identifiers for target types */ -enum { - DND_UNKNOWN, - DND_NAUTILUS_GTK_SIDEBAR_ROW, - DND_TEXT_URI_LIST -}; - -/* Target types for dragging from the shortcuts list */ -static const GtkTargetEntry dnd_source_targets[] = { - { "DND_NAUTILUS_GTK_SIDEBAR_ROW", GTK_TARGET_SAME_WIDGET, DND_NAUTILUS_GTK_SIDEBAR_ROW } -}; - -/* Target types for dropping into the shortcuts list */ -static const GtkTargetEntry dnd_drop_targets [] = { - { "DND_NAUTILUS_GTK_SIDEBAR_ROW", GTK_TARGET_SAME_WIDGET, DND_NAUTILUS_GTK_SIDEBAR_ROW } -}; - -G_DEFINE_TYPE (NautilusGtkPlacesSidebar, nautilus_gtk_places_sidebar, GTK_TYPE_SCROLLED_WINDOW); - -static void -emit_open_location (NautilusGtkPlacesSidebar *sidebar, - GFile *location, - NautilusGtkPlacesOpenFlags open_flags) -{ - if ((open_flags & sidebar->open_flags) == 0) - open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; - - g_signal_emit (sidebar, places_sidebar_signals[OPEN_LOCATION], 0, - location, open_flags); -} - -static void -emit_show_error_message (NautilusGtkPlacesSidebar *sidebar, - const gchar *primary, - const gchar *secondary) -{ - g_signal_emit (sidebar, places_sidebar_signals[SHOW_ERROR_MESSAGE], 0, - primary, secondary); -} - -static void -emit_show_connect_to_server (NautilusGtkPlacesSidebar *sidebar) -{ - g_signal_emit (sidebar, places_sidebar_signals[SHOW_CONNECT_TO_SERVER], 0); -} - -static void -emit_show_enter_location (NautilusGtkPlacesSidebar *sidebar) -{ - g_signal_emit (sidebar, places_sidebar_signals[SHOW_ENTER_LOCATION], 0); -} - -static void -emit_show_other_locations (NautilusGtkPlacesSidebar *sidebar) -{ - g_signal_emit (sidebar, places_sidebar_signals[SHOW_OTHER_LOCATIONS], 0); -} - -static void -emit_show_other_locations_with_flags (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkPlacesOpenFlags open_flags) -{ - g_signal_emit (sidebar, places_sidebar_signals[SHOW_OTHER_LOCATIONS_WITH_FLAGS], - 0, open_flags); -} - -static void -emit_show_starred_location (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkPlacesOpenFlags open_flags) -{ - g_signal_emit (sidebar, places_sidebar_signals[SHOW_STARRED_LOCATION], 0, - open_flags); -} - - -static void -emit_mount_operation (NautilusGtkPlacesSidebar *sidebar, - GMountOperation *mount_op) -{ - g_signal_emit (sidebar, places_sidebar_signals[MOUNT], 0, mount_op); -} - -static void -emit_unmount_operation (NautilusGtkPlacesSidebar *sidebar, - GMountOperation *mount_op) -{ - g_signal_emit (sidebar, places_sidebar_signals[UNMOUNT], 0, mount_op); -} - -static GdkDragAction -emit_drag_action_requested (NautilusGtkPlacesSidebar *sidebar, - GdkDragContext *context, - GFile *dest_file, - GList *source_file_list) -{ - GdkDragAction ret_action = 0; - - g_signal_emit (sidebar, places_sidebar_signals[DRAG_ACTION_REQUESTED], 0, - context, dest_file, source_file_list, &ret_action); - - return ret_action; -} - -static GdkDragAction -emit_drag_action_ask (NautilusGtkPlacesSidebar *sidebar, - GdkDragAction actions) -{ - GdkDragAction ret_action = 0; - - g_signal_emit (sidebar, places_sidebar_signals[DRAG_ACTION_ASK], 0, - actions, &ret_action); - - return ret_action; -} - -static void -emit_drag_perform_drop (NautilusGtkPlacesSidebar *sidebar, - GFile *dest_file, - GList *source_file_list, - GdkDragAction action) -{ - g_signal_emit (sidebar, places_sidebar_signals[DRAG_PERFORM_DROP], 0, - dest_file, source_file_list, action); -} -static void -list_box_header_func (GtkListBoxRow *row, - GtkListBoxRow *before, - gpointer user_data) -{ - NautilusGtkPlacesSidebarSectionType row_section_type; - NautilusGtkPlacesSidebarSectionType before_section_type; - GtkWidget *separator; - - gtk_list_box_row_set_header (row, NULL); - - g_object_get (row, "section-type", &row_section_type, NULL); - if (before) - { - g_object_get (before, "section-type", &before_section_type, NULL); - } - else - { - before_section_type = SECTION_INVALID; - gtk_widget_set_margin_top (GTK_WIDGET (row), 4); - } - - if (before && before_section_type != row_section_type) - { - separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); - gtk_widget_set_margin_top (separator, 4); - gtk_widget_set_margin_bottom (separator, 4); - gtk_list_box_row_set_header (row, separator); - } -} - -static GtkWidget* -add_place (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkPlacesSidebarPlaceType place_type, - NautilusGtkPlacesSidebarSectionType section_type, - const gchar *name, - GIcon *start_icon, - GIcon *end_icon, - const gchar *uri, - GDrive *drive, - GVolume *volume, - GMount *mount, -#ifdef HAVE_CLOUDPROVIDERS - CloudProvidersAccount *cloud_provider_account, -#else - gpointer *cloud_provider_account, -#endif - const gint index, - const gchar *tooltip) -{ - gboolean show_eject, show_unmount; - gboolean show_eject_button; - GtkWidget *row; - GtkWidget *eject_button; - GtkWidget *event_box; - - check_unmount_and_eject (mount, volume, drive, - &show_unmount, &show_eject); - - if (show_unmount || show_eject) - g_assert (place_type != PLACES_BOOKMARK); - - show_eject_button = (show_unmount || show_eject); - - row = g_object_new (NAUTILUS_TYPE_GTK_SIDEBAR_ROW, - "sidebar", sidebar, - "start-icon", start_icon, - "end-icon", end_icon, - "label", name, - "tooltip", tooltip, - "ejectable", show_eject_button, - "order-index", index, - "section-type", section_type, - "place-type", place_type, - "uri", uri, - "drive", drive, - "volume", volume, - "mount", mount, -#ifdef HAVE_CLOUDPROVIDERS - "cloud-provider-account", cloud_provider_account, -#endif - NULL); - - eject_button = nautilus_gtk_sidebar_row_get_eject_button (NAUTILUS_GTK_SIDEBAR_ROW (row)); - event_box = nautilus_gtk_sidebar_row_get_event_box (NAUTILUS_GTK_SIDEBAR_ROW (row)); - - g_signal_connect_swapped (eject_button, "clicked", - G_CALLBACK (eject_or_unmount_bookmark), row); - g_signal_connect (event_box, "button-press-event", - G_CALLBACK (on_button_press_event), row); - g_signal_connect (event_box, "button-release-event", - G_CALLBACK (on_button_release_event), row); - - gtk_container_add (GTK_CONTAINER (sidebar->list_box), GTK_WIDGET (row)); - gtk_widget_show_all (row); - - return row; -} - -static GIcon * -special_directory_get_gicon (GUserDirectory directory) -{ -#define ICON_CASE(x) \ - case G_USER_DIRECTORY_ ## x: \ - return g_themed_icon_new_with_default_fallbacks (ICON_NAME_FOLDER_ ## x); - - switch (directory) - { - - ICON_CASE (DESKTOP); - ICON_CASE (DOCUMENTS); - ICON_CASE (DOWNLOAD); - ICON_CASE (MUSIC); - ICON_CASE (PICTURES); - ICON_CASE (PUBLIC_SHARE); - ICON_CASE (TEMPLATES); - ICON_CASE (VIDEOS); - - default: - return g_themed_icon_new_with_default_fallbacks (ICON_NAME_FOLDER); - } - -#undef ICON_CASE -} - -static gboolean -recent_files_setting_is_enabled (NautilusGtkPlacesSidebar *sidebar) -{ - GtkSettings *settings; - gboolean enabled; - - settings = gtk_widget_get_settings (GTK_WIDGET (sidebar)); - g_object_get (settings, "gtk-recent-files-enabled", &enabled, NULL); - - return enabled; -} - -static gboolean -recent_scheme_is_supported (void) -{ - const gchar * const *supported; - - supported = g_vfs_get_supported_uri_schemes (g_vfs_get_default ()); - if (supported != NULL) - return g_strv_contains (supported, "recent"); - - return FALSE; -} - -static gboolean -should_show_recent (NautilusGtkPlacesSidebar *sidebar) -{ - return recent_files_setting_is_enabled (sidebar) && - ((sidebar->show_recent_set && sidebar->show_recent) || - (!sidebar->show_recent_set && recent_scheme_is_supported ())); -} - -static gboolean -path_is_home_dir (const gchar *path) -{ - GFile *home_dir; - GFile *location; - const gchar *home_path; - gboolean res; - - home_path = g_get_home_dir (); - if (!home_path) - return FALSE; - - home_dir = g_file_new_for_path (home_path); - location = g_file_new_for_path (path); - res = g_file_equal (home_dir, location); - - g_object_unref (home_dir); - g_object_unref (location); - - return res; -} - -static void -open_home (NautilusGtkPlacesSidebar *sidebar) -{ - const gchar *home_path; - GFile *home_dir; - - home_path = g_get_home_dir (); - if (!home_path) - return; - - home_dir = g_file_new_for_path (home_path); - emit_open_location (sidebar, home_dir, 0); - - g_object_unref (home_dir); -} - -static void -add_special_dirs (NautilusGtkPlacesSidebar *sidebar) -{ - GList *dirs; - gint index; - - dirs = NULL; - for (index = 0; index < G_USER_N_DIRECTORIES; index++) - { - const gchar *path; - GFile *root; - GIcon *start_icon; - gchar *name; - gchar *mount_uri; - gchar *tooltip; - - if (!_nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (index)) - continue; - - path = g_get_user_special_dir (index); - - /* XDG resets special dirs to the home directory in case - * it's not finiding what it expects. We don't want the home - * to be added multiple times in that weird configuration. - */ - if (path == NULL || - path_is_home_dir (path) || - g_list_find_custom (dirs, path, (GCompareFunc) g_strcmp0) != NULL) - continue; - - root = g_file_new_for_path (path); - - name = _nautilus_gtk_bookmarks_manager_get_bookmark_label (sidebar->bookmarks_manager, root); - if (!name) - name = g_file_get_basename (root); - - start_icon = special_directory_get_gicon (index); - mount_uri = g_file_get_uri (root); - tooltip = g_file_get_parse_name (root); - - add_place (sidebar, PLACES_XDG_DIR, - SECTION_COMPUTER, - name, start_icon, NULL, mount_uri, - NULL, NULL, NULL, NULL, 0, - tooltip); - g_free (name); - g_object_unref (root); - g_object_unref (start_icon); - g_free (mount_uri); - g_free (tooltip); - - dirs = g_list_prepend (dirs, (gchar *)path); - } - - g_list_free (dirs); -} - -static gchar * -get_home_directory_uri (void) -{ - const gchar *home; - - home = g_get_home_dir (); - if (!home) - return NULL; - - return g_filename_to_uri (home, NULL, NULL); -} - -static gchar * -get_desktop_directory_uri (void) -{ - const gchar *name; - - name = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); - - /* "To disable a directory, point it to the homedir." - * See http://freedesktop.org/wiki/Software/xdg-user-dirs - */ - if (path_is_home_dir (name)) - return NULL; - - return g_filename_to_uri (name, NULL, NULL); -} - -static gboolean -should_show_file (NautilusGtkPlacesSidebar *sidebar, - GFile *file) -{ - gchar *path; - - if (!sidebar->local_only) - return TRUE; - - path = g_file_get_path (file); - if (path) - { - g_free (path); - return TRUE; - } - - return FALSE; -} - -static gboolean -file_is_shown (NautilusGtkPlacesSidebar *sidebar, - GFile *file) -{ - gchar *uri; - GList *rows; - GList *l; - gboolean found = FALSE; - - rows = gtk_container_get_children (GTK_CONTAINER (sidebar->list_box)); - l = rows; - while (l != NULL && !found) - { - g_object_get (l->data, "uri", &uri, NULL); - if (uri) - { - GFile *other; - other = g_file_new_for_uri (uri); - found = g_file_equal (file, other); - g_object_unref (other); - g_free (uri); - } - l = l->next; - } - - g_list_free (rows); - - return found; -} - -static void -on_app_shortcuts_query_complete (GObject *source, - GAsyncResult *result, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GFile *file = G_FILE (source); - GFileInfo *info; - - info = g_file_query_info_finish (file, result, NULL); - - if (info) - { - gchar *uri; - gchar *tooltip; - const gchar *name; - GIcon *start_icon; - int pos = 0; - - name = g_file_info_get_display_name (info); - start_icon = g_file_info_get_symbolic_icon (info); - uri = g_file_get_uri (file); - tooltip = g_file_get_parse_name (file); - - /* XXX: we could avoid this by using an ancillary closure - * with the index coming from add_application_shortcuts(), - * but in terms of algorithmic overhead, the application - * shortcuts is not going to be really big - */ - pos = g_slist_index (sidebar->shortcuts, file); - - add_place (sidebar, PLACES_BUILT_IN, - SECTION_COMPUTER, - name, start_icon, NULL, uri, - NULL, NULL, NULL, NULL, - pos, - tooltip); - - g_free (uri); - g_free (tooltip); - - g_object_unref (info); - } -} - -static void -add_application_shortcuts (NautilusGtkPlacesSidebar *sidebar) -{ - GSList *l; - - for (l = sidebar->shortcuts; l; l = l->next) - { - GFile *file = l->data; - - if (!should_show_file (sidebar, file)) - continue; - - if (file_is_shown (sidebar, file)) - continue; - - g_file_query_info_async (file, - "standard::display-name,standard::symbolic-icon", - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - sidebar->cancellable, - on_app_shortcuts_query_complete, - sidebar); - } -} - -typedef struct { - NautilusGtkPlacesSidebar *sidebar; - int index; - gboolean is_native; -} BookmarkQueryClosure; - -static void -on_bookmark_query_info_complete (GObject *source, - GAsyncResult *result, - gpointer data) -{ - BookmarkQueryClosure *clos = data; - NautilusGtkPlacesSidebar *sidebar = clos->sidebar; - GFile *root = G_FILE (source); - GError *error = NULL; - GFileInfo *info; - gchar *bookmark_name; - gchar *mount_uri; - gchar *tooltip; - GIcon *start_icon; - - info = g_file_query_info_finish (root, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto out; - - bookmark_name = _nautilus_gtk_bookmarks_manager_get_bookmark_label (sidebar->bookmarks_manager, root); - if (bookmark_name == NULL && info != NULL) - bookmark_name = g_strdup (g_file_info_get_display_name (info)); - else if (bookmark_name == NULL) - { - /* Don't add non-UTF-8 bookmarks */ - bookmark_name = g_file_get_basename (root); - if (!g_utf8_validate (bookmark_name, -1, NULL)) - { - g_free (bookmark_name); - goto out; - } - } - - if (info) - start_icon = g_object_ref (g_file_info_get_symbolic_icon (info)); - else - start_icon = g_themed_icon_new_with_default_fallbacks (clos->is_native ? ICON_NAME_FOLDER : ICON_NAME_FOLDER_NETWORK); - - mount_uri = g_file_get_uri (root); - tooltip = g_file_get_parse_name (root); - - add_place (sidebar, PLACES_BOOKMARK, - SECTION_BOOKMARKS, - bookmark_name, start_icon, NULL, mount_uri, - NULL, NULL, NULL, NULL, clos->index, - tooltip); - - g_free (mount_uri); - g_free (tooltip); - g_free (bookmark_name); - g_object_unref (start_icon); - -out: - g_clear_object (&info); - g_clear_error (&error); - g_slice_free (BookmarkQueryClosure, clos); -} - -static gboolean -is_external_volume (GVolume *volume) -{ - gboolean is_external; - GDrive *drive; - gchar *id; - - drive = g_volume_get_drive (volume); - id = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS); - - is_external = g_volume_can_eject (volume); - - /* NULL volume identifier only happens on removable devices */ - is_external |= !id; - - if (drive) - is_external |= g_drive_is_removable (drive); - - g_clear_object (&drive); - g_free (id); - - return is_external; -} - -static void -update_trash_icon (NautilusGtkPlacesSidebar *sidebar) -{ - if (sidebar->trash_row) - { - GIcon *icon; - - icon = nautilus_trash_monitor_get_symbolic_icon (); - nautilus_gtk_sidebar_row_set_start_icon (NAUTILUS_GTK_SIDEBAR_ROW (sidebar->trash_row), icon); - g_object_unref (icon); - } -} - -#ifdef HAVE_CLOUDPROVIDERS - -static gboolean -create_cloud_provider_account_row (NautilusGtkPlacesSidebar *sidebar, - CloudProvidersAccount *account) -{ - GIcon *end_icon; - GIcon *start_icon; - gchar *mount_uri; - gchar *name; - gchar *tooltip; - guint provider_account_status; - - start_icon = cloud_providers_account_get_icon (account); - name = cloud_providers_account_get_name (account); - provider_account_status = cloud_providers_account_get_status (account); - mount_uri = cloud_providers_account_get_path (account); - if (start_icon != NULL - && name != NULL - && provider_account_status != CLOUD_PROVIDERS_ACCOUNT_STATUS_INVALID - && mount_uri != NULL) - { - switch (provider_account_status) - { - case CLOUD_PROVIDERS_ACCOUNT_STATUS_IDLE: - end_icon = NULL; - break; - - case CLOUD_PROVIDERS_ACCOUNT_STATUS_SYNCING: - end_icon = g_themed_icon_new ("emblem-synchronizing-symbolic"); - break; - - case CLOUD_PROVIDERS_ACCOUNT_STATUS_ERROR: - end_icon = g_themed_icon_new ("dialog-warning-symbolic"); - break; - - default: - return FALSE; - } - - mount_uri = g_strconcat ("file://", mount_uri, NULL); - - /* translators: %s is the name of a cloud provider for files */ - tooltip = g_strdup_printf (_("Open %s"), name); - - add_place (sidebar, PLACES_BUILT_IN, - SECTION_CLOUD, - name, start_icon, end_icon, mount_uri, - NULL, NULL, NULL, account, 0, - tooltip); - - return TRUE; - } - else - { - return FALSE; - } -} - -static void -on_account_updated (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - CloudProvidersAccount *account = CLOUD_PROVIDERS_ACCOUNT (object); - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - if (create_cloud_provider_account_row (sidebar, account)) - { - g_signal_handlers_disconnect_by_data (account, sidebar); - sidebar->unready_accounts = g_list_remove (sidebar->unready_accounts, account); - g_object_unref (account); - } -} - -#endif - -static void -update_places (NautilusGtkPlacesSidebar *sidebar) -{ - GList *mounts, *l, *ll; - GMount *mount; - GList *drives; - GDrive *drive; - GList *volumes; - GVolume *volume; - GSList *bookmarks, *sl; - gint index; - gchar *original_uri, *mount_uri, *name, *identifier; - GtkListBoxRow *selected; - gchar *home_uri; - GIcon *start_icon; - GFile *root; - gchar *tooltip; - GList *network_mounts, *network_volumes; - GIcon *new_bookmark_icon; -#ifdef HAVE_CLOUDPROVIDERS - GList *cloud_providers; - GList *cloud_providers_accounts; - CloudProvidersAccount *cloud_provider_account; - CloudProvidersProvider *cloud_provider; -#endif - GtkStyleContext *context; - - /* save original selection */ - selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box)); - if (selected) - g_object_get (selected, "uri", &original_uri, NULL); - else - original_uri = NULL; - - g_cancellable_cancel (sidebar->cancellable); - - g_object_unref (sidebar->cancellable); - sidebar->cancellable = g_cancellable_new (); - - /* Reset drag state, just in case we update the places while dragging or - * ending a drag */ - stop_drop_feedback (sidebar); - gtk_container_foreach (GTK_CONTAINER (sidebar->list_box), - (GtkCallback) gtk_widget_destroy, - NULL); - - network_mounts = network_volumes = NULL; - - /* add built-in places */ - if (should_show_recent (sidebar)) - { - mount_uri = "recent:///"; - start_icon = g_themed_icon_new_with_default_fallbacks ("document-open-recent-symbolic"); - add_place (sidebar, PLACES_BUILT_IN, - SECTION_COMPUTER, - _("Recent"), start_icon, NULL, mount_uri, - NULL, NULL, NULL, NULL, 0, - _("Recent files")); - g_object_unref (start_icon); - } - - if (sidebar->show_starred_location) - { - mount_uri = "starred:///"; - start_icon = g_themed_icon_new_with_default_fallbacks ("starred-symbolic"); - add_place (sidebar, PLACES_STARRED_LOCATION, - SECTION_COMPUTER, - _("Starred"), start_icon, NULL, mount_uri, - NULL, NULL, NULL, NULL, 0, - /* TODO: Rename to 'Starred files' */ - _("Favorite files")); - g_object_unref (start_icon); - } - - /* home folder */ - home_uri = get_home_directory_uri (); - start_icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_HOME); - add_place (sidebar, PLACES_BUILT_IN, - SECTION_COMPUTER, - _("Home"), start_icon, NULL, home_uri, - NULL, NULL, NULL, NULL, 0, - _("Open your personal folder")); - g_object_unref (start_icon); - g_free (home_uri); - - /* desktop */ - if (sidebar->show_desktop) - { - mount_uri = get_desktop_directory_uri (); - if (mount_uri) - { - start_icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_DESKTOP); - add_place (sidebar, PLACES_BUILT_IN, - SECTION_COMPUTER, - _("Desktop"), start_icon, NULL, mount_uri, - NULL, NULL, NULL, NULL, 0, - _("Open the contents of your desktop in a folder")); - g_object_unref (start_icon); - g_free (mount_uri); - } - } - - /* XDG directories */ - add_special_dirs (sidebar); - - if (sidebar->show_enter_location) - { - start_icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_NETWORK_SERVER); - add_place (sidebar, PLACES_ENTER_LOCATION, - SECTION_COMPUTER, - _("Enter Location"), start_icon, NULL, NULL, - NULL, NULL, NULL, NULL, 0, - _("Manually enter a location")); - g_object_unref (start_icon); - } - - /* Trash */ - if (!sidebar->local_only && sidebar->show_trash) - { - start_icon = nautilus_trash_monitor_get_symbolic_icon (); - sidebar->trash_row = add_place (sidebar, PLACES_BUILT_IN, - SECTION_COMPUTER, - _("Trash"), start_icon, NULL, "trash:///", - NULL, NULL, NULL, NULL, 0, - _("Open the trash")); - g_object_add_weak_pointer (G_OBJECT (sidebar->trash_row), - (gpointer *) &sidebar->trash_row); - g_object_unref (start_icon); - } - - /* Application-side shortcuts */ - add_application_shortcuts (sidebar); - - /* Cloud providers */ -#ifdef HAVE_CLOUDPROVIDERS - cloud_providers = cloud_providers_collector_get_providers (sidebar->cloud_manager); - for (l = sidebar->unready_accounts; l != NULL; l = l->next) - { - g_signal_handlers_disconnect_by_data (l->data, sidebar); - } - g_list_free_full (sidebar->unready_accounts, g_object_unref); - sidebar->unready_accounts = NULL; - for (l = cloud_providers; l != NULL; l = l->next) - { - cloud_provider = CLOUD_PROVIDERS_PROVIDER (l->data); - g_signal_connect_swapped (cloud_provider, "accounts-changed", - G_CALLBACK (update_places), sidebar); - cloud_providers_accounts = cloud_providers_provider_get_accounts (cloud_provider); - for (ll = cloud_providers_accounts; ll != NULL; ll = ll->next) - { - cloud_provider_account = CLOUD_PROVIDERS_ACCOUNT (ll->data); - if (!create_cloud_provider_account_row (sidebar, cloud_provider_account)) - { - - g_signal_connect (cloud_provider_account, "notify::name", - G_CALLBACK (on_account_updated), sidebar); - g_signal_connect (cloud_provider_account, "notify::status", - G_CALLBACK (on_account_updated), sidebar); - g_signal_connect (cloud_provider_account, "notify::status-details", - G_CALLBACK (on_account_updated), sidebar); - g_signal_connect (cloud_provider_account, "notify::path", - G_CALLBACK (on_account_updated), sidebar); - sidebar->unready_accounts = g_list_append (sidebar->unready_accounts, - g_object_ref (cloud_provider_account)); - continue; - } - - } - } -#endif - - /* go through all connected drives */ - drives = g_volume_monitor_get_connected_drives (sidebar->volume_monitor); - - for (l = drives; l != NULL; l = l->next) - { - drive = l->data; - - volumes = g_drive_get_volumes (drive); - if (volumes != NULL) - { - for (ll = volumes; ll != NULL; ll = ll->next) - { - volume = ll->data; - identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS); - - if (g_strcmp0 (identifier, "network") == 0) - { - g_free (identifier); - network_volumes = g_list_prepend (network_volumes, volume); - continue; - } - g_free (identifier); - - if (sidebar->show_other_locations && !is_external_volume (volume)) - { - g_object_unref (volume); - continue; - } - - mount = g_volume_get_mount (volume); - if (mount != NULL) - { - /* Show mounted volume in the sidebar */ - start_icon = g_mount_get_symbolic_icon (mount); - root = g_mount_get_default_location (mount); - mount_uri = g_file_get_uri (root); - name = g_mount_get_name (mount); - tooltip = g_file_get_parse_name (root); - - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_MOUNTS, - name, start_icon, NULL, mount_uri, - drive, volume, mount, NULL, 0, tooltip); - g_object_unref (root); - g_object_unref (mount); - g_object_unref (start_icon); - g_free (tooltip); - g_free (name); - g_free (mount_uri); - } - else - { - /* Do show the unmounted volumes in the sidebar; - * this is so the user can mount it (in case automounting - * is off). - * - * Also, even if automounting is enabled, this gives a visual - * cue that the user should remember to yank out the media if - * he just unmounted it. - */ - start_icon = g_volume_get_symbolic_icon (volume); - name = g_volume_get_name (volume); - tooltip = g_strdup_printf (_("Mount and open “%s”"), name); - - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_MOUNTS, - name, start_icon, NULL, NULL, - drive, volume, NULL, NULL, 0, tooltip); - g_object_unref (start_icon); - g_free (name); - g_free (tooltip); - } - g_object_unref (volume); - } - g_list_free (volumes); - } - else - { - if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive)) - { - /* If the drive has no mountable volumes and we cannot detect media change.. we - * display the drive in the sidebar so the user can manually poll the drive by - * right clicking and selecting "Rescan..." - * - * This is mainly for drives like floppies where media detection doesn't - * work.. but it's also for human beings who like to turn off media detection - * in the OS to save battery juice. - */ - start_icon = g_drive_get_symbolic_icon (drive); - name = g_drive_get_name (drive); - tooltip = g_strdup_printf (_("Mount and open “%s”"), name); - - add_place (sidebar, PLACES_BUILT_IN, - SECTION_MOUNTS, - name, start_icon, NULL, NULL, - drive, NULL, NULL, NULL, 0, tooltip); - g_object_unref (start_icon); - g_free (tooltip); - g_free (name); - } - } - } - g_list_free_full (drives, g_object_unref); - - /* add all network volumes that are not associated with a drive, and - * loop devices - */ - volumes = g_volume_monitor_get_volumes (sidebar->volume_monitor); - for (l = volumes; l != NULL; l = l->next) - { - gboolean is_loop = FALSE; - volume = l->data; - drive = g_volume_get_drive (volume); - if (drive != NULL) - { - g_object_unref (volume); - g_object_unref (drive); - continue; - } - - identifier = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_CLASS); - - if (g_strcmp0 (identifier, "network") == 0) - { - g_free (identifier); - network_volumes = g_list_prepend (network_volumes, volume); - continue; - } - else if (g_strcmp0 (identifier, "loop") == 0) - is_loop = TRUE; - g_free (identifier); - - if (sidebar->show_other_locations && - !is_external_volume (volume) && - !is_loop) - { - g_object_unref (volume); - continue; - } - - mount = g_volume_get_mount (volume); - if (mount != NULL) - { - char *mount_uri; - start_icon = g_mount_get_symbolic_icon (mount); - root = g_mount_get_default_location (mount); - mount_uri = g_file_get_uri (root); - tooltip = g_file_get_parse_name (root); - name = g_mount_get_name (mount); - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_MOUNTS, - name, start_icon, NULL, mount_uri, - NULL, volume, mount, NULL, 0, tooltip); - g_object_unref (mount); - g_object_unref (root); - g_object_unref (start_icon); - g_free (name); - g_free (tooltip); - g_free (mount_uri); - } - else - { - /* see comment above in why we add an icon for an unmounted mountable volume */ - start_icon = g_volume_get_symbolic_icon (volume); - name = g_volume_get_name (volume); - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_MOUNTS, - name, start_icon, NULL, NULL, - NULL, volume, NULL, NULL, 0, name); - g_object_unref (start_icon); - g_free (name); - } - g_object_unref (volume); - } - g_list_free (volumes); - - /* file system root */ - if (!sidebar->show_other_locations) - { - mount_uri = "file:///"; /* No need to strdup */ - start_icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_FILESYSTEM); - add_place (sidebar, PLACES_BUILT_IN, - SECTION_MOUNTS, - sidebar->hostname, start_icon, NULL, mount_uri, - NULL, NULL, NULL, NULL, 0, - _("Open the contents of the file system")); - g_object_unref (start_icon); - } - - /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */ - mounts = g_volume_monitor_get_mounts (sidebar->volume_monitor); - - for (l = mounts; l != NULL; l = l->next) - { - mount = l->data; - if (g_mount_is_shadowed (mount)) - { - g_object_unref (mount); - continue; - } - volume = g_mount_get_volume (mount); - if (volume != NULL) - { - g_object_unref (volume); - g_object_unref (mount); - continue; - } - root = g_mount_get_default_location (mount); - - if (!g_file_is_native (root)) - { - network_mounts = g_list_prepend (network_mounts, mount); - g_object_unref (root); - continue; - } - - start_icon = g_mount_get_symbolic_icon (mount); - mount_uri = g_file_get_uri (root); - name = g_mount_get_name (mount); - tooltip = g_file_get_parse_name (root); - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_COMPUTER, - name, start_icon, NULL, mount_uri, - NULL, NULL, mount, NULL, 0, tooltip); - g_object_unref (root); - g_object_unref (mount); - g_object_unref (start_icon); - g_free (name); - g_free (mount_uri); - g_free (tooltip); - } - g_list_free (mounts); - - /* add bookmarks */ - bookmarks = _nautilus_gtk_bookmarks_manager_list_bookmarks (sidebar->bookmarks_manager); - - for (sl = bookmarks, index = 0; sl; sl = sl->next, index++) - { - gboolean is_native; - BookmarkQueryClosure *clos; - - root = sl->data; - is_native = g_file_is_native (root); - - if (_nautilus_gtk_bookmarks_manager_get_is_builtin (sidebar->bookmarks_manager, root)) - continue; - - if (sidebar->local_only && !is_native) - continue; - - clos = g_slice_new (BookmarkQueryClosure); - clos->sidebar = sidebar; - clos->index = index; - clos->is_native = is_native; - g_file_query_info_async (root, - "standard::display-name,standard::symbolic-icon", - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - sidebar->cancellable, - on_bookmark_query_info_complete, - clos); - } - - g_slist_free_full (bookmarks, g_object_unref); - - /* Add new bookmark row */ - new_bookmark_icon = g_themed_icon_new ("bookmark-new-symbolic"); - sidebar->new_bookmark_row = add_place (sidebar, PLACES_DROP_FEEDBACK, - SECTION_BOOKMARKS, - _("New bookmark"), new_bookmark_icon, NULL, NULL, - NULL, NULL, NULL, NULL, 0, - _("Add a new bookmark")); - context = gtk_widget_get_style_context (sidebar->new_bookmark_row); - gtk_style_context_add_class (context, "sidebar-new-bookmark-row"); - g_object_unref (new_bookmark_icon); - - /* network */ - if (!sidebar->local_only) - { - if (sidebar->show_connect_to_server) - { - start_icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_NETWORK_SERVER); - add_place (sidebar, PLACES_CONNECT_TO_SERVER, - SECTION_MOUNTS, - _("Connect to Server"), start_icon, NULL, - NULL, NULL, NULL, NULL, NULL, 0, - _("Connect to a network server address")); - g_object_unref (start_icon); - } - - network_volumes = g_list_reverse (network_volumes); - for (l = network_volumes; l != NULL; l = l->next) - { - volume = l->data; - mount = g_volume_get_mount (volume); - - if (mount != NULL) - { - network_mounts = g_list_prepend (network_mounts, mount); - continue; - } - else - { - start_icon = g_volume_get_symbolic_icon (volume); - name = g_volume_get_name (volume); - tooltip = g_strdup_printf (_("Mount and open “%s”"), name); - - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_MOUNTS, - name, start_icon, NULL, NULL, - NULL, volume, NULL, NULL, 0, tooltip); - g_object_unref (start_icon); - g_free (name); - g_free (tooltip); - } - } - - network_mounts = g_list_reverse (network_mounts); - for (l = network_mounts; l != NULL; l = l->next) - { - mount = l->data; - root = g_mount_get_default_location (mount); - start_icon = g_mount_get_symbolic_icon (mount); - mount_uri = g_file_get_uri (root); - name = g_mount_get_name (mount); - tooltip = g_file_get_parse_name (root); - add_place (sidebar, PLACES_MOUNTED_VOLUME, - SECTION_MOUNTS, - name, start_icon, NULL, mount_uri, - NULL, NULL, mount, NULL, 0, tooltip); - g_object_unref (root); - g_object_unref (start_icon); - g_free (name); - g_free (mount_uri); - g_free (tooltip); - } - } - - g_list_free_full (network_volumes, g_object_unref); - g_list_free_full (network_mounts, g_object_unref); - - /* Other locations */ - if (sidebar->show_other_locations) - { - start_icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_OTHER_LOCATIONS); - - add_place (sidebar, PLACES_OTHER_LOCATIONS, - SECTION_OTHER_LOCATIONS, - _("Other Locations"), start_icon, NULL, "other-locations:///", - NULL, NULL, NULL, NULL, 0, _("Show other locations")); - - g_object_unref (start_icon); - } - - gtk_widget_show_all (GTK_WIDGET (sidebar)); - /* We want this hidden by default, but need to do it after the show_all call */ - nautilus_gtk_sidebar_row_hide (NAUTILUS_GTK_SIDEBAR_ROW (sidebar->new_bookmark_row), TRUE); - - /* restore original selection */ - if (original_uri) - { - GFile *restore; - - restore = g_file_new_for_uri (original_uri); - nautilus_gtk_places_sidebar_set_location (sidebar, restore); - g_object_unref (restore); - g_free (original_uri); - } -} - -static gboolean -check_valid_drop_target (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkSidebarRow *row, - GdkDragContext *context) -{ - NautilusGtkPlacesSidebarPlaceType place_type; - NautilusGtkPlacesSidebarSectionType section_type; - gboolean valid = FALSE; - gchar *uri; - GFile *dest_file; - gint drag_action; - - if (row == NULL) - return FALSE; - - g_object_get (row, - "place-type", &place_type, - "section_type", §ion_type, - "uri", &uri, - NULL); - - if (place_type == PLACES_STARRED_LOCATION) - { - g_free (uri); - return FALSE; - } - - if (place_type == PLACES_CONNECT_TO_SERVER) - { - g_free (uri); - return FALSE; - } - - if (place_type == PLACES_DROP_FEEDBACK) - { - g_free (uri); - return TRUE; - } - - /* Disallow drops on recent:/// */ - if (place_type == PLACES_BUILT_IN) - { - if (g_strcmp0 (uri, "recent:///") == 0) - { - g_free (uri); - return FALSE; - } - } - - /* Dragging a bookmark? */ - if (sidebar->drag_data_received && - sidebar->drag_data_info == DND_NAUTILUS_GTK_SIDEBAR_ROW) - { - /* Don't allow reordering bookmarks into non-bookmark areas */ - valid = section_type == SECTION_BOOKMARKS; - } - else - { - /* Dragging a file */ - if (context) - { - if (uri != NULL) - { - dest_file = g_file_new_for_uri (uri); - drag_action = emit_drag_action_requested (sidebar, context, dest_file, sidebar->drag_list); - valid = drag_action > 0; - - g_object_unref (dest_file); - } - else - { - valid = FALSE; - } - } - else - { - /* We cannot discern if it is valid or not because there is not drag - * context available to ask the client. - * Simply make insensitive the drop targets we know are not valid for - * files, that are the ones remaining. - */ - valid = TRUE; - } - } - - g_free (uri); - return valid; -} - -static void -update_possible_drop_targets (NautilusGtkPlacesSidebar *sidebar, - gboolean dragging, - GdkDragContext *context) -{ - GList *rows; - GList *l; - gboolean sensitive; - - rows = gtk_container_get_children (GTK_CONTAINER (sidebar->list_box)); - - for (l = rows; l != NULL; l = l->next) - { - sensitive = !dragging || check_valid_drop_target (sidebar, NAUTILUS_GTK_SIDEBAR_ROW (l->data), context); - gtk_widget_set_sensitive (GTK_WIDGET (l->data), sensitive); - } - - g_list_free (rows); -} - -static gboolean -get_drag_data (GtkWidget *list_box, - GdkDragContext *context, - guint time) -{ - GdkAtom target; - - target = gtk_drag_dest_find_target (list_box, context, NULL); - - if (target == GDK_NONE) - return FALSE; - - gtk_drag_get_data (list_box, context, target, time); - - return TRUE; -} - -static void -free_drag_data (NautilusGtkPlacesSidebar *sidebar) -{ - sidebar->drag_data_received = FALSE; - - if (sidebar->drag_list) - { - g_list_free_full (sidebar->drag_list, g_object_unref); - sidebar->drag_list = NULL; - } - -} - -static void -start_drop_feedback (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkSidebarRow *row, - GdkDragContext *context) -{ - if (sidebar->drag_data_info != DND_NAUTILUS_GTK_SIDEBAR_ROW) - { - nautilus_gtk_sidebar_row_reveal (NAUTILUS_GTK_SIDEBAR_ROW (sidebar->new_bookmark_row)); - /* If the state is permanent, don't change it. The application controls it. */ - if (sidebar->drop_state != DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT) - sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED; - } - - update_possible_drop_targets (sidebar, TRUE, context); -} - -static void -stop_drop_feedback (NautilusGtkPlacesSidebar *sidebar) -{ - update_possible_drop_targets (sidebar, FALSE, NULL); - - free_drag_data (sidebar); - - if (sidebar->drop_state != DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT && - sidebar->new_bookmark_row != NULL) - { - nautilus_gtk_sidebar_row_hide (NAUTILUS_GTK_SIDEBAR_ROW (sidebar->new_bookmark_row), FALSE); - sidebar->drop_state = DROP_STATE_NORMAL; - } - - if (sidebar->drag_row != NULL) - { - gtk_widget_show (sidebar->drag_row); - sidebar->drag_row = NULL; - } - - if (sidebar->row_placeholder != NULL) - { - gtk_widget_destroy (sidebar->row_placeholder); - sidebar->row_placeholder = NULL; - } - - sidebar->dragging_over = FALSE; - sidebar->drag_data_info = DND_UNKNOWN; -} - -static gboolean -on_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - if (sidebar->drag_row == NULL || sidebar->dragging_over) - return FALSE; - - if (!(event->state & GDK_BUTTON1_MASK)) - return FALSE; - - if (gtk_drag_check_threshold (widget, - sidebar->drag_root_x, sidebar->drag_root_y, - event->x_root, event->y_root)) - { - sidebar->dragging_over = TRUE; - - gtk_drag_begin_with_coordinates (widget, sidebar->source_targets, GDK_ACTION_MOVE, - GDK_BUTTON_PRIMARY, (GdkEvent*)event, - -1, -1); - } - - return FALSE; -} - -static void -drag_begin_callback (GtkWidget *widget, - GdkDragContext *context, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - GtkAllocation allocation; - GtkWidget *drag_widget; - GtkWidget *window; - - gtk_widget_get_allocation (sidebar->drag_row, &allocation); - gtk_widget_hide (sidebar->drag_row); - - drag_widget = GTK_WIDGET (nautilus_gtk_sidebar_row_clone (NAUTILUS_GTK_SIDEBAR_ROW (sidebar->drag_row))); - window = gtk_window_new (GTK_WINDOW_POPUP); - sidebar->drag_row_height = allocation.height; - gtk_widget_set_size_request (window, allocation.width, allocation.height); - - gtk_container_add (GTK_CONTAINER (window), drag_widget); - gtk_widget_show_all (window); - gtk_widget_set_opacity (window, 0.8); - - gtk_drag_set_icon_widget (context, - window, - sidebar->drag_row_x, - sidebar->drag_row_y); -} - -static GtkWidget * -create_placeholder_row (NautilusGtkPlacesSidebar *sidebar) -{ - return g_object_new (NAUTILUS_TYPE_GTK_SIDEBAR_ROW, - "placeholder", TRUE, - NULL); -} - -static gboolean -drag_motion_callback (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - gpointer user_data) -{ - gint action; - GtkListBoxRow *row; - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - NautilusGtkPlacesSidebarPlaceType place_type; - gchar *drop_target_uri = NULL; - gint row_index; - gint row_placeholder_index; - - sidebar->dragging_over = TRUE; - action = 0; - row = gtk_list_box_get_row_at_y (GTK_LIST_BOX (sidebar->list_box), y); - - gtk_list_box_drag_unhighlight_row (GTK_LIST_BOX (sidebar->list_box)); - - /* Nothing to do if no drag data */ - if (!sidebar->drag_data_received && - !get_drag_data (sidebar->list_box, context, time)) - goto out; - - /* Nothing to do if the target is not valid drop destination */ - if (!check_valid_drop_target (sidebar, NAUTILUS_GTK_SIDEBAR_ROW (row), context)) - goto out; - - if (sidebar->drag_data_received && - sidebar->drag_data_info == DND_NAUTILUS_GTK_SIDEBAR_ROW) - { - /* Dragging bookmarks always moves them to another position in the bookmarks list */ - action = GDK_ACTION_MOVE; - if (sidebar->row_placeholder == NULL) - { - sidebar->row_placeholder = create_placeholder_row (sidebar); - gtk_widget_show (sidebar->row_placeholder); - g_object_ref_sink (sidebar->row_placeholder); - } - else if (GTK_WIDGET (row) == sidebar->row_placeholder) - { - goto out; - } - - if (gtk_widget_get_parent (sidebar->row_placeholder) != NULL) - { - gtk_container_remove (GTK_CONTAINER (sidebar->list_box), - sidebar->row_placeholder); - } - - if (row != NULL) - { - gint dest_y, dest_x; - - g_object_get (row, "order-index", &row_index, NULL); - g_object_get (sidebar->row_placeholder, "order-index", &row_placeholder_index, NULL); - /* We order the bookmarks sections based on the bookmark index that we - * set on the row as order-index property, but we have to deal with - * the placeholder row wanting to be between two consecutive bookmarks, - * with two consecutive order-index values which is the usual case. - * For that, in the list box sort func we give priority to the placeholder row, - * that means that if the index-order is the same as another bookmark - * the placeholder row goes before. However if we want to show it after - * the current row, for instance when the cursor is in the lower half - * of the row, we need to increase the order-index. - */ - row_placeholder_index = row_index; - gtk_widget_translate_coordinates (widget, GTK_WIDGET (row), - x, y, - &dest_x, &dest_y); - - if (dest_y > sidebar->drag_row_height / 2 && row_index > 0) - row_placeholder_index++; - } - else - { - /* If the user is dragging over an area that has no row, place the row - * placeholder in the last position - */ - row_placeholder_index = G_MAXINT32; - } - - g_object_set (sidebar->row_placeholder, "order-index", row_placeholder_index, NULL); - - gtk_list_box_prepend (GTK_LIST_BOX (sidebar->list_box), - sidebar->row_placeholder); - } - else - { - gtk_list_box_drag_highlight_row (GTK_LIST_BOX (sidebar->list_box), row); - - g_object_get (row, - "place-type", &place_type, - "uri", &drop_target_uri, - NULL); - /* URIs are being dragged. See if the caller wants to handle a - * file move/copy operation itself, or if we should only try to - * create bookmarks out of the dragged URIs. - */ - if (sidebar->drag_list != NULL) - { - if (place_type == PLACES_DROP_FEEDBACK) - { - action = GDK_ACTION_COPY; - } - else - { - /* uri may be NULL for unmounted volumes, for example, so we don't allow drops there */ - if (drop_target_uri != NULL) - { - GFile *dest_file = g_file_new_for_uri (drop_target_uri); - - action = emit_drag_action_requested (sidebar, context, dest_file, sidebar->drag_list); - - g_object_unref (dest_file); - } - } - } - - g_free (drop_target_uri); - } - - out: - start_drop_feedback (sidebar, NAUTILUS_GTK_SIDEBAR_ROW (row), context); - - g_signal_stop_emission_by_name (sidebar->list_box, "drag-motion"); - - gdk_drag_status (context, action, time); - - return TRUE; -} - -/* Takes an array of URIs and turns it into a list of GFile */ -static GList * -build_file_list_from_uris (const gchar **uris) -{ - GList *result; - gint i; - - result = NULL; - for (i = 0; uris && uris[i]; i++) - { - GFile *file; - - file = g_file_new_for_uri (uris[i]); - result = g_list_prepend (result, file); - } - - return g_list_reverse (result); -} - -/* Reorders the bookmark to the specified position */ -static void -reorder_bookmarks (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkSidebarRow *row, - gint new_position) -{ - gchar *uri; - GFile *file; - - g_object_get (row, "uri", &uri, NULL); - file = g_file_new_for_uri (uri); - _nautilus_gtk_bookmarks_manager_reorder_bookmark (sidebar->bookmarks_manager, file, new_position, NULL); - - g_object_unref (file); - g_free (uri); -} - -/* Creates bookmarks for the specified files at the given position in the bookmarks list */ -static void -drop_files_as_bookmarks (NautilusGtkPlacesSidebar *sidebar, - GList *files, - gint position) -{ - GList *l; - - for (l = files; l; l = l->next) - { - GFile *f = G_FILE (l->data); - GFileInfo *info = g_file_query_info (f, - G_FILE_ATTRIBUTE_STANDARD_TYPE, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, - NULL); - - if (info) - { - if ((g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY || g_file_info_get_file_type (info) == G_FILE_TYPE_MOUNTABLE || g_file_info_get_file_type (info) == G_FILE_TYPE_SHORTCUT)) - _nautilus_gtk_bookmarks_manager_insert_bookmark (sidebar->bookmarks_manager, f, position++, NULL); - - g_object_unref (info); - } - } -} - -static void -drag_data_get_callback (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - GdkAtom target = gtk_selection_data_get_target (data); - - if (target == gdk_atom_intern_static_string ("DND_NAUTILUS_GTK_SIDEBAR_ROW")) - { - gtk_selection_data_set (data, - target, - 8, - (void*)&sidebar->drag_row, - sizeof (gpointer)); - } -} - -static void -drag_data_received_callback (GtkWidget *list_box, - GdkDragContext *context, - int x, - int y, - GtkSelectionData *selection_data, - guint info, - guint time, - gpointer user_data) -{ - gint target_order_index; - NautilusGtkPlacesSidebarPlaceType target_place_type; - NautilusGtkPlacesSidebarSectionType target_section_type; - gchar *target_uri; - gboolean success; - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - GtkListBoxRow *target_row; - - if (!sidebar->drag_data_received) - { - if (gtk_selection_data_get_target (selection_data) != GDK_NONE && - info == DND_TEXT_URI_LIST) - { - gchar **uris; - - uris = gtk_selection_data_get_uris (selection_data); - /* Free spurious drag data from previous drags if present */ - if (sidebar->drag_list != NULL) - g_list_free_full (sidebar->drag_list, g_object_unref); - sidebar->drag_list = build_file_list_from_uris ((const char **) uris); - g_strfreev (uris); - } - else - { - sidebar->drag_list = NULL; - } - sidebar->drag_data_received = TRUE; - sidebar->drag_data_info = info; - } - - g_signal_stop_emission_by_name (list_box, "drag-data-received"); - - if (!sidebar->drop_occurred) - return; - - target_row = gtk_list_box_get_row_at_y (GTK_LIST_BOX (sidebar->list_box), y); - - if (target_row == NULL) - return; - - g_object_get (target_row, - "place-type", &target_place_type, - "section-type", &target_section_type, - "order-index", &target_order_index, - "uri", &target_uri, - NULL); - - success = FALSE; - - if (!check_valid_drop_target (sidebar, NAUTILUS_GTK_SIDEBAR_ROW (target_row), context)) - goto out; - - if (sidebar->drag_data_info == DND_NAUTILUS_GTK_SIDEBAR_ROW) - { - GtkWidget **source_row; - /* A bookmark got reordered */ - if (target_section_type != SECTION_BOOKMARKS) - goto out; - - source_row = (void*) gtk_selection_data_get_data (selection_data); - - if (sidebar->row_placeholder != NULL) - g_object_get (sidebar->row_placeholder, "order-index", &target_order_index, NULL); - - reorder_bookmarks (sidebar, NAUTILUS_GTK_SIDEBAR_ROW (*source_row), target_order_index); - success = TRUE; - } - else - { - /* Dropping URIs! */ - GdkDragAction real_action; - gchar **uris; - GList *source_file_list; - - /* file transfer requested */ - real_action = gdk_drag_context_get_selected_action (context); - - if (real_action == GDK_ACTION_ASK) - real_action = emit_drag_action_ask (sidebar, gdk_drag_context_get_actions (context)); - - if (real_action > 0) - { - GFile *dest_file; - - uris = gtk_selection_data_get_uris (selection_data); - source_file_list = build_file_list_from_uris ((const gchar **) uris); - - if (target_place_type == PLACES_DROP_FEEDBACK) - { - drop_files_as_bookmarks (sidebar, source_file_list, target_order_index); - } - else - { - dest_file = g_file_new_for_uri (target_uri); - - emit_drag_perform_drop (sidebar, dest_file, source_file_list, real_action); - - g_object_unref (dest_file); - } - - success = TRUE; - g_list_free_full (source_file_list, g_object_unref); - g_strfreev (uris); - } - } - -out: - sidebar->drop_occurred = FALSE; - gtk_drag_finish (context, success, FALSE, time); - stop_drop_feedback (sidebar); - g_free (target_uri); -} - -static void -drag_end_callback (GtkWidget *widget, - GdkDragContext *context, - gpointer user_data) -{ - stop_drop_feedback (NAUTILUS_GTK_PLACES_SIDEBAR (user_data)); -} - -/* This functions is called every time the drag source leaves - * the sidebar widget. - * The problem is that, we start showing hints for drop when the source - * start being above the sidebar or when the application request so show - * drop hints, but at some moment we need to restore to normal - * state. - * One could think that here we could simply call stop_drop_feedback, - * but that's not true, because this function is called also before drag_drop, - * which needs the data from the drag so we cannot free the drag data here. - * So now one could think we could just do nothing here, and wait for - * drag-end or drag-failed signals and just stop_drop_feedback there. But that - * is also not true, since when the drag comes from a diferent widget than the - * sidebar, when the drag stops the last drag signal we receive is drag-leave. - * So here what we will do is restore the state of the sidebar as if no drag - * is being done (and if the application didnt request for permanent hints with - * nautilus_gtk_places_sidebar_show_drop_hints) and we will free the drag data next time - * we build new drag data in drag_data_received. - */ -static void -drag_leave_callback (GtkWidget *widget, - GdkDragContext *context, - guint time, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - if (sidebar->drop_state != DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT) - { - update_possible_drop_targets (sidebar, FALSE, context); - nautilus_gtk_sidebar_row_hide (NAUTILUS_GTK_SIDEBAR_ROW (sidebar->new_bookmark_row), FALSE); - sidebar->drop_state = DROP_STATE_NORMAL; - } - - sidebar->drag_data_received = FALSE; - sidebar->dragging_over = FALSE; - sidebar->drag_data_info = DND_UNKNOWN; -} - -static gboolean -drag_drop_callback (GtkWidget *list_box, - GdkDragContext *context, - gint x, - gint y, - guint time, - gpointer user_data) -{ - gboolean retval = FALSE; - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - sidebar->drop_occurred = TRUE; - retval = get_drag_data (sidebar->list_box, context, time); - g_signal_stop_emission_by_name (sidebar->list_box, "drag-drop"); - - return retval; -} - -static void -check_unmount_and_eject (GMount *mount, - GVolume *volume, - GDrive *drive, - gboolean *show_unmount, - gboolean *show_eject) -{ - *show_unmount = FALSE; - *show_eject = FALSE; - - if (drive != NULL) - *show_eject = g_drive_can_eject (drive); - - if (volume != NULL) - *show_eject |= g_volume_can_eject (volume); - - if (mount != NULL) - { - *show_eject |= g_mount_can_eject (mount); - *show_unmount = g_mount_can_unmount (mount) && !*show_eject; - } -} - -static void -check_visibility (GMount *mount, - GVolume *volume, - GDrive *drive, - gboolean *show_mount, - gboolean *show_unmount, - gboolean *show_eject, - gboolean *show_rescan, - gboolean *show_start, - gboolean *show_stop) -{ - *show_mount = FALSE; - *show_rescan = FALSE; - *show_start = FALSE; - *show_stop = FALSE; - - check_unmount_and_eject (mount, volume, drive, show_unmount, show_eject); - - if (drive != NULL) - { - if (g_drive_is_media_removable (drive) && - !g_drive_is_media_check_automatic (drive) && - g_drive_can_poll_for_media (drive)) - *show_rescan = TRUE; - - *show_start = g_drive_can_start (drive) || g_drive_can_start_degraded (drive); - *show_stop = g_drive_can_stop (drive); - - if (*show_stop) - *show_unmount = FALSE; - } - - if (volume != NULL) - { - if (mount == NULL) - *show_mount = g_volume_can_mount (volume); - } -} - -typedef struct { - GtkWidget *add_shortcut_item; - GtkWidget *remove_item; - GtkWidget *rename_item; - GtkWidget *separator_item; - GtkWidget *mount_item; - GtkWidget *unmount_item; - GtkWidget *eject_item; - GtkWidget *rescan_item; - GtkWidget *start_item; - GtkWidget *stop_item; -} PopoverData; - -static void -check_popover_sensitivity (NautilusGtkSidebarRow *row, - PopoverData *data) -{ - gboolean show_mount; - gboolean show_unmount; - gboolean show_eject; - gboolean show_rescan; - gboolean show_start; - gboolean show_stop; - NautilusGtkPlacesSidebarPlaceType type; - GDrive *drive; - GVolume *volume; - GMount *mount; - GtkWidget *sidebar; - GActionGroup *actions; - GAction *action; - - g_object_get (row, - "sidebar", &sidebar, - "place-type", &type, - "drive", &drive, - "volume", &volume, - "mount", &mount, - NULL); - - gtk_widget_set_visible (data->add_shortcut_item, (type == PLACES_MOUNTED_VOLUME)); - - actions = gtk_widget_get_action_group (sidebar, "row"); - action = g_action_map_lookup_action (G_ACTION_MAP (actions), "remove"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (type == PLACES_BOOKMARK)); - action = g_action_map_lookup_action (G_ACTION_MAP (actions), "rename"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (type == PLACES_BOOKMARK || - type == PLACES_XDG_DIR)); - action = g_action_map_lookup_action (G_ACTION_MAP (actions), "open"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !gtk_list_box_row_is_selected (GTK_LIST_BOX_ROW (row))); - - check_visibility (mount, volume, drive, - &show_mount, &show_unmount, &show_eject, &show_rescan, &show_start, &show_stop); - - gtk_widget_set_visible (data->separator_item, show_mount || show_unmount || show_eject); - gtk_widget_set_visible (data->mount_item, show_mount); - gtk_widget_set_visible (data->unmount_item, show_unmount); - gtk_widget_set_visible (data->eject_item, show_eject); - gtk_widget_set_visible (data->rescan_item, show_rescan); - gtk_widget_set_visible (data->start_item, show_start); - gtk_widget_set_visible (data->stop_item, show_stop); - - /* Adjust start/stop items to reflect the type of the drive */ - g_object_set (data->start_item, "text", _("_Start"), NULL); - g_object_set (data->stop_item, "text", _("_Stop"), NULL); - if ((show_start || show_stop) && drive != NULL) - { - switch (g_drive_get_start_stop_type (drive)) - { - case G_DRIVE_START_STOP_TYPE_SHUTDOWN: - /* start() for type G_DRIVE_START_STOP_TYPE_SHUTDOWN is normally not used */ - g_object_set (data->start_item, "text", _("_Power On"), NULL); - g_object_set (data->stop_item, "text", _("_Safely Remove Drive"), NULL); - break; - - case G_DRIVE_START_STOP_TYPE_NETWORK: - g_object_set (data->start_item, "text", _("_Connect Drive"), NULL); - g_object_set (data->stop_item, "text", _("_Disconnect Drive"), NULL); - break; - - case G_DRIVE_START_STOP_TYPE_MULTIDISK: - g_object_set (data->start_item, "text", _("_Start Multi-disk Device"), NULL); - g_object_set (data->stop_item, "text", _("_Stop Multi-disk Device"), NULL); - break; - - case G_DRIVE_START_STOP_TYPE_PASSWORD: - /* stop() for type G_DRIVE_START_STOP_TYPE_PASSWORD is normally not used */ - g_object_set (data->start_item, "text", _("_Unlock Device"), NULL); - g_object_set (data->stop_item, "text", _("_Lock Device"), NULL); - break; - - default: - case G_DRIVE_START_STOP_TYPE_UNKNOWN: - /* uses defaults set above */ - break; - } - } - - if (drive) - g_object_unref (drive); - if (volume) - g_object_unref (volume); - if (mount) - g_object_unref (mount); - - g_object_unref (sidebar); -} - -static void -drive_start_from_bookmark_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - error = NULL; - if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_drive_get_name (G_DRIVE (source_object)); - primary = g_strdup_printf (_("Unable to start “%s”"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } -} - -static void -volume_mount_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - NautilusGtkSidebarRow *row = NAUTILUS_GTK_SIDEBAR_ROW (user_data); - NautilusGtkPlacesSidebar *sidebar; - GVolume *volume; - GError *error; - gchar *primary; - gchar *name; - GMount *mount; - - volume = G_VOLUME (source_object); - g_object_get (row, "sidebar", &sidebar, NULL); - - error = NULL; - if (!g_volume_mount_finish (volume, result, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED && - error->code != G_IO_ERROR_ALREADY_MOUNTED) - { - name = g_volume_get_name (G_VOLUME (source_object)); - if (g_str_has_prefix (error->message, "Error unlocking")) - primary = g_strdup_printf (_("Error unlocking “%s”"), name); - else - primary = g_strdup_printf (_("Unable to access “%s”"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - sidebar->mounting = FALSE; - nautilus_gtk_sidebar_row_set_busy (row, FALSE); - - mount = g_volume_get_mount (volume); - if (mount != NULL) - { - GFile *location; - - location = g_mount_get_default_location (mount); - emit_open_location (sidebar, location, sidebar->go_to_after_mount_open_flags); - - g_object_unref (G_OBJECT (location)); - g_object_unref (G_OBJECT (mount)); - } - - g_object_unref (row); - g_object_unref (sidebar); -} - -static void -mount_volume (NautilusGtkSidebarRow *row, - GVolume *volume) -{ - NautilusGtkPlacesSidebar *sidebar; - GMountOperation *mount_op; - - g_object_get (row, "sidebar", &sidebar, NULL); - - mount_op = get_mount_operation (sidebar); - g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION); - - g_object_ref (row); - g_object_ref (sidebar); - g_volume_mount (volume, 0, mount_op, NULL, volume_mount_cb, row); -} - -static void -open_drive (NautilusGtkSidebarRow *row, - GDrive *drive, - NautilusGtkPlacesOpenFlags open_flags) -{ - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, "sidebar", &sidebar, NULL); - - if (drive != NULL && - (g_drive_can_start (drive) || g_drive_can_start_degraded (drive))) - { - GMountOperation *mount_op; - - nautilus_gtk_sidebar_row_set_busy (row, TRUE); - mount_op = get_mount_operation (sidebar); - g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, NULL); - g_object_unref (mount_op); - } -} - -static void -open_volume (NautilusGtkSidebarRow *row, - GVolume *volume, - NautilusGtkPlacesOpenFlags open_flags) -{ - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, "sidebar", &sidebar, NULL); - - if (volume != NULL && !sidebar->mounting) - { - sidebar->mounting = TRUE; - sidebar->go_to_after_mount_open_flags = open_flags; - nautilus_gtk_sidebar_row_set_busy (row, TRUE); - mount_volume (row, volume); - } -} - -static void -open_uri (NautilusGtkPlacesSidebar *sidebar, - const gchar *uri, - NautilusGtkPlacesOpenFlags open_flags) -{ - GFile *location; - - location = g_file_new_for_uri (uri); - emit_open_location (sidebar, location, open_flags); - g_object_unref (location); -} - -static void -open_row (NautilusGtkSidebarRow *row, - NautilusGtkPlacesOpenFlags open_flags) -{ - gchar *uri; - GDrive *drive; - GVolume *volume; - NautilusGtkPlacesSidebarPlaceType place_type; - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, - "sidebar", &sidebar, - "uri", &uri, - "place-type", &place_type, - "drive", &drive, - "volume", &volume, - NULL); - - if (place_type == PLACES_OTHER_LOCATIONS) - { - emit_show_other_locations (sidebar); - emit_show_other_locations_with_flags (sidebar, open_flags); - } - else if (place_type == PLACES_STARRED_LOCATION) - { - emit_show_starred_location (sidebar, open_flags); - } - else if (uri != NULL) - { - open_uri (sidebar, uri, open_flags); - } - else if (place_type == PLACES_CONNECT_TO_SERVER) - { - emit_show_connect_to_server (sidebar); - } - else if (place_type == PLACES_ENTER_LOCATION) - { - emit_show_enter_location (sidebar); - } - else if (volume != NULL) - { - open_volume (row, volume, open_flags); - } - else if (drive != NULL) - { - open_drive (row, drive, open_flags); - } - - g_object_unref (sidebar); - if (drive) - g_object_unref (drive); - if (volume) - g_object_unref (volume); - g_free (uri); -} - -/* Callback used for the "Open" menu items in the context menu */ -static void -open_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - NautilusGtkPlacesOpenFlags flags; - - flags = (NautilusGtkPlacesOpenFlags)g_variant_get_int32 (parameter); - open_row (sidebar->context_row, flags); -} - -/* Add bookmark for the selected item - just used from mount points */ -static void -add_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - gchar *uri; - gchar *name; - GFile *location; - - g_object_get (sidebar->context_row, - "uri", &uri, - "label", &name, - NULL); - - if (uri != NULL) - { - location = g_file_new_for_uri (uri); - if (_nautilus_gtk_bookmarks_manager_insert_bookmark (sidebar->bookmarks_manager, location, -1, NULL)) - _nautilus_gtk_bookmarks_manager_set_bookmark_label (sidebar->bookmarks_manager, location, name, NULL); - g_object_unref (location); - } - - g_free (uri); - g_free (name); -} - -static void -rename_entry_changed (GtkEntry *entry, - NautilusGtkPlacesSidebar *sidebar) -{ - NautilusGtkPlacesSidebarPlaceType type; - gchar *name; - gchar *uri; - const gchar *new_name; - gboolean found = FALSE; - GList *rows; - GList *l; - - new_name = gtk_entry_get_text (GTK_ENTRY (sidebar->rename_entry)); - - if (strcmp (new_name, "") == 0) - { - gtk_widget_set_sensitive (sidebar->rename_button, FALSE); - gtk_label_set_label (GTK_LABEL (sidebar->rename_error), ""); - return; - } - - rows = gtk_container_get_children (GTK_CONTAINER (sidebar->list_box)); - for (l = rows; l && !found; l = l->next) - { - g_object_get (l->data, - "place-type", &type, - "uri", &uri, - "label", &name, - NULL); - - if ((type == PLACES_XDG_DIR || type == PLACES_BOOKMARK) && - strcmp (uri, sidebar->rename_uri) != 0 && - strcmp (new_name, name) == 0) - found = TRUE; - - g_free (uri); - g_free (name); - } - g_list_free (rows); - - gtk_widget_set_sensitive (sidebar->rename_button, !found); - gtk_label_set_label (GTK_LABEL (sidebar->rename_error), - found ? _("This name is already taken") : ""); -} - -static void -do_rename (GtkButton *button, - NautilusGtkPlacesSidebar *sidebar) -{ - gchar *new_text; - GFile *file; - - new_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (sidebar->rename_entry))); - - file = g_file_new_for_uri (sidebar->rename_uri); - if (!_nautilus_gtk_bookmarks_manager_has_bookmark (sidebar->bookmarks_manager, file)) - _nautilus_gtk_bookmarks_manager_insert_bookmark (sidebar->bookmarks_manager, file, -1, NULL); - - _nautilus_gtk_bookmarks_manager_set_bookmark_label (sidebar->bookmarks_manager, file, new_text, NULL); - - g_object_unref (file); - g_free (new_text); - - g_clear_pointer (&sidebar->rename_uri, g_free); - - if (sidebar->rename_popover) - gtk_popover_popdown (GTK_POPOVER (sidebar->rename_popover)); -} - -static void -on_rename_popover_destroy (GtkWidget *rename_popover, - NautilusGtkPlacesSidebar *sidebar) -{ - if (sidebar) - { - sidebar->rename_popover = NULL; - sidebar->rename_entry = NULL; - sidebar->rename_button = NULL; - sidebar->rename_error = NULL; - } -} - -static void -create_rename_popover (NautilusGtkPlacesSidebar *sidebar) -{ - GtkWidget *popover; - GtkWidget *grid; - GtkWidget *label; - GtkWidget *entry; - GtkWidget *button; - GtkWidget *error; - gchar *str; - - if (sidebar->rename_popover) - return; - - popover = gtk_popover_new (GTK_WIDGET (sidebar)); - /* Clean sidebar pointer when its destroyed, most of the times due to its - * relative_to associated row being destroyed */ - g_signal_connect (popover, "destroy", G_CALLBACK (on_rename_popover_destroy), sidebar); - gtk_popover_set_position (GTK_POPOVER (popover), GTK_POS_RIGHT); - grid = gtk_grid_new (); - gtk_container_add (GTK_CONTAINER (popover), grid); - g_object_set (grid, - "margin", 10, - "row-spacing", 6, - "column-spacing", 6, - NULL); - entry = gtk_entry_new (); - gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); - g_signal_connect (entry, "changed", G_CALLBACK (rename_entry_changed), sidebar); - str = g_strdup_printf ("<b>%s</b>", _("Name")); - label = gtk_label_new (str); - gtk_widget_set_halign (label, GTK_ALIGN_START); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); - g_free (str); - button = gtk_button_new_with_mnemonic (_("_Rename")); - gtk_widget_set_can_default (button, TRUE); - gtk_style_context_add_class (gtk_widget_get_style_context (button), "suggested-action"); - g_signal_connect (button, "clicked", G_CALLBACK (do_rename), sidebar); - error = gtk_label_new (""); - gtk_widget_set_halign (error, GTK_ALIGN_START); - gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1); - gtk_grid_attach (GTK_GRID (grid), entry, 0, 1, 1, 1); - gtk_grid_attach (GTK_GRID (grid), button,1, 1, 1, 1); - gtk_grid_attach (GTK_GRID (grid), error, 0, 2, 2, 1); - gtk_widget_show_all (grid); - gtk_popover_set_default_widget (GTK_POPOVER (popover), button); - - sidebar->rename_popover = popover; - sidebar->rename_entry = entry; - sidebar->rename_button = button; - sidebar->rename_error = error; -} - -/* Style the row differently while we show a popover for it. - * Otherwise, the popover is 'pointing to nothing'. Since the - * main popover and the rename popover interleave their hiding - * and showing, we have to count to ensure that we don't loose - * the state before the last popover is gone. - * - * This would be nicer as a state, but reusing hover for this - * interferes with the normal handling of this state, so just - * use a style class. - */ -static void -update_popover_shadowing (GtkWidget *row, - gboolean shown) -{ - GtkStyleContext *context; - gint count; - - count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "popover-count")); - count = shown ? count + 1 : count - 1; - g_object_set_data (G_OBJECT (row), "popover-count", GINT_TO_POINTER (count)); - - context = gtk_widget_get_style_context (row); - if (count > 0) - gtk_style_context_add_class (context, "has-open-popup"); - else - gtk_style_context_remove_class (context, "has-open-popup"); -} - -static void -set_prelight (GtkPopover *popover) -{ - update_popover_shadowing (gtk_popover_get_relative_to (popover), TRUE); -} - -static void -unset_prelight (GtkPopover *popover) -{ - update_popover_shadowing (gtk_popover_get_relative_to (popover), FALSE); -} - -static void -setup_popover_shadowing (GtkWidget *popover) -{ - g_signal_connect (popover, "map", G_CALLBACK (set_prelight), NULL); - g_signal_connect (popover, "unmap", G_CALLBACK (unset_prelight), NULL); -} - -static void -show_rename_popover (NautilusGtkSidebarRow *row) -{ - gchar *name; - gchar *uri; - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, - "sidebar", &sidebar, - "label", &name, - "uri", &uri, - NULL); - - create_rename_popover (sidebar); - - if (sidebar->rename_uri) - g_free (sidebar->rename_uri); - sidebar->rename_uri = g_strdup (uri); - - gtk_entry_set_text (GTK_ENTRY (sidebar->rename_entry), name); - gtk_popover_set_relative_to (GTK_POPOVER (sidebar->rename_popover), GTK_WIDGET (row)); - setup_popover_shadowing (sidebar->rename_popover); - - gtk_popover_popup (GTK_POPOVER (sidebar->rename_popover)); - gtk_widget_grab_focus (sidebar->rename_entry); - - g_free (name); - g_free (uri); - g_object_unref (sidebar); -} - -static void -rename_bookmark (NautilusGtkSidebarRow *row) -{ - NautilusGtkPlacesSidebarPlaceType type; - - g_object_get (row, "place-type", &type, NULL); - - if (type != PLACES_BOOKMARK && type != PLACES_XDG_DIR) - return; - - show_rename_popover (row); -} - -static void -rename_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - - rename_bookmark (sidebar->context_row); -} - -static void -remove_bookmark (NautilusGtkSidebarRow *row) -{ - NautilusGtkPlacesSidebarPlaceType type; - gchar *uri; - GFile *file; - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, - "sidebar", &sidebar, - "place-type", &type, - "uri", &uri, - NULL); - - if (type == PLACES_BOOKMARK) - { - file = g_file_new_for_uri (uri); - _nautilus_gtk_bookmarks_manager_remove_bookmark (sidebar->bookmarks_manager, file, NULL); - g_object_unref (file); - } - - g_free (uri); - g_object_unref (sidebar); -} - -static void -remove_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - - remove_bookmark (sidebar->context_row); -} - -static void -mount_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GVolume *volume; - - g_object_get (sidebar->context_row, - "volume", &volume, - NULL); - - if (volume != NULL) - mount_volume (sidebar->context_row, volume); - - g_object_unref (volume); -} - -/* Callback used from g_mount_unmount_with_operation() */ -static void -unmount_mount_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - GMount *mount; - GError *error; - - mount = G_MOUNT (source_object); - - error = NULL; - if (!g_mount_unmount_with_operation_finish (mount, result, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - gchar *name; - gchar *primary; - - name = g_mount_get_name (mount); - primary = g_strdup_printf (_("Unable to unmount “%s”"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static GMountOperation * -get_mount_operation (NautilusGtkPlacesSidebar *sidebar) -{ - GMountOperation *mount_op; - - mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar)))); - - emit_mount_operation (sidebar, mount_op); - - return mount_op; -} - -static GMountOperation * -get_unmount_operation (NautilusGtkPlacesSidebar *sidebar) -{ - GMountOperation *mount_op; - - mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar)))); - - emit_unmount_operation (sidebar, mount_op); - - return mount_op; -} - -/* Returns TRUE if file1 is prefix of file2 or if both files have the - * same path - */ -static gboolean -file_prefix_or_same (GFile *file1, - GFile *file2) -{ - return g_file_has_prefix (file1, file2) || - g_file_equal (file1, file2); -} - -static gboolean -is_current_location_on_volume (NautilusGtkPlacesSidebar *sidebar, - GMount *mount, - GVolume *volume, - GDrive *drive) -{ - gboolean current_location_on_volume; - GFile *mount_default_location; - GMount *mount_for_volume; - GList *volumes_for_drive; - GList *volume_for_drive; - - current_location_on_volume = FALSE; - - if (sidebar->current_location != NULL) - { - if (mount != NULL) - { - mount_default_location = g_mount_get_default_location (mount); - current_location_on_volume = file_prefix_or_same (sidebar->current_location, - mount_default_location); - - g_object_unref (mount_default_location); - } - /* This code path is probably never reached since mount always exists, - * and if it doesn't exists we don't offer a way to eject a volume or - * drive in the UI. Do it for defensive programming - */ - else if (volume != NULL) - { - mount_for_volume = g_volume_get_mount (volume); - if (mount_for_volume != NULL) - { - mount_default_location = g_mount_get_default_location (mount_for_volume); - current_location_on_volume = file_prefix_or_same (sidebar->current_location, - mount_default_location); - - g_object_unref (mount_default_location); - g_object_unref (mount_for_volume); - } - } - /* This code path is probably never reached since mount always exists, - * and if it doesn't exists we don't offer a way to eject a volume or - * drive in the UI. Do it for defensive programming - */ - else if (drive != NULL) - { - volumes_for_drive = g_drive_get_volumes (drive); - for (volume_for_drive = volumes_for_drive; volume_for_drive != NULL; volume_for_drive = volume_for_drive->next) - { - mount_for_volume = g_volume_get_mount (volume_for_drive->data); - if (mount_for_volume != NULL) - { - mount_default_location = g_mount_get_default_location (mount_for_volume); - current_location_on_volume = file_prefix_or_same (sidebar->current_location, - mount_default_location); - - g_object_unref (mount_default_location); - g_object_unref (mount_for_volume); - - if (current_location_on_volume) - break; - } - } - g_list_free_full (volumes_for_drive, g_object_unref); - } - } - - return current_location_on_volume; -} - -static void -do_unmount (GMount *mount, - NautilusGtkPlacesSidebar *sidebar) -{ - if (mount != NULL) - { - GMountOperation *mount_op; - - if (is_current_location_on_volume (sidebar, mount, NULL, NULL)) - open_home (sidebar); - - mount_op = get_unmount_operation (sidebar); - g_mount_unmount_with_operation (mount, - 0, - mount_op, - NULL, - unmount_mount_cb, - g_object_ref (sidebar)); - g_object_unref (mount_op); - } -} - -static void -unmount_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GMount *mount; - - g_object_get (sidebar->context_row, - "mount", &mount, - NULL); - - do_unmount (mount, sidebar); - - if (mount) - g_object_unref (mount); -} - -static void -drive_stop_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = user_data; - - error = NULL; - if (!g_drive_stop_finish (G_DRIVE (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_drive_get_name (G_DRIVE (source_object)); - primary = g_strdup_printf (_("Unable to stop “%s”"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static void -drive_eject_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = user_data; - - error = NULL; - if (!g_drive_eject_with_operation_finish (G_DRIVE (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_drive_get_name (G_DRIVE (source_object)); - primary = g_strdup_printf (_("Unable to eject “%s”"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static void -volume_eject_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = user_data; - - error = NULL; - if (!g_volume_eject_with_operation_finish (G_VOLUME (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_volume_get_name (G_VOLUME (source_object)); - primary = g_strdup_printf (_("Unable to eject %s"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static void -mount_eject_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = user_data; - - error = NULL; - if (!g_mount_eject_with_operation_finish (G_MOUNT (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_mount_get_name (G_MOUNT (source_object)); - primary = g_strdup_printf (_("Unable to eject %s"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static void -do_eject (GMount *mount, - GVolume *volume, - GDrive *drive, - NautilusGtkPlacesSidebar *sidebar) -{ - GMountOperation *mount_op; - - mount_op = get_unmount_operation (sidebar); - - if (is_current_location_on_volume (sidebar, mount, volume, drive)) - open_home (sidebar); - - if (mount != NULL) - g_mount_eject_with_operation (mount, 0, mount_op, NULL, mount_eject_cb, - g_object_ref (sidebar)); - /* This code path is probably never reached since mount always exists, - * and if it doesn't exists we don't offer a way to eject a volume or - * drive in the UI. Do it for defensive programming - */ - else if (volume != NULL) - g_volume_eject_with_operation (volume, 0, mount_op, NULL, volume_eject_cb, - g_object_ref (sidebar)); - /* This code path is probably never reached since mount always exists, - * and if it doesn't exists we don't offer a way to eject a volume or - * drive in the UI. Do it for defensive programming - */ - else if (drive != NULL) - { - if (g_drive_can_stop (drive)) - g_drive_stop (drive, 0, mount_op, NULL, drive_stop_cb, - g_object_ref (sidebar)); - else - g_drive_eject_with_operation (drive, 0, mount_op, NULL, drive_eject_cb, - g_object_ref (sidebar)); - } - g_object_unref (mount_op); -} - -static void -eject_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GMount *mount; - GVolume *volume; - GDrive *drive; - - g_object_get (sidebar->context_row, - "mount", &mount, - "volume", &volume, - "drive", &drive, - NULL); - - do_eject (mount, volume, drive, sidebar); - - if (mount) - g_object_unref (mount); - if (volume) - g_object_unref (volume); - if (drive) - g_object_unref (drive); -} - -static gboolean -eject_or_unmount_bookmark (NautilusGtkSidebarRow *row) -{ - gboolean can_unmount, can_eject; - GMount *mount; - GVolume *volume; - GDrive *drive; - gboolean ret; - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, - "sidebar", &sidebar, - "mount", &mount, - "volume", &volume, - "drive", &drive, - NULL); - ret = FALSE; - - check_unmount_and_eject (mount, volume, drive, &can_unmount, &can_eject); - /* if we can eject, it has priority over unmount */ - if (can_eject) - { - do_eject (mount, volume, drive, sidebar); - ret = TRUE; - } - else if (can_unmount) - { - do_unmount (mount, sidebar); - ret = TRUE; - } - - g_object_unref (sidebar); - if (mount) - g_object_unref (mount); - if (volume) - g_object_unref (volume); - if (drive) - g_object_unref (drive); - - return ret; -} - -static gboolean -eject_or_unmount_selection (NautilusGtkPlacesSidebar *sidebar) -{ - gboolean ret; - GtkListBoxRow *row; - - row = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box)); - ret = eject_or_unmount_bookmark (NAUTILUS_GTK_SIDEBAR_ROW (row)); - - return ret; -} - -static void -drive_poll_for_media_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - error = NULL; - if (!g_drive_poll_for_media_finish (G_DRIVE (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_drive_get_name (G_DRIVE (source_object)); - primary = g_strdup_printf (_("Unable to poll “%s” for media changes"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static void -rescan_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GDrive *drive; - - g_object_get (sidebar->context_row, - "drive", &drive, - NULL); - - if (drive != NULL) - { - g_drive_poll_for_media (drive, NULL, drive_poll_for_media_cb, g_object_ref (sidebar)); - g_object_unref (drive); - } -} - -static void -drive_start_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar; - GError *error; - gchar *primary; - gchar *name; - - sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (user_data); - - error = NULL; - if (!g_drive_start_finish (G_DRIVE (source_object), res, &error)) - { - if (error->code != G_IO_ERROR_FAILED_HANDLED) - { - name = g_drive_get_name (G_DRIVE (source_object)); - primary = g_strdup_printf (_("Unable to start “%s”"), name); - g_free (name); - emit_show_error_message (sidebar, primary, error->message); - g_free (primary); - } - g_error_free (error); - } - - g_object_unref (sidebar); -} - -static void -start_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GDrive *drive; - - g_object_get (sidebar->context_row, - "drive", &drive, - NULL); - - if (drive != NULL) - { - GMountOperation *mount_op; - - mount_op = get_mount_operation (sidebar); - - g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_cb, g_object_ref (sidebar)); - - g_object_unref (mount_op); - g_object_unref (drive); - } -} - -static void -stop_shortcut_cb (GSimpleAction *action, - GVariant *parameter, - gpointer data) -{ - NautilusGtkPlacesSidebar *sidebar = data; - GDrive *drive; - - g_object_get (sidebar->context_row, - "drive", &drive, - NULL); - - if (drive != NULL) - { - GMountOperation *mount_op; - - mount_op = get_unmount_operation (sidebar); - g_drive_stop (drive, G_MOUNT_UNMOUNT_NONE, mount_op, NULL, drive_stop_cb, - g_object_ref (sidebar)); - - g_object_unref (mount_op); - g_object_unref (drive); - } -} - -static gboolean -on_key_press_event (GtkWidget *widget, - GdkEventKey *event, - NautilusGtkPlacesSidebar *sidebar) -{ - guint modifiers; - GtkListBoxRow *row; - - if (event) - { - row = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box)); - if (row) - { - modifiers = gtk_accelerator_get_default_mod_mask (); - - if (event->keyval == GDK_KEY_Return || - event->keyval == GDK_KEY_KP_Enter || - event->keyval == GDK_KEY_ISO_Enter || - event->keyval == GDK_KEY_space) - { - NautilusGtkPlacesOpenFlags open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; - - if ((event->state & modifiers) == GDK_SHIFT_MASK) - open_flags = NAUTILUS_GTK_PLACES_OPEN_NEW_TAB; - else if ((event->state & modifiers) == GDK_CONTROL_MASK) - open_flags = NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW; - - open_row (NAUTILUS_GTK_SIDEBAR_ROW (row), open_flags); - - return TRUE; - } - - if (event->keyval == GDK_KEY_Down && - (event->state & modifiers) == GDK_MOD1_MASK) - return eject_or_unmount_selection (sidebar); - - if ((event->keyval == GDK_KEY_Delete || - event->keyval == GDK_KEY_KP_Delete) && - (event->state & modifiers) == 0) - { - remove_bookmark (NAUTILUS_GTK_SIDEBAR_ROW (row)); - return TRUE; - } - - if ((event->keyval == GDK_KEY_F2) && - (event->state & modifiers) == 0) - { - rename_bookmark (NAUTILUS_GTK_SIDEBAR_ROW (row)); - return TRUE; - } - - if ((event->keyval == GDK_KEY_Menu) || - ((event->keyval == GDK_KEY_F10) && - (event->state & modifiers) == GDK_SHIFT_MASK)) - - { - popup_menu_cb (NAUTILUS_GTK_SIDEBAR_ROW (row)); - return TRUE; - } - } - } - - return FALSE; -} - -static GActionEntry entries[] = { - { "open", open_shortcut_cb, "i", NULL, NULL }, - { "open-other", open_shortcut_cb, "i", NULL, NULL }, - { "bookmark", add_shortcut_cb, NULL, NULL, NULL }, - { "remove", remove_shortcut_cb, NULL, NULL, NULL }, - { "rename", rename_shortcut_cb, NULL, NULL, NULL }, - { "mount", mount_shortcut_cb, NULL, NULL, NULL }, - { "unmount", unmount_shortcut_cb, NULL, NULL, NULL }, - { "eject", eject_shortcut_cb, NULL, NULL, NULL }, - { "rescan", rescan_shortcut_cb, NULL, NULL, NULL }, - { "start", start_shortcut_cb, NULL, NULL, NULL }, - { "stop", stop_shortcut_cb, NULL, NULL, NULL }, -}; - -static void -add_actions (NautilusGtkPlacesSidebar *sidebar) -{ - GActionGroup *actions; - - actions = G_ACTION_GROUP (g_simple_action_group_new ()); - g_action_map_add_action_entries (G_ACTION_MAP (actions), - entries, G_N_ELEMENTS (entries), - sidebar); - gtk_widget_insert_action_group (GTK_WIDGET (sidebar), "row", actions); - g_object_unref (actions); -} - -static GtkWidget * -append_separator (GtkWidget *box) -{ - GtkWidget *separator; - - separator = g_object_new (GTK_TYPE_SEPARATOR, - "orientation", GTK_ORIENTATION_HORIZONTAL, - "visible", TRUE, - "margin-top", 6, - "margin-bottom", 6, - NULL); - gtk_container_add (GTK_CONTAINER (box), separator); - - return separator; -} - -static GtkWidget * -add_button (GtkWidget *box, - const gchar *label, - const gchar *action) -{ - GtkWidget *item; - - item = g_object_new (GTK_TYPE_MODEL_BUTTON, - "visible", TRUE, - "action-name", action, - "text", label, - NULL); - gtk_container_add (GTK_CONTAINER (box), item); - - return item; -} - -static GtkWidget * -add_open_button (GtkWidget *box, - const gchar *label, - NautilusGtkPlacesOpenFlags flags) -{ - GtkWidget *item; - - item = g_object_new (GTK_TYPE_MODEL_BUTTON, - "visible", TRUE, - "action-name", flags == NAUTILUS_GTK_PLACES_OPEN_NORMAL ? "row.open" : "row.open-other", - "action-target", g_variant_new_int32 (flags), - "text", label, - NULL); - gtk_container_add (GTK_CONTAINER (box), item); - - return item; -} - -static void -on_row_popover_destroy (GtkWidget *row_popover, - NautilusGtkPlacesSidebar *sidebar) -{ - if (sidebar) - sidebar->popover = NULL; -} - -#ifdef HAVE_CLOUDPROVIDERS -static void -build_popup_menu_using_gmenu (NautilusGtkSidebarRow *row) -{ - CloudProvidersAccount *cloud_provider_account; - NautilusGtkPlacesSidebar *sidebar; - GMenuModel *cloud_provider_menu; - GActionGroup *cloud_provider_action_group; - - g_object_get (row, - "sidebar", &sidebar, - "cloud-provider-account", &cloud_provider_account, - NULL); - - /* Cloud provider account */ - if (cloud_provider_account) - { - GMenu *menu = g_menu_new (); - GMenuItem *item; - item = g_menu_item_new (_("_Open"), "row.open"); - g_menu_item_set_action_and_target_value (item, "row.open", g_variant_new_int32(NAUTILUS_GTK_PLACES_OPEN_NORMAL)); - g_menu_append_item (menu, item); - if (sidebar->open_flags & NAUTILUS_GTK_PLACES_OPEN_NEW_TAB) - { - item = g_menu_item_new (_("Open in New _Tab"), "row.open-other"); - g_menu_item_set_action_and_target_value (item, "row.open-other", g_variant_new_int32(NAUTILUS_GTK_PLACES_OPEN_NEW_TAB)); - g_menu_append_item (menu, item); - } - if (sidebar->open_flags & NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW) - { - item = g_menu_item_new (_("Open in New _Window"), "row.open-other"); - g_menu_item_set_action_and_target_value (item, "row.open-other", g_variant_new_int32(NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW)); - g_menu_append_item (menu, item); - } - cloud_provider_menu = cloud_providers_account_get_menu_model (cloud_provider_account); - cloud_provider_action_group = cloud_providers_account_get_action_group (cloud_provider_account); - if (cloud_provider_menu != NULL && cloud_provider_action_group != NULL) - { - g_menu_append_section (menu, NULL, cloud_provider_menu); - gtk_widget_insert_action_group (GTK_WIDGET (sidebar), - "cloudprovider", - G_ACTION_GROUP (cloud_provider_action_group)); - } - add_actions (sidebar); - if (sidebar->popover) - gtk_widget_destroy (sidebar->popover); - - sidebar->popover = gtk_popover_new_from_model (GTK_WIDGET (sidebar), - G_MENU_MODEL (menu)); - g_signal_connect (sidebar->popover, "destroy", - G_CALLBACK (on_row_popover_destroy), sidebar); - g_object_unref (sidebar); - g_object_unref (cloud_provider_account); - } -} -#endif - -/* Constructs the popover for the sidebar row if needed */ -static void -create_row_popover (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkSidebarRow *row) -{ - PopoverData data; - GtkWidget *box; - -#ifdef HAVE_CLOUDPROVIDERS - CloudProvidersAccount *cloud_provider_account; - - g_object_get (row, "cloud-provider-account", &cloud_provider_account, NULL); - - if (cloud_provider_account) - { - build_popup_menu_using_gmenu (row); - return; - } -#endif - - sidebar->popover = gtk_popover_new (GTK_WIDGET (sidebar)); - /* Clean sidebar pointer when its destroyed, most of the times due to its - * relative_to associated row being destroyed */ - g_signal_connect (sidebar->popover, "destroy", G_CALLBACK (on_row_popover_destroy), sidebar); - setup_popover_shadowing (sidebar->popover); - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - g_object_set (box, "margin", 10, NULL); - gtk_widget_show (box); - gtk_container_add (GTK_CONTAINER (sidebar->popover), box); - - add_open_button (box, _("_Open"), NAUTILUS_GTK_PLACES_OPEN_NORMAL); - - if (sidebar->open_flags & NAUTILUS_GTK_PLACES_OPEN_NEW_TAB) - add_open_button (box, _("Open in New _Tab"), NAUTILUS_GTK_PLACES_OPEN_NEW_TAB); - - if (sidebar->open_flags & NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW) - add_open_button (box, _("Open in New _Window"), NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW); - - append_separator (box); - - data.add_shortcut_item = add_button (box, _("_Add Bookmark"), "row.bookmark"); - data.remove_item = add_button (box, _("_Remove"), "row.remove"); - data.rename_item = add_button (box, _("Rename…"), "row.rename"); - - data.separator_item = append_separator (box); - - data.mount_item = add_button (box, _("_Mount"), "row.mount"); - data.unmount_item = add_button (box, _("_Unmount"), "row.unmount"); - data.eject_item = add_button (box, _("_Eject"), "row.eject"); - data.rescan_item = add_button (box, _("_Detect Media"), "row.rescan"); - data.start_item = add_button (box, _("_Start"), "row.start"); - data.stop_item = add_button (box, _("_Stop"), "row.stop"); - - /* Update everything! */ - check_popover_sensitivity (row, &data); - - if (sidebar->populate_all) - { - gchar *uri; - GVolume *volume; - GFile *file; - - g_object_get (row, - "uri", &uri, - "volume", &volume, - NULL); - - if (uri) - file = g_file_new_for_uri (uri); - else - file = NULL; - - g_signal_emit (sidebar, places_sidebar_signals[POPULATE_POPUP], 0, - box, file, volume); - - if (file) - g_object_unref (file); - - g_free (uri); - if (volume) - g_object_unref (volume); - } -} - -static void -show_row_popover (NautilusGtkSidebarRow *row) -{ - NautilusGtkPlacesSidebar *sidebar; - - g_object_get (row, "sidebar", &sidebar, NULL); - - if (sidebar->popover) - gtk_widget_destroy (sidebar->popover); - - create_row_popover (sidebar, row); - - gtk_popover_set_relative_to (GTK_POPOVER (sidebar->popover), GTK_WIDGET (row)); - - sidebar->context_row = row; - gtk_popover_popup (GTK_POPOVER (sidebar->popover)); - - g_object_unref (sidebar); -} - -static void -on_row_activated (GtkListBox *list_box, - GtkListBoxRow *row, - gpointer user_data) -{ - NautilusGtkSidebarRow *selected_row; - - /* Avoid to open a location if the user is dragging. Changing the location - * while dragging usually makes clients changing the view of the files, which - * is confusing while the user has the attention on the drag - */ - if (NAUTILUS_GTK_PLACES_SIDEBAR (user_data)->dragging_over) - return; - - selected_row = NAUTILUS_GTK_SIDEBAR_ROW (gtk_list_box_get_selected_row (list_box)); - open_row (selected_row, 0); -} - -static gboolean -on_button_press_event (GtkWidget *widget, - GdkEventButton *event, - NautilusGtkSidebarRow *row) -{ - NautilusGtkPlacesSidebar *sidebar; - NautilusGtkPlacesSidebarSectionType section_type; - - g_object_get (NAUTILUS_GTK_SIDEBAR_ROW (row), - "sidebar", &sidebar, - "section_type", §ion_type, - NULL); - - if (section_type == SECTION_BOOKMARKS) - { - sidebar->drag_row = GTK_WIDGET (row); - sidebar->drag_row_x = (gint)event->x; - sidebar->drag_row_y = (gint)event->y; - - sidebar->drag_root_x = event->x_root; - sidebar->drag_root_y = event->y_root; - } - - g_object_unref (sidebar); - - return FALSE; -} - -static gboolean -on_button_release_event (GtkWidget *widget, - GdkEventButton *event, - NautilusGtkSidebarRow *row) -{ - gboolean ret = FALSE; - NautilusGtkPlacesSidebarPlaceType row_type; - - if (event && row) - { - g_object_get (row, "place-type", &row_type, NULL); - - if (event->button == 1) - ret = FALSE; - else if (event->button == 2) - { - NautilusGtkPlacesOpenFlags open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; - - open_flags = (event->state & GDK_CONTROL_MASK) ? - NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW : - NAUTILUS_GTK_PLACES_OPEN_NEW_TAB; - - open_row (NAUTILUS_GTK_SIDEBAR_ROW (row), open_flags); - ret = TRUE; - } - else if (event->button == 3) - { - if (row_type != PLACES_CONNECT_TO_SERVER) - show_row_popover (NAUTILUS_GTK_SIDEBAR_ROW (row)); - } - } - - return ret; -} - -static void -popup_menu_cb (NautilusGtkSidebarRow *row) -{ - NautilusGtkPlacesSidebarPlaceType row_type; - - g_object_get (row, "place-type", &row_type, NULL); - - if (row_type != PLACES_CONNECT_TO_SERVER) - show_row_popover (row); -} - -static void -long_press_cb (GtkGesture *gesture, - gdouble x, - gdouble y, - NautilusGtkPlacesSidebar *sidebar) -{ - GtkWidget *row; - - row = GTK_WIDGET (gtk_list_box_get_row_at_y (GTK_LIST_BOX (sidebar->list_box), y)); - if (NAUTILUS_IS_GTK_SIDEBAR_ROW (row)) - popup_menu_cb (NAUTILUS_GTK_SIDEBAR_ROW (row)); -} - -static gint -list_box_sort_func (GtkListBoxRow *row1, - GtkListBoxRow *row2, - gpointer user_data) -{ - NautilusGtkPlacesSidebarSectionType section_type_1, section_type_2; - NautilusGtkPlacesSidebarPlaceType place_type_1, place_type_2; - gchar *label_1, *label_2; - gint index_1, index_2; - gint retval = 0; - - g_object_get (row1, - "label", &label_1, - "place-type", &place_type_1, - "section-type", §ion_type_1, - "order-index", &index_1, - NULL); - g_object_get (row2, - "label", &label_2, - "place-type", &place_type_2, - "section-type", §ion_type_2, - "order-index", &index_2, - NULL); - - /* Always last position for "connect to server" */ - if (place_type_1 == PLACES_CONNECT_TO_SERVER) - { - retval = 1; - } - else if (place_type_2 == PLACES_CONNECT_TO_SERVER) - { - retval = -1; - } - else - { - if (section_type_1 == section_type_2) - { - if ((section_type_1 == SECTION_COMPUTER && - place_type_1 == place_type_2 && - place_type_1 == PLACES_XDG_DIR) || - section_type_1 == SECTION_MOUNTS) - { - retval = g_utf8_collate (label_1, label_2); - } - else if ((place_type_1 == PLACES_BOOKMARK || place_type_2 == PLACES_DROP_FEEDBACK) && - (place_type_1 == PLACES_DROP_FEEDBACK || place_type_2 == PLACES_BOOKMARK)) - { - retval = index_1 - index_2; - } - /* We order the bookmarks sections based on the bookmark index that we - * set on the row as a order-index property, but we have to deal with - * the placeholder row wanted to be between two consecutive bookmarks, - * with two consecutive order-index values which is the usual case. - * For that, in the list box sort func we give priority to the placeholder row, - * that means that if the index-order is the same as another bookmark - * the placeholder row goes before. However if we want to show it after - * the current row, for instance when the cursor is in the lower half - * of the row, we need to increase the order-index. - */ - else if (place_type_1 == PLACES_BOOKMARK_PLACEHOLDER && place_type_2 == PLACES_BOOKMARK) - { - if (index_1 == index_2) - retval = index_1 - index_2 - 1; - else - retval = index_1 - index_2; - } - else if (place_type_1 == PLACES_BOOKMARK && place_type_2 == PLACES_BOOKMARK_PLACEHOLDER) - { - if (index_1 == index_2) - retval = index_1 - index_2 + 1; - else - retval = index_1 - index_2; - } - } - else - { - /* Order by section. That means the order in the enum of section types - * define the actual order of them in the list */ - retval = section_type_1 - section_type_2; - } - } - - g_free (label_1); - g_free (label_2); - - return retval; -} - -static void -update_hostname (NautilusGtkPlacesSidebar *sidebar) -{ - GVariant *variant; - gsize len; - const gchar *hostname; - - if (sidebar->hostnamed_proxy == NULL) - return; - - variant = g_dbus_proxy_get_cached_property (sidebar->hostnamed_proxy, - "PrettyHostname"); - if (variant == NULL) - return; - - hostname = g_variant_get_string (variant, &len); - if (len > 0 && - g_strcmp0 (sidebar->hostname, hostname) != 0) - { - g_free (sidebar->hostname); - sidebar->hostname = g_strdup (hostname); - update_places (sidebar); - } - - g_variant_unref (variant); -} - -static void -hostname_proxy_new_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = user_data; - GError *error = NULL; - GDBusProxy *proxy; - - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - { - g_error_free (error); - return; - } - - sidebar->hostnamed_proxy = proxy; - g_clear_object (&sidebar->hostnamed_cancellable); - - if (error != NULL) - { - g_debug ("Failed to create D-Bus proxy: %s", error->message); - g_error_free (error); - return; - } - - g_signal_connect_swapped (sidebar->hostnamed_proxy, - "g-properties-changed", - G_CALLBACK (update_hostname), - sidebar); - update_hostname (sidebar); -} - -static void -create_volume_monitor (NautilusGtkPlacesSidebar *sidebar) -{ - g_assert (sidebar->volume_monitor == NULL); - - sidebar->volume_monitor = g_volume_monitor_get (); - - g_signal_connect_object (sidebar->volume_monitor, "volume_added", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "volume_removed", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "volume_changed", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "mount_added", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "mount_removed", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "mount_changed", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "drive_disconnected", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "drive_connected", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); - g_signal_connect_object (sidebar->volume_monitor, "drive_changed", - G_CALLBACK (update_places), sidebar, G_CONNECT_SWAPPED); -} - -static void -shell_shows_desktop_changed (GtkSettings *settings, - GParamSpec *pspec, - gpointer user_data) -{ - NautilusGtkPlacesSidebar *sidebar = user_data; - gboolean show_desktop; - - g_assert (settings == sidebar->gtk_settings); - - /* Check if the user explicitly set this and, if so, don't change it. */ - if (sidebar->show_desktop_set) - return; - - g_object_get (settings, "gtk-shell-shows-desktop", &show_desktop, NULL); - - if (show_desktop != sidebar->show_desktop) - { - sidebar->show_desktop = show_desktop; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_DESKTOP]); - } -} - -static void -nautilus_gtk_places_sidebar_init (NautilusGtkPlacesSidebar *sidebar) -{ - GtkTargetList *target_list; - gboolean show_desktop; - GtkStyleContext *context; - - sidebar->cancellable = g_cancellable_new (); - - sidebar->show_trash = TRUE; - - create_volume_monitor (sidebar); - - sidebar->open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; - - sidebar->bookmarks_manager = _nautilus_gtk_bookmarks_manager_new ((GtkBookmarksChangedFunc)update_places, sidebar); - - sidebar->trash_monitor = nautilus_trash_monitor_get (); - sidebar->trash_monitor_changed_id = g_signal_connect_swapped (sidebar->trash_monitor, "trash-state-changed", - G_CALLBACK (update_trash_icon), sidebar); - - gtk_widget_set_size_request (GTK_WIDGET (sidebar), 140, 280); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sidebar), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sidebar), GTK_SHADOW_IN); - - context = gtk_widget_get_style_context (GTK_WIDGET (sidebar)); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_SIDEBAR); - gtk_style_context_set_junction_sides (context, GTK_JUNCTION_RIGHT | GTK_JUNCTION_LEFT); - - /* list box */ - sidebar->list_box = gtk_list_box_new (); - - gtk_list_box_set_header_func (GTK_LIST_BOX (sidebar->list_box), - list_box_header_func, sidebar, NULL); - gtk_list_box_set_sort_func (GTK_LIST_BOX (sidebar->list_box), - list_box_sort_func, NULL, NULL); - gtk_list_box_set_selection_mode (GTK_LIST_BOX (sidebar->list_box), GTK_SELECTION_SINGLE); - gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (sidebar->list_box), TRUE); - - g_signal_connect (sidebar->list_box, "row-activated", - G_CALLBACK (on_row_activated), sidebar); - g_signal_connect (sidebar->list_box, "key-press-event", - G_CALLBACK (on_key_press_event), sidebar); - - sidebar->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (sidebar)); - gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (sidebar->long_press_gesture), TRUE); - g_signal_connect (sidebar->long_press_gesture, "pressed", - G_CALLBACK (long_press_cb), sidebar); - - /* DND support */ - gtk_drag_dest_set (sidebar->list_box, - 0, - NULL, 0, - GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK); - target_list = gtk_target_list_new (dnd_drop_targets, G_N_ELEMENTS (dnd_drop_targets)); - gtk_target_list_add_uri_targets (target_list, DND_TEXT_URI_LIST); - gtk_drag_dest_set_target_list (sidebar->list_box, target_list); - gtk_target_list_unref (target_list); - sidebar->source_targets = gtk_target_list_new (dnd_source_targets, G_N_ELEMENTS (dnd_source_targets)); - gtk_target_list_add_text_targets (sidebar->source_targets, 0); - - g_signal_connect (sidebar->list_box, "motion-notify-event", - G_CALLBACK (on_motion_notify_event), sidebar); - g_signal_connect (sidebar->list_box, "drag-begin", - G_CALLBACK (drag_begin_callback), sidebar); - g_signal_connect (sidebar->list_box, "drag-motion", - G_CALLBACK (drag_motion_callback), sidebar); - g_signal_connect (sidebar->list_box, "drag-data-get", - G_CALLBACK (drag_data_get_callback), sidebar); - g_signal_connect (sidebar->list_box, "drag-data-received", - G_CALLBACK (drag_data_received_callback), sidebar); - g_signal_connect (sidebar->list_box, "drag-drop", - G_CALLBACK (drag_drop_callback), sidebar); - g_signal_connect (sidebar->list_box, "drag-end", - G_CALLBACK (drag_end_callback), sidebar); - g_signal_connect (sidebar->list_box, "drag-leave", - G_CALLBACK (drag_leave_callback), sidebar); - sidebar->drag_row = NULL; - sidebar->row_placeholder = NULL; - sidebar->dragging_over = FALSE; - sidebar->drag_data_info = DND_UNKNOWN; - - gtk_container_add (GTK_CONTAINER (sidebar), sidebar->list_box); - - sidebar->hostname = g_strdup (_("Computer")); - sidebar->hostnamed_cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - NULL, - "org.freedesktop.hostname1", - "/org/freedesktop/hostname1", - "org.freedesktop.hostname1", - sidebar->hostnamed_cancellable, - hostname_proxy_new_cb, - sidebar); - - sidebar->drop_state = DROP_STATE_NORMAL; - - /* Don't bother trying to trace this across hierarchy changes... */ - sidebar->gtk_settings = gtk_settings_get_default (); - g_signal_connect (sidebar->gtk_settings, "notify::gtk-shell-shows-desktop", - G_CALLBACK (shell_shows_desktop_changed), sidebar); - g_object_get (sidebar->gtk_settings, "gtk-shell-shows-desktop", &show_desktop, NULL); - sidebar->show_desktop = show_desktop; - - /* Cloud providers */ -#ifdef HAVE_CLOUDPROVIDERS - sidebar->cloud_manager = cloud_providers_collector_dup_singleton (); - g_signal_connect_swapped (sidebar->cloud_manager, - "providers-changed", - G_CALLBACK (update_places), - sidebar); -#endif - - /* populate the sidebar */ - update_places (sidebar); - - add_actions (sidebar); -} - -static void -nautilus_gtk_places_sidebar_set_property (GObject *obj, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (obj); - - switch (property_id) - { - case PROP_LOCATION: - nautilus_gtk_places_sidebar_set_location (sidebar, g_value_get_object (value)); - break; - - case PROP_OPEN_FLAGS: - nautilus_gtk_places_sidebar_set_open_flags (sidebar, g_value_get_flags (value)); - break; - - case PROP_SHOW_RECENT: - nautilus_gtk_places_sidebar_set_show_recent (sidebar, g_value_get_boolean (value)); - break; - - case PROP_SHOW_DESKTOP: - nautilus_gtk_places_sidebar_set_show_desktop (sidebar, g_value_get_boolean (value)); - break; - - case PROP_SHOW_CONNECT_TO_SERVER: -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - nautilus_gtk_places_sidebar_set_show_connect_to_server (sidebar, g_value_get_boolean (value)); -G_GNUC_END_IGNORE_DEPRECATIONS - break; - - case PROP_SHOW_ENTER_LOCATION: - nautilus_gtk_places_sidebar_set_show_enter_location (sidebar, g_value_get_boolean (value)); - break; - - case PROP_SHOW_OTHER_LOCATIONS: - nautilus_gtk_places_sidebar_set_show_other_locations (sidebar, g_value_get_boolean (value)); - break; - - case PROP_SHOW_TRASH: - nautilus_gtk_places_sidebar_set_show_trash (sidebar, g_value_get_boolean (value)); - break; - - case PROP_SHOW_STARRED_LOCATION: - nautilus_gtk_places_sidebar_set_show_starred_location (sidebar, g_value_get_boolean (value)); - break; - - case PROP_LOCAL_ONLY: - nautilus_gtk_places_sidebar_set_local_only (sidebar, g_value_get_boolean (value)); - break; - - case PROP_POPULATE_ALL: - if (sidebar->populate_all != g_value_get_boolean (value)) - { - sidebar->populate_all = g_value_get_boolean (value); - g_object_notify_by_pspec (obj, pspec); - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); - break; - } -} - -static void -nautilus_gtk_places_sidebar_get_property (GObject *obj, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - NautilusGtkPlacesSidebar *sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (obj); - - switch (property_id) - { - case PROP_LOCATION: - g_value_take_object (value, nautilus_gtk_places_sidebar_get_location (sidebar)); - break; - - case PROP_OPEN_FLAGS: - g_value_set_flags (value, nautilus_gtk_places_sidebar_get_open_flags (sidebar)); - break; - - case PROP_SHOW_RECENT: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_recent (sidebar)); - break; - - case PROP_SHOW_DESKTOP: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_desktop (sidebar)); - break; - - case PROP_SHOW_CONNECT_TO_SERVER: -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_connect_to_server (sidebar)); -G_GNUC_END_IGNORE_DEPRECATIONS - break; - - case PROP_SHOW_ENTER_LOCATION: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_enter_location (sidebar)); - break; - - case PROP_SHOW_OTHER_LOCATIONS: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_other_locations (sidebar)); - break; - - case PROP_SHOW_TRASH: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_trash (sidebar)); - break; - - case PROP_SHOW_STARRED_LOCATION: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_show_starred_location (sidebar)); - break; - - case PROP_LOCAL_ONLY: - g_value_set_boolean (value, nautilus_gtk_places_sidebar_get_local_only (sidebar)); - break; - - case PROP_POPULATE_ALL: - g_value_set_boolean (value, sidebar->populate_all); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); - break; - } -} - -static void -nautilus_gtk_places_sidebar_dispose (GObject *object) -{ - NautilusGtkPlacesSidebar *sidebar; -#ifdef HAVE_CLOUDPROVIDERS - GList *l; -#endif - - sidebar = NAUTILUS_GTK_PLACES_SIDEBAR (object); - - if (sidebar->cancellable) - { - g_cancellable_cancel (sidebar->cancellable); - g_object_unref (sidebar->cancellable); - sidebar->cancellable = NULL; - } - - free_drag_data (sidebar); - - if (sidebar->bookmarks_manager != NULL) - { - _nautilus_gtk_bookmarks_manager_free (sidebar->bookmarks_manager); - sidebar->bookmarks_manager = NULL; - } - - if (sidebar->popover) - { - gtk_widget_destroy (sidebar->popover); - sidebar->popover = NULL; - } - - if (sidebar->rename_popover) - { - gtk_widget_destroy (sidebar->rename_popover); - sidebar->rename_popover = NULL; - sidebar->rename_entry = NULL; - sidebar->rename_button = NULL; - sidebar->rename_error = NULL; - } - - if (sidebar->trash_monitor) - { - g_signal_handler_disconnect (sidebar->trash_monitor, sidebar->trash_monitor_changed_id); - sidebar->trash_monitor_changed_id = 0; - g_clear_object (&sidebar->trash_monitor); - } - - if (sidebar->trash_row) - { - g_object_remove_weak_pointer (G_OBJECT (sidebar->trash_row), - (gpointer *) &sidebar->trash_row); - sidebar->trash_row = NULL; - } - - if (sidebar->volume_monitor != NULL) - { - g_signal_handlers_disconnect_by_func (sidebar->volume_monitor, - update_places, sidebar); - g_clear_object (&sidebar->volume_monitor); - } - - if (sidebar->hostnamed_cancellable != NULL) - { - g_cancellable_cancel (sidebar->hostnamed_cancellable); - g_clear_object (&sidebar->hostnamed_cancellable); - } - - g_clear_object (&sidebar->hostnamed_proxy); - g_free (sidebar->hostname); - sidebar->hostname = NULL; - - if (sidebar->gtk_settings) - { - g_signal_handlers_disconnect_by_func (sidebar->gtk_settings, shell_shows_desktop_changed, sidebar); - sidebar->gtk_settings = NULL; - } - - g_clear_object (&sidebar->current_location); - g_clear_pointer (&sidebar->rename_uri, g_free); - - g_clear_object (&sidebar->long_press_gesture); - - if (sidebar->source_targets) - { - gtk_target_list_unref (sidebar->source_targets); - sidebar->source_targets = NULL; - } - - g_slist_free_full (sidebar->shortcuts, g_object_unref); - sidebar->shortcuts = NULL; - -#ifdef HAVE_CLOUDPROVIDERS - for (l = sidebar->unready_accounts; l != NULL; l = l->next) - { - g_signal_handlers_disconnect_by_data (l->data, sidebar); - } - g_list_free_full (sidebar->unready_accounts, g_object_unref); - sidebar->unready_accounts = NULL; - - if (sidebar->cloud_manager) - { - g_signal_handlers_disconnect_by_data (sidebar->cloud_manager, sidebar); - for (l = cloud_providers_collector_get_providers (sidebar->cloud_manager); - l != NULL; l = l->next) - { - g_signal_handlers_disconnect_by_data (l->data, sidebar); - } - g_object_unref (sidebar->cloud_manager); - sidebar->cloud_manager = NULL; - } -#endif - - G_OBJECT_CLASS (nautilus_gtk_places_sidebar_parent_class)->dispose (object); -} - -static void -nautilus_gtk_places_sidebar_finalize (GObject *object) -{ - G_OBJECT_CLASS (nautilus_gtk_places_sidebar_parent_class)->finalize (object); -} - -static void -nautilus_gtk_places_sidebar_class_init (NautilusGtkPlacesSidebarClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); - - - gobject_class->dispose = nautilus_gtk_places_sidebar_dispose; - gobject_class->finalize = nautilus_gtk_places_sidebar_finalize; - gobject_class->set_property = nautilus_gtk_places_sidebar_set_property; - gobject_class->get_property = nautilus_gtk_places_sidebar_get_property; - - /** - * NautilusGtkPlacesSidebar::open-location: - * @sidebar: the object which received the signal. - * @location: (type Gio.File): #GFile to which the caller should switch. - * @open_flags: a single value from #NautilusGtkPlacesOpenFlags specifying how the @location should be opened. - * - * The places sidebar emits this signal when the user selects a location - * in it. The calling application should display the contents of that - * location; for example, a file manager should show a list of files in - * the specified location. - * - * Since: 3.10 - */ - places_sidebar_signals [OPEN_LOCATION] = - g_signal_new ("open-location", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, open_location), - NULL, NULL, - NULL, - G_TYPE_NONE, 2, - G_TYPE_OBJECT, - GTK_TYPE_PLACES_OPEN_FLAGS); - - /** - * NautilusGtkPlacesSidebar::populate-popup: - * @sidebar: the object which received the signal. - * @container: (type Gtk.Widget): a #GtkMenu or another #GtkContainer - * @selected_item: (type Gio.File) (nullable): #GFile with the item to which - * the popup should refer, or %NULL in the case of a @selected_volume. - * @selected_volume: (type Gio.Volume) (nullable): #GVolume if the selected - * item is a volume, or %NULL if it is a file. - * - * The places sidebar emits this signal when the user invokes a contextual - * popup on one of its items. In the signal handler, the application may - * add extra items to the menu as appropriate. For example, a file manager - * may want to add a "Properties" command to the menu. - * - * It is not necessary to store the @selected_item for each menu item; - * during their callbacks, the application can use nautilus_gtk_places_sidebar_get_location() - * to get the file to which the item refers. - * - * The @selected_item argument may be %NULL in case the selection refers to - * a volume. In this case, @selected_volume will be non-%NULL. In this case, - * the calling application will have to g_object_ref() the @selected_volume and - * keep it around to use it in the callback. - * - * The @container and all its contents are destroyed after the user - * dismisses the popup. The popup is re-created (and thus, this signal is - * emitted) every time the user activates the contextual menu. - * - * Before 3.18, the @container always was a #GtkMenu, and you were expected - * to add your items as #GtkMenuItems. Since 3.18, the popup may be implemented - * as a #GtkPopover, in which case @container will be something else, e.g. a - * #GtkBox, to which you may add #GtkModelButtons or other widgets, such as - * #GtkEntries, #GtkSpinButtons, etc. If your application can deal with this - * situation, you can set #NautilusGtkPlacesSidebar::populate-all to %TRUE to request - * that this signal is emitted for populating popovers as well. - * - * Since: 3.10 - */ - places_sidebar_signals [POPULATE_POPUP] = - g_signal_new ("populate-popup", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, populate_popup), - NULL, NULL, - NULL, - G_TYPE_NONE, 3, - GTK_TYPE_WIDGET, - G_TYPE_FILE, - G_TYPE_VOLUME); - - /** - * NautilusGtkPlacesSidebar::show-error-message: - * @sidebar: the object which received the signal. - * @primary: primary message with a summary of the error to show. - * @secondary: secondary message with details of the error to show. - * - * The places sidebar emits this signal when it needs the calling - * application to present an error message. Most of these messages - * refer to mounting or unmounting media, for example, when a drive - * cannot be started for some reason. - * - * Since: 3.10 - */ - places_sidebar_signals [SHOW_ERROR_MESSAGE] = - g_signal_new ("show-error-message", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, show_error_message), - NULL, NULL, - NULL, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_STRING); - - /** - * NautilusGtkPlacesSidebar::show-connect-to-server: - * @sidebar: the object which received the signal. - * - * The places sidebar emits this signal when it needs the calling - * application to present an way to connect directly to a network server. - * For example, the application may bring up a dialog box asking for - * a URL like "sftp://ftp.example.com". It is up to the application to create - * the corresponding mount by using, for example, g_file_mount_enclosing_volume(). - * - * Deprecated: 3.18: use the #NautilusGtkPlacesSidebar::show-other-locations signal - * to connect to network servers. - */ - places_sidebar_signals [SHOW_CONNECT_TO_SERVER] = - g_signal_new ("show-connect-to-server", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, show_connect_to_server), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * NautilusGtkPlacesSidebar::show-enter-location: - * @sidebar: the object which received the signal. - * - * The places sidebar emits this signal when it needs the calling - * application to present an way to directly enter a location. - * For example, the application may bring up a dialog box asking for - * a URL like "http://http.example.com". - * - * Since: 3.14 - */ - places_sidebar_signals [SHOW_ENTER_LOCATION] = - g_signal_new ("show-enter-location", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, show_enter_location), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * NautilusGtkPlacesSidebar::drag-action-requested: - * @sidebar: the object which received the signal. - * @context: (type Gdk.DragContext): #GdkDragContext with information about the drag operation - * @dest_file: (type Gio.File): #GFile with the tentative location that is being hovered for a drop - * @source_file_list: (type GLib.List) (element-type GFile) (transfer none): - * List of #GFile that are being dragged - * - * When the user starts a drag-and-drop operation and the sidebar needs - * to ask the application for which drag action to perform, then the - * sidebar will emit this signal. - * - * The application can evaluate the @context for customary actions, or - * it can check the type of the files indicated by @source_file_list against the - * possible actions for the destination @dest_file. - * - * The drag action to use must be the return value of the signal handler. - * - * Returns: The drag action to use, for example, #GDK_ACTION_COPY - * or #GDK_ACTION_MOVE, or 0 if no action is allowed here (i.e. drops - * are not allowed in the specified @dest_file). - * - * Since: 3.10 - */ - places_sidebar_signals [DRAG_ACTION_REQUESTED] = - g_signal_new ("drag-action-requested", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, drag_action_requested), - NULL, NULL, - NULL, - G_TYPE_INT, 3, - GDK_TYPE_DRAG_CONTEXT, - G_TYPE_OBJECT, - G_TYPE_POINTER /* GList of GFile */ ); - - /** - * NautilusGtkPlacesSidebar::drag-action-ask: - * @sidebar: the object which received the signal. - * @actions: Possible drag actions that need to be asked for. - * - * The places sidebar emits this signal when it needs to ask the application - * to pop up a menu to ask the user for which drag action to perform. - * - * Returns: the final drag action that the sidebar should pass to the drag side - * of the drag-and-drop operation. - * - * Since: 3.10 - */ - places_sidebar_signals [DRAG_ACTION_ASK] = - g_signal_new ("drag-action-ask", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, drag_action_ask), - NULL, NULL, - NULL, - G_TYPE_INT, 1, - G_TYPE_INT); - - /** - * NautilusGtkPlacesSidebar::drag-perform-drop: - * @sidebar: the object which received the signal. - * @dest_file: (type Gio.File): Destination #GFile. - * @source_file_list: (type GLib.List) (element-type GFile) (transfer none): - * #GList of #GFile that got dropped. - * @action: Drop action to perform. - * - * The places sidebar emits this signal when the user completes a - * drag-and-drop operation and one of the sidebar's items is the - * destination. This item is in the @dest_file, and the - * @source_file_list has the list of files that are dropped into it and - * which should be copied/moved/etc. based on the specified @action. - * - * Since: 3.10 - */ - places_sidebar_signals [DRAG_PERFORM_DROP] = - g_signal_new ("drag-perform-drop", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, drag_perform_drop), - NULL, NULL, - NULL, - G_TYPE_NONE, 3, - G_TYPE_OBJECT, - G_TYPE_POINTER, /* GList of GFile */ - G_TYPE_INT); - - /** - * NautilusGtkPlacesSidebar::show-other-locations: - * @sidebar: the object which received the signal. - * - * The places sidebar emits this signal when it needs the calling - * application to present a way to show other locations e.g. drives - * and network access points. - * For example, the application may bring up a page showing persistent - * volumes and discovered network addresses. - * - * Deprecated: 3.20: use the #NautilusGtkPlacesSidebar::show-other-locations-with-flags - * which includes the open flags in order to allow the user to specify to open - * in a new tab or window, in a similar way than #NautilusGtkPlacesSidebar::open-location - * - * Since: 3.18 - */ - places_sidebar_signals [SHOW_OTHER_LOCATIONS] = - g_signal_new ("show-other-locations", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_DEPRECATED, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, show_other_locations), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * NautilusGtkPlacesSidebar::show-other-locations-with-flags: - * @sidebar: the object which received the signal. - * @open_flags: a single value from #NautilusGtkPlacesOpenFlags specifying how it should be opened. - * - * The places sidebar emits this signal when it needs the calling - * application to present a way to show other locations e.g. drives - * and network access points. - * For example, the application may bring up a page showing persistent - * volumes and discovered network addresses. - * - * Since: 3.20 - */ - places_sidebar_signals [SHOW_OTHER_LOCATIONS_WITH_FLAGS] = - g_signal_new ("show-other-locations-with-flags", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, show_other_locations_with_flags), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_PLACES_OPEN_FLAGS); - - /** - * NautilusGtkPlacesSidebar::mount: - * @sidebar: the object which received the signal. - * @mount_operation: the #GMountOperation that is going to start. - * - * The places sidebar emits this signal when it starts a new operation - * because the user clicked on some location that needs mounting. - * In this way the application using the #NautilusGtkPlacesSidebar can track the - * progress of the operation and, for example, show a notification. - * - * Since: 3.20 - */ - places_sidebar_signals [MOUNT] = - g_signal_new ("mount", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, mount), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_MOUNT_OPERATION); - /** - * NautilusGtkPlacesSidebar::unmount: - * @sidebar: the object which received the signal. - * @mount_operation: the #GMountOperation that is going to start. - * - * The places sidebar emits this signal when it starts a new operation - * because the user for example ejected some drive or unmounted a mount. - * In this way the application using the #NautilusGtkPlacesSidebar can track the - * progress of the operation and, for example, show a notification. - * - * Since: 3.20 - */ - places_sidebar_signals [UNMOUNT] = - g_signal_new ("unmount", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, unmount), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_MOUNT_OPERATION); - - /** - * NautilusGtkPlacesSidebar::show-starred-location: - * @sidebar: the object which received the signal. - * @open_flags: a single value from #NautilusGtkPlacesOpenFlags specifying how the - * starred file should be opened. - * - * The places sidebar emits this signal when it needs the calling - * application to present a way to show the starred files. In GNOME, - * starred files are implemented by setting the nao:predefined-tag-favorite - * tag in the tracker database. - * - * Since: 3.22.26 - */ - places_sidebar_signals [SHOW_STARRED_LOCATION] = - g_signal_new ("show-starred-location", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NautilusGtkPlacesSidebarClass, show_starred_location), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_PLACES_OPEN_FLAGS); - - properties[PROP_LOCATION] = - g_param_spec_object ("location", - "Location to Select", - "The location to highlight in the sidebar", - G_TYPE_FILE, - G_PARAM_READWRITE); - properties[PROP_OPEN_FLAGS] = - g_param_spec_flags ("open-flags", - "Open Flags", - "Modes in which the calling application can open locations selected in the sidebar", - GTK_TYPE_PLACES_OPEN_FLAGS, - NAUTILUS_GTK_PLACES_OPEN_NORMAL, - G_PARAM_READWRITE); - properties[PROP_SHOW_RECENT] = - g_param_spec_boolean ("show-recent", - "Show recent files", - "Whether the sidebar includes a builtin shortcut for recent files", - TRUE, - G_PARAM_READWRITE); - properties[PROP_SHOW_DESKTOP] = - g_param_spec_boolean ("show-desktop", - "Show 'Desktop'", - "Whether the sidebar includes a builtin shortcut to the Desktop folder", - TRUE, - G_PARAM_READWRITE); - properties[PROP_SHOW_CONNECT_TO_SERVER] = - g_param_spec_boolean ("show-connect-to-server", - "Show 'Connect to Server'", - "Whether the sidebar includes a builtin shortcut to a 'Connect to server' dialog", - FALSE, - G_PARAM_READWRITE | G_PARAM_DEPRECATED); - properties[PROP_SHOW_ENTER_LOCATION] = - g_param_spec_boolean ("show-enter-location", - "Show 'Enter Location'", - "Whether the sidebar includes a builtin shortcut to manually enter a location", - FALSE, - G_PARAM_READWRITE); - properties[PROP_LOCAL_ONLY] = - g_param_spec_boolean ("local-only", - "Local Only", - "Whether the sidebar only includes local files", - FALSE, - G_PARAM_READWRITE); - properties[PROP_SHOW_TRASH] = - g_param_spec_boolean ("show-trash", - "Show 'Trash'", - "Whether the sidebar includes a builtin shortcut to the Trash location", - TRUE, - G_PARAM_READWRITE); - properties[PROP_SHOW_OTHER_LOCATIONS] = - g_param_spec_boolean ("show-other-locations", - "Show 'Other locations'", - "Whether the sidebar includes an item to show external locations", - FALSE, - G_PARAM_READWRITE); - properties[PROP_SHOW_STARRED_LOCATION] = - g_param_spec_boolean ("show-starred-location", - "Show “Starred Location”", - "Whether the sidebar includes an item to show starred files", - FALSE, - G_PARAM_READWRITE); - - - /** - * NautilusGtkPlacesSidebar:populate-all: - * - * If :populate-all is %TRUE, the #NautilusGtkPlacesSidebar::populate-popup signal - * is also emitted for popovers. - * - * Since: 3.18 - */ - properties[PROP_POPULATE_ALL] = - g_param_spec_boolean ("populate-all", - "Populate all", - "Whether to emit ::populate-popup for popups that are not menus", - FALSE, - G_PARAM_READWRITE); - - g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); - - gtk_widget_class_set_css_name (widget_class, "placessidebar"); -} - -/** - * nautilus_gtk_places_sidebar_new: - * - * Creates a new #NautilusGtkPlacesSidebar widget. - * - * The application should connect to at least the - * #NautilusGtkPlacesSidebar::open-location signal to be notified - * when the user makes a selection in the sidebar. - * - * Returns: a newly created #NautilusGtkPlacesSidebar - * - * Since: 3.10 - */ -GtkWidget * -nautilus_gtk_places_sidebar_new (void) -{ - return GTK_WIDGET (g_object_new (nautilus_gtk_places_sidebar_get_type (), NULL)); -} - -/* Public methods for NautilusGtkPlacesSidebar */ - -/** - * nautilus_gtk_places_sidebar_set_open_flags: - * @sidebar: a places sidebar - * @flags: Bitmask of modes in which the calling application can open locations - * - * Sets the way in which the calling application can open new locations from - * the places sidebar. For example, some applications only open locations - * “directly” into their main view, while others may support opening locations - * in a new notebook tab or a new window. - * - * This function is used to tell the places @sidebar about the ways in which the - * application can open new locations, so that the sidebar can display (or not) - * the “Open in new tab” and “Open in new window” menu items as appropriate. - * - * When the #NautilusGtkPlacesSidebar::open-location signal is emitted, its flags - * argument will be set to one of the @flags that was passed in - * nautilus_gtk_places_sidebar_set_open_flags(). - * - * Passing 0 for @flags will cause #NAUTILUS_GTK_PLACES_OPEN_NORMAL to always be sent - * to callbacks for the “open-location” signal. - * - * Since: 3.10 - */ -void -nautilus_gtk_places_sidebar_set_open_flags (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkPlacesOpenFlags flags) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - if (sidebar->open_flags != flags) - { - sidebar->open_flags = flags; - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_OPEN_FLAGS]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_open_flags: - * @sidebar: a #NautilusGtkPlacesSidebar - * - * Gets the open flags. - * - * Returns: the #NautilusGtkPlacesOpenFlags of @sidebar - * - * Since: 3.10 - */ -NautilusGtkPlacesOpenFlags -nautilus_gtk_places_sidebar_get_open_flags (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), 0); - - return sidebar->open_flags; -} - -/** - * nautilus_gtk_places_sidebar_set_location: - * @sidebar: a places sidebar - * @location: (nullable): location to select, or %NULL for no current path - * - * Sets the location that is being shown in the widgets surrounding the - * @sidebar, for example, in a folder view in a file manager. In turn, the - * @sidebar will highlight that location if it is being shown in the list of - * places, or it will unhighlight everything if the @location is not among the - * places in the list. - * - * Since: 3.10 - */ -void -nautilus_gtk_places_sidebar_set_location (NautilusGtkPlacesSidebar *sidebar, - GFile *location) -{ - GList *children; - GList *child; - gchar *row_uri; - gchar *uri; - gboolean found = FALSE; - - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - gtk_list_box_unselect_all (GTK_LIST_BOX (sidebar->list_box)); - - if (sidebar->current_location != NULL) - g_object_unref (sidebar->current_location); - sidebar->current_location = location; - if (sidebar->current_location != NULL) - g_object_ref (sidebar->current_location); - - if (location == NULL) - goto out; - - uri = g_file_get_uri (location); - - children = gtk_container_get_children (GTK_CONTAINER (sidebar->list_box)); - for (child = children; child != NULL && !found; child = child->next) - { - g_object_get (child->data, "uri", &row_uri, NULL); - if (row_uri != NULL && g_strcmp0 (row_uri, uri) == 0) - { - gtk_list_box_select_row (GTK_LIST_BOX (sidebar->list_box), - GTK_LIST_BOX_ROW (child->data)); - found = TRUE; - } - - g_free (row_uri); - } - - g_free (uri); - g_list_free (children); - - out: - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_LOCATION]); -} - -/** - * nautilus_gtk_places_sidebar_get_location: - * @sidebar: a places sidebar - * - * Gets the currently selected location in the @sidebar. This can be %NULL when - * nothing is selected, for example, when nautilus_gtk_places_sidebar_set_location() has - * been called with a location that is not among the sidebar’s list of places to - * show. - * - * You can use this function to get the selection in the @sidebar. Also, if you - * connect to the #NautilusGtkPlacesSidebar::populate-popup signal, you can use this - * function to get the location that is being referred to during the callbacks - * for your menu items. - * - * Returns: (nullable) (transfer full): a #GFile with the selected location, or - * %NULL if nothing is visually selected. - * - * Since: 3.10 - */ -GFile * -nautilus_gtk_places_sidebar_get_location (NautilusGtkPlacesSidebar *sidebar) -{ - GtkListBoxRow *selected; - GFile *file; - - g_return_val_if_fail (sidebar != NULL, NULL); - - file = NULL; - selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box)); - - if (selected) - { - gchar *uri; - - g_object_get (selected, "uri", &uri, NULL); - file = g_file_new_for_uri (uri); - g_free (uri); - } - - return file; -} - -gchar * -nautilus_gtk_places_sidebar_get_location_title (NautilusGtkPlacesSidebar *sidebar) -{ - GtkListBoxRow *selected; - gchar *title; - - g_return_val_if_fail (sidebar != NULL, NULL); - - title = NULL; - selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box)); - - if (selected) - g_object_get (selected, "label", &title, NULL); - - return title; -} - -/** - * nautilus_gtk_places_sidebar_set_show_recent: - * @sidebar: a places sidebar - * @show_recent: whether to show an item for recent files - * - * Sets whether the @sidebar should show an item for recent files. - * The default value for this option is determined by the desktop - * environment, but this function can be used to override it on a - * per-application basis. - * - * Since: 3.18 - */ -void -nautilus_gtk_places_sidebar_set_show_recent (NautilusGtkPlacesSidebar *sidebar, - gboolean show_recent) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - sidebar->show_recent_set = TRUE; - - show_recent = !!show_recent; - if (sidebar->show_recent != show_recent) - { - sidebar->show_recent = show_recent; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_RECENT]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_show_recent: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_recent() - * - * Returns: %TRUE if the sidebar will display a builtin shortcut for recent files - * - * Since: 3.18 - */ -gboolean -nautilus_gtk_places_sidebar_get_show_recent (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->show_recent; -} - -/** - * nautilus_gtk_places_sidebar_set_show_desktop: - * @sidebar: a places sidebar - * @show_desktop: whether to show an item for the Desktop folder - * - * Sets whether the @sidebar should show an item for the Desktop folder. - * The default value for this option is determined by the desktop - * environment and the user’s configuration, but this function can be - * used to override it on a per-application basis. - * - * Since: 3.10 - */ -void -nautilus_gtk_places_sidebar_set_show_desktop (NautilusGtkPlacesSidebar *sidebar, - gboolean show_desktop) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - /* Don't bother disconnecting from the GtkSettings -- it will just - * complicate things. Besides, it's highly unlikely that this will - * change while we're running, but we can ignore it if it does. - */ - sidebar->show_desktop_set = TRUE; - - show_desktop = !!show_desktop; - if (sidebar->show_desktop != show_desktop) - { - sidebar->show_desktop = show_desktop; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_DESKTOP]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_show_desktop: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_desktop() - * - * Returns: %TRUE if the sidebar will display a builtin shortcut to the desktop folder. - * - * Since: 3.10 - */ -gboolean -nautilus_gtk_places_sidebar_get_show_desktop (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->show_desktop; -} - -/** - * nautilus_gtk_places_sidebar_set_show_connect_to_server: - * @sidebar: a places sidebar - * @show_connect_to_server: whether to show an item for the Connect to Server command - * - * Sets whether the @sidebar should show an item for connecting to a network server; - * this is off by default. An application may want to turn this on if it implements - * a way for the user to connect to network servers directly. - * - * If you enable this, you should connect to the - * #NautilusGtkPlacesSidebar::show-connect-to-server signal. - * - * Since: 3.10 - * - * Deprecated: 3.18: It is recommended to group this functionality with the drives - * and network location under the new 'Other Location' item - */ -void -nautilus_gtk_places_sidebar_set_show_connect_to_server (NautilusGtkPlacesSidebar *sidebar, - gboolean show_connect_to_server) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - show_connect_to_server = !!show_connect_to_server; - if (sidebar->show_connect_to_server != show_connect_to_server) - { - sidebar->show_connect_to_server = show_connect_to_server; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_CONNECT_TO_SERVER]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_show_connect_to_server: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_connect_to_server() - * - * Returns: %TRUE if the sidebar will display a “Connect to Server” item. - * - * Deprecated: 3.18: It is recommended to group this functionality with the drives - * and network location under the new 'Other Location' item - */ -gboolean -nautilus_gtk_places_sidebar_get_show_connect_to_server (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->show_connect_to_server; -} - -/** - * nautilus_gtk_places_sidebar_set_show_enter_location: - * @sidebar: a places sidebar - * @show_enter_location: whether to show an item to enter a location - * - * Sets whether the @sidebar should show an item for entering a location; - * this is off by default. An application may want to turn this on if manually - * entering URLs is an expected user action. - * - * If you enable this, you should connect to the - * #NautilusGtkPlacesSidebar::show-enter-location signal. - * - * Since: 3.14 - */ -void -nautilus_gtk_places_sidebar_set_show_enter_location (NautilusGtkPlacesSidebar *sidebar, - gboolean show_enter_location) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - show_enter_location = !!show_enter_location; - if (sidebar->show_enter_location != show_enter_location) - { - sidebar->show_enter_location = show_enter_location; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_ENTER_LOCATION]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_show_enter_location: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_enter_location() - * - * Returns: %TRUE if the sidebar will display an “Enter Location” item. - * - * Since: 3.14 - */ -gboolean -nautilus_gtk_places_sidebar_get_show_enter_location (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->show_enter_location; -} - -/** - * nautilus_gtk_places_sidebar_set_show_other_locations: - * @sidebar: a places sidebar - * @show_other_locations: whether to show an item for the Other Locations view - * - * Sets whether the @sidebar should show an item for the application to show - * an Other Locations view; this is off by default. When set to %TRUE, persistent - * devices such as hard drives are hidden, otherwise they are shown in the sidebar. - * An application may want to turn this on if it implements a way for the user to - * see and interact with drives and network servers directly. - * - * If you enable this, you should connect to the - * #NautilusGtkPlacesSidebar::show-other-locations signal. - * - * Since: 3.18 - */ -void -nautilus_gtk_places_sidebar_set_show_other_locations (NautilusGtkPlacesSidebar *sidebar, - gboolean show_other_locations) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - show_other_locations = !!show_other_locations; - if (sidebar->show_other_locations != show_other_locations) - { - sidebar->show_other_locations = show_other_locations; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_OTHER_LOCATIONS]); - } - } - -/** - * nautilus_gtk_places_sidebar_get_show_other_locations: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_other_locations() - * - * Returns: %TRUE if the sidebar will display an “Other Locations” item. - * - * Since: 3.18 - */ -gboolean -nautilus_gtk_places_sidebar_get_show_other_locations (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->show_other_locations; -} - -/** - * nautilus_gtk_places_sidebar_set_show_trash: - * @sidebar: a places sidebar - * @show_trash: whether to show an item for the Trash location - * - * Sets whether the @sidebar should show an item for the Trash location. - * - * Since: 3.18 - */ -void -nautilus_gtk_places_sidebar_set_show_trash (NautilusGtkPlacesSidebar *sidebar, - gboolean show_trash) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - show_trash = !!show_trash; - if (sidebar->show_trash != show_trash) - { - sidebar->show_trash = show_trash; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_TRASH]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_show_trash: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_trash() - * - * Returns: %TRUE if the sidebar will display a “Trash” item. - * - * Since: 3.18 - */ -gboolean -nautilus_gtk_places_sidebar_get_show_trash (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), TRUE); - - return sidebar->show_trash; -} - -/** - * nautilus_gtk_places_sidebar_set_local_only: - * @sidebar: a places sidebar - * @local_only: whether to show only local files - * - * Sets whether the @sidebar should only show local files. - * - * Since: 3.12 - */ -void -nautilus_gtk_places_sidebar_set_local_only (NautilusGtkPlacesSidebar *sidebar, - gboolean local_only) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - local_only = !!local_only; - if (sidebar->local_only != local_only) - { - sidebar->local_only = local_only; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_LOCAL_ONLY]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_local_only: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_local_only(). - * - * Returns: %TRUE if the sidebar will only show local files. - * - * Since: 3.12 - */ -gboolean -nautilus_gtk_places_sidebar_get_local_only (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->local_only; -} - -static GSList * -find_shortcut_link (NautilusGtkPlacesSidebar *sidebar, - GFile *location) -{ - GSList *l; - - for (l = sidebar->shortcuts; l; l = l->next) - { - GFile *shortcut; - - shortcut = G_FILE (l->data); - if (g_file_equal (shortcut, location)) - return l; - } - - return NULL; -} - -/** - * nautilus_gtk_places_sidebar_add_shortcut: - * @sidebar: a places sidebar - * @location: location to add as an application-specific shortcut - * - * Applications may want to present some folders in the places sidebar if - * they could be immediately useful to users. For example, a drawing - * program could add a “/usr/share/clipart” location when the sidebar is - * being used in an “Insert Clipart” dialog box. - * - * This function adds the specified @location to a special place for immutable - * shortcuts. The shortcuts are application-specific; they are not shared - * across applications, and they are not persistent. If this function - * is called multiple times with different locations, then they are added - * to the sidebar’s list in the same order as the function is called. - * - * Since: 3.10 - */ -void -nautilus_gtk_places_sidebar_add_shortcut (NautilusGtkPlacesSidebar *sidebar, - GFile *location) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - g_return_if_fail (G_IS_FILE (location)); - - g_object_ref (location); - sidebar->shortcuts = g_slist_append (sidebar->shortcuts, location); - - update_places (sidebar); -} - -/** - * nautilus_gtk_places_sidebar_remove_shortcut: - * @sidebar: a places sidebar - * @location: location to remove - * - * Removes an application-specific shortcut that has been previously been - * inserted with nautilus_gtk_places_sidebar_add_shortcut(). If the @location is not a - * shortcut in the sidebar, then nothing is done. - * - * Since: 3.10 - */ -void -nautilus_gtk_places_sidebar_remove_shortcut (NautilusGtkPlacesSidebar *sidebar, - GFile *location) -{ - GSList *link; - GFile *shortcut; - - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - g_return_if_fail (G_IS_FILE (location)); - - link = find_shortcut_link (sidebar, location); - if (!link) - return; - - shortcut = G_FILE (link->data); - g_object_unref (shortcut); - - sidebar->shortcuts = g_slist_delete_link (sidebar->shortcuts, link); - update_places (sidebar); -} - -/** - * nautilus_gtk_places_sidebar_list_shortcuts: - * @sidebar: a places sidebar - * - * Gets the list of shortcuts. - * - * Returns: (element-type GFile) (transfer full): - * A #GSList of #GFile of the locations that have been added as - * application-specific shortcuts with nautilus_gtk_places_sidebar_add_shortcut(). - * To free this list, you can use - * |[<!-- language="C" --> - * g_slist_free_full (list, (GDestroyNotify) g_object_unref); - * ]| - * - * Since: 3.10 - */ -GSList * -nautilus_gtk_places_sidebar_list_shortcuts (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), NULL); - - return g_slist_copy_deep (sidebar->shortcuts, (GCopyFunc) g_object_ref, NULL); -} - -/** - * nautilus_gtk_places_sidebar_get_nth_bookmark: - * @sidebar: a places sidebar - * @n: index of the bookmark to query - * - * This function queries the bookmarks added by the user to the places sidebar, - * and returns one of them. This function is used by #GtkFileChooser to implement - * the “Alt-1”, “Alt-2”, etc. shortcuts, which activate the cooresponding bookmark. - * - * Returns: (nullable) (transfer full): The bookmark specified by the index @n, or - * %NULL if no such index exist. Note that the indices start at 0, even though - * the file chooser starts them with the keyboard shortcut "Alt-1". - * - * Since: 3.10 - */ -GFile * -nautilus_gtk_places_sidebar_get_nth_bookmark (NautilusGtkPlacesSidebar *sidebar, - gint n) -{ - GList *rows; - GList *l; - int k; - GFile *file; - - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), NULL); - - file = NULL; - rows = gtk_container_get_children (GTK_CONTAINER (sidebar->list_box)); - l = rows; - - k = 0; - while (l != NULL) - { - NautilusGtkPlacesSidebarPlaceType place_type; - gchar *uri; - - g_object_get (l->data, - "place-type", &place_type, - "uri", &uri, - NULL); - if (place_type == PLACES_BOOKMARK) - { - if (k == n) - { - file = g_file_new_for_uri (uri); - g_free (uri); - break; - } - k++; - } - g_free (uri); - l = l->next; - } - - g_list_free (rows); - - return file; -} - -/** - * nautilus_gtk_places_sidebar_set_drop_targets_visible: - * @sidebar: a places sidebar. - * @visible: whether to show the valid targets or not. - * @context: drag context used to ask the source about the action that wants to - * perform, so hints are more accurate. - * - * Make the NautilusGtkPlacesSidebar show drop targets, so it can show the available - * drop targets and a "new bookmark" row. This improves the Drag-and-Drop - * experience of the user and allows applications to show all available - * drop targets at once. - * - * This needs to be called when the application is aware of an ongoing drag - * that might target the sidebar. The drop-targets-visible state will be unset - * automatically if the drag finishes in the NautilusGtkPlacesSidebar. You only need - * to unset the state when the drag ends on some other widget on your application. - * - * Since: 3.18 - */ -void -nautilus_gtk_places_sidebar_set_drop_targets_visible (NautilusGtkPlacesSidebar *sidebar, - gboolean visible, - GdkDragContext *context) -{ - if (visible) - { - sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT; - start_drop_feedback (sidebar, NULL, context); - } - else - { - if (sidebar->drop_state == DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT || - sidebar->drop_state == DROP_STATE_NEW_BOOKMARK_ARMED) - { - if (!sidebar->dragging_over) - { - sidebar->drop_state = DROP_STATE_NORMAL; - stop_drop_feedback (sidebar); - } - else - { - /* In case this is called while we are dragging we need to mark the - * drop state as no permanent so the leave timeout can do its job. - * This will only happen in applications that call this in a wrong - * time */ - sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED; - } - } - } -} - -/** - * nautilus_gtk_places_sidebar_set_show_starred_location: - * @sidebar: a places sidebar - * @show_starred_location: whether to show an item for Starred files - * - * If you enable this, you should connect to the - * #NautilusGtkPlacesSidebar::show-starred-location signal. - * - * Since: 3.22.26 - */ -void -nautilus_gtk_places_sidebar_set_show_starred_location (NautilusGtkPlacesSidebar *sidebar, - gboolean show_starred_location) -{ - g_return_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar)); - - show_starred_location = !!show_starred_location; - if (sidebar->show_starred_location != show_starred_location) - { - sidebar->show_starred_location = show_starred_location; - update_places (sidebar); - g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_STARRED_LOCATION]); - } -} - -/** - * nautilus_gtk_places_sidebar_get_show_starred_location: - * @sidebar: a places sidebar - * - * Returns the value previously set with nautilus_gtk_places_sidebar_set_show_starred_location() - * - * Returns: %TRUE if the sidebar will display a Starred item. - * - * Since: 3.22.26 - */ -gboolean -nautilus_gtk_places_sidebar_get_show_starred_location (NautilusGtkPlacesSidebar *sidebar) -{ - g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_SIDEBAR (sidebar), FALSE); - - return sidebar->show_starred_location; -} diff --git a/src/gtk/nautilusgtkplacessidebar.h b/src/gtk/nautilusgtkplacessidebar.h deleted file mode 100644 index e7111ecf6..000000000 --- a/src/gtk/nautilusgtkplacessidebar.h +++ /dev/null @@ -1,159 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusGtkPlacesSidebar - sidebar widget for places in the filesystem - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 2.1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * This code comes from Nautilus, GNOME’s file manager. - * - * Authors : Mr Jamie McCracken (jamiemcc at blueyonder dot co dot uk) - * Federico Mena Quintero <federico@gnome.org> - */ - -#ifndef __NAUTILUS_GTK_PLACES_SIDEBAR_H__ -#define __NAUTILUS_GTK_PLACES_SIDEBAR_H__ - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#endif - -#include <gtk/gtkwidget.h> - -G_BEGIN_DECLS - -#define NAUTILUS_TYPE_GTK_PLACES_SIDEBAR (nautilus_gtk_places_sidebar_get_type ()) -#define NAUTILUS_GTK_PLACES_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_GTK_PLACES_SIDEBAR, NautilusGtkPlacesSidebar)) -#define NAUTILUS_GTK_PLACES_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_GTK_PLACES_SIDEBAR, NautilusGtkPlacesSidebarClass)) -#define NAUTILUS_IS_GTK_PLACES_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_GTK_PLACES_SIDEBAR)) -#define NAUTILUS_IS_GTK_PLACES_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_GTK_PLACES_SIDEBAR)) -#define NAUTILUS_GTK_PLACES_SIDEBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_GTK_PLACES_SIDEBAR, NautilusGtkPlacesSidebarClass)) - -typedef struct _NautilusGtkPlacesSidebar NautilusGtkPlacesSidebar; -typedef struct _NautilusGtkPlacesSidebarClass NautilusGtkPlacesSidebarClass; - -/** - * NautilusGtkPlacesOpenFlags: - * @NAUTILUS_GTK_PLACES_OPEN_NORMAL: This is the default mode that #NautilusGtkPlacesSidebar uses if no other flags - * are specified. It indicates that the calling application should open the selected location - * in the normal way, for example, in the folder view beside the sidebar. - * @NAUTILUS_GTK_PLACES_OPEN_NEW_TAB: When passed to nautilus_gtk_places_sidebar_set_open_flags(), this indicates - * that the application can open folders selected from the sidebar in new tabs. This value - * will be passed to the #NautilusGtkPlacesSidebar::open-location signal when the user selects - * that a location be opened in a new tab instead of in the standard fashion. - * @NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW: Similar to @NAUTILUS_GTK_PLACES_OPEN_NEW_TAB, but indicates that the application - * can open folders in new windows. - * - * These flags serve two purposes. First, the application can call nautilus_gtk_places_sidebar_set_open_flags() - * using these flags as a bitmask. This tells the sidebar that the application is able to open - * folders selected from the sidebar in various ways, for example, in new tabs or in new windows in - * addition to the normal mode. - * - * Second, when one of these values gets passed back to the application in the - * #NautilusGtkPlacesSidebar::open-location signal, it means that the application should - * open the selected location in the normal way, in a new tab, or in a new - * window. The sidebar takes care of determining the desired way to open the location, - * based on the modifier keys that the user is pressing at the time the selection is made. - * - * If the application never calls nautilus_gtk_places_sidebar_set_open_flags(), then the sidebar will only - * use #NAUTILUS_GTK_PLACES_OPEN_NORMAL in the #NautilusGtkPlacesSidebar::open-location signal. This is the - * default mode of operation. - */ -typedef enum { - NAUTILUS_GTK_PLACES_OPEN_NORMAL = 1 << 0, - NAUTILUS_GTK_PLACES_OPEN_NEW_TAB = 1 << 1, - NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW = 1 << 2 -} NautilusGtkPlacesOpenFlags; - -GDK_AVAILABLE_IN_3_10 -GType nautilus_gtk_places_sidebar_get_type (void) G_GNUC_CONST; -GDK_AVAILABLE_IN_3_10 -GtkWidget * nautilus_gtk_places_sidebar_new (void); - -GDK_AVAILABLE_IN_3_10 -NautilusGtkPlacesOpenFlags nautilus_gtk_places_sidebar_get_open_flags (NautilusGtkPlacesSidebar *sidebar); -GDK_AVAILABLE_IN_3_10 -void nautilus_gtk_places_sidebar_set_open_flags (NautilusGtkPlacesSidebar *sidebar, - NautilusGtkPlacesOpenFlags flags); - -GDK_AVAILABLE_IN_3_10 -GFile * nautilus_gtk_places_sidebar_get_location (NautilusGtkPlacesSidebar *sidebar); -GDK_AVAILABLE_IN_3_10 -void nautilus_gtk_places_sidebar_set_location (NautilusGtkPlacesSidebar *sidebar, - GFile *location); - -GDK_AVAILABLE_IN_3_18 -gboolean nautilus_gtk_places_sidebar_get_show_recent (NautilusGtkPlacesSidebar *sidebar); -GDK_AVAILABLE_IN_3_18 -void nautilus_gtk_places_sidebar_set_show_recent (NautilusGtkPlacesSidebar *sidebar, - gboolean show_recent); - -GDK_AVAILABLE_IN_3_10 -gboolean nautilus_gtk_places_sidebar_get_show_desktop (NautilusGtkPlacesSidebar *sidebar); -GDK_AVAILABLE_IN_3_10 -void nautilus_gtk_places_sidebar_set_show_desktop (NautilusGtkPlacesSidebar *sidebar, - gboolean show_desktop); - -GDK_DEPRECATED_IN_3_18 -gboolean nautilus_gtk_places_sidebar_get_show_connect_to_server (NautilusGtkPlacesSidebar *sidebar); -GDK_DEPRECATED_IN_3_18 -void nautilus_gtk_places_sidebar_set_show_connect_to_server (NautilusGtkPlacesSidebar *sidebar, - gboolean show_connect_to_server); -GDK_AVAILABLE_IN_3_14 -gboolean nautilus_gtk_places_sidebar_get_show_enter_location (NautilusGtkPlacesSidebar *sidebar); -GDK_AVAILABLE_IN_3_14 -void nautilus_gtk_places_sidebar_set_show_enter_location (NautilusGtkPlacesSidebar *sidebar, - gboolean show_enter_location); - -GDK_AVAILABLE_IN_3_12 -void nautilus_gtk_places_sidebar_set_local_only (NautilusGtkPlacesSidebar *sidebar, - gboolean local_only); -GDK_AVAILABLE_IN_3_12 -gboolean nautilus_gtk_places_sidebar_get_local_only (NautilusGtkPlacesSidebar *sidebar); - - -GDK_AVAILABLE_IN_3_10 -void nautilus_gtk_places_sidebar_add_shortcut (NautilusGtkPlacesSidebar *sidebar, - GFile *location); -GDK_AVAILABLE_IN_3_10 -void nautilus_gtk_places_sidebar_remove_shortcut (NautilusGtkPlacesSidebar *sidebar, - GFile *location); -GDK_AVAILABLE_IN_3_10 -GSList * nautilus_gtk_places_sidebar_list_shortcuts (NautilusGtkPlacesSidebar *sidebar); - -GDK_AVAILABLE_IN_3_10 -GFile * nautilus_gtk_places_sidebar_get_nth_bookmark (NautilusGtkPlacesSidebar *sidebar, - gint n); -GDK_AVAILABLE_IN_3_18 -void nautilus_gtk_places_sidebar_set_drop_targets_visible (NautilusGtkPlacesSidebar *sidebar, - gboolean visible, - GdkDragContext *context); -GDK_AVAILABLE_IN_3_18 -gboolean nautilus_gtk_places_sidebar_get_show_trash (NautilusGtkPlacesSidebar *sidebar); -GDK_AVAILABLE_IN_3_18 -void nautilus_gtk_places_sidebar_set_show_trash (NautilusGtkPlacesSidebar *sidebar, - gboolean show_trash); - -GDK_AVAILABLE_IN_3_18 -void nautilus_gtk_places_sidebar_set_show_other_locations (NautilusGtkPlacesSidebar *sidebar, - gboolean show_other_locations); -GDK_AVAILABLE_IN_3_18 -gboolean nautilus_gtk_places_sidebar_get_show_other_locations (NautilusGtkPlacesSidebar *sidebar); - -GDK_AVAILABLE_IN_3_22 -void nautilus_gtk_places_sidebar_set_show_starred_location (NautilusGtkPlacesSidebar *sidebar, - gboolean show_starred_location); -GDK_AVAILABLE_IN_3_22 -gboolean nautilus_gtk_places_sidebar_get_show_starred_location (NautilusGtkPlacesSidebar *sidebar); -G_END_DECLS - -#endif /* __NAUTILUS_GTK_PLACES_SIDEBAR_H__ */ diff --git a/src/gtk/nautilusgtkplacessidebarprivate.h b/src/gtk/nautilusgtkplacessidebarprivate.h deleted file mode 100644 index 6c6dd3daa..000000000 --- a/src/gtk/nautilusgtkplacessidebarprivate.h +++ /dev/null @@ -1,60 +0,0 @@ -/* nautilusgtkplacessidebarprivate.h - * - * Copyright (C) 2015 Red Hat - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Authors: Carlos Soriano <csoriano@gnome.org> - */ - -#ifndef __NAUTILUS_GTK_PLACES_SIDEBAR_PRIVATE_H__ -#define __NAUTILUS_GTK_PLACES_SIDEBAR_PRIVATE_H__ - -#include <glib.h> -#include "nautilusgtkplacessidebar.h" - -G_BEGIN_DECLS - -/* Keep order, since it's used for the sort functions */ -typedef enum { - SECTION_INVALID, - SECTION_COMPUTER, - SECTION_MOUNTS, - SECTION_CLOUD, - SECTION_BOOKMARKS, - SECTION_OTHER_LOCATIONS, - N_SECTIONS -} NautilusGtkPlacesSidebarSectionType; - -typedef enum { - PLACES_INVALID, - PLACES_BUILT_IN, - PLACES_XDG_DIR, - PLACES_MOUNTED_VOLUME, - PLACES_BOOKMARK, - PLACES_HEADING, - PLACES_CONNECT_TO_SERVER, - PLACES_ENTER_LOCATION, - PLACES_DROP_FEEDBACK, - PLACES_BOOKMARK_PLACEHOLDER, - PLACES_OTHER_LOCATIONS, - PLACES_STARRED_LOCATION, - N_PLACES -} NautilusGtkPlacesSidebarPlaceType; - -gchar *nautilus_gtk_places_sidebar_get_location_title (NautilusGtkPlacesSidebar *sidebar); - -G_END_DECLS - -#endif /* __NAUTILUS_GTK_PLACES_SIDEBAR_PRIVATE_H__ */ diff --git a/src/gtk/nautilusgtkplacesview.c b/src/gtk/nautilusgtkplacesview.c index 62505c0e1..b38777f2a 100644 --- a/src/gtk/nautilusgtkplacesview.c +++ b/src/gtk/nautilusgtkplacesview.c @@ -50,8 +50,8 @@ struct _NautilusGtkPlacesViewPrivate { GVolumeMonitor *volume_monitor; - NautilusGtkPlacesOpenFlags open_flags; - NautilusGtkPlacesOpenFlags current_open_flags; + GtkPlacesOpenFlags open_flags; + GtkPlacesOpenFlags current_open_flags; GFile *server_list_file; GFileMonitor *server_list_monitor; @@ -150,14 +150,14 @@ static GParamSpec *properties [LAST_PROP]; static void emit_open_location (NautilusGtkPlacesView *view, GFile *location, - NautilusGtkPlacesOpenFlags open_flags) + GtkPlacesOpenFlags open_flags) { NautilusGtkPlacesViewPrivate *priv; priv = nautilus_gtk_places_view_get_instance_private (view); if ((open_flags & priv->open_flags) == 0) - open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; + open_flags = GTK_PLACES_OPEN_NORMAL; g_signal_emit (view, places_view_signals[OPEN_LOCATION], 0, location, open_flags); } @@ -350,7 +350,7 @@ set_busy_cursor (NautilusGtkPlacesView *view, static void activate_row (NautilusGtkPlacesView *view, NautilusGtkPlacesViewRow *row, - NautilusGtkPlacesOpenFlags flags) + GtkPlacesOpenFlags flags) { NautilusGtkPlacesViewPrivate *priv; GVolume *volume; @@ -1567,7 +1567,7 @@ open_cb (GtkMenuItem *item, NautilusGtkPlacesView *self; self = NAUTILUS_GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), NAUTILUS_TYPE_GTK_PLACES_VIEW)); - activate_row (self, row, NAUTILUS_GTK_PLACES_OPEN_NORMAL); + activate_row (self, row, GTK_PLACES_OPEN_NORMAL); } static void @@ -1577,7 +1577,7 @@ open_in_new_tab_cb (GtkMenuItem *item, NautilusGtkPlacesView *self; self = NAUTILUS_GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), NAUTILUS_TYPE_GTK_PLACES_VIEW)); - activate_row (self, row, NAUTILUS_GTK_PLACES_OPEN_NEW_TAB); + activate_row (self, row, GTK_PLACES_OPEN_NEW_TAB); } static void @@ -1587,7 +1587,7 @@ open_in_new_window_cb (GtkMenuItem *item, NautilusGtkPlacesView *self; self = NAUTILUS_GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), NAUTILUS_TYPE_GTK_PLACES_VIEW)); - activate_row (self, row, NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW); + activate_row (self, row, GTK_PLACES_OPEN_NEW_WINDOW); } static void @@ -1709,7 +1709,7 @@ build_popup_menu (NautilusGtkPlacesView *view, gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); - if (priv->open_flags & NAUTILUS_GTK_PLACES_OPEN_NEW_TAB) + if (priv->open_flags & GTK_PLACES_OPEN_NEW_TAB) { item = gtk_menu_item_new_with_mnemonic (_("Open in New _Tab")); g_signal_connect (item, @@ -1720,7 +1720,7 @@ build_popup_menu (NautilusGtkPlacesView *view, gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); } - if (priv->open_flags & NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW) + if (priv->open_flags & GTK_PLACES_OPEN_NEW_WINDOW) { item = gtk_menu_item_new_with_mnemonic (_("Open in New _Window")); g_signal_connect (item, @@ -1829,7 +1829,7 @@ on_key_press_event (GtkWidget *widget, GtkWidget *focus_widget; GtkWindow *toplevel; - priv->current_open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; + priv->current_open_flags = GTK_PLACES_OPEN_NORMAL; toplevel = get_toplevel (GTK_WIDGET (view)); if (!toplevel) @@ -1841,9 +1841,9 @@ on_key_press_event (GtkWidget *widget, return FALSE; if ((event->state & modifiers) == GDK_SHIFT_MASK) - priv->current_open_flags = NAUTILUS_GTK_PLACES_OPEN_NEW_TAB; + priv->current_open_flags = GTK_PLACES_OPEN_NEW_TAB; else if ((event->state & modifiers) == GDK_CONTROL_MASK) - priv->current_open_flags = NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW; + priv->current_open_flags = GTK_PLACES_OPEN_NEW_WINDOW; activate_row (view, NAUTILUS_GTK_PLACES_VIEW_ROW (focus_widget), priv->current_open_flags); @@ -1981,7 +1981,7 @@ on_listbox_row_activated (NautilusGtkPlacesView *view, NautilusGtkPlacesViewPrivate *priv; GdkEvent *event; guint button; - NautilusGtkPlacesOpenFlags open_flags; + GtkPlacesOpenFlags open_flags; priv = nautilus_gtk_places_view_get_instance_private (view); @@ -1989,7 +1989,7 @@ on_listbox_row_activated (NautilusGtkPlacesView *view, gdk_event_get_button (event, &button); if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE && button == GDK_BUTTON_MIDDLE) - open_flags = NAUTILUS_GTK_PLACES_OPEN_NEW_TAB; + open_flags = GTK_PLACES_OPEN_NEW_TAB; else open_flags = priv->current_open_flags; @@ -2291,7 +2291,7 @@ nautilus_gtk_places_view_class_init (NautilusGtkPlacesViewClass *klass) * NautilusGtkPlacesView::open-location: * @view: the object which received the signal. * @location: (type Gio.File): #GFile to which the caller should switch. - * @open_flags: a single value from #NautilusGtkPlacesOpenFlags specifying how the @location + * @open_flags: a single value from #GtkPlacesOpenFlags specifying how the @location * should be opened. * * The places view emits this signal when the user selects a location @@ -2362,7 +2362,7 @@ nautilus_gtk_places_view_class_init (NautilusGtkPlacesViewClass *klass) "Open Flags", "Modes in which the calling application can open locations selected in the sidebar", GTK_TYPE_PLACES_OPEN_FLAGS, - NAUTILUS_GTK_PLACES_OPEN_NORMAL, + GTK_PLACES_OPEN_NORMAL, G_PARAM_READWRITE); g_object_class_install_properties (object_class, LAST_PROP, properties); @@ -2401,7 +2401,7 @@ nautilus_gtk_places_view_init (NautilusGtkPlacesView *self) priv = nautilus_gtk_places_view_get_instance_private (self); priv->volume_monitor = g_volume_monitor_get (); - priv->open_flags = NAUTILUS_GTK_PLACES_OPEN_NORMAL; + priv->open_flags = GTK_PLACES_OPEN_NORMAL; priv->path_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); priv->space_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); @@ -2447,14 +2447,14 @@ nautilus_gtk_places_view_new (void) * argument will be set to one of the @flags that was passed in * nautilus_gtk_places_view_set_open_flags(). * - * Passing 0 for @flags will cause #NAUTILUS_GTK_PLACES_OPEN_NORMAL to always be sent + * Passing 0 for @flags will cause #GTK_PLACES_OPEN_NORMAL to always be sent * to callbacks for the “open-location” signal. * * Since: 3.18 */ void nautilus_gtk_places_view_set_open_flags (NautilusGtkPlacesView *view, - NautilusGtkPlacesOpenFlags flags) + GtkPlacesOpenFlags flags) { NautilusGtkPlacesViewPrivate *priv; @@ -2471,15 +2471,15 @@ nautilus_gtk_places_view_set_open_flags (NautilusGtkPlacesView *view, /** * nautilus_gtk_places_view_get_open_flags: - * @view: a #NautilusGtkPlacesSidebar + * @view: a #GtkPlacesSidebar * * Gets the open flags. * - * Returns: the #NautilusGtkPlacesOpenFlags of @view + * Returns: the #GtkPlacesOpenFlags of @view * * Since: 3.18 */ -NautilusGtkPlacesOpenFlags +GtkPlacesOpenFlags nautilus_gtk_places_view_get_open_flags (NautilusGtkPlacesView *view) { NautilusGtkPlacesViewPrivate *priv; diff --git a/src/gtk/nautilusgtkplacesviewprivate.h b/src/gtk/nautilusgtkplacesviewprivate.h index b821476cf..92f1dd92f 100644 --- a/src/gtk/nautilusgtkplacesviewprivate.h +++ b/src/gtk/nautilusgtkplacesviewprivate.h @@ -22,7 +22,6 @@ #if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) #endif -#include "nautilusgtkplacessidebar.h" G_BEGIN_DECLS @@ -43,9 +42,9 @@ struct _NautilusGtkPlacesViewClass void (* open_location) (NautilusGtkPlacesView *view, GFile *location, - NautilusGtkPlacesOpenFlags open_flags); + GtkPlacesOpenFlags open_flags); - void (* show_error_message) (NautilusGtkPlacesSidebar *sidebar, + void (* show_error_message) (GtkPlacesSidebar *sidebar, const gchar *primary, const gchar *secondary); @@ -62,9 +61,9 @@ struct _NautilusGtkPlacesView GType nautilus_gtk_places_view_get_type (void) G_GNUC_CONST; -NautilusGtkPlacesOpenFlags nautilus_gtk_places_view_get_open_flags (NautilusGtkPlacesView *view); +GtkPlacesOpenFlags nautilus_gtk_places_view_get_open_flags (NautilusGtkPlacesView *view); void nautilus_gtk_places_view_set_open_flags (NautilusGtkPlacesView *view, - NautilusGtkPlacesOpenFlags flags); + GtkPlacesOpenFlags flags); const gchar* nautilus_gtk_places_view_get_search_query (NautilusGtkPlacesView *view); void nautilus_gtk_places_view_set_search_query (NautilusGtkPlacesView *view, diff --git a/src/gtk/nautilusgtkplacesviewrow.c b/src/gtk/nautilusgtkplacesviewrow.c index f07dd4e70..121c5823b 100644 --- a/src/gtk/nautilusgtkplacesviewrow.c +++ b/src/gtk/nautilusgtkplacesviewrow.c @@ -29,6 +29,14 @@ * instead of including gtk.h */ #ifdef GTK_COMPILATION +#include "gtkbutton.h" +#include "gtkeventbox.h" +#include "gtkimage.h" +#include "gtkintl.h" +#include "gtklabel.h" +#include "gtkspinner.h" +#include "gtkstack.h" +#include "gtktypebuiltins.h" #else #include <gtk/gtk.h> #endif diff --git a/src/gtk/nautilusgtksidebarrow.c b/src/gtk/nautilusgtksidebarrow.c deleted file mode 100644 index 7cc24b09f..000000000 --- a/src/gtk/nautilusgtksidebarrow.c +++ /dev/null @@ -1,667 +0,0 @@ -/* nautilusgtksidebarrow.c - * - * Copyright (C) 2015 Carlos Soriano <csoriano@gnome.org> - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#include "nautilusgtksidebarrowprivate.h" -/* For section and place type enums */ -#include "nautilusgtkplacessidebarprivate.h" -#include "nautilusgtkplacessidebar.h" - -#ifdef HAVE_CLOUDPROVIDERS -#include <cloudproviders/cloudprovidersaccount.h> -#endif - -struct _NautilusGtkSidebarRow -{ - GtkListBoxRow parent_instance; - GIcon *start_icon; - GIcon *end_icon; - GtkWidget *start_icon_widget; - GtkWidget *end_icon_widget; - gchar *label; - gchar *tooltip; - GtkWidget *label_widget; - gboolean ejectable; - GtkWidget *eject_button; - gint order_index; - NautilusGtkPlacesSidebarSectionType section_type; - NautilusGtkPlacesSidebarPlaceType place_type; - gchar *uri; - GDrive *drive; - GVolume *volume; - GMount *mount; - GObject *cloud_provider_account; - gboolean placeholder; - NautilusGtkPlacesSidebar *sidebar; - GtkWidget *event_box; - GtkWidget *revealer; - GtkWidget *busy_spinner; -}; - -G_DEFINE_TYPE (NautilusGtkSidebarRow, nautilus_gtk_sidebar_row, GTK_TYPE_LIST_BOX_ROW) - -enum -{ - PROP_0, - PROP_START_ICON, - PROP_END_ICON, - PROP_LABEL, - PROP_TOOLTIP, - PROP_EJECTABLE, - PROP_SIDEBAR, - PROP_ORDER_INDEX, - PROP_SECTION_TYPE, - PROP_PLACE_TYPE, - PROP_URI, - PROP_DRIVE, - PROP_VOLUME, - PROP_MOUNT, - PROP_CLOUD_PROVIDER_ACCOUNT, - PROP_PLACEHOLDER, - LAST_PROP -}; - -static GParamSpec *properties [LAST_PROP]; - -#ifdef HAVE_CLOUDPROVIDERS - -static void -cloud_row_update (NautilusGtkSidebarRow *self) -{ - CloudProvidersAccount *account; - GIcon *end_icon; - gint provider_status; - - account = CLOUD_PROVIDERS_ACCOUNT (self->cloud_provider_account); - provider_status = cloud_providers_account_get_status (account); - switch (provider_status) - { - case CLOUD_PROVIDERS_ACCOUNT_STATUS_IDLE: - end_icon = NULL; - break; - - case CLOUD_PROVIDERS_ACCOUNT_STATUS_SYNCING: - end_icon = g_themed_icon_new ("emblem-synchronizing-symbolic"); - break; - - case CLOUD_PROVIDERS_ACCOUNT_STATUS_ERROR: - end_icon = g_themed_icon_new ("dialog-warning-symbolic"); - break; - - default: - return; - } - - g_object_set (self, - "label", cloud_providers_account_get_name (account), - NULL); - g_object_set (self, - "tooltip", cloud_providers_account_get_status_details (account), - NULL); - g_object_set (self, - "end-icon", end_icon, - NULL); - - if (end_icon != NULL) - g_object_unref (end_icon); -} - -#endif - -static void -nautilus_gtk_sidebar_row_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - NautilusGtkSidebarRow *self = NAUTILUS_GTK_SIDEBAR_ROW (object); - - switch (prop_id) - { - case PROP_SIDEBAR: - g_value_set_object (value, self->sidebar); - break; - - case PROP_START_ICON: - g_value_set_object (value, self->start_icon); - break; - - case PROP_END_ICON: - g_value_set_object (value, self->end_icon); - break; - - case PROP_LABEL: - g_value_set_string (value, self->label); - break; - - case PROP_TOOLTIP: - g_value_set_string (value, self->tooltip); - break; - - case PROP_EJECTABLE: - g_value_set_boolean (value, self->ejectable); - break; - - case PROP_ORDER_INDEX: - g_value_set_int (value, self->order_index); - break; - - case PROP_SECTION_TYPE: - g_value_set_int (value, self->section_type); - break; - - case PROP_PLACE_TYPE: - g_value_set_int (value, self->place_type); - break; - - case PROP_URI: - g_value_set_string (value, self->uri); - break; - - case PROP_DRIVE: - g_value_set_object (value, self->drive); - break; - - case PROP_VOLUME: - g_value_set_object (value, self->volume); - break; - - case PROP_MOUNT: - g_value_set_object (value, self->mount); - break; - - case PROP_CLOUD_PROVIDER_ACCOUNT: - g_value_set_object (value, self->cloud_provider_account); - break; - - case PROP_PLACEHOLDER: - g_value_set_boolean (value, self->placeholder); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -nautilus_gtk_sidebar_row_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - NautilusGtkSidebarRow *self = NAUTILUS_GTK_SIDEBAR_ROW (object); - GtkStyleContext *context; - - switch (prop_id) - { - case PROP_SIDEBAR: - self->sidebar = g_value_get_object (value); - break; - - case PROP_START_ICON: - { - g_clear_object (&self->start_icon); - object = g_value_get_object (value); - if (object != NULL) - { - self->start_icon = G_ICON (g_object_ref (object)); - gtk_image_set_from_gicon (GTK_IMAGE (self->start_icon_widget), - self->start_icon, - GTK_ICON_SIZE_MENU); - } - else - { - gtk_image_clear (GTK_IMAGE (self->start_icon_widget)); - } - break; - } - - case PROP_END_ICON: - { - g_clear_object (&self->end_icon); - object = g_value_get_object (value); - if (object != NULL) - { - self->end_icon = G_ICON (g_object_ref (object)); - gtk_image_set_from_gicon (GTK_IMAGE (self->end_icon_widget), - self->end_icon, - GTK_ICON_SIZE_MENU); - gtk_widget_show (self->end_icon_widget); - } - else - { - gtk_image_clear (GTK_IMAGE (self->end_icon_widget)); - gtk_widget_hide (self->end_icon_widget); - } - break; - } - - case PROP_LABEL: - g_free (self->label); - self->label = g_strdup (g_value_get_string (value)); - gtk_label_set_text (GTK_LABEL (self->label_widget), self->label); - break; - - case PROP_TOOLTIP: - g_free (self->tooltip); - self->tooltip = g_strdup (g_value_get_string (value)); - gtk_widget_set_tooltip_text (GTK_WIDGET (self), self->tooltip); - break; - - case PROP_EJECTABLE: - self->ejectable = g_value_get_boolean (value); - if (self->ejectable) - gtk_widget_show (self->eject_button); - else - gtk_widget_hide (self->eject_button); - break; - - case PROP_ORDER_INDEX: - self->order_index = g_value_get_int (value); - break; - - case PROP_SECTION_TYPE: - self->section_type = g_value_get_int (value); - if (self->section_type == SECTION_COMPUTER || - self->section_type == SECTION_OTHER_LOCATIONS) - gtk_label_set_ellipsize (GTK_LABEL (self->label_widget), PANGO_ELLIPSIZE_NONE); - else - gtk_label_set_ellipsize (GTK_LABEL (self->label_widget), PANGO_ELLIPSIZE_END); - break; - - case PROP_PLACE_TYPE: - self->place_type = g_value_get_int (value); - break; - - case PROP_URI: - g_free (self->uri); - self->uri = g_strdup (g_value_get_string (value)); - break; - - case PROP_DRIVE: - g_set_object (&self->drive, g_value_get_object (value)); - break; - - case PROP_VOLUME: - g_set_object (&self->volume, g_value_get_object (value)); - break; - - case PROP_MOUNT: - g_set_object (&self->mount, g_value_get_object (value)); - break; - - case PROP_CLOUD_PROVIDER_ACCOUNT: -#ifdef HAVE_CLOUDPROVIDERS - if (self->cloud_provider_account != NULL) - g_signal_handlers_disconnect_by_data (self->cloud_provider_account, self); - - self->cloud_provider_account = g_value_dup_object (value); - - if (self->cloud_provider_account != NULL) - { - g_signal_connect_swapped (self->cloud_provider_account, "notify::name", - G_CALLBACK (cloud_row_update), self); - g_signal_connect_swapped (self->cloud_provider_account, "notify::status", - G_CALLBACK (cloud_row_update), self); - g_signal_connect_swapped (self->cloud_provider_account, "notify::status-details", - G_CALLBACK (cloud_row_update), self); - } -#endif - break; - - case PROP_PLACEHOLDER: - { - self->placeholder = g_value_get_boolean (value); - if (self->placeholder) - { - g_clear_object (&self->start_icon); - g_clear_object (&self->end_icon); - g_free (self->label); - self->label = NULL; - g_free (self->tooltip); - self->tooltip = NULL; - gtk_widget_set_tooltip_text (GTK_WIDGET (self), NULL); - self->ejectable = FALSE; - self->section_type = SECTION_BOOKMARKS; - self->place_type = PLACES_BOOKMARK_PLACEHOLDER; - g_free (self->uri); - self->uri = NULL; - g_clear_object (&self->drive); - g_clear_object (&self->volume); - g_clear_object (&self->mount); - g_clear_object (&self->cloud_provider_account); - - gtk_container_foreach (GTK_CONTAINER (self), - (GtkCallback) gtk_widget_destroy, - NULL); - - context = gtk_widget_get_style_context (GTK_WIDGET (self)); - gtk_style_context_add_class (context, "sidebar-placeholder-row"); - } - - break; - } - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -on_child_revealed (GObject *self, - GParamSpec *pspec, - gpointer user_data) -{ - /* We need to hide the actual widget because if not the GtkListBoxRow will - * still allocate the paddings, even if the revealer is not revealed, and - * therefore the row will be still somewhat visible. */ - if (!gtk_revealer_get_reveal_child (GTK_REVEALER (self))) - gtk_widget_hide (GTK_WIDGET (NAUTILUS_GTK_SIDEBAR_ROW (user_data))); -} - -void -nautilus_gtk_sidebar_row_reveal (NautilusGtkSidebarRow *self) -{ - gtk_widget_show_all (GTK_WIDGET (self)); - gtk_revealer_set_reveal_child (GTK_REVEALER (self->revealer), TRUE); -} - -void -nautilus_gtk_sidebar_row_hide (NautilusGtkSidebarRow *self, - gboolean inmediate) -{ - guint transition_duration; - - transition_duration = gtk_revealer_get_transition_duration (GTK_REVEALER (self->revealer)); - if (inmediate) - gtk_revealer_set_transition_duration (GTK_REVEALER (self->revealer), 0); - - gtk_revealer_set_reveal_child (GTK_REVEALER (self->revealer), FALSE); - - gtk_revealer_set_transition_duration (GTK_REVEALER (self->revealer), transition_duration); -} - -void -nautilus_gtk_sidebar_row_set_start_icon (NautilusGtkSidebarRow *self, - GIcon *icon) -{ - g_return_if_fail (NAUTILUS_IS_GTK_SIDEBAR_ROW (self)); - - if (self->start_icon != icon) - { - g_set_object (&self->start_icon, icon); - if (self->start_icon != NULL) - gtk_image_set_from_gicon (GTK_IMAGE (self->start_icon_widget), self->start_icon, - GTK_ICON_SIZE_MENU); - else - gtk_image_clear (GTK_IMAGE (self->start_icon_widget)); - - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_START_ICON]); - } -} - -void -nautilus_gtk_sidebar_row_set_end_icon (NautilusGtkSidebarRow *self, - GIcon *icon) -{ - g_return_if_fail (NAUTILUS_IS_GTK_SIDEBAR_ROW (self)); - - if (self->end_icon != icon) - { - g_set_object (&self->end_icon, icon); - if (self->end_icon != NULL) - gtk_image_set_from_gicon (GTK_IMAGE (self->end_icon_widget), self->end_icon, - GTK_ICON_SIZE_MENU); - else - if (self->end_icon_widget != NULL) - gtk_image_clear (GTK_IMAGE (self->end_icon_widget)); - - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_END_ICON]); - } -} - -static void -nautilus_gtk_sidebar_row_finalize (GObject *object) -{ - NautilusGtkSidebarRow *self = NAUTILUS_GTK_SIDEBAR_ROW (object); - - g_clear_object (&self->start_icon); - g_clear_object (&self->end_icon); - g_free (self->label); - self->label = NULL; - g_free (self->tooltip); - self->tooltip = NULL; - g_free (self->uri); - self->uri = NULL; - g_clear_object (&self->drive); - g_clear_object (&self->volume); - g_clear_object (&self->mount); -#ifdef HAVE_CLOUDPROVIDERS - if (self->cloud_provider_account != NULL) - g_signal_handlers_disconnect_by_data (self->cloud_provider_account, self); - g_clear_object (&self->cloud_provider_account); -#endif - - G_OBJECT_CLASS (nautilus_gtk_sidebar_row_parent_class)->finalize (object); -} - -static void -nautilus_gtk_sidebar_row_init (NautilusGtkSidebarRow *self) -{ - gtk_widget_init_template (GTK_WIDGET (self)); -} - -static void -nautilus_gtk_sidebar_row_class_init (NautilusGtkSidebarRowClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - object_class->get_property = nautilus_gtk_sidebar_row_get_property; - object_class->set_property = nautilus_gtk_sidebar_row_set_property; - object_class->finalize = nautilus_gtk_sidebar_row_finalize; - - properties [PROP_SIDEBAR] = - g_param_spec_object ("sidebar", - "Sidebar", - "Sidebar", - NAUTILUS_TYPE_GTK_PLACES_SIDEBAR, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_START_ICON] = - g_param_spec_object ("start-icon", - "start-icon", - "The start icon.", - G_TYPE_ICON, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_END_ICON] = - g_param_spec_object ("end-icon", - "end-icon", - "The end icon.", - G_TYPE_ICON, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_LABEL] = - g_param_spec_string ("label", - "label", - "The label text.", - NULL, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_TOOLTIP] = - g_param_spec_string ("tooltip", - "Tooltip", - "Tooltip", - NULL, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_EJECTABLE] = - g_param_spec_boolean ("ejectable", - "Ejectable", - "Ejectable", - FALSE, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_ORDER_INDEX] = - g_param_spec_int ("order-index", - "OrderIndex", - "Order Index", - 0, G_MAXINT, 0, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_SECTION_TYPE] = - g_param_spec_int ("section-type", - "section type", - "The section type.", - SECTION_INVALID, N_SECTIONS, SECTION_INVALID, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY)); - - properties [PROP_PLACE_TYPE] = - g_param_spec_int ("place-type", - "place type", - "The place type.", - PLACES_INVALID, N_PLACES, PLACES_INVALID, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY)); - - properties [PROP_URI] = - g_param_spec_string ("uri", - "Uri", - "Uri", - NULL, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_DRIVE] = - g_param_spec_object ("drive", - "Drive", - "Drive", - G_TYPE_DRIVE, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_VOLUME] = - g_param_spec_object ("volume", - "Volume", - "Volume", - G_TYPE_VOLUME, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_MOUNT] = - g_param_spec_object ("mount", - "Mount", - "Mount", - G_TYPE_MOUNT, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_CLOUD_PROVIDER_ACCOUNT] = - g_param_spec_object ("cloud-provider-account", - "CloudProvidersAccount", - "CloudProvidersAccount", - G_TYPE_OBJECT, - (G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - properties [PROP_PLACEHOLDER] = - g_param_spec_boolean ("placeholder", - "Placeholder", - "Placeholder", - FALSE, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_properties (object_class, LAST_PROP, properties); - - gtk_widget_class_set_template_from_resource (widget_class, - "/org/gnome/nautilus/gtk/ui/nautilusgtksidebarrow.ui"); - - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, start_icon_widget); - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, end_icon_widget); - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, label_widget); - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, eject_button); - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, event_box); - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, revealer); - gtk_widget_class_bind_template_child (widget_class, NautilusGtkSidebarRow, busy_spinner); - - gtk_widget_class_bind_template_callback (widget_class, on_child_revealed); - gtk_widget_class_set_css_name (widget_class, "row"); -} - -NautilusGtkSidebarRow* -nautilus_gtk_sidebar_row_clone (NautilusGtkSidebarRow *self) -{ - return g_object_new (NAUTILUS_TYPE_GTK_SIDEBAR_ROW, - "sidebar", self->sidebar, - "start-icon", self->start_icon, - "end-icon", self->end_icon, - "label", self->label, - "tooltip", self->tooltip, - "ejectable", self->ejectable, - "order-index", self->order_index, - "section-type", self->section_type, - "place-type", self->place_type, - "uri", self->uri, - "drive", self->drive, - "volume", self->volume, - "mount", self->mount, - "cloud-provider-account", self->cloud_provider_account, - NULL); -} - -GtkWidget* -nautilus_gtk_sidebar_row_get_eject_button (NautilusGtkSidebarRow *self) -{ - return self->eject_button; -} - -GtkWidget* -nautilus_gtk_sidebar_row_get_event_box (NautilusGtkSidebarRow *self) -{ - return self->event_box; -} - -void -nautilus_gtk_sidebar_row_set_busy (NautilusGtkSidebarRow *row, - gboolean is_busy) -{ - g_return_if_fail (NAUTILUS_IS_GTK_SIDEBAR_ROW (row)); - - gtk_widget_set_visible (row->busy_spinner, is_busy); -} diff --git a/src/gtk/nautilusgtksidebarrow.ui b/src/gtk/nautilusgtksidebarrow.ui deleted file mode 100644 index 26265fcb3..000000000 --- a/src/gtk/nautilusgtksidebarrow.ui +++ /dev/null @@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<interface domain="gtk30"> - <template class="NautilusGtkSidebarRow" parent="GtkListBoxRow"> - <property name="visible">True</property> - <property name="margin-top">1</property> - <property name="margin-bottom">1</property> - <property name="focus-on-click">False</property> - <style> - <class name="sidebar-row"/> - </style> - <child> - <object class="GtkRevealer" id="revealer"> - <property name="visible">1</property> - <property name="reveal-child">1</property> - <signal name="notify::child-revealed" handler="on_child_revealed"/> - <style> - <class name="sidebar-revealer"/> - </style> - <child> - <object class="GtkEventBox" id="event_box"> - <property name="visible">1</property> - <child> - <object class="GtkBox"> - <property name="visible">1</property> - <child> - <object class="GtkImage" id="start_icon_widget"> - <property name="visible">True</property> - <style> - <class name="sidebar-icon"/> - </style> - </object> - </child> - <child> - <object class="GtkLabel" id="label_widget"> - <property name="visible">1</property> - <property name="hexpand">1</property> - <property name="xalign">0</property> - <style> - <class name="sidebar-label"/> - </style> - </object> - </child> - <child> - <object class="GtkImage" id="end_icon_widget"> - <property name="visible">False</property> - <property name="hexpand">True</property> - <property name="halign">end</property> - <property name="valign">center</property> - <property name="no-show-all">1</property> - <style> - <class name="sidebar-icon"/> - </style> - </object> - </child> - <child> - <object class="GtkButton" id="eject_button"> - <property name="visible">1</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="margin-start">4px</property> - <property name="no-show-all">1</property> - <property name="tooltip-text" translatable="yes">Unmount</property> - <child> - <object class="GtkImage"> - <property name="visible">1</property> - <property name="icon-name">media-eject-symbolic</property> - <property name="icon-size">1</property> - </object> - </child> - <style> - <class name="image-button"/> - <class name="sidebar-button"/> - </style> - </object> - </child> - <child> - <object class="GtkSpinner" id="busy_spinner"> - <property name="active">1</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="margin-start">4px</property> - <property name="no-show-all">1</property> - </object> - </child> - </object> - </child> - </object> - </child> - </object> - </child> - </template> -</interface> diff --git a/src/gtk/nautilusgtksidebarrowprivate.h b/src/gtk/nautilusgtksidebarrowprivate.h deleted file mode 100644 index 437384954..000000000 --- a/src/gtk/nautilusgtksidebarrowprivate.h +++ /dev/null @@ -1,61 +0,0 @@ -/* nautilusgtksidebarrowprivate.h - * - * Copyright (C) 2015 Carlos Soriano <csoriano@gnome.org> - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef NAUTILUS_GTK_SIDEBAR_ROW_PRIVATE_H -#define NAUTILUS_GTK_SIDEBAR_ROW_PRIVATE_H - -#include <glib.h> - -G_BEGIN_DECLS - -#define NAUTILUS_TYPE_GTK_SIDEBAR_ROW (nautilus_gtk_sidebar_row_get_type()) -#define NAUTILUS_GTK_SIDEBAR_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_GTK_SIDEBAR_ROW, NautilusGtkSidebarRow)) -#define NAUTILUS_GTK_SIDEBAR_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_GTK_SIDEBAR_ROW, NautilusGtkSidebarRowClass)) -#define NAUTILUS_IS_GTK_SIDEBAR_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_GTK_SIDEBAR_ROW)) -#define NAUTILUS_IS_GTK_SIDEBAR_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_GTK_SIDEBAR_ROW)) -#define NAUTILUS_GTK_SIDEBAR_ROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_GTK_SIDEBAR_ROW, NautilusGtkSidebarRowClass)) - -typedef struct _NautilusGtkSidebarRow NautilusGtkSidebarRow; -typedef struct _NautilusGtkSidebarRowClass NautilusGtkSidebarRowClass; - -struct _NautilusGtkSidebarRowClass -{ - GtkListBoxRowClass parent; -}; - -GType nautilus_gtk_sidebar_row_get_type (void) G_GNUC_CONST; - -NautilusGtkSidebarRow *nautilus_gtk_sidebar_row_new (void); -NautilusGtkSidebarRow *nautilus_gtk_sidebar_row_clone (NautilusGtkSidebarRow *self); - -/* Use these methods instead of gtk_widget_hide/show to use an animation */ -void nautilus_gtk_sidebar_row_hide (NautilusGtkSidebarRow *self, - gboolean inmediate); -void nautilus_gtk_sidebar_row_reveal (NautilusGtkSidebarRow *self); - -GtkWidget *nautilus_gtk_sidebar_row_get_eject_button (NautilusGtkSidebarRow *self); -GtkWidget *nautilus_gtk_sidebar_row_get_event_box (NautilusGtkSidebarRow *self); -void nautilus_gtk_sidebar_row_set_start_icon (NautilusGtkSidebarRow *self, - GIcon *icon); -void nautilus_gtk_sidebar_row_set_end_icon (NautilusGtkSidebarRow *self, - GIcon *icon); -void nautilus_gtk_sidebar_row_set_busy (NautilusGtkSidebarRow *row, - gboolean is_busy); - -G_END_DECLS - -#endif /* NAUTILUS_GTK_SIDEBAR_ROW_PRIVATE_H */ diff --git a/src/meson.build b/src/meson.build index a8c650e97..20865fff4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -62,13 +62,6 @@ libnautilus_sources = [ 'animation/ide-box-theatric.h', 'animation/ide-cairo.c', 'animation/ide-cairo.h', - 'gtk/nautilusgtkbookmarksmanager.c', - 'gtk/nautilusgtkbookmarksmanager.h', - 'gtk/nautilusgtkplacessidebar.c', - 'gtk/nautilusgtkplacessidebarprivate.h', - 'gtk/nautilusgtkplacessidebar.h', - 'gtk/nautilusgtksidebarrow.c', - 'gtk/nautilusgtksidebarrowprivate.h', 'gtk/nautilusgtkplacesview.c', 'gtk/nautilusgtkplacesviewprivate.h', 'gtk/nautilusgtkplacesviewrow.c', diff --git a/src/nautilus-places-view.c b/src/nautilus-places-view.c index a2edbfc85..5d4eef9f0 100644 --- a/src/nautilus-places-view.c +++ b/src/nautilus-places-view.c @@ -61,9 +61,9 @@ enum }; static void -open_location_cb (NautilusPlacesView *view, - GFile *location, - NautilusGtkPlacesOpenFlags open_flags) +open_location_cb (NautilusPlacesView *view, + GFile *location, + GtkPlacesOpenFlags open_flags) { NautilusOpenFlags flags; GtkWidget *slot; diff --git a/src/nautilus-window.c b/src/nautilus-window.c index c69febd7f..f92858bdf 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -47,8 +47,6 @@ #define DEBUG_FLAG NAUTILUS_DEBUG_WINDOW #include "nautilus-debug.h" -#include "gtk/nautilusgtkplacessidebar.h" - #include "nautilus-application.h" #include "nautilus-bookmark-list.h" #include "nautilus-clipboard.h" @@ -478,8 +476,8 @@ action_show_current_location_menu (GSimpleAction *action, static void on_location_changed (NautilusWindow *window) { - nautilus_gtk_places_sidebar_set_location (NAUTILUS_GTK_PLACES_SIDEBAR (window->places_sidebar), - nautilus_window_slot_get_location (nautilus_window_get_active_slot (window))); + gtk_places_sidebar_set_location (GTK_PLACES_SIDEBAR (window->places_sidebar), + nautilus_window_slot_get_location (nautilus_window_get_active_slot (window))); } static void @@ -879,29 +877,29 @@ setup_side_pane_width (NautilusWindow *window) /* Callback used when the places sidebar changes location; we need to change the displayed folder */ static void -open_location_cb (NautilusWindow *window, - GFile *location, - NautilusGtkPlacesOpenFlags open_flags) +open_location_cb (NautilusWindow *window, + GFile *location, + GtkPlacesOpenFlags open_flags) { NautilusOpenFlags flags; NautilusApplication *application; switch (open_flags) { - case NAUTILUS_GTK_PLACES_OPEN_NEW_TAB: + case GTK_PLACES_OPEN_NEW_TAB: { flags = NAUTILUS_OPEN_FLAG_NEW_TAB | NAUTILUS_OPEN_FLAG_DONT_MAKE_ACTIVE; } break; - case NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW: + case GTK_PLACES_OPEN_NEW_WINDOW: { flags = NAUTILUS_OPEN_FLAG_NEW_WINDOW; } break; - case NAUTILUS_GTK_PLACES_OPEN_NORMAL: /* fall-through */ + case GTK_PLACES_OPEN_NORMAL: /* fall-through */ default: { flags = 0; @@ -929,10 +927,10 @@ places_sidebar_unmount_operation_cb (NautilusWindow *window, /* Callback used when the places sidebar needs us to present an error message */ static void -places_sidebar_show_error_message_cb (NautilusGtkPlacesSidebar *sidebar, - const char *primary, - const char *secondary, - gpointer user_data) +places_sidebar_show_error_message_cb (GtkPlacesSidebar *sidebar, + const char *primary, + const char *secondary, + gpointer user_data) { NautilusWindow *window = NAUTILUS_WINDOW (user_data); @@ -940,8 +938,8 @@ places_sidebar_show_error_message_cb (NautilusGtkPlacesSidebar *sidebar, } static void -places_sidebar_show_other_locations_with_flags (NautilusWindow *window, - NautilusGtkPlacesOpenFlags open_flags) +places_sidebar_show_other_locations_with_flags (NautilusWindow *window, + GtkPlacesOpenFlags open_flags) { GFile *location; @@ -953,8 +951,8 @@ places_sidebar_show_other_locations_with_flags (NautilusWindow *wind } static void -places_sidebar_show_starred_location (NautilusWindow *window, - NautilusGtkPlacesOpenFlags open_flags) +places_sidebar_show_starred_location (NautilusWindow *window, + GtkPlacesOpenFlags open_flags) { GFile *location; @@ -995,9 +993,9 @@ nautilus_window_start_dnd (NautilusWindow *window, { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); - nautilus_gtk_places_sidebar_set_drop_targets_visible (NAUTILUS_GTK_PLACES_SIDEBAR (window->places_sidebar), - TRUE, - context); + gtk_places_sidebar_set_drop_targets_visible (GTK_PLACES_SIDEBAR (window->places_sidebar), + TRUE, + context); } void @@ -1006,18 +1004,18 @@ nautilus_window_end_dnd (NautilusWindow *window, { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); - nautilus_gtk_places_sidebar_set_drop_targets_visible (NAUTILUS_GTK_PLACES_SIDEBAR (window->places_sidebar), - FALSE, - context); + gtk_places_sidebar_set_drop_targets_visible (GTK_PLACES_SIDEBAR (window->places_sidebar), + FALSE, + context); } /* Callback used when the places sidebar needs to know the drag action to suggest */ static GdkDragAction -places_sidebar_drag_action_requested_cb (NautilusGtkPlacesSidebar *sidebar, - GdkDragContext *context, - GFile *dest_file, - GList *source_file_list, - gpointer user_data) +places_sidebar_drag_action_requested_cb (GtkPlacesSidebar *sidebar, + GdkDragContext *context, + GFile *dest_file, + GList *source_file_list, + gpointer user_data) { GList *items; char *uri; @@ -1058,9 +1056,9 @@ out: /* Callback used when the places sidebar needs us to pop up a menu with possible drag actions */ static GdkDragAction -places_sidebar_drag_action_ask_cb (NautilusGtkPlacesSidebar *sidebar, - GdkDragAction actions, - gpointer user_data) +places_sidebar_drag_action_ask_cb (GtkPlacesSidebar *sidebar, + GdkDragAction actions, + gpointer user_data) { return nautilus_drag_drop_action_ask (GTK_WIDGET (sidebar), actions); } @@ -1087,11 +1085,11 @@ build_uri_list_from_gfile_list (GList *file_list) /* Callback used when the places sidebar has URIs dropped into it. We do a normal file operation for them. */ static void -places_sidebar_drag_perform_drop_cb (NautilusGtkPlacesSidebar *sidebar, - GFile *dest_file, - GList *source_file_list, - GdkDragAction action, - gpointer user_data) +places_sidebar_drag_perform_drop_cb (GtkPlacesSidebar *sidebar, + GFile *dest_file, + GList *source_file_list, + GdkDragAction action, + gpointer user_data) { char *dest_uri; GList *source_uri_list; @@ -1244,11 +1242,11 @@ add_menu_separator (GtkWidget *menu) } static void -places_sidebar_populate_popup_cb (NautilusGtkPlacesSidebar *sidebar, - GtkWidget *menu, - GFile *selected_file, - GVolume *selected_volume, - gpointer user_data) +places_sidebar_populate_popup_cb (GtkPlacesSidebar *sidebar, + GtkWidget *menu, + GFile *selected_file, + GVolume *selected_volume, + gpointer user_data) { NautilusWindow *window = NAUTILUS_WINDOW (user_data); GFile *trash; @@ -1325,10 +1323,10 @@ nautilus_window_set_up_sidebar (NautilusWindow *window) G_CALLBACK (side_pane_notify_position_callback), window); - nautilus_gtk_places_sidebar_set_open_flags (NAUTILUS_GTK_PLACES_SIDEBAR (window->places_sidebar), - (NAUTILUS_GTK_PLACES_OPEN_NORMAL - | NAUTILUS_GTK_PLACES_OPEN_NEW_TAB - | NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW)); + gtk_places_sidebar_set_open_flags (GTK_PLACES_SIDEBAR (window->places_sidebar), + (GTK_PLACES_OPEN_NORMAL + | GTK_PLACES_OPEN_NEW_TAB + | GTK_PLACES_OPEN_NEW_WINDOW)); g_signal_connect_swapped (window->places_sidebar, "open-location", G_CALLBACK (open_location_cb), window); @@ -2701,27 +2699,6 @@ nautilus_window_init (NautilusWindow *window) g_type_ensure (NAUTILUS_TYPE_NOTEBOOK); gtk_widget_init_template (GTK_WIDGET (window)); - window->places_sidebar = nautilus_gtk_places_sidebar_new (); - g_object_set (window->places_sidebar, - "vexpand", TRUE, - "visible", TRUE, - "populate-all", TRUE, - "show-other-locations", TRUE, - "show-starred-location", TRUE, - NULL); - gtk_box_append (GTK_BOX (window->sidebar), window->places_sidebar); - - g_signal_connect_object (window->places_sidebar, - "show-other-locations-with-flags", - G_CALLBACK (places_sidebar_show_other_locations_with_flags), - window, - G_CONNECT_SWAPPED); - g_signal_connect_object (window->places_sidebar, - "show-starred-location", - G_CALLBACK (places_sidebar_show_starred_location), - window, - G_CONNECT_SWAPPED); - g_signal_connect (window, "notify::is-maximized", G_CALLBACK (on_is_maximized_changed), NULL); @@ -2799,6 +2776,7 @@ nautilus_window_class_init (NautilusWindowClass *class) gtk_widget_class_bind_template_child (wclass, NautilusWindow, toolbar); gtk_widget_class_bind_template_child (wclass, NautilusWindow, content_paned); gtk_widget_class_bind_template_child (wclass, NautilusWindow, sidebar); + gtk_widget_class_bind_template_child (wclass, NautilusWindow, places_sidebar); gtk_widget_class_bind_template_child (wclass, NautilusWindow, main_view); gtk_widget_class_bind_template_child (wclass, NautilusWindow, notebook); gtk_widget_class_bind_template_child (wclass, NautilusWindow, in_app_notification_undo); @@ -2810,6 +2788,9 @@ nautilus_window_class_init (NautilusWindowClass *class) gtk_widget_class_bind_template_child (wclass, NautilusWindow, notification_operation_open); gtk_widget_class_bind_template_child (wclass, NautilusWindow, notification_operation_close); + gtk_widget_class_bind_template_callback (wclass, places_sidebar_show_other_locations_with_flags); + gtk_widget_class_bind_template_callback (wclass, places_sidebar_show_starred_location); + signals[SLOT_ADDED] = g_signal_new ("slot-added", G_TYPE_FROM_CLASS (class), diff --git a/src/resources/nautilus.gresource.xml b/src/resources/nautilus.gresource.xml index d27f7b5ff..9e129b669 100644 --- a/src/resources/nautilus.gresource.xml +++ b/src/resources/nautilus.gresource.xml @@ -26,7 +26,6 @@ <file>ui/nautilus-files-view-select-items.ui</file> <file>ui/nautilus-operations-ui-manager-request-passphrase.ui</file> <file>ui/nautilus-view-icon-item-ui.ui</file> - <file alias="gtk/ui/nautilusgtksidebarrow.ui">../gtk/nautilusgtksidebarrow.ui</file> <file alias="gtk/ui/nautilusgtkplacesview.ui">../gtk/nautilusgtkplacesview.ui</file> <file alias="gtk/ui/nautilusgtkplacesviewrow.ui">../gtk/nautilusgtkplacesviewrow.ui</file> <file alias="icons/filmholes.png">../../icons/filmholes.png</file> diff --git a/src/resources/ui/nautilus-window.ui b/src/resources/ui/nautilus-window.ui index 407014ecc..853a693ca 100644 --- a/src/resources/ui/nautilus-window.ui +++ b/src/resources/ui/nautilus-window.ui @@ -20,6 +20,17 @@ <property name="visible">False</property> <property name="orientation">vertical</property> <property name="spacing">6</property> + <child> + <object class="GtkPlacesSidebar" id="places_sidebar"> + <property name="vexpand">True</property> + <property name="visible">True</property> + <property name="populate-all">True</property> + <property name="show-other-locations">True</property> + <property name="show-starred-location">True</property> + <signal name="show-other-locations-with-flags" handler="places_sidebar_show_other_locations_with_flags" object="NautilusWindow" swapped="yes" /> + <signal name="show-starred-location" handler="places_sidebar_show_starred_location" object="NautilusWindow" swapped="yes" /> + </object> + </child> </object> <packing> <property name="resize">False</property> |