[Xfce4-commits] [xfce/thunar] 13/46: Replace our own shortcuts pane with GtkPlacesSidebar
noreply at xfce.org
noreply at xfce.org
Tue Aug 15 02:35:21 CEST 2017
This is an automated email from the git hooks/post-receive script.
a n d r e p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository xfce/thunar.
commit 858e919762e3a8d1eba4fcb1f7ae9146db892325
Author: Jonas Kümmerlin <rgcjonas at gmail.com>
Date: Sun Aug 9 18:53:05 2015 +0200
Replace our own shortcuts pane with GtkPlacesSidebar
---
po/POTFILES.in | 2 -
thunar/Makefile.am | 4 -
thunar/thunar-location-entry.c | 1 -
thunar/thunar-shortcuts-model.c | 2263 ---------------------------------------
thunar/thunar-shortcuts-model.h | 129 ---
thunar/thunar-shortcuts-pane.c | 391 ++++++-
thunar/thunar-shortcuts-view.c | 2139 ------------------------------------
thunar/thunar-shortcuts-view.h | 46 -
8 files changed, 343 insertions(+), 4632 deletions(-)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 587f917..9eddda1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -66,9 +66,7 @@ thunar/thunar-renamer-progress.c
thunar/thunar-sendto-model.c
thunar/thunar-session-client.c
thunar/thunar-shortcuts-icon-renderer.c
-thunar/thunar-shortcuts-model.c
thunar/thunar-shortcuts-pane.c
-thunar/thunar-shortcuts-view.c
thunar/thunar-side-pane.c
thunar/thunar-simple-job.c
thunar/thunar-size-label.c
diff --git a/thunar/Makefile.am b/thunar/Makefile.am
index ac6511e..4ee978e 100644
--- a/thunar/Makefile.am
+++ b/thunar/Makefile.am
@@ -171,12 +171,8 @@ thunar_SOURCES = \
thunar-session-client.h \
thunar-shortcuts-icon-renderer.c \
thunar-shortcuts-icon-renderer.h \
- thunar-shortcuts-model.c \
- thunar-shortcuts-model.h \
thunar-shortcuts-pane.c \
thunar-shortcuts-pane.h \
- thunar-shortcuts-view.c \
- thunar-shortcuts-view.h \
thunar-side-pane.c \
thunar-side-pane.h \
thunar-simple-job.c \
diff --git a/thunar/thunar-location-entry.c b/thunar/thunar-location-entry.c
index 9c101a4..20202d3 100644
--- a/thunar/thunar-location-entry.c
+++ b/thunar/thunar-location-entry.c
@@ -34,7 +34,6 @@
#include <thunar/thunar-marshal.h>
#include <thunar/thunar-path-entry.h>
#include <thunar/thunar-private.h>
-#include <thunar/thunar-shortcuts-model.h>
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
deleted file mode 100644
index ef2a5d2..0000000
--- a/thunar/thunar-shortcuts-model.c
+++ /dev/null
@@ -1,2263 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
- * Copyright (c) 2012 Nick Schermer <nick at xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <thunar/thunar-file.h>
-#include <thunar/thunar-shortcuts-model.h>
-#include <thunar/thunar-device-monitor.h>
-#include <thunar/thunar-preferences.h>
-#include <thunar/thunar-util.h>
-#include <thunar/thunar-private.h>
-
-#define SPINNER_CYCLE_DURATION 1000
-#define SPINNER_NUM_STEPS 12
-
-
-
-#define THUNAR_SHORTCUT(obj) ((ThunarShortcut *) (obj))
-
-
-
-typedef struct _ThunarShortcut ThunarShortcut;
-
-
-
-enum
-{
- PROP_0,
- PROP_HIDDEN_BOOKMARKS,
- PROP_FILE_SIZE_BINARY
-};
-
-
-
-static void thunar_shortcuts_model_tree_model_init (GtkTreeModelIface *iface);
-static void thunar_shortcuts_model_drag_source_init (GtkTreeDragSourceIface *iface);
-static void thunar_shortcuts_model_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void thunar_shortcuts_model_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void thunar_shortcuts_model_finalize (GObject *object);
-static GtkTreeModelFlags thunar_shortcuts_model_get_flags (GtkTreeModel *tree_model);
-static gint thunar_shortcuts_model_get_n_columns (GtkTreeModel *tree_model);
-static GType thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model,
- gint idx);
-static gboolean thunar_shortcuts_model_get_iter (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreePath *path);
-static GtkTreePath *thunar_shortcuts_model_get_path (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static void thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint column,
- GValue *value);
-static gboolean thunar_shortcuts_model_iter_next (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gboolean thunar_shortcuts_model_iter_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent);
-static gboolean thunar_shortcuts_model_iter_has_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gint thunar_shortcuts_model_iter_n_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gboolean thunar_shortcuts_model_iter_nth_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n);
-static gboolean thunar_shortcuts_model_iter_parent (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *child);
-static gboolean thunar_shortcuts_model_row_draggable (GtkTreeDragSource *source,
- GtkTreePath *path);
-static gboolean thunar_shortcuts_model_drag_data_get (GtkTreeDragSource *source,
- GtkTreePath *path,
- GtkSelectionData *selection_data);
-static gboolean thunar_shortcuts_model_drag_data_delete (GtkTreeDragSource *source,
- GtkTreePath *path);
-static void thunar_shortcuts_model_header_visibility (ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_shortcut_devices (ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_shortcut_places (ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_shortcut_network (ThunarShortcutsModel *model);
-static gboolean thunar_shortcuts_model_get_hidden (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut);
-static void thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut);
-static void thunar_shortcuts_model_remove_shortcut (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut);
-static gboolean thunar_shortcuts_model_load (gpointer data);
-static void thunar_shortcuts_model_save (ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_monitor (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data);
-static void thunar_shortcuts_model_file_changed (ThunarFile *file,
- ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_file_destroy (ThunarFile *file,
- ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_device_added (ThunarDeviceMonitor *device_monitor,
- ThunarDevice *device,
- ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_device_removed (ThunarDeviceMonitor *device_monitor,
- ThunarDevice *device,
- ThunarShortcutsModel *model);
-static void thunar_shortcuts_model_device_changed (ThunarDeviceMonitor *device_monitor,
- ThunarDevice *device,
- ThunarShortcutsModel *model);
-
-static void thunar_shortcut_free (ThunarShortcut *shortcut,
- ThunarShortcutsModel *model);
-
-
-
-struct _ThunarShortcutsModelClass
-{
- GObjectClass __parent__;
-};
-
-struct _ThunarShortcutsModel
-{
- GObject __parent__;
-
- /* the model stamp is only used when debugging is
- * enabled, to make sure we don't accept iterators
- * generated by another model.
- */
-#ifndef NDEBUG
- gint stamp;
-#endif
-
- GList *shortcuts;
-
- ThunarPreferences *preferences;
- gchar **hidden_bookmarks;
- gboolean file_size_binary;
-
- ThunarDeviceMonitor *device_monitor;
-
- gint64 bookmarks_time;
- GFile *bookmarks_file;
- GFileMonitor *bookmarks_monitor;
- guint bookmarks_idle_id;
-
- guint busy_timeout_id;
-};
-
-struct _ThunarShortcut
-{
- ThunarShortcutGroup group;
-
- gchar *name;
- GIcon *gicon;
- gchar *tooltip;
- gint sort_id;
-
- guint busy : 1;
- guint busy_pulse;
-
- GFile *location;
- ThunarFile *file;
- ThunarDevice *device;
-
- guint hidden : 1;
-};
-
-
-
-G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsModel, thunar_shortcuts_model, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, thunar_shortcuts_model_tree_model_init)
- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE, thunar_shortcuts_model_drag_source_init))
-
-
-
-static void
-thunar_shortcuts_model_class_init (ThunarShortcutsModelClass *klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = thunar_shortcuts_model_finalize;
- gobject_class->get_property = thunar_shortcuts_model_get_property;
- gobject_class->set_property = thunar_shortcuts_model_set_property;
-
- g_object_class_install_property (gobject_class,
- PROP_HIDDEN_BOOKMARKS,
- g_param_spec_boxed ("hidden-bookmarks",
- NULL,
- NULL,
- G_TYPE_STRV,
- EXO_PARAM_READWRITE));
-
- /**
- * ThunarPropertiesDialog:file_size_binary:
- *
- * Whether the file size should be shown in binary or decimal.
- **/
- g_object_class_install_property (gobject_class,
- PROP_FILE_SIZE_BINARY,
- g_param_spec_boolean ("file-size-binary",
- "FileSizeBinary",
- NULL,
- FALSE,
- EXO_PARAM_READWRITE));
-}
-
-
-
-static void
-thunar_shortcuts_model_tree_model_init (GtkTreeModelIface *iface)
-{
- iface->get_flags = thunar_shortcuts_model_get_flags;
- iface->get_n_columns = thunar_shortcuts_model_get_n_columns;
- iface->get_column_type = thunar_shortcuts_model_get_column_type;
- iface->get_iter = thunar_shortcuts_model_get_iter;
- iface->get_path = thunar_shortcuts_model_get_path;
- iface->get_value = thunar_shortcuts_model_get_value;
- iface->iter_next = thunar_shortcuts_model_iter_next;
- iface->iter_children = thunar_shortcuts_model_iter_children;
- iface->iter_has_child = thunar_shortcuts_model_iter_has_child;
- iface->iter_n_children = thunar_shortcuts_model_iter_n_children;
- iface->iter_nth_child = thunar_shortcuts_model_iter_nth_child;
- iface->iter_parent = thunar_shortcuts_model_iter_parent;
-}
-
-
-
-static void
-thunar_shortcuts_model_drag_source_init (GtkTreeDragSourceIface *iface)
-{
- iface->row_draggable = thunar_shortcuts_model_row_draggable;
- iface->drag_data_get = thunar_shortcuts_model_drag_data_get;
- iface->drag_data_delete = thunar_shortcuts_model_drag_data_delete;
-}
-
-
-
-static void
-thunar_shortcuts_model_init (ThunarShortcutsModel *model)
-{
-#ifndef NDEBUG
- model->stamp = g_random_int ();
-#endif
-
- /* hidden bookmarks */
- model->preferences = thunar_preferences_get ();
- exo_binding_new (G_OBJECT (model->preferences), "hidden-bookmarks",
- G_OBJECT (model), "hidden-bookmarks");
-
- /* binary file size */
- exo_binding_new (G_OBJECT (model->preferences), "misc-file-size-binary",
- G_OBJECT (model), "file-size-binary");
-
- /* load volumes */
- thunar_shortcuts_model_shortcut_devices (model);
-
- /* add network */
- thunar_shortcuts_model_shortcut_network (model);
-
- /* add bookmarks */
- thunar_shortcuts_model_shortcut_places (model);
-}
-
-
-
-static void
-thunar_shortcuts_model_finalize (GObject *object)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (object);
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- /* stop the busy timeout */
- if (model->busy_timeout_id != 0)
- g_source_remove (model->busy_timeout_id);
-
- /* stop bookmark load idle */
- if (model->bookmarks_idle_id != 0)
- g_source_remove (model->bookmarks_idle_id);
-
- /* free all shortcuts */
- g_list_foreach (model->shortcuts, (GFunc) thunar_shortcut_free, model);
- g_list_free (model->shortcuts);
-
- /* disconnect from the preferences */
- g_object_unref (model->preferences);
-
- /* free hidden list */
- g_strfreev (model->hidden_bookmarks);
-
- /* detach from the file monitor */
- if (model->bookmarks_monitor != NULL)
- {
- g_file_monitor_cancel (model->bookmarks_monitor);
- g_object_unref (model->bookmarks_monitor);
- }
-
- if (model->bookmarks_file != NULL)
- g_object_unref (model->bookmarks_file);
-
- /* unlink from the device monitor */
- g_signal_handlers_disconnect_matched (model->device_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
- g_object_unref (model->device_monitor);
-
- (*G_OBJECT_CLASS (thunar_shortcuts_model_parent_class)->finalize) (object);
-}
-
-
-
-static void
-thunar_shortcuts_model_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (object);
-
- switch (prop_id)
- {
- case PROP_HIDDEN_BOOKMARKS:
- g_value_set_boxed (value, model->hidden_bookmarks);
- break;
-
- case PROP_FILE_SIZE_BINARY:
- g_value_set_boolean (value, model->file_size_binary);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-thunar_shortcuts_model_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (object);
- GList *lp;
- ThunarShortcut *shortcut;
- gboolean hidden;
- GtkTreeIter iter;
- GtkTreePath *path;
- guint idx;
-
- switch (prop_id)
- {
- case PROP_HIDDEN_BOOKMARKS:
- g_strfreev (model->hidden_bookmarks);
- model->hidden_bookmarks = g_value_dup_boxed (value);
-
- /* update shortcuts */
- for (lp = model->shortcuts, idx = 0; lp != NULL; lp = lp->next, idx++)
- {
- shortcut = lp->data;
-
- /* skip devices and headers*/
- if (shortcut->device != NULL
- || (shortcut->file == NULL && shortcut->location == NULL))
- continue;
-
- /* update state if required */
- hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- if (shortcut->hidden != hidden)
- {
- shortcut->hidden = hidden;
-
- GTK_TREE_ITER_INIT (iter, model->stamp, lp);
-
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
- }
- }
-
- /* update header visibility */
- thunar_shortcuts_model_header_visibility (model);
- break;
-
- case PROP_FILE_SIZE_BINARY:
- model->file_size_binary = g_value_get_boolean (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static GtkTreeModelFlags
-thunar_shortcuts_model_get_flags (GtkTreeModel *tree_model)
-{
- return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY;
-}
-
-
-
-static gint
-thunar_shortcuts_model_get_n_columns (GtkTreeModel *tree_model)
-{
- return THUNAR_SHORTCUTS_MODEL_N_COLUMNS;
-}
-
-
-
-static GType
-thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model,
- gint idx)
-{
- switch (idx)
- {
- case THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER:
- return G_TYPE_BOOLEAN;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM:
- return G_TYPE_BOOLEAN;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
- return G_TYPE_BOOLEAN;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
- return G_TYPE_STRING;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_TOOLTIP:
- return G_TYPE_STRING;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_FILE:
- return THUNAR_TYPE_FILE;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION:
- return G_TYPE_FILE;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_GICON:
- return G_TYPE_ICON;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE:
- return THUNAR_TYPE_DEVICE;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE:
- return G_TYPE_BOOLEAN;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT:
- return G_TYPE_BOOLEAN;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_GROUP:
- return G_TYPE_UINT;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY:
- return G_TYPE_BOOLEAN;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE:
- return G_TYPE_UINT;
- }
-
- _thunar_assert_not_reached ();
- return G_TYPE_INVALID;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_get_iter (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreePath *path)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
- GList *lp;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- _thunar_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
-
- /* determine the list item for the path */
- lp = g_list_nth (model->shortcuts, gtk_tree_path_get_indices (path)[0]);
- if (G_LIKELY (lp != NULL))
- {
- GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-
-static GtkTreePath*
-thunar_shortcuts_model_get_path (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
- gint idx;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), NULL);
- _thunar_return_val_if_fail (iter->stamp == model->stamp, NULL);
-
- /* lookup the list item in the shortcuts list */
- idx = g_list_position (model->shortcuts, iter->user_data);
- if (G_LIKELY (idx >= 0))
- return gtk_tree_path_new_from_indices (idx, -1);
-
- return NULL;
-}
-
-
-
-static void
-thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint column,
- GValue *value)
-{
- ThunarShortcut *shortcut;
- gboolean can_eject;
- GFile *file;
- gchar *disk_usage;
- guint32 trash_items;
- gchar *trash_string;
- gchar *parse_name;
- gboolean file_size_binary;
-
- _thunar_return_if_fail (iter->stamp == THUNAR_SHORTCUTS_MODEL (tree_model)->stamp);
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (tree_model));
-
- /* determine the shortcut for the list item */
- shortcut = THUNAR_SHORTCUT (((GList *) iter->user_data)->data);
- if (shortcut == NULL)
- return;
-
- switch (column)
- {
- case THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER:
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, (shortcut->group & THUNAR_SHORTCUT_GROUP_HEADER) != 0);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM:
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, (shortcut->group & THUNAR_SHORTCUT_GROUP_HEADER) == 0);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, !shortcut->hidden);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
- g_value_init (value, G_TYPE_STRING);
- if (G_UNLIKELY (shortcut->device != NULL))
- g_value_take_string (value, thunar_device_get_name (shortcut->device));
- else if (shortcut->name != NULL)
- g_value_set_static_string (value, shortcut->name);
- else if (shortcut->file != NULL)
- g_value_set_static_string (value, thunar_file_get_display_name (shortcut->file));
- else if (shortcut->location != NULL)
- g_value_take_string (value, thunar_g_file_get_display_name_remote (shortcut->location));
- else
- g_value_set_static_string (value, "");
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_TOOLTIP:
- g_value_init (value, G_TYPE_STRING);
- if ((shortcut->group & THUNAR_SHORTCUT_GROUP_DEVICES) != 0)
- {
- if (shortcut->device != NULL)
- file = thunar_device_get_root (shortcut->device);
- else if (shortcut->file != NULL)
- file = g_object_ref (thunar_file_get_file (shortcut->file));
- else
- file = NULL;
-
- if (file != NULL)
- {
- file_size_binary = THUNAR_SHORTCUTS_MODEL (tree_model)->file_size_binary;
- disk_usage = thunar_g_file_get_free_space_string (file, file_size_binary);
- g_object_unref (file);
- g_value_take_string (value, disk_usage);
- }
- break;
- }
- else if ((shortcut->group & THUNAR_SHORTCUT_GROUP_PLACES_TRASH) != 0)
- {
- trash_items = thunar_file_get_item_count (shortcut->file);
- if (trash_items == 0)
- {
- g_value_set_static_string (value, _("Trash is empty"));
- }
- else
- {
- trash_string = g_strdup_printf (ngettext ("Trash contains %d file",
- "Trash contains %d files",
- trash_items), trash_items);
- g_value_take_string (value, trash_string);
- }
- break;
- }
- else if (shortcut->tooltip == NULL)
- {
- if (shortcut->file != NULL)
- file = thunar_file_get_file (shortcut->file);
- else if (shortcut->location != NULL)
- file = shortcut->location;
- else
- file = NULL;
-
- if (G_LIKELY (file != NULL))
- {
- parse_name = g_file_get_parse_name (file);
- shortcut->tooltip = g_markup_escape_text (parse_name, -1);
- g_free (parse_name);
- }
- }
-
- g_value_set_static_string (value, shortcut->tooltip);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_FILE:
- g_value_init (value, THUNAR_TYPE_FILE);
- g_value_set_object (value, shortcut->file);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_GICON:
- g_value_init (value, G_TYPE_ICON);
- g_value_set_object (value, shortcut->gicon);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE:
- g_value_init (value, THUNAR_TYPE_DEVICE);
- g_value_set_object (value, shortcut->device);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION:
- g_value_init (value, G_TYPE_FILE);
- if (shortcut->location != NULL)
- g_value_set_object (value, shortcut->location);
- else if (shortcut->file != NULL)
- g_value_set_object (value, thunar_file_get_file (shortcut->file));
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE:
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value,
- shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT:
- if (shortcut->device != NULL)
- can_eject = thunar_device_can_eject (shortcut->device);
- else
- can_eject = FALSE;
-
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, can_eject);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_GROUP:
- g_value_init (value, G_TYPE_UINT);
- g_value_set_uint (value, shortcut->group);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY:
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, shortcut->busy);
- break;
-
- case THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE:
- g_value_init (value, G_TYPE_UINT);
- g_value_set_uint (value, shortcut->busy_pulse);
- break;
-
- default:
- _thunar_assert_not_reached ();
- }
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_iter_next (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (tree_model), FALSE);
- _thunar_return_val_if_fail (iter->stamp == THUNAR_SHORTCUTS_MODEL (tree_model)->stamp, FALSE);
-
- iter->user_data = g_list_next (iter->user_data);
- return (iter->user_data != NULL);
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_iter_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
-
- if (G_LIKELY (parent == NULL && model->shortcuts != NULL))
- {
- GTK_TREE_ITER_INIT (*iter, model->stamp, model->shortcuts);
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_iter_has_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- return FALSE;
-}
-
-
-
-static gint
-thunar_shortcuts_model_iter_n_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), 0);
-
- return (iter == NULL) ? g_list_length (model->shortcuts) : 0;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_iter_nth_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
-
- if (G_LIKELY (parent == NULL))
- {
- GTK_TREE_ITER_INIT (*iter, model->stamp, g_list_nth (model->shortcuts, n));
- return (iter->user_data != NULL);
- }
-
- return FALSE;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_iter_parent (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *child)
-{
- return FALSE;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_row_draggable (GtkTreeDragSource *source,
- GtkTreePath *path)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (source);
- ThunarShortcut *shortcut;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- _thunar_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
-
- /* lookup the ThunarShortcut for the path */
- shortcut = g_list_nth_data (model->shortcuts, gtk_tree_path_get_indices (path)[0]);
-
- /* special shortcuts cannot be reordered */
- return (shortcut != NULL && shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_drag_data_get (GtkTreeDragSource *source,
- GtkTreePath *path,
- GtkSelectionData *selection_data)
-{
- /* we simply return FALSE here, as the drag handling is done in
- * the ThunarShortcutsView class.
- */
- return FALSE;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_drag_data_delete (GtkTreeDragSource *source,
- GtkTreePath *path)
-{
- /* we simply return FALSE here, as this function can only be
- * called if the user is re-arranging shortcuts within the
- * model, which will be handle by the exchange method.
- */
- return FALSE;
-}
-
-
-
-static void
-thunar_shortcuts_model_header_visibility (ThunarShortcutsModel *model)
-{
- GList *lp;
- ThunarShortcut *shortcut;
- ThunarShortcut *header;
- guint n_children = 0;
- GList *lp_header = NULL;
- gint idx_header = 0;
- gint i;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- for (lp = model->shortcuts, i = 0; lp != NULL; lp = lp->next, i++)
- {
- shortcut = lp->data;
-
- if ((shortcut->group & THUNAR_SHORTCUT_GROUP_HEADER) != 0)
- {
- if (lp_header != NULL)
- {
- update_header:
-
- header = lp_header->data;
- if (header->hidden != (n_children == 0))
- {
- /* set new visibility */
- header->hidden = (n_children == 0);
-
- /* notify view */
- path = gtk_tree_path_new_from_indices (idx_header, -1);
- GTK_TREE_ITER_INIT (iter, model->stamp, lp_header);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
- }
-
- if (lp == NULL)
- return;
- }
-
- /* reset for new */
- idx_header = i;
- lp_header = lp;
- n_children = 0;
- }
- else if (!shortcut->hidden)
- {
- n_children++;
- }
- }
-
- _thunar_assert (lp == NULL);
- if (lp_header != NULL)
- goto update_header;
-}
-
-
-
-static void
-thunar_shortcuts_model_shortcut_devices (ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut;
- GList *devices;
- GList *lp;
-
- /* add the devices heading */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES_HEADER;
- shortcut->name = g_strdup (_("DEVICES"));
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* the filesystem entry */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES_FILESYSTEM;
- shortcut->name = g_strdup (_("File System"));
- shortcut->file = thunar_file_get_for_uri ("file:///", NULL);
- shortcut->gicon = g_themed_icon_new ("drive-harddisk");
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* connect to the device monitor */
- model->device_monitor = thunar_device_monitor_get ();
-
- /* get a list of all devices available */
- devices = thunar_device_monitor_get_devices (model->device_monitor);
- for (lp = devices; lp != NULL; lp = lp->next)
- {
- thunar_shortcuts_model_device_added (NULL, lp->data, model);
- g_object_unref (G_OBJECT (lp->data));
- }
- g_list_free (devices);
-
- /* monitor for changes */
- g_signal_connect (model->device_monitor, "device-added", G_CALLBACK (thunar_shortcuts_model_device_added), model);
- g_signal_connect (model->device_monitor, "device-removed", G_CALLBACK (thunar_shortcuts_model_device_removed), model);
- g_signal_connect (model->device_monitor, "device-changed", G_CALLBACK (thunar_shortcuts_model_device_changed), model);
-
- thunar_shortcuts_model_header_visibility (model);
-}
-
-
-
-static void
-thunar_shortcuts_model_shortcut_network (ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut;
-
- /* add the network heading */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_NETWORK_HEADER;
- shortcut->name = g_strdup (_("NETWORK"));
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* the browse network entry */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_NETWORK_DEFAULT;
- shortcut->name = g_strdup (_("Browse Network"));
- shortcut->location = g_file_new_for_uri ("network://");
- shortcut->gicon = g_themed_icon_new ("network-workgroup");
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-}
-
-
-
-static void
-thunar_shortcuts_model_shortcut_places (ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut;
- GFile *home;
- GFile *desktop;
- GFile *trash;
- ThunarFile *file;
-
- /* add the places heading */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_HEADER;
- shortcut->name = g_strdup (_("PLACES"));
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* get home path */
- home = thunar_g_file_new_for_home ();
-
- /* add home entry */
- file = thunar_file_get (home, NULL);
- if (file != NULL)
- {
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_DEFAULT;
- shortcut->file = file;
- shortcut->gicon = g_themed_icon_new ("go-home");
- shortcut->sort_id = 0;
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
-
- /* add desktop entry */
- desktop = thunar_g_file_new_for_desktop ();
- if (!g_file_equal (desktop, home))
- {
- file = thunar_file_get (desktop, NULL);
- if (file != NULL)
- {
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_DEFAULT;
- shortcut->file = file;
- shortcut->sort_id = 1;
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
- }
- g_object_unref (desktop);
- g_object_unref (home);
-
- /* append the trash icon if the trash is supported */
- if (thunar_g_vfs_is_uri_scheme_supported ("trash"))
- {
- trash = thunar_g_file_new_for_trash ();
- file = thunar_file_get (trash, NULL);
- g_object_unref (trash);
-
- if (file != NULL)
- {
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_TRASH;
- shortcut->file = file;
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
- }
-
- /* determine the URI to the Gtk+ bookmarks file */
- model->bookmarks_file = thunar_g_file_new_for_bookmarks ();
-
- /* register with the alteration monitor for the bookmarks file */
- model->bookmarks_monitor = g_file_monitor_file (model->bookmarks_file, G_FILE_MONITOR_NONE, NULL, NULL);
- if (G_LIKELY (model->bookmarks_monitor != NULL))
- {
- g_signal_connect (model->bookmarks_monitor, "changed",
- G_CALLBACK (thunar_shortcuts_model_monitor), model);
- }
-
- /* read the Gtk+ bookmarks file */
- model->bookmarks_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, thunar_shortcuts_model_load, model, NULL);
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_get_hidden (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut)
-{
- gchar *uri;
- guint n;
- gboolean hidden = FALSE;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- _thunar_return_val_if_fail (shortcut->device == NULL, FALSE);
-
- if (model->hidden_bookmarks == NULL)
- return FALSE;
-
- /* get the uri */
- if (shortcut->file != NULL)
- uri = thunar_file_dup_uri (shortcut->file);
- else if (shortcut->location != NULL)
- uri = g_file_get_uri (shortcut->location);
- else
- _thunar_assert_not_reached ();
-
- if (uri == NULL)
- return FALSE;
-
- for (n = 0; !hidden && model->hidden_bookmarks[n] != NULL; n++)
- hidden = (g_strcmp0 (model->hidden_bookmarks[n], uri) == 0);
-
- g_free (uri);
-
- return hidden;
-}
-
-
-
-static gint
-thunar_shortcuts_model_sort_func (gconstpointer shortcut_a,
- gconstpointer shortcut_b)
-{
- const ThunarShortcut *a = shortcut_a;
- const ThunarShortcut *b = shortcut_b;
-
- /* sort groups */
- if (a->group != b->group)
- return a->group - b->group;
-
- /* use sort order */
- if (a->sort_id != b->sort_id)
- return a->sort_id > b->sort_id ? 1 : -1;
-
- /* properly sort devices by timestamp */
- if (a->device != NULL && b->device != NULL)
- return thunar_device_sort (a->device, b->device);
-
- return g_strcmp0 (a->name, b->name);
-}
-
-
-
-static void
-thunar_shortcuts_model_add_shortcut_with_path (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut,
- GtkTreePath *path)
-{
- GtkTreeIter iter;
- GtkTreePath *sorted_path = NULL;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (shortcut->file == NULL || THUNAR_IS_FILE (shortcut->file));
-
- /* we want to stay informed about changes to the file */
- if (G_LIKELY (shortcut->file != NULL))
- {
- /* watch the file for changes */
- thunar_file_watch (shortcut->file);
-
- /* connect appropriate signals */
- g_signal_connect (G_OBJECT (shortcut->file), "changed",
- G_CALLBACK (thunar_shortcuts_model_file_changed), model);
- g_signal_connect (G_OBJECT (shortcut->file), "destroy",
- G_CALLBACK (thunar_shortcuts_model_file_destroy), model);
- }
-
- if (path == NULL)
- {
- /* insert the new shortcut to the shortcuts list */
- model->shortcuts = g_list_insert_sorted (model->shortcuts, shortcut, thunar_shortcuts_model_sort_func);
- sorted_path = gtk_tree_path_new_from_indices (g_list_index (model->shortcuts, shortcut), -1);
- path = sorted_path;
- }
- else
- {
- model->shortcuts = g_list_insert (model->shortcuts, shortcut, gtk_tree_path_get_indices (path)[0]);
- }
-
- /* tell everybody that we have a new shortcut */
- gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
-
- if (sorted_path)
- gtk_tree_path_free (sorted_path);
-}
-
-
-
-static void
-thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut)
-{
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (shortcut->file == NULL || THUNAR_IS_FILE (shortcut->file));
-
- thunar_shortcuts_model_add_shortcut_with_path (model, shortcut, NULL);
-}
-
-
-
-static void
-thunar_shortcuts_model_remove_shortcut (ThunarShortcutsModel *model,
- ThunarShortcut *shortcut)
-{
- GtkTreePath *path;
- gint idx;
- gboolean needs_save;
-
- /* determine the index of the shortcut */
- idx = g_list_index (model->shortcuts, shortcut);
- if (G_LIKELY (idx >= 0))
- {
- /* unlink the shortcut from the model */
- model->shortcuts = g_list_remove (model->shortcuts, shortcut);
-
- /* tell everybody that we have lost a shortcut */
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
- gtk_tree_path_free (path);
-
- /* check if we need to save */
- needs_save = (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
-
- /* actually free the shortcut */
- thunar_shortcut_free (shortcut, model);
-
- /* the shortcuts list was changed, so write the gtk bookmarks file */
- if (needs_save)
- thunar_shortcuts_model_save (model);
-
- /* update header visibility */
- thunar_shortcuts_model_header_visibility (model);
- }
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_local_file (GFile *gfile)
-{
- _thunar_return_val_if_fail (G_IS_FILE (gfile), FALSE);
-
- /* schemes we'd like to have as ThunarFiles in the model */
- if (g_file_has_uri_scheme (gfile, "file")
- || g_file_has_uri_scheme (gfile, "computer")
- || g_file_has_uri_scheme (gfile, "recent"))
- return TRUE;
-
- return FALSE;
-}
-
-
-
-static void
-thunar_shortcuts_model_load_line (GFile *file_path,
- const gchar *name,
- gint row_num,
- gpointer user_data)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
- ThunarShortcut *shortcut;
- ThunarFile *file;
-
- _thunar_return_if_fail (G_IS_FILE (file_path));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
-
- /* handle local and remove files differently */
- if (thunar_shortcuts_model_local_file (file_path))
- {
- /* try to open the file corresponding to the uri */
- file = thunar_file_get (file_path, NULL);
- if (G_UNLIKELY (file == NULL))
- return;
-
- /* make sure the file refers to a directory */
- if (G_UNLIKELY (thunar_file_is_directory (file)))
- {
- /* create the shortcut entry */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
- shortcut->file = file;
- shortcut->sort_id = row_num;
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- shortcut->name = g_strdup (name);
-
- /* append the shortcut to the list */
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
- else
- {
- g_object_unref (file);
- }
- }
- else
- {
- /* create the shortcut entry */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
- shortcut->gicon = g_themed_icon_new ("folder-remote");
- shortcut->location = g_object_ref (file_path);
- shortcut->sort_id = row_num;
- shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
- shortcut->name = g_strdup (name);
-
- /* append the shortcut to the list */
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_load (gpointer data)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (data);
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
-
- GDK_THREADS_ENTER ();
-
- /* parse the bookmarks */
- thunar_util_load_bookmarks (model->bookmarks_file,
- thunar_shortcuts_model_load_line,
- model);
-
- /* update the visibility */
- thunar_shortcuts_model_header_visibility (model);
-
- GDK_THREADS_LEAVE ();
-
- model->bookmarks_idle_id = 0;
-
- return FALSE;
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_reload (gpointer data)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (data);
- ThunarShortcut *shortcut;
- GtkTreePath *path;
- GList *lp;
- gint idx;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
-
- GDK_THREADS_ENTER ();
-
- /* drop all existing user-defined shortcuts from the model */
- for (idx = 0, lp = model->shortcuts; lp != NULL; )
- {
- /* grab the shortcut */
- shortcut = THUNAR_SHORTCUT (lp->data);
-
- /* advance to the next list item */
- lp = g_list_next (lp);
-
- /* drop the shortcut if it is user-defined */
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
- {
- /* unlink the shortcut from the model */
- model->shortcuts = g_list_remove (model->shortcuts, shortcut);
-
- /* tell everybody that we have lost a shortcut */
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
- gtk_tree_path_free (path);
-
- /* actually free the shortcut */
- thunar_shortcut_free (shortcut, model);
- }
- else
- {
- ++idx;
- }
- }
-
- GDK_THREADS_LEAVE ();
-
- /* load new bookmarks */
- return thunar_shortcuts_model_load (data);
-}
-
-
-
-static void
-thunar_shortcuts_model_monitor (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (model->bookmarks_monitor == monitor);
-
- /* leave if we saved less than 2 seconds ago */
- if (model->bookmarks_time + 2 * G_USEC_PER_SEC > g_get_real_time ())
- return;
-
- /* reload the shortcuts model */
- if (model->bookmarks_idle_id == 0)
- model->bookmarks_idle_id = g_idle_add (thunar_shortcuts_model_reload, model);
-}
-
-
-
-static void
-thunar_shortcuts_model_save (ThunarShortcutsModel *model)
-{
- GString *contents;
- ThunarShortcut *shortcut;
- gchar *bookmarks_path;
- gchar *uri;
- GList *lp;
- GError *err = NULL;
- GFile *parent = NULL;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- contents = g_string_new (NULL);
-
- for (lp = model->shortcuts; lp != NULL; lp = lp->next)
- {
- shortcut = THUNAR_SHORTCUT (lp->data);
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
- {
- if (shortcut->file != NULL)
- uri = thunar_file_dup_uri (shortcut->file);
- else if (shortcut->location != NULL)
- uri = g_file_get_uri (shortcut->location);
- else
- continue;
-
- if (G_LIKELY (shortcut->name != NULL))
- g_string_append_printf (contents, "%s %s\n", uri, shortcut->name);
- else
- g_string_append_printf (contents, "%s\n", uri);
- g_free (uri);
- }
- }
-
- /* create folder if it does not exist */
- parent = g_file_get_parent (model->bookmarks_file);
- if (!g_file_make_directory_with_parents (parent, NULL, &err))
- {
- if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_EXISTS))
- {
- g_clear_error (&err);
- }
- else
- {
- g_warning ("Failed to create bookmarks folder: %s", err->message);
- g_error_free (err);
- }
- }
- g_clear_object (&parent);
-
- /* write data to the disk */
- bookmarks_path = g_file_get_path (model->bookmarks_file);
- if (!g_file_set_contents (bookmarks_path, contents->str, contents->len, &err))
- {
- g_warning ("Failed to write \"%s\": %s", bookmarks_path, err->message);
- g_error_free (err);
- }
- g_free (bookmarks_path);
- g_string_free (contents, TRUE);
-
- /* store the save time */
- model->bookmarks_time = g_get_real_time ();
-}
-
-
-
-static void
-thunar_shortcuts_model_file_changed (ThunarFile *file,
- ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut;
- GtkTreePath *path;
- GtkTreeIter iter;
- GList *lp;
- gint idx;
-
- _thunar_return_if_fail (THUNAR_IS_FILE (file));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- /* check if the file still refers to a directory or a not mounted URI,
- * otherwise we cannot keep it on the shortcuts list, and so we'll treat
- * it like the file was destroyed (and thereby removed) */
-
- if (G_UNLIKELY (!thunar_file_is_directory (file)))
- {
- thunar_shortcuts_model_file_destroy (file, model);
- return;
- }
-
- for (idx = 0, lp = model->shortcuts; lp != NULL; ++idx, lp = lp->next)
- {
- shortcut = THUNAR_SHORTCUT (lp->data);
- if (shortcut->file == file)
- {
- GTK_TREE_ITER_INIT (iter, model->stamp, lp);
-
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
- break;
- }
- }
-}
-
-
-
-static void
-thunar_shortcuts_model_file_destroy (ThunarFile *file,
- ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut = NULL;
- GList *lp;
-
- _thunar_return_if_fail (THUNAR_IS_FILE (file));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- /* lookup the shortcut matching the file */
- for (lp = model->shortcuts; lp != NULL; lp = lp->next)
- {
- shortcut = THUNAR_SHORTCUT (lp->data);
- if (shortcut->file == file)
- break;
- }
-
- /* verify that we actually found a shortcut */
- _thunar_assert (lp != NULL);
- _thunar_assert (THUNAR_IS_FILE (shortcut->file));
-
- /* drop the shortcut from the model */
- thunar_shortcuts_model_remove_shortcut (model, shortcut);
-}
-
-
-
-static void
-thunar_shortcuts_model_device_added (ThunarDeviceMonitor *device_monitor,
- ThunarDevice *device,
- ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut;
-
- _thunar_return_if_fail (device_monitor == NULL || THUNAR_DEVICE_MONITOR (device_monitor));
- _thunar_return_if_fail (device_monitor == NULL || model->device_monitor == device_monitor);
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- /* allocate a new shortcut */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->device = g_object_ref (device);
- shortcut->hidden = thunar_device_get_hidden (device);
-
- switch (thunar_device_get_kind (device))
- {
- case THUNAR_DEVICE_KIND_VOLUME:
- shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES_VOLUMES;
- break;
-
- case THUNAR_DEVICE_KIND_MOUNT_LOCAL:
- shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES_MOUNTS;
- break;
-
- case THUNAR_DEVICE_KIND_MOUNT_REMOTE:
- shortcut->group = THUNAR_SHORTCUT_GROUP_NETWORK_MOUNTS;
- break;
- }
-
- /* insert in the model */
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* header visibility if call is from monitor */
- if (device_monitor != NULL
- && !shortcut->hidden)
- thunar_shortcuts_model_header_visibility (model);
-}
-
-
-
-static void
-thunar_shortcuts_model_device_removed (ThunarDeviceMonitor *device_monitor,
- ThunarDevice *device,
- ThunarShortcutsModel *model)
-{
- GList *lp;
-
- _thunar_return_if_fail (THUNAR_DEVICE_MONITOR (device_monitor));
- _thunar_return_if_fail (model->device_monitor == device_monitor);
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- /* find the shortcut */
- for (lp = model->shortcuts; lp != NULL; lp = lp->next)
- if (THUNAR_SHORTCUT (lp->data)->device == device)
- break;
-
- /* something is broken if we don't have a shortcut here */
- _thunar_assert (lp != NULL);
- _thunar_assert (THUNAR_SHORTCUT (lp->data)->device == device);
-
- /* drop the shortcut from the model */
- if (G_LIKELY (lp != NULL))
- thunar_shortcuts_model_remove_shortcut (model, lp->data);
-}
-
-
-
-static void
-thunar_shortcuts_model_device_changed (ThunarDeviceMonitor *device_monitor,
- ThunarDevice *device,
- ThunarShortcutsModel *model)
-{
- GtkTreeIter iter;
- GList *lp;
- gint idx;
- GtkTreePath *path;
- ThunarShortcut *shortcut;
- gboolean update_header = FALSE;
-
- _thunar_return_if_fail (THUNAR_DEVICE_MONITOR (device_monitor));
- _thunar_return_if_fail (model->device_monitor == device_monitor);
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- /* find the shortcut */
- for (lp = model->shortcuts, idx = 0; lp != NULL; lp = lp->next, idx++)
- if (THUNAR_SHORTCUT (lp->data)->device == device)
- break;
-
- /* something is broken if we don't have a shortcut here */
- _thunar_assert (lp != NULL);
- _thunar_assert (THUNAR_SHORTCUT (lp->data)->device == device);
-
- if (G_LIKELY (lp != NULL))
- {
- shortcut = lp->data;
-
- /* cleanup tooltip */
- g_free (shortcut->tooltip);
- shortcut->tooltip = NULL;
-
- /* hidden state */
- if (shortcut->hidden != thunar_device_get_hidden (device))
- {
- shortcut->hidden = thunar_device_get_hidden (device);
- update_header = TRUE;
- }
-
- /* generate an iterator for the path */
- GTK_TREE_ITER_INIT (iter, model->stamp, lp);
-
- /* tell the view that the volume has changed in some way */
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
- }
-
- /* header visibility */
- if (update_header)
- thunar_shortcuts_model_header_visibility (model);
-}
-
-
-
-static void
-thunar_shortcut_free (ThunarShortcut *shortcut,
- ThunarShortcutsModel *model)
-{
- if (G_LIKELY (shortcut->file != NULL))
- {
- /* drop the file watch */
- thunar_file_unwatch (shortcut->file);
-
- /* unregister from the file */
- g_signal_handlers_disconnect_matched (shortcut->file,
- G_SIGNAL_MATCH_DATA, 0,
- 0, NULL, NULL, model);
- g_object_unref (shortcut->file);
- }
-
- if (G_LIKELY (shortcut->device != NULL))
- g_object_unref (shortcut->device);
-
- if (G_LIKELY (shortcut->gicon != NULL))
- g_object_unref (shortcut->gicon);
-
- if (G_LIKELY (shortcut->location != NULL))
- g_object_unref (shortcut->location);
-
- g_free (shortcut->name);
- g_free (shortcut->tooltip);
-
- /* release the shortcut itself */
- g_slice_free (ThunarShortcut, shortcut);
-}
-
-
-
-static gboolean
-thunar_shortcuts_model_busy_timeout (gpointer data)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (data);
- gboolean keep_running = FALSE;
- ThunarShortcut *shortcut;
- GtkTreePath *path;
- guint idx;
- GtkTreeIter iter;
- GList *lp;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (data), FALSE);
-
- for (lp = model->shortcuts, idx = 0; lp != NULL; lp = lp->next, idx++)
- {
- shortcut = lp->data;
- if (!shortcut->busy)
- continue;
-
- /* loop the pulse of the shortcut */
- shortcut->busy_pulse++;
- if (shortcut->busy_pulse >= SPINNER_NUM_STEPS)
- shortcut->busy_pulse = 0;
-
- /* generate an iterator for the path */
- GTK_TREE_ITER_INIT (iter, model->stamp, lp);
-
- /* notify the views about the change */
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
-
- /* keep the timeout running */
- keep_running = TRUE;
- }
-
- return keep_running;
-}
-
-
-
-static void
-thunar_shortcuts_model_busy_timeout_destroyed (gpointer data)
-{
- THUNAR_SHORTCUTS_MODEL (data)->busy_timeout_id = 0;
-}
-
-
-
-/**
- * thunar_shortcuts_model_get_default:
- *
- * Returns the default #ThunarShortcutsModel instance shared by
- * all #ThunarShortcutsView instances.
- *
- * Call #g_object_unref() on the returned object when you
- * don't need it any longer.
- *
- * Return value: the default #ThunarShortcutsModel instance.
- **/
-ThunarShortcutsModel*
-thunar_shortcuts_model_get_default (void)
-{
- static ThunarShortcutsModel *model = NULL;
-
- if (G_UNLIKELY (model == NULL))
- {
- model = g_object_new (THUNAR_TYPE_SHORTCUTS_MODEL, NULL);
- g_object_add_weak_pointer (G_OBJECT (model), (gpointer) &model);
- }
- else
- {
- g_object_ref (G_OBJECT (model));
- }
-
- return model;
-}
-
-
-
-/**
- * thunar_shortcuts_model_has_bookmark:
- * @model : a #ThunarShortcutsModel instance.
- * @file : a #ThuanrFile instance.
- *
- * Returns %TRUE if there is a bookmark (not a mount or volume) with
- * @file as destination.
- *
- * Return value: %TRUE if @file was found, else %FALSE.
- **/
-gboolean
-thunar_shortcuts_model_has_bookmark (ThunarShortcutsModel *model,
- GFile *file)
-{
- GList *lp;
- ThunarShortcut *shortcut;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- _thunar_return_val_if_fail (G_IS_FILE (file), FALSE);
-
- for (lp = model->shortcuts; lp != NULL; lp = lp->next)
- {
- shortcut = lp->data;
-
- /* only check bookmarks */
- if (shortcut->group != THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
- continue;
-
- if (shortcut->file != NULL
- && g_file_equal (thunar_file_get_file (shortcut->file), file))
- return TRUE;
-
- if (shortcut->location != NULL
- && g_file_equal (shortcut->location, file))
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-
-/**
- * thunar_shortcuts_model_iter_for_file:
- * @model : a #ThunarShortcutsModel instance.
- * @file : a #ThuanrFile instance.
- * @iter : pointer to a #GtkTreeIter.
- *
- * Tries to lookup the #GtkTreeIter, that belongs to a shortcut, which
- * refers to @file and stores it to @iter. If no such #GtkTreeIter was
- * found, %FALSE will be returned and @iter won't be changed. Else
- * %TRUE will be returned and @iter will be set appropriately.
- *
- * Return value: %TRUE if @file was found, else %FALSE.
- **/
-gboolean
-thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model,
- ThunarFile *file,
- GtkTreeIter *iter)
-{
- GFile *mount_point;
- GList *lp;
- ThunarShortcut *shortcut;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
- _thunar_return_val_if_fail (iter != NULL, FALSE);
-
- for (lp = model->shortcuts; lp != NULL; lp = lp->next)
- {
- shortcut = lp->data;
-
- /* check if we have a location that matches */
- if (shortcut->file == file)
- {
- GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
- return TRUE;
- }
-
- if (shortcut->location != NULL
- && g_file_equal (shortcut->location, thunar_file_get_file (file)))
- {
- GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
- return TRUE;
- }
-
- /* but maybe we have a mounted(!) volume with a matching mount point */
- if (shortcut->device != NULL
- && !thunar_device_get_hidden (shortcut->device))
- {
- mount_point = thunar_device_get_root (shortcut->device);
- if (mount_point != NULL)
- {
- if (g_file_equal (mount_point, thunar_file_get_file (file)))
- {
- GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
- g_object_unref (mount_point);
- return TRUE;
- }
-
- g_object_unref (mount_point);
- }
- }
- }
-
- return FALSE;
-}
-
-
-
-/**
- * thunar_shortcuts_model_drop_possible:
- * @model : a #ThunarShortcutstModel.
- * @path : a #GtkTreePath.
- *
- * Determines whether a drop is possible before the given @path, at the same depth
- * as @path. I.e., can we drop data at that location. @path does not have to exist;
- * the return value will almost certainly be FALSE if the parent of @path doesn't
- * exist, though.
- *
- * Return value: %TRUE if it's possible to drop data before @path, else %FALSE.
- **/
-gboolean
-thunar_shortcuts_model_drop_possible (ThunarShortcutsModel *model,
- GtkTreePath *path)
-{
- ThunarShortcut *shortcut;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- _thunar_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
-
- /* determine the list item for the path */
- shortcut = g_list_nth_data (model->shortcuts, gtk_tree_path_get_indices (path)[0]);
-
- /* append to the list is not possible */
- if (G_LIKELY (shortcut == NULL))
- return FALSE;
-
- /* cannot drop before special shortcuts! */
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
- return TRUE;
-
- /* we can drop at the end of the bookmarks (before network header) */
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_NETWORK_HEADER)
- return TRUE;
-
- return FALSE;
-}
-
-
-
-/**
- * thunar_shortcuts_model_add:
- * @model : a #ThunarShortcutsModel.
- * @dst_path : the destination path.
- * @file : the #ThunarFile that should be added to the shortcuts list.
- *
- * Adds the shortcut @file to the @model at @dst_path, unless @file is
- * already present in @model in which case no action is performed.
- **/
-void
-thunar_shortcuts_model_add (ThunarShortcutsModel *model,
- GtkTreePath *dst_path,
- gpointer file)
-{
- ThunarShortcut *shortcut;
- GFile *location;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (dst_path == NULL || gtk_tree_path_get_depth (dst_path) > 0);
- _thunar_return_if_fail (dst_path == NULL || gtk_tree_path_get_indices (dst_path)[0] >= 0);
- _thunar_return_if_fail (dst_path == NULL || gtk_tree_path_get_indices (dst_path)[0] <= (gint) g_list_length (model->shortcuts));
- _thunar_return_if_fail (THUNAR_IS_FILE (file) || G_IS_FILE (file));
-
- location = G_IS_FILE (file) ? file : thunar_file_get_file (file);
-
- /* verify that the file is not already in use as shortcut */
- if (thunar_shortcuts_model_has_bookmark (model, location))
- return;
-
- /* create the new shortcut that will be inserted */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
-
- if (thunar_shortcuts_model_local_file (location))
- {
- shortcut->file = thunar_file_get (location, NULL);
- }
- else
- {
- shortcut->location = g_object_ref (G_OBJECT (location));
- shortcut->gicon = g_themed_icon_new ("folder-remote");
- }
-
- /* add the shortcut to the list at the given position */
- thunar_shortcuts_model_add_shortcut_with_path (model, shortcut, dst_path);
-
- /* the shortcuts list was changed, so write the gtk bookmarks file */
- thunar_shortcuts_model_save (model);
-}
-
-
-
-/**
- * thunar_shortcuts_model_move:
- * @model : a #ThunarShortcutsModel.
- * @src_path : the source path.
- * @dst_path : the destination path.
- *
- * Moves the shortcut at @src_path to @dst_path, adjusting other
- * shortcut's positions as required.
- **/
-void
-thunar_shortcuts_model_move (ThunarShortcutsModel *model,
- GtkTreePath *src_path,
- GtkTreePath *dst_path)
-{
- ThunarShortcut *shortcut;
- GtkTreePath *path;
- GList *lp;
- gint *order;
- gint index_src;
- gint index_dst;
- gint idx;
- gint n_shortcuts;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (gtk_tree_path_get_depth (src_path) > 0);
- _thunar_return_if_fail (gtk_tree_path_get_depth (dst_path) > 0);
- _thunar_return_if_fail (gtk_tree_path_get_indices (src_path)[0] >= 0);
- _thunar_return_if_fail (gtk_tree_path_get_indices (src_path)[0] < (gint) g_list_length (model->shortcuts));
- _thunar_return_if_fail (gtk_tree_path_get_indices (dst_path)[0] > 0);
-
- index_src = gtk_tree_path_get_indices (src_path)[0];
- index_dst = gtk_tree_path_get_indices (dst_path)[0];
-
- if (G_UNLIKELY (index_src == index_dst))
- return;
-
- /* generate the order for the rows prior the dst/src rows */
- n_shortcuts = g_list_length (model->shortcuts);
- order = g_newa (gint, n_shortcuts);
- for (idx = 0, lp = model->shortcuts; idx < index_src && idx < index_dst; ++idx, lp = lp->next)
- order[idx] = idx;
-
- if (idx == index_src)
- {
- shortcut = THUNAR_SHORTCUT (lp->data);
-
- for (; idx < index_dst; ++idx, lp = lp->next)
- {
- if (lp->next == NULL)
- break;
- lp->data = lp->next->data;
- order[idx] = idx + 1;
- }
-
- lp->data = shortcut;
- order[idx++] = index_src;
- }
- else
- {
- for (; idx < index_src; ++idx, lp = lp->next)
- ;
-
- _thunar_assert (idx == index_src);
-
- shortcut = THUNAR_SHORTCUT (lp->data);
-
- for (; idx > index_dst; --idx, lp = lp->prev)
- {
- lp->data = lp->prev->data;
- order[idx] = idx - 1;
- }
-
- _thunar_assert (idx == index_dst);
-
- lp->data = shortcut;
- order[idx] = index_src;
- idx = index_src + 1;
- }
-
- /* generate the remaining order */
- for (; idx < n_shortcuts; ++idx)
- order[idx] = idx;
-
- /* tell all listeners about the reordering just performed */
- path = gtk_tree_path_new_first ();
- gtk_tree_model_rows_reordered (GTK_TREE_MODEL (model), path, NULL, order);
- gtk_tree_path_free (path);
-
- /* the shortcuts list was changed, so write the gtk bookmarks file */
- thunar_shortcuts_model_save (model);
-}
-
-
-
-/**
- * thunar_shortcuts_model_remove:
- * @model : a #ThunarShortcutsModel.
- * @path : the #GtkTreePath of the shortcut to remove.
- *
- * Removes the shortcut at @path from the @model and syncs to
- * on-disk storage. @path must refer to a valid, user-defined
- * shortcut, as you cannot remove system-defined entities (they
- * are managed internally).
- **/
-void
-thunar_shortcuts_model_remove (ThunarShortcutsModel *model,
- GtkTreePath *path)
-{
- ThunarShortcut *shortcut;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (gtk_tree_path_get_depth (path) > 0);
- _thunar_return_if_fail (gtk_tree_path_get_indices (path)[0] >= 0);
- _thunar_return_if_fail (gtk_tree_path_get_indices (path)[0] < (gint) g_list_length (model->shortcuts));
-
- /* lookup the shortcut for the given path */
- shortcut = g_list_nth_data (model->shortcuts, gtk_tree_path_get_indices (path)[0]);
-
- /* verify that the shortcut is removable */
- _thunar_assert (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
-
- /* remove the shortcut (using the file destroy handler) */
- thunar_shortcuts_model_remove_shortcut (model, shortcut);
-}
-
-
-
-/**
- * thunar_shortcuts_model_rename:
- * @model : a #ThunarShortcutsModel.
- * @iter : the #GtkTreeIter which refers to the shortcut that
- * should be renamed to @name.
- * @name : the new name for the shortcut at @path or %NULL to
- * return to the default name.
- *
- * Renames the shortcut at @iter to the new @name in @model.
- *
- * @name may be %NULL or an empty to reset the shortcut to
- * its default name.
- **/
-void
-thunar_shortcuts_model_rename (ThunarShortcutsModel *model,
- GtkTreeIter *iter,
- const gchar *name)
-{
- ThunarShortcut *shortcut;
- GtkTreePath *path;
-
- _thunar_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (iter->stamp == model->stamp);
- _thunar_return_if_fail (iter->user_data != NULL);
-
- /* lookup the shortcut for the given path */
- shortcut = THUNAR_SHORTCUT (((GList *) iter->user_data)->data);
-
- /* verify the shortcut */
- _thunar_assert (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
-
- /* perform the rename */
- if (G_UNLIKELY (shortcut->name != NULL))
- g_free (shortcut->name);
- if (G_UNLIKELY (name == NULL || *name == '\0'))
- shortcut->name = NULL;
- else
- shortcut->name = g_strdup (name);
-
- /* notify the views about the change */
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, iter);
- gtk_tree_path_free (path);
-
- /* save the changes to the model */
- thunar_shortcuts_model_save (model);
-}
-
-
-
-void
-thunar_shortcuts_model_set_busy (ThunarShortcutsModel *model,
- ThunarDevice *device,
- gboolean busy)
-{
- ThunarShortcut *shortcut;
- GList *lp;
- guint idx;
- GtkTreeIter iter;
- GtkTreePath *path;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
-
- /* get the device */
- for (lp = model->shortcuts, idx = 0; lp != NULL; lp = lp->next, idx++)
- if (THUNAR_SHORTCUT (lp->data)->device == device)
- break;
-
- if (lp == NULL)
- return;
-
- shortcut = lp->data;
- _thunar_assert (shortcut->device == device);
-
- if (G_LIKELY (shortcut->busy != busy))
- {
- shortcut->busy = busy;
-
- if (busy && model->busy_timeout_id == 0)
- {
- /* start the global cycle timeout */
- model->busy_timeout_id =
- gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT,
- SPINNER_CYCLE_DURATION / SPINNER_NUM_STEPS,
- thunar_shortcuts_model_busy_timeout, model,
- thunar_shortcuts_model_busy_timeout_destroyed);
- }
- else if (!busy)
- {
- /* generate an iterator for the path */
- GTK_TREE_ITER_INIT (iter, model->stamp, lp);
-
- /* notify the views about the change */
- path = gtk_tree_path_new_from_indices (idx, -1);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
- }
- }
-}
-
-
-
-
-void
-thunar_shortcuts_model_set_hidden (ThunarShortcutsModel *model,
- GtkTreePath *path,
- gboolean hidden)
-{
- ThunarShortcut *shortcut;
- guint length;
- gchar **bookmarks;
- guint pos;
- gchar *uri;
- guint n;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (gtk_tree_path_get_depth (path) > 0);
- _thunar_return_if_fail (gtk_tree_path_get_indices (path)[0] >= 0);
- _thunar_return_if_fail (gtk_tree_path_get_indices (path)[0] < (gint) g_list_length (model->shortcuts));
-
- /* lookup the shortcut for the given path */
- shortcut = g_list_nth_data (model->shortcuts, gtk_tree_path_get_indices (path)[0]);
- _thunar_return_if_fail (shortcut != NULL);
-
- if (shortcut->device != NULL)
- {
- /* if this is a device, store in the device monitor */
- thunar_device_monitor_set_hidden (model->device_monitor, shortcut->device, hidden);
- return;
- }
-
- /* get the uri */
- if (shortcut->file != NULL)
- uri = thunar_file_dup_uri (shortcut->file);
- else if (shortcut->location != NULL)
- uri = g_file_get_uri (shortcut->location);
- else
- _thunar_assert_not_reached ();
-
- /* prepare array */
- length = model->hidden_bookmarks != NULL ? g_strv_length (model->hidden_bookmarks) : 0;
- bookmarks = g_new0 (gchar *, length + 2);
- pos = 0;
-
- /* copy other uuid in the new list */
- if (model->hidden_bookmarks != NULL)
- {
- for (n = 0; model->hidden_bookmarks[n] != NULL; n++)
- if (g_strcmp0 (model->hidden_bookmarks[n], uri) != 0)
- bookmarks[pos++] = g_strdup (model->hidden_bookmarks[n]);
- }
-
- /* add the new uri if it should hide */
- if (hidden)
- bookmarks[pos++] = uri;
- else
- g_free (uri);
-
- /* store new list */
- g_object_set (G_OBJECT (model->preferences), "hidden-bookmarks", bookmarks, NULL);
- g_strfreev (bookmarks);
-
- /* header visibility */
- thunar_shortcuts_model_header_visibility (model);
-}
diff --git a/thunar/thunar-shortcuts-model.h b/thunar/thunar-shortcuts-model.h
deleted file mode 100644
index cb87a1f..0000000
--- a/thunar/thunar-shortcuts-model.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __THUNAR_SHORTCUTS_MODEL_H__
-#define __THUNAR_SHORTCUTS_MODEL_H__
-
-#include <thunar/thunar-file.h>
-#include <thunar/thunar-device.h>
-
-G_BEGIN_DECLS;
-
-typedef struct _ThunarShortcutsModelClass ThunarShortcutsModelClass;
-typedef struct _ThunarShortcutsModel ThunarShortcutsModel;
-typedef enum _ThunarShortcutGroup ThunarShortcutGroup;
-
-#define THUNAR_TYPE_SHORTCUTS_MODEL (thunar_shortcuts_model_get_type ())
-#define THUNAR_SHORTCUTS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_SHORTCUTS_MODEL, ThunarShortcutsModel))
-#define THUNAR_SHORTCUTS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_SHORTCUTS_MODEL, ThunarShortcutsModelClass))
-#define THUNAR_IS_SHORTCUTS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_SHORTCUTS_MODEL))
-#define THUNAR_IS_SHORTCUTS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SHORTCUTS_MODEL))
-#define THUNAR_SHORTCUTS_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_MODEL_SHORTCUTS_MODEL, ThunarShortcutsModelClass))
-
-typedef enum
-{
- THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER,
- THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM,
- THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE,
- THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
- THUNAR_SHORTCUTS_MODEL_COLUMN_TOOLTIP,
- THUNAR_SHORTCUTS_MODEL_COLUMN_FILE,
- THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION,
- THUNAR_SHORTCUTS_MODEL_COLUMN_GICON,
- THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE,
- THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE,
- THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT,
- THUNAR_SHORTCUTS_MODEL_COLUMN_GROUP,
- THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY,
- THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE,
- THUNAR_SHORTCUTS_MODEL_N_COLUMNS,
-} ThunarShortcutsModelColumn;
-
-#define THUNAR_SHORTCUT_GROUP_DEVICES (THUNAR_SHORTCUT_GROUP_DEVICES_HEADER \
- | THUNAR_SHORTCUT_GROUP_DEVICES_FILESYSTEM \
- | THUNAR_SHORTCUT_GROUP_DEVICES_VOLUMES \
- | THUNAR_SHORTCUT_GROUP_DEVICES_MOUNTS)
-#define THUNAR_SHORTCUT_GROUP_PLACES (THUNAR_SHORTCUT_GROUP_PLACES_HEADER \
- | THUNAR_SHORTCUT_GROUP_PLACES_DEFAULT \
- | THUNAR_SHORTCUT_GROUP_PLACES_TRASH \
- | THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
-#define THUNAR_SHORTCUT_GROUP_NETWORK (THUNAR_SHORTCUT_GROUP_NETWORK_HEADER \
- | THUNAR_SHORTCUT_GROUP_NETWORK_DEFAULT \
- | THUNAR_SHORTCUT_GROUP_NETWORK_MOUNTS)
-#define THUNAR_SHORTCUT_GROUP_HEADER (THUNAR_SHORTCUT_GROUP_DEVICES_HEADER \
- | THUNAR_SHORTCUT_GROUP_PLACES_HEADER \
- | THUNAR_SHORTCUT_GROUP_NETWORK_HEADER)
-
-enum _ThunarShortcutGroup
-{
- /* THUNAR_SHORTCUT_GROUP_DEVICES */
- THUNAR_SHORTCUT_GROUP_DEVICES_HEADER = (1 << 0), /* devices header */
- THUNAR_SHORTCUT_GROUP_DEVICES_FILESYSTEM = (1 << 1), /* local filesystem */
- THUNAR_SHORTCUT_GROUP_DEVICES_VOLUMES = (1 << 2), /* local ThunarDevices */
- THUNAR_SHORTCUT_GROUP_DEVICES_MOUNTS = (1 << 3), /* local mounts, like cameras and archives */
-
- /* THUNAR_SHORTCUT_GROUP_PLACES */
- THUNAR_SHORTCUT_GROUP_PLACES_HEADER = (1 << 4), /* places header */
- THUNAR_SHORTCUT_GROUP_PLACES_DEFAULT = (1 << 5), /* home and desktop */
- THUNAR_SHORTCUT_GROUP_PLACES_TRASH = (1 << 6), /* trash */
- THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS = (1 << 7), /* gtk-bookmarks */
-
- /* THUNAR_SHORTCUT_GROUP_NETWORK */
- THUNAR_SHORTCUT_GROUP_NETWORK_HEADER = (1 << 8), /* network header */
- THUNAR_SHORTCUT_GROUP_NETWORK_DEFAULT = (1 << 9), /* browse network */
- THUNAR_SHORTCUT_GROUP_NETWORK_MOUNTS = (1 << 10), /* remote ThunarDevices */
-};
-
-
-
-GType thunar_shortcuts_model_get_type (void) G_GNUC_CONST;
-
-ThunarShortcutsModel *thunar_shortcuts_model_get_default (void);
-
-gboolean thunar_shortcuts_model_has_bookmark (ThunarShortcutsModel *model,
- GFile *file);
-
-gboolean thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model,
- ThunarFile *file,
- GtkTreeIter *iter);
-
-gboolean thunar_shortcuts_model_drop_possible (ThunarShortcutsModel *model,
- GtkTreePath *path);
-
-void thunar_shortcuts_model_add (ThunarShortcutsModel *model,
- GtkTreePath *dst_path,
- gpointer file);
-void thunar_shortcuts_model_move (ThunarShortcutsModel *model,
- GtkTreePath *src_path,
- GtkTreePath *dst_path);
-void thunar_shortcuts_model_remove (ThunarShortcutsModel *model,
- GtkTreePath *path);
-void thunar_shortcuts_model_rename (ThunarShortcutsModel *model,
- GtkTreeIter *iter,
- const gchar *name);
-void thunar_shortcuts_model_set_busy (ThunarShortcutsModel *model,
- ThunarDevice *device,
- gboolean busy);
-void thunar_shortcuts_model_set_hidden (ThunarShortcutsModel *model,
- GtkTreePath *path,
- gboolean hidden);
-
-G_END_DECLS;
-
-#endif /* !__THUNAR_SHORTCUTS_MODEL_H__ */
diff --git a/thunar/thunar-shortcuts-pane.c b/thunar/thunar-shortcuts-pane.c
index 590a92c..fa646b4 100644
--- a/thunar/thunar-shortcuts-pane.c
+++ b/thunar/thunar-shortcuts-pane.c
@@ -1,6 +1,7 @@
/* vi:set et ai sw=2 sts=2 ts=2: */
/*-
* Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2015 Jonas Kümmerlin <rgcjonas at gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,12 +24,17 @@
#include <thunar/thunar-gobject-extensions.h>
#include <thunar/thunar-private.h>
-#include <thunar/thunar-shortcuts-model.h>
#include <thunar/thunar-shortcuts-pane.h>
#include <thunar/thunar-shortcuts-pane-ui.h>
-#include <thunar/thunar-shortcuts-view.h>
#include <thunar/thunar-side-pane.h>
#include <thunar/thunar-stock.h>
+#include <thunar/thunar-browser.h>
+#include <thunar/thunar-dialogs.h>
+#include <thunar/thunar-application.h>
+#include <thunar/thunar-dnd.h>
+#include <thunar/thunar-gtk-extensions.h>
+#include <thunar/thunar-gio-extensions.h>
+#include <thunar/thunar-util.h>
@@ -67,17 +73,35 @@ static void thunar_shortcuts_pane_set_ui_manager (ThunarComponen
GtkUIManager *ui_manager);
static void thunar_shortcuts_pane_action_shortcuts_add (GtkAction *action,
ThunarShortcutsPane *shortcuts_pane);
+static void thunar_shortcuts_pane_open_location (GtkPlacesSidebar *sidebar,
+ GFile *location,
+ GtkPlacesOpenFlags flags,
+ ThunarShortcutsPane *shortcuts_pane);
+static gint thunar_shortcuts_pane_drag_action_requested (GtkPlacesSidebar *sidebar,
+ GdkDragContext *context,
+ GFile *dest_file,
+ GList *source_file_list,
+ ThunarShortcutsPane *shortcuts_pane);
+static void thunar_shortcuts_pane_drag_perform_drop (GtkPlacesSidebar *sidebar,
+ GFile *dest_file,
+ GList *source_file_list,
+ GdkDragAction action,
+ ThunarShortcutsPane *shortcuts_pane);
+static gint thunar_shortcuts_pane_drag_action_ask (GtkPlacesSidebar *sidebar,
+ GdkDragAction actions,
+ ThunarShortcutsPane *shortcuts_pane);
+
struct _ThunarShortcutsPaneClass
{
- GtkScrolledWindowClass __parent__;
+ GtkBinClass __parent__;
};
struct _ThunarShortcutsPane
{
- GtkScrolledWindow __parent__;
+ GtkBin __parent__;
ThunarFile *current_directory;
GList *selected_files;
@@ -86,7 +110,7 @@ struct _ThunarShortcutsPane
GtkUIManager *ui_manager;
guint ui_merge_id;
- GtkWidget *view;
+ GtkWidget *places;
guint idle_select_directory;
};
@@ -100,10 +124,11 @@ static const GtkActionEntry action_entries[] =
-G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsPane, thunar_shortcuts_pane, GTK_TYPE_SCROLLED_WINDOW,
+G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsPane, thunar_shortcuts_pane, GTK_TYPE_BIN,
G_IMPLEMENT_INTERFACE (THUNAR_TYPE_NAVIGATOR, thunar_shortcuts_pane_navigator_init)
G_IMPLEMENT_INTERFACE (THUNAR_TYPE_COMPONENT, thunar_shortcuts_pane_component_init)
- G_IMPLEMENT_INTERFACE (THUNAR_TYPE_SIDE_PANE, thunar_shortcuts_pane_side_pane_init))
+ G_IMPLEMENT_INTERFACE (THUNAR_TYPE_SIDE_PANE, thunar_shortcuts_pane_side_pane_init)
+ G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL))
@@ -168,20 +193,17 @@ thunar_shortcuts_pane_init (ThunarShortcutsPane *shortcuts_pane)
gtk_action_group_set_translation_domain (shortcuts_pane->action_group, GETTEXT_PACKAGE);
gtk_action_group_add_actions (shortcuts_pane->action_group, action_entries, G_N_ELEMENTS (action_entries), shortcuts_pane);
- /* configure the GtkScrolledWindow */
- gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (shortcuts_pane), NULL);
- gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (shortcuts_pane), NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (shortcuts_pane), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (shortcuts_pane), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ /* configure the places sidebar */
+ shortcuts_pane->places = gtk_places_sidebar_new ();
+ gtk_places_sidebar_set_open_flags (GTK_PLACES_SIDEBAR (shortcuts_pane->places), GTK_PLACES_OPEN_NORMAL|GTK_PLACES_OPEN_NEW_TAB|GTK_PLACES_OPEN_NEW_WINDOW);
- /* allocate the shortcuts view */
- shortcuts_pane->view = thunar_shortcuts_view_new ();
- gtk_container_add (GTK_CONTAINER (shortcuts_pane), shortcuts_pane->view);
- gtk_widget_show (shortcuts_pane->view);
+ g_signal_connect (shortcuts_pane->places, "open-location", G_CALLBACK (thunar_shortcuts_pane_open_location), shortcuts_pane);
+ g_signal_connect (shortcuts_pane->places, "drag-action-requested", G_CALLBACK (thunar_shortcuts_pane_drag_action_requested), shortcuts_pane);
+ g_signal_connect (shortcuts_pane->places, "drag-perform-drop", G_CALLBACK (thunar_shortcuts_pane_drag_perform_drop), shortcuts_pane);
+ g_signal_connect (shortcuts_pane->places, "drag-action-ask", G_CALLBACK (thunar_shortcuts_pane_drag_action_ask), shortcuts_pane);
- /* connect the "shortcut-activated" signal */
- g_signal_connect_swapped (G_OBJECT (shortcuts_pane->view), "shortcut-activated", G_CALLBACK (thunar_navigator_change_directory), shortcuts_pane);
- g_signal_connect_swapped (G_OBJECT (shortcuts_pane->view), "shortcut-activated-tab", G_CALLBACK (thunar_navigator_open_new_tab), shortcuts_pane);
+ gtk_container_add (GTK_CONTAINER (shortcuts_pane), shortcuts_pane->places);
+ gtk_widget_show (shortcuts_pane->places);
}
@@ -292,8 +314,8 @@ thunar_shortcuts_pane_set_current_directory_idle (gpointer data)
if (shortcuts_pane->current_directory != NULL)
{
- thunar_shortcuts_view_select_by_file (THUNAR_SHORTCUTS_VIEW (shortcuts_pane->view),
- shortcuts_pane->current_directory);
+ gtk_places_sidebar_set_location (GTK_PLACES_SIDEBAR (shortcuts_pane->places),
+ thunar_file_get_file (shortcuts_pane->current_directory));
}
/* unset id */
@@ -378,20 +400,12 @@ thunar_shortcuts_pane_set_selected_files (ThunarComponent *component,
if (lp == NULL && selected_files != NULL)
{
/* check if atleast one of the selected folders is not already present in the model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (shortcuts_pane->view));
- if (G_LIKELY (model != NULL))
- {
- /* check all selected folders */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- for (lp = selected_files; lp != NULL; lp = lp->next)
- if (!thunar_shortcuts_model_has_bookmark (THUNAR_SHORTCUTS_MODEL (child_model), thunar_file_get_file (lp->data)))
- break;
- }
+ /* TODO */
/* display the action and change the label appropriately */
g_object_set (G_OBJECT (action),
"label", ngettext ("Side Pane (Create Shortcut)", "Side Pane (Create Shortcuts)", n),
- "sensitive", (lp != NULL),
+ "sensitive", /*(lp != NULL)*/ TRUE,
"tooltip", ngettext ("Add the selected folder to the shortcuts side pane",
"Add the selected folders to the shortcuts side pane", n),
"visible", TRUE,
@@ -462,35 +476,316 @@ thunar_shortcuts_pane_set_ui_manager (ThunarComponent *component,
g_object_notify (G_OBJECT (shortcuts_pane), "ui-manager");
}
+struct bookmark
+{
+ struct bookmark *next;
+ GFile *file;
+ gchar *name;
+};
+
+static void store_bookmark (GFile *file,
+ const gchar *name,
+ gint row_num,
+ gpointer user_data)
+{
+ struct bookmark **plist = user_data;
+ struct bookmark *bm = g_slice_new0 (struct bookmark);
+
+ _thunar_return_if_fail (plist != NULL);
+
+ bm->next = *plist;
+ bm->file = g_object_ref (file);
+ bm->name = g_strdup (name);
+
+ *plist = bm;
+}
+
static void
thunar_shortcuts_pane_action_shortcuts_add (GtkAction *action,
ThunarShortcutsPane *shortcuts_pane)
{
- GtkTreeModel *model;
- GtkTreeModel *child_model;
- GList *lp;
+ GFile *bookmark_file = NULL, *parent = NULL;
+ gchar *uri = NULL;
+ GString *contents = NULL;
+ struct bookmark *bm_list = NULL, *bm_i = NULL;
+ GList *lp = NULL;
+ GError *error = NULL;
_thunar_return_if_fail (GTK_IS_ACTION (action));
_thunar_return_if_fail (THUNAR_IS_SHORTCUTS_PANE (shortcuts_pane));
- /* determine the shortcuts model for the view */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (shortcuts_pane->view));
- if (G_LIKELY (model != NULL))
- {
- /* add all selected folders to the model */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- for (lp = shortcuts_pane->selected_files; lp != NULL; lp = lp->next)
- if (G_LIKELY (thunar_file_is_directory (lp->data)))
+ bookmark_file = thunar_g_file_new_for_bookmarks ();
+
+ thunar_util_load_bookmarks (bookmark_file, store_bookmark, &bm_list);
+
+ /* add all selected folders to the list - unless they are already contained in there */
+ /* FIXME: complexity */
+ for (lp = shortcuts_pane->selected_files; lp != NULL; lp = lp->next)
+ if (G_LIKELY (thunar_file_is_directory (lp->data)))
+ {
+ uri = thunar_file_dup_uri (lp->data);
+
+ for (bm_i = bm_list; bm_i != NULL; bm_i = bm_i->next)
{
- /* append the folder to the shortcuts model */
- thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (child_model), NULL, lp->data);
+ if (g_file_equal(thunar_file_get_file (lp->data), bm_i->file))
+ break;
}
- /* update the user interface to reflect the new action state */
- lp = thunar_g_file_list_copy (shortcuts_pane->selected_files);
- thunar_component_set_selected_files (THUNAR_COMPONENT (shortcuts_pane), lp);
- thunar_g_file_list_free (lp);
+ if (bm_i == NULL)
+ {
+ bm_i = g_slice_new0 (struct bookmark);
+ bm_i->next = bm_list;
+ bm_i->file = g_object_ref (thunar_file_get_file (lp->data));
+ bm_i->name = NULL;
+
+ bm_list = bm_i;
+ }
+ }
+
+ /* create the new contents of the file */
+ contents = g_string_new ("");
+
+ for (bm_i = bm_list; bm_i != NULL; bm_i = bm_i->next)
+ {
+ uri = g_file_get_uri (bm_i->file);
+ if (!uri)
+ continue;
+
+ /* Since we built the list in reverse, we will prepend instead of append
+ * to the string. That way, it evens out. */
+ g_string_prepend_c (contents, '\n');
+
+ if (bm_i->name)
+ {
+ g_string_prepend (contents, bm_i->name);
+ g_string_prepend_c (contents, ' ');
+ }
+
+ g_string_prepend (contents, uri);
+
+ g_free (uri);
}
+
+ /* save the contents back into the file */
+ parent = g_file_get_parent (bookmark_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 (bookmark_file,
+ contents->str,
+ contents->len,
+ NULL, FALSE, 0, NULL,
+ NULL, &error))
+
+ /* update the user interface to reflect the new action state */
+ lp = thunar_g_file_list_copy (shortcuts_pane->selected_files);
+ thunar_component_set_selected_files (THUNAR_COMPONENT (shortcuts_pane), lp);
+ thunar_g_file_list_free (lp);
+
+out:
+ if (error)
+ {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ }
+ g_string_free (contents, TRUE);
+ g_object_unref (parent);
+ g_object_unref (bookmark_file);
+
+ for (bm_i = bm_list; bm_i != NULL; bm_i = bm_list)
+ {
+ g_object_unref (bm_i->file);
+ g_free (bm_i->name);
+
+ bm_list = bm_i->next;
+ g_slice_free (struct bookmark, bm_i);
+ }
+}
+
+
+
+static void
+thunar_shortcuts_pane_poke_location_finish (ThunarBrowser *browser,
+ GFile *location,
+ ThunarFile *file,
+ ThunarFile *target_file,
+ GError *error,
+ gpointer user_data)
+{
+ gchar *name;
+ GtkPlacesOpenFlags open_in;
+ ThunarApplication *application;
+
+ _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_PANE (browser));
+ _thunar_return_if_fail (G_IS_FILE (location));
+
+ open_in = (GtkPlacesOpenFlags)GPOINTER_TO_INT (user_data);
+
+ /* sotre the new file in the shortcuts model */
+ if (error == NULL)
+ {
+ if (open_in == GTK_PLACES_OPEN_NEW_WINDOW)
+ {
+ /* open a new window for the target folder */
+ application = thunar_application_get ();
+ thunar_application_open_window (application, target_file,
+ gtk_widget_get_screen (GTK_WIDGET (browser)), NULL);
+ g_object_unref (application);
+ }
+ else if (open_in == GTK_PLACES_OPEN_NEW_TAB)
+ {
+ thunar_navigator_open_new_tab (THUNAR_NAVIGATOR (browser), target_file);
+ }
+ else if (thunar_file_check_loaded (target_file))
+ {
+ thunar_navigator_change_directory (THUNAR_NAVIGATOR (browser), target_file);
+ }
+ else
+ {
+ g_warning ("WTF: File to be activated but not loaded!");
+ }
+ }
+ else
+ {
+ name = thunar_g_file_get_display_name_remote (location);
+ thunar_dialogs_show_error (GTK_WIDGET (browser), error, _("Failed to open \"%s\""), name);
+ g_free (name);
+ }
+}
+
+
+
+static void
+thunar_shortcuts_pane_open_location (GtkPlacesSidebar *sidebar,
+ GFile *location,
+ GtkPlacesOpenFlags flags,
+ ThunarShortcutsPane *shortcuts_pane)
+{
+ thunar_browser_poke_location (THUNAR_BROWSER (shortcuts_pane), location,
+ GTK_WIDGET (shortcuts_pane),
+ thunar_shortcuts_pane_poke_location_finish,
+ GINT_TO_POINTER (flags));
+}
+
+
+
+static gint thunar_shortcuts_pane_drag_action_requested (GtkPlacesSidebar *sidebar,
+ GdkDragContext *context,
+ GFile *dest_file,
+ GList *source_file_list,
+ ThunarShortcutsPane *shortcuts_pane)
+{
+ ThunarFile *th_dest_file;
+ GdkDragAction suggested_action;
+
+ /* create ThunarFile* instances for the given file */
+ th_dest_file = thunar_file_get (dest_file, NULL);
+
+ _thunar_return_val_if_fail (th_dest_file != NULL, 0);
+
+ /* check for allowed drop actions */
+ thunar_file_accepts_drop (th_dest_file, source_file_list, context, &suggested_action);
+
+ /* cleanup */
+ g_object_unref (th_dest_file);
+
+ return suggested_action;
+}
+
+
+
+void thunar_shortcuts_pane_drag_perform_drop (GtkPlacesSidebar *sidebar,
+ GFile *dest_file,
+ GList *source_file_list,
+ GdkDragAction action,
+ ThunarShortcutsPane *shortcuts_pane)
+{
+ ThunarFile *th_dest_file;
+
+ if (G_UNLIKELY ((action & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)) == 0))
+ return;
+
+ /* get the thunar file */
+ th_dest_file = thunar_file_get (dest_file, NULL);
+
+ _thunar_return_if_fail (th_dest_file != NULL);
+
+ /* perform the drop */
+ thunar_dnd_perform (GTK_WIDGET (shortcuts_pane), th_dest_file, source_file_list, action, NULL);
+
+ /* cleanup */
+ g_object_unref (th_dest_file);
+}
+
+static void drag_ask_menu_copy_activated (GtkMenuItem *menuitem,
+ GdkDragAction *out_action)
+{
+ *out_action = GDK_ACTION_COPY;
+}
+static void drag_ask_menu_link_activated (GtkMenuItem *menuitem,
+ GdkDragAction *out_action)
+{
+ *out_action = GDK_ACTION_LINK;
+}
+static void drag_ask_menu_move_activated (GtkMenuItem *menuitem,
+ GdkDragAction *out_action)
+{
+ *out_action = GDK_ACTION_MOVE;
+}
+
+static gint thunar_shortcuts_pane_drag_action_ask (GtkPlacesSidebar *sidebar,
+ GdkDragAction actions,
+ ThunarShortcutsPane *shortcuts_pane)
+{
+ GtkWidget *menu, *item;
+ GdkDragAction chosen_action = 0;
+
+ /* prepare the popup menu */
+ menu = gtk_menu_new ();
+
+ /* append copy */
+ if (actions & GDK_ACTION_COPY)
+ {
+ item = gtk_menu_item_new_with_mnemonic (_ ("_Copy here"));
+ g_signal_connect (item, "activate", G_CALLBACK (drag_ask_menu_copy_activated), &chosen_action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+ if (actions & GDK_ACTION_MOVE)
+ {
+ item = gtk_menu_item_new_with_mnemonic (_ ("_Move here"));
+ g_signal_connect (item, "activate", G_CALLBACK (drag_ask_menu_move_activated), &chosen_action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+ if (actions & GDK_ACTION_LINK)
+ {
+ item = gtk_menu_item_new_with_mnemonic (_ ("_Link here"));
+ g_signal_connect (item, "activate", G_CALLBACK (drag_ask_menu_link_activated), &chosen_action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* append the separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+
+ /* append the cancel item */
+ item = gtk_menu_item_new_with_mnemonic (_ ("_Cancel"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* run the menu on the widget's screen (takes over the floating reference of menu) */
+ thunar_gtk_menu_run (GTK_MENU (menu), sidebar, NULL, NULL, 3, 0);
+
+ return chosen_action;
}
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
deleted file mode 100644
index 4119cae..0000000
--- a/thunar/thunar-shortcuts-view.c
+++ /dev/null
@@ -1,2139 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009-2011 Jannis Pohlmann <jannis at xfce.org>
- * Copyright (c) 2012 Nick Schermer <nick at xfce.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include <gdk/gdkkeysyms.h>
-
-#include <thunar/thunar-application.h>
-#include <thunar/thunar-browser.h>
-#include <thunar/thunar-dialogs.h>
-#include <thunar/thunar-dnd.h>
-#include <thunar/thunar-gio-extensions.h>
-#include <thunar/thunar-gtk-extensions.h>
-#include <thunar/thunar-preferences.h>
-#include <thunar/thunar-private.h>
-#include <thunar/thunar-shortcuts-icon-renderer.h>
-#include <thunar/thunar-shortcuts-model.h>
-#include <thunar/thunar-shortcuts-view.h>
-#include <thunar/thunar-device-monitor.h>
-#include <thunar/thunar-stock.h>
-
-
-
-/* Identifiers for signals */
-enum
-{
- SHORTCUT_ACTIVATED,
- SHORTCUT_ACTIVATED_TAB,
- LAST_SIGNAL,
-};
-
-/* Identifiers for DnD target types */
-enum
-{
- GTK_TREE_MODEL_ROW,
- TEXT_URI_LIST,
-};
-
-/* Target for open action */
-typedef enum
-{
- OPEN_IN_VIEW,
- OPEN_IN_WINDOW,
- OPEN_IN_TAB
-}
-OpenTarget;
-
-
-
-static void thunar_shortcuts_view_finalize (GObject *object);
-static gboolean thunar_shortcuts_view_button_press_event (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean thunar_shortcuts_view_button_release_event (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean thunar_shortcuts_view_key_release_event (GtkWidget *widget,
- GdkEventKey *event);
-static void thunar_shortcuts_view_drag_begin (GtkWidget *widget,
- GdkDragContext *context);
-static void thunar_shortcuts_view_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint timestamp);
-static gboolean thunar_shortcuts_view_drag_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint timestamp);
-static gboolean thunar_shortcuts_view_drag_motion (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint timestamp);
-static void thunar_shortcuts_view_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint timestamp);
-static gboolean thunar_shortcuts_view_popup_menu (GtkWidget *widget);
-static void thunar_shortcuts_view_row_activated (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column);
-static gboolean thunar_shortcuts_view_selection_func (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer user_data);
-static void thunar_shortcuts_view_context_menu_visibility (ThunarShortcutsView *view,
- GdkEventButton *event,
- GtkTreeModel *model);
-static void thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
- GdkEventButton *event,
- GtkTreeModel *model,
- GtkTreeIter *iter);
-static void thunar_shortcuts_view_remove_activated (GtkWidget *item,
- GtkTreeModel *model);
-static void thunar_shortcuts_view_editing_canceled (GtkCellRenderer *renderer,
- ThunarShortcutsView *view);
-static void thunar_shortcuts_view_rename_activated (GtkWidget *item,
- ThunarShortcutsView *view);
-static void thunar_shortcuts_view_renamed (GtkCellRenderer *renderer,
- const gchar *path_string,
- const gchar *text,
- ThunarShortcutsView *view);
-static GdkDragAction thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView *view,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkTreePath **path_return,
- GdkDragAction *action_return,
- GtkTreeViewDropPosition *position_return);
-static GtkTreePath *thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView *view,
- gint x,
- gint y);
-static void thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view,
- GList *path_list,
- GtkTreePath *dst_path);
-static void thunar_shortcuts_view_open_clicked (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_open (ThunarShortcutsView *view,
- OpenTarget open_in);
-static void thunar_shortcuts_view_open_in_new_window_clicked (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_open_in_new_tab_clicked (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_create_shortcut (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_eject (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_mount (ThunarShortcutsView *view);
-static void thunar_shortcuts_view_unmount (ThunarShortcutsView *view);
-
-
-
-struct _ThunarShortcutsViewClass
-{
- GtkTreeViewClass __parent__;
-};
-
-struct _ThunarShortcutsView
-{
- GtkTreeView __parent__;
-
-
- ThunarPreferences *preferences;
- GtkCellRenderer *icon_renderer;
-
- ThunarxProviderFactory *provider_factory;
-
- /* the currently pressed mouse button, set in the
- * button-press-event handler if the associated
- * button-release-event should activate.
- */
- gint pressed_button;
- guint pressed_eject_button : 1;
-
- /* drop site support */
- guint drop_data_ready : 1; /* whether the drop data was received already */
- guint drop_occurred : 1;
- GList *drop_file_list; /* the list of URIs that are contained in the drop data */
-
- /* id of the signal used to queue a resize on the
- * column whenever the shortcuts icon size is changed.
- */
- gulong queue_resize_signal_id;
-};
-
-
-
-/* Target types for dragging from the shortcuts view */
-static const GtkTargetEntry drag_targets[] = {
- { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW },
-};
-
-/* Target types for dropping into the shortcuts view */
-static const GtkTargetEntry drop_targets[] = {
- { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW },
- { "text/uri-list", 0, TEXT_URI_LIST },
-};
-
-
-
-static guint view_signals[LAST_SIGNAL];
-
-
-
-G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsView, thunar_shortcuts_view, GTK_TYPE_TREE_VIEW,
- G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL))
-
-
-
-static void
-thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass)
-{
- GtkTreeViewClass *gtktree_view_class;
- GtkWidgetClass *gtkwidget_class;
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = thunar_shortcuts_view_finalize;
-
- gtkwidget_class = GTK_WIDGET_CLASS (klass);
- gtkwidget_class->button_press_event = thunar_shortcuts_view_button_press_event;
- gtkwidget_class->button_release_event = thunar_shortcuts_view_button_release_event;
- gtkwidget_class->key_release_event = thunar_shortcuts_view_key_release_event;
- gtkwidget_class->drag_begin = thunar_shortcuts_view_drag_begin;
- gtkwidget_class->drag_data_received = thunar_shortcuts_view_drag_data_received;
- gtkwidget_class->drag_drop = thunar_shortcuts_view_drag_drop;
- gtkwidget_class->drag_motion = thunar_shortcuts_view_drag_motion;
- gtkwidget_class->drag_leave = thunar_shortcuts_view_drag_leave;
- gtkwidget_class->popup_menu = thunar_shortcuts_view_popup_menu;
-
- gtktree_view_class = GTK_TREE_VIEW_CLASS (klass);
- gtktree_view_class->row_activated = thunar_shortcuts_view_row_activated;
-
- /**
- * ThunarShortcutsView:shortcut-activated:
- *
- * Invoked whenever a shortcut is activated by the user.
- **/
- view_signals[SHORTCUT_ACTIVATED] =
- g_signal_new (I_("shortcut-activated"),
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, THUNAR_TYPE_FILE);
-
- /**
- * ThunarShortcutsView:shortcut-activated-tab:
- *
- * Invoked whenever a shortcut is activated by the user and should be opened in a new tab,
- **/
- view_signals[SHORTCUT_ACTIVATED_TAB] =
- g_signal_new (I_("shortcut-activated-tab"),
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, THUNAR_TYPE_FILE);
-}
-
-
-
-static void
-thunar_shortcuts_view_init (ThunarShortcutsView *view)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkTreeSelection *selection;
-
- /* configure the tree view */
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (view), THUNAR_SHORTCUTS_MODEL_COLUMN_TOOLTIP);
-
- /* grab a reference on the provider factory */
- view->provider_factory = thunarx_provider_factory_get_default ();
-
- /* grab a reference on the preferences; be sure to redraw the view
- * whenever the "shortcuts-icon-emblems" preference changes.
- */
- view->preferences = thunar_preferences_get ();
- g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::shortcuts-icon-emblems", G_CALLBACK (gtk_widget_queue_draw), view);
-
- /* allocate a single column for our renderers */
- column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
- "reorderable", FALSE,
- "resizable", FALSE,
- "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE,
- "spacing", 2,
- NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
-
- /* queue a resize on the column whenever the icon size is changed */
- view->queue_resize_signal_id = g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::shortcuts-icon-size",
- G_CALLBACK (gtk_tree_view_column_queue_resize), column);
-
- /* header */
- renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
- "weight", PANGO_WEIGHT_BOLD,
- "xpad", 6,
- "ypad", 6,
- NULL);
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "text", THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER,
- NULL);
-
- /* separator for indent */
- renderer = gtk_cell_renderer_text_new ();
- g_object_set (G_OBJECT (renderer), "xpad", 6, NULL);
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM,
- NULL);
-
- /* allocate the special icon renderer */
- view->icon_renderer = thunar_shortcuts_icon_renderer_new ();
- gtk_tree_view_column_pack_start (column, view->icon_renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, view->icon_renderer,
- "gicon", THUNAR_SHORTCUTS_MODEL_COLUMN_GICON,
- "file", THUNAR_SHORTCUTS_MODEL_COLUMN_FILE,
- "device", THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM,
- NULL);
-
- /* sync the "emblems" property of the icon renderer with the "shortcuts-icon-emblems" preference
- * and the "size" property of the renderer with the "shortcuts-icon-size" preference.
- */
- exo_binding_new (G_OBJECT (view->preferences), "shortcuts-icon-size", G_OBJECT (view->icon_renderer), "size");
- exo_binding_new (G_OBJECT (view->preferences), "shortcuts-icon-emblems", G_OBJECT (view->icon_renderer), "emblems");
-
- /* allocate the text renderer (ellipsizing as required, but "File System" must fit) */
- renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
- "ellipsize", PANGO_ELLIPSIZE_END,
- NULL);
- g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (thunar_shortcuts_view_renamed), view);
- gtk_tree_view_column_pack_start (column, renderer, TRUE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "text", THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM,
- NULL);
-
- /* spinner to indicate (un)mount/eject delay */
- renderer = gtk_cell_renderer_spinner_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY,
- "active", THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY,
- "pulse", THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE,
- NULL);
-
- /* allocate icon renderer for the eject symbol */
- renderer = gtk_cell_renderer_pixbuf_new ();
- g_object_set (renderer, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, "icon-name", "media-eject", NULL);
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT,
- NULL);
-
- /* enable drag support for the shortcuts view (actually used to support reordering) */
- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (view), GDK_BUTTON1_MASK, drag_targets,
- G_N_ELEMENTS (drag_targets), GDK_ACTION_MOVE);
-
- /* enable drop support for the shortcuts view (both internal reordering
- * and adding new shortcuts from other widgets)
- */
- gtk_drag_dest_set (GTK_WIDGET (view), 0, drop_targets, G_N_ELEMENTS (drop_targets),
- GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- gtk_tree_selection_set_select_function (selection, thunar_shortcuts_view_selection_func, NULL, NULL);
-}
-
-
-
-static void
-thunar_shortcuts_view_finalize (GObject *object)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (object);
-
- /* release drop path list (if drag_leave wasn't called) */
- thunar_g_file_list_free (view->drop_file_list);
-
- /* release the provider factory */
- g_object_unref (G_OBJECT (view->provider_factory));
-
- /* disconnect the queue resize signal handler */
- g_signal_handler_disconnect (G_OBJECT (view->preferences), view->queue_resize_signal_id);
-
- /* disconnect from the preferences object */
- g_signal_handlers_disconnect_matched (G_OBJECT (view->preferences), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, view);
- g_object_unref (G_OBJECT (view->preferences));
-
- (*G_OBJECT_CLASS (thunar_shortcuts_view_parent_class)->finalize) (object);
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- gboolean result;
- gboolean can_eject;
- gint icon_width, icon_height, column_width;
-
- /* reset the pressed button state */
- view->pressed_button = -1;
- view->pressed_eject_button = 0;
-
- /* completely ignore double click events */
- if (event->type == GDK_2BUTTON_PRESS)
- return TRUE;
-
- /* let the widget process the event first (handles focussing and scrolling) */
- result = (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->button_press_event) (widget, event);
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
-
- /* resolve the path at the cursor position */
- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), event->x, event->y, &path, NULL, NULL, NULL))
- {
- /* check if we should popup the context menu */
- if (G_UNLIKELY (event->button == 3))
- {
- /* determine the iterator for the path */
- if (gtk_tree_model_get_iter (model, &iter, path))
- {
- /* popup the context menu */
- thunar_shortcuts_view_context_menu (view, event, model, &iter);
-
- /* we effectively handled the event */
- result = TRUE;
- }
- }
- else if (event->button == 1 || event->button == 2)
- {
- /* check if we clicked the eject button area */
- column_width = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0));
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
- if (event->button == 1 && event->x >= column_width - icon_width - 3)
- {
- /* check if that shortcut actually has an eject button */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- if (gtk_tree_model_get_iter (model, &iter, path))
- {
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT, &can_eject, -1);
- if (can_eject)
- view->pressed_eject_button = 1;
- }
- }
- else
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path, gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), FALSE);
-
- /* remember the button as pressed and handle it in the release handler */
- view->pressed_button = event->button;
- }
-
- /* release the path */
- gtk_tree_path_free (path);
- }
- else if (event->button == 3)
- {
- thunar_shortcuts_view_context_menu_visibility (view, event, model);
- result = TRUE;
- }
-
- return result;
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
- gboolean in_tab;
-
- /* check if we have an event matching the pressed button state */
- if (G_LIKELY (view->pressed_button == (gint) event->button))
- {
- /* check if the eject button has been pressed */
- if (view->pressed_eject_button)
- {
- thunar_shortcuts_view_eject (view);
- }
- else if (G_LIKELY (event->button == 1))
- {
- /* button 1 opens in the same window */
- thunar_shortcuts_view_open (view, OPEN_IN_VIEW);
- }
- else if (G_UNLIKELY (event->button == 2))
- {
- /* button 2 opens in a new window or tab */
- g_object_get (view->preferences, "misc-middle-click-in-tab", &in_tab, NULL);
-
- /* holding ctrl inverts the action */
- if ((event->state & GDK_CONTROL_MASK) != 0)
- in_tab = !in_tab;
-
- thunar_shortcuts_view_open (view, in_tab ? OPEN_IN_TAB : OPEN_IN_WINDOW);
- }
- }
-
- /* reset the pressed button state */
- view->pressed_button = -1;
- view->pressed_eject_button = 0;
-
- /* call the parent's release event handler */
- return (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->button_release_event) (widget, event);
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_key_release_event (GtkWidget *widget,
- GdkEventKey *event)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
-
- /* work nicer with keyboard navigation */
- switch (event->keyval)
- {
- case GDK_KEY_Up:
- case GDK_KEY_Down:
- case GDK_KEY_KP_Up:
- case GDK_KEY_KP_Down:
- thunar_shortcuts_view_open (view, OPEN_IN_VIEW);
-
- /* keep focus on us */
- gtk_widget_grab_focus (widget);
- break;
- }
-
- /* call the parent's release event handler */
- return (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->key_release_event) (widget, event);
-}
-
-
-
-static void
-thunar_shortcuts_view_drag_begin (GtkWidget *widget,
- GdkDragContext *context)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
-
- /* reset the pressed button state */
- view->pressed_button = -1;
-
- /* call the parent's drag_begin() handler */
- if (GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->drag_begin != NULL)
- (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->drag_begin) (widget, context);
-}
-
-
-
-static void
-thunar_shortcuts_view_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint timestamp)
-{
- GtkTreeViewDropPosition position = GTK_TREE_VIEW_DROP_BEFORE;
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
- GdkDragAction actions;
- GdkDragAction action;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- ThunarFile *file;
- gboolean succeed = FALSE;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* check if we don't already know the drop data */
- if (G_LIKELY (!view->drop_data_ready))
- {
- /* extract the URI list from the selection data (if valid) */
- if (info == TEXT_URI_LIST && gtk_selection_data_get_format (selection_data) == 8 && gtk_selection_data_get_length (selection_data) > 0)
- view->drop_file_list = thunar_g_file_list_new_from_string ((const gchar *) gtk_selection_data_get_data (selection_data));
-
- /* reset the state */
- view->drop_data_ready = TRUE;
- }
-
- /* check if the data was droppped */
- if (G_UNLIKELY (view->drop_occurred))
- {
- /* reset the state */
- view->drop_occurred = FALSE;
-
- /* verify that we only handle text/uri-list here */
- if (G_LIKELY (info == TEXT_URI_LIST))
- {
- /* determine the drop actions */
- actions = thunar_shortcuts_view_compute_drop_actions (view, context, x, y, &path, &action, &position);
- if (G_LIKELY (actions != 0))
- {
- /* check if we should add a shortcut */
- if (position == GTK_TREE_VIEW_DROP_BEFORE || position == GTK_TREE_VIEW_DROP_AFTER)
- {
- /* if position is "after", we need to advance the path,
- * as the drop_uri_list() will insert "at" the path.
- */
- if (position == GTK_TREE_VIEW_DROP_AFTER)
- gtk_tree_path_next (path);
-
- /* just add the required shortcuts then */
- thunar_shortcuts_view_drop_uri_list (view, view->drop_file_list, path);
- }
- else if (G_LIKELY ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)) != 0))
- {
- /* get the shortcuts model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
-
- /* determine the iterator for the path */
- if (gtk_tree_model_get_iter (model, &iter, path))
- {
- /* determine the file for the iter */
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, -1);
- if (G_LIKELY (file != NULL))
- {
- /* ask the user what to do with the drop data */
- if (G_UNLIKELY (action == GDK_ACTION_ASK))
- action = thunar_dnd_ask (widget, file, view->drop_file_list, timestamp, actions);
-
- /* perform the requested action */
- if (G_LIKELY (action != 0))
- {
- /* really perform the drop :-) */
- succeed = thunar_dnd_perform (widget, file, view->drop_file_list, action, NULL);
- }
-
- /* release the file */
- g_object_unref (G_OBJECT (file));
- }
- }
- }
-
- /* release the tree path */
- gtk_tree_path_free (path);
- }
- }
-
- /* disable the drop highlighting */
- thunar_shortcuts_view_drag_leave (widget, context, timestamp);
-
- /* tell the peer that we handled the drop */
- gtk_drag_finish (context, succeed, FALSE, timestamp);
- }
- else
- {
- gdk_drag_status (context, 0, timestamp);
- }
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_drag_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint timestamp)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreePath *dst_path;
- GtkTreePath *src_path;
- GtkTreeIter iter;
- GdkAtom target;
- GtkTreeModel *child_model;
- GtkTreePath *child_dst_path;
- GtkTreePath *child_src_path;
-
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE);
-
- /* determine the drop target */
- target = gtk_drag_dest_find_target (widget, context, NULL);
- if (G_LIKELY (target == gdk_atom_intern_static_string ("text/uri-list")))
- {
- /* set state so the drag-data-received handler
- * knows that this is really a drop this time.
- */
- view->drop_occurred = TRUE;
-
- /* request the drag data from the source. */
- gtk_drag_get_data (widget, context, target, timestamp);
- }
- else if (target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
- {
- /* compute the drop position */
- dst_path = thunar_shortcuts_view_compute_drop_position (view, x, y);
-
- /* determine the source path */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* get the source path */
- src_path = gtk_tree_model_get_path (model, &iter);
-
- /* if we drop downwards, correct the drop destination */
- if (gtk_tree_path_compare (src_path, dst_path) < 0)
- gtk_tree_path_prev (dst_path);
-
- /* convert iters */
- src_path = gtk_tree_model_get_path (model, &iter);
- child_src_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), src_path);
- child_dst_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), dst_path);
- gtk_tree_path_free (src_path);
-
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-
- /* perform the move */
- thunar_shortcuts_model_move (THUNAR_SHORTCUTS_MODEL (child_model), child_src_path, child_dst_path);
-
- gtk_tree_path_free (child_src_path);
- gtk_tree_path_free (child_dst_path);
-
- /* make sure the new position is selectde */
- gtk_tree_selection_select_path (selection, dst_path);
- }
-
- /* release the dst path */
- gtk_tree_path_free (dst_path);
-
- /* finish the dnd operation */
- gtk_drag_finish (context, TRUE, FALSE, timestamp);
- }
- else
- {
- /* we cannot handle the drop */
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_drag_motion (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint timestamp)
-{
- GtkTreeViewDropPosition position = GTK_TREE_VIEW_DROP_BEFORE;
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
- GdkDragAction action = 0;
- GtkTreeModel *model;
- GtkTreePath *path = NULL;
- GdkAtom target;
-
- /* reset the "drop-file" of the icon renderer */
- g_object_set (G_OBJECT (view->icon_renderer), "drop-file", NULL, NULL);
-
- /* determine the drag target */
- target = gtk_drag_dest_find_target (widget, context, NULL);
- if (target == gdk_atom_intern_static_string ("text/uri-list"))
- {
- /* request the drop data on-demand (if we don't have it already) */
- if (G_UNLIKELY (!view->drop_data_ready))
- {
- /* request the drag data from the source */
- gtk_drag_get_data (widget, context, target, timestamp);
-
- /* gdk_drag_status() will be called by drag_data_received */
- return TRUE;
- }
- else
- {
- /* compute the drop position */
- thunar_shortcuts_view_compute_drop_actions (view, context, x, y, &path, &action, &position);
- }
- }
- else if (target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
- {
- /* check the action that should be performed */
- if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_LINK || (gdk_drag_context_get_actions (context) & GDK_ACTION_LINK) != 0)
- action = GDK_ACTION_LINK;
- else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_COPY || (gdk_drag_context_get_actions (context) & GDK_ACTION_COPY) != 0)
- action = GDK_ACTION_COPY;
- else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE || (gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) != 0)
- action = GDK_ACTION_MOVE;
- else
- return FALSE;
-
- /* compute the drop position for the coordinates */
- path = thunar_shortcuts_view_compute_drop_position (view, x, y);
- if (path == NULL)
- return FALSE;
-
- /* check if path is about to append to the model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- if (gtk_tree_path_get_indices (path)[0] >= gtk_tree_model_iter_n_children (model, NULL))
- {
- /* set the position to "after" and move the path to
- * point to the previous row instead; required to
- * get the highlighting in GtkTreeView correct.
- */
- position = GTK_TREE_VIEW_DROP_AFTER;
- gtk_tree_path_prev (path);
- }
- }
- else
- {
- /* we cannot handle the drop */
- return FALSE;
- }
-
- /* check if we have a drop path */
- if (G_LIKELY (path != NULL))
- {
- /* highlight the appropriate row */
- gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), path, position);
- gtk_tree_path_free (path);
- }
-
- /* tell Gdk whether we can drop here */
- gdk_drag_status (context, action, timestamp);
-
- return TRUE;
-}
-
-
-
-static void
-thunar_shortcuts_view_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint timestamp)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
-
- /* reset the "drop-file" of the icon renderer */
- g_object_set (G_OBJECT (view->icon_renderer), "drop-file", NULL, NULL);
-
- /* reset the "drop data ready" status and free the URI list */
- if (G_LIKELY (view->drop_data_ready))
- {
- thunar_g_file_list_free (view->drop_file_list);
- view->drop_data_ready = FALSE;
- view->drop_file_list = NULL;
- }
-
- /* schedule a repaint to make sure the special drop icon for the target row
- * is reset to its default (http://bugzilla.xfce.org/show_bug.cgi?id=2498).
- */
- gtk_widget_queue_draw (widget);
-
- /* call the parent's handler */
- (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->drag_leave) (widget, context, timestamp);
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_popup_menu (GtkWidget *widget)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- /* determine the selection for the tree view */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-
- /* determine the selected row */
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* popup the context menu */
- thunar_shortcuts_view_context_menu (view, NULL, model, &iter);
- return TRUE;
- }
- else if (GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->popup_menu != NULL)
- {
- /* call the parent's "popup-menu" handler */
- return (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->popup_menu) (widget);
- }
-
- return FALSE;
-}
-
-
-
-static void
-thunar_shortcuts_view_row_activated (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (tree_view);
-
- /* call the parent's "row-activated" handler */
- if (GTK_TREE_VIEW_CLASS (thunar_shortcuts_view_parent_class)->row_activated != NULL)
- (*GTK_TREE_VIEW_CLASS (thunar_shortcuts_view_parent_class)->row_activated) (tree_view, path, column);
-
- /* open the selected shortcut */
- thunar_shortcuts_view_open (view, OPEN_IN_VIEW);
-}
-
-
-
-static gboolean
-thunar_shortcuts_view_selection_func (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer user_data)
-{
- GtkTreeIter iter;
- gboolean is_header;
-
- /* don't allow selecting headers */
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER, &is_header, -1);
- return !is_header;
-}
-
-
-
-static void
-thunar_shortcuts_view_context_menu_visibility_toggled (GtkCheckMenuItem *item,
- GtkTreeModel *model)
-{
- gboolean hidden;
- GtkTreePath *path;
- GtkTreeRowReference *row;
-
- _thunar_return_if_fail (GTK_IS_CHECK_MENU_ITEM (item));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-
- row = g_object_get_data (G_OBJECT (item), I_("thunar-shortcuts-row"));
- path = gtk_tree_row_reference_get_path (row);
- if (G_LIKELY (path != NULL))
- {
- hidden = !gtk_check_menu_item_get_active (item);
- thunar_shortcuts_model_set_hidden (THUNAR_SHORTCUTS_MODEL (model), path, hidden);
- gtk_tree_path_free (path);
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_context_menu_visibility (ThunarShortcutsView *view,
- GdkEventButton *event,
- GtkTreeModel *model)
-{
- GtkTreeIter iter;
- guint mask = 0;
- ThunarShortcutGroup group;
- GtkWidget *menu;
- GtkWidget *mi;
- gchar *label;
- GtkTreeSelection *selection;
- gboolean visible;
- GtkTreePath *path;
- GtkTreeModel *child_model;
- GtkWidget *submenu;
-
- /* unselect the items */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- gtk_tree_selection_unselect_all (GTK_TREE_SELECTION (selection));
-
- /* prepare the popup menu */
- menu = submenu = gtk_menu_new ();
-
- /* process all items below the header */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (child_model), &iter))
- return;
- path = gtk_tree_model_get_path (child_model, &iter);
- do
- {
- /* get all the info */
- gtk_tree_model_get (GTK_TREE_MODEL (child_model), &iter,
- THUNAR_SHORTCUTS_MODEL_COLUMN_GROUP, &group,
- THUNAR_SHORTCUTS_MODEL_COLUMN_NAME, &label,
- THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE, &visible,
- -1);
-
- if ((group & THUNAR_SHORTCUT_GROUP_HEADER) != 0)
- {
- /* get the mask of the group */
- if ((group & THUNAR_SHORTCUT_GROUP_DEVICES) != 0)
- mask = THUNAR_SHORTCUT_GROUP_DEVICES;
- else if ((group & THUNAR_SHORTCUT_GROUP_PLACES) != 0)
- mask = THUNAR_SHORTCUT_GROUP_PLACES;
- else if ((group & THUNAR_SHORTCUT_GROUP_NETWORK) != 0)
- mask = THUNAR_SHORTCUT_GROUP_NETWORK;
- else
- _thunar_assert_not_reached ();
-
- /* create menu items */
- mi = gtk_menu_item_new_with_label (label);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
- gtk_widget_show (mi);
-
- submenu = gtk_menu_new ();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), submenu);
- }
- else if ((group & mask) != 0)
- {
- mi = gtk_check_menu_item_new_with_label (label);
- gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi);
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), visible);
- g_object_set_data_full (G_OBJECT (mi), I_("thunar-shortcuts-row"),
- gtk_tree_row_reference_new (child_model, path),
- (GDestroyNotify) gtk_tree_row_reference_free);
- g_signal_connect (G_OBJECT (mi), "toggled",
- G_CALLBACK (thunar_shortcuts_view_context_menu_visibility_toggled), child_model);
- gtk_widget_show (mi);
- }
-
- g_free (label);
- gtk_tree_path_next (path);
- }
- while (gtk_tree_model_iter_next (child_model, &iter));
-
- gtk_tree_path_free (path);
-
- /* run the menu on the view's screen (taking over the floating reference on menu) */
- thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (view), NULL, NULL,
- (event != NULL) ? event->button : 0,
- (event != NULL) ? event->time : gtk_get_current_event_time ());
-}
-
-
-
-static void
-thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
- GdkEventButton *event,
- GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- GtkTreePath *path;
- ThunarFile *file;
- GtkWidget *image;
- GtkWidget *menu;
- GtkWidget *item;
- GtkWidget *window;
- gboolean mutable;
- ThunarDevice *device;
- GList *providers, *lp;
- GList *actions = NULL, *tmp;
- ThunarShortcutGroup group;
- gboolean is_header;
- GFile *mount_point;
- GtkTreeModel *shortcuts_model;
- gboolean can_mount;
- gboolean can_unmount;
- gboolean can_eject;
-
- /* check if this is an item menu or a header menu */
- gtk_tree_model_get (model, iter, THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER, &is_header, -1);
- if (is_header)
- {
- thunar_shortcuts_view_context_menu_visibility (view, event, model);
- return;
- }
-
- /* determine the tree path for the given iter */
- path = gtk_tree_model_get_path (model, iter);
- if (G_UNLIKELY (path == NULL))
- return;
-
- /* check whether the shortcut at the given path is mutable */
- gtk_tree_model_get (model, iter,
- THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file,
- THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device,
- THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE, &mutable,
- THUNAR_SHORTCUTS_MODEL_COLUMN_GROUP, &group,
- -1);
-
- /* prepare the popup menu */
- menu = gtk_menu_new ();
-
- /* append the "Open" menu action */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Open"));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_clicked), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* set the stock icon */
- image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
-
- /* append the "Open in New Tab" menu action */
- item = gtk_image_menu_item_new_with_mnemonic (_("Open in New Tab"));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_in_new_tab_clicked), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* append the "Open in New Window" menu action */
- item = gtk_image_menu_item_new_with_mnemonic (_("Open in New Window"));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_in_new_window_clicked), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- switch (group)
- {
- case THUNAR_SHORTCUT_GROUP_DEVICES_VOLUMES:
- can_mount = thunar_device_can_mount (device);
- can_unmount = thunar_device_can_unmount (device);
- can_eject = thunar_device_can_eject (device);
-
- if (!can_mount && !can_unmount && !can_eject)
- break;
-
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* append the "Mount" item */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Mount"));
- gtk_widget_set_visible (item, can_mount);
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_mount), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- /* append the "Unmount" item */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount"));
- gtk_widget_set_visible (item, can_unmount);
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_unmount), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- /* append the "Disconnect" (eject + safely remove drive) item */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Eject"));
- gtk_widget_set_visible (item, can_eject);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_eject), view);
- break;
-
- case THUNAR_SHORTCUT_GROUP_NETWORK_MOUNTS:
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* get the mount point */
- mount_point = thunar_device_get_root (device);
- shortcuts_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-
- /* append the "Disconnect" item */
- item = gtk_image_menu_item_new_with_mnemonic (_("Create _Shortcut"));
- gtk_widget_set_sensitive (item, mount_point != NULL && !thunar_shortcuts_model_has_bookmark (THUNAR_SHORTCUTS_MODEL (shortcuts_model), mount_point));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_create_shortcut), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- image = gtk_image_new_from_stock (THUNAR_STOCK_SHORTCUTS, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
-
- if (mount_point != NULL)
- g_object_unref (mount_point);
-
- /* fall-through */
-
- case THUNAR_SHORTCUT_GROUP_DEVICES_MOUNTS:
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* append the "Disconnect" item */
- item = gtk_image_menu_item_new_with_mnemonic (_("Disconn_ect"));
- gtk_widget_set_sensitive (item, thunar_device_can_eject (device));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_eject), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- image = gtk_image_new_from_stock (GTK_STOCK_DISCONNECT, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- break;
-
- case THUNAR_SHORTCUT_GROUP_PLACES_TRASH:
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* append the "Empty Trash" menu action */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Empty Trash"));
- gtk_widget_set_sensitive (item, (thunar_file_get_item_count (file) > 0));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_empty_trash), view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
- break;
-
- default:
- break;
- }
-
- /* create provider menu items if there is a non-trashed file */
- if (G_LIKELY (file != NULL && !thunar_file_is_trashed (file)))
- {
- /* load the menu providers from the provider factory */
- providers = thunarx_provider_factory_list_providers (view->provider_factory, THUNARX_TYPE_MENU_PROVIDER);
- if (G_LIKELY (providers != NULL))
- {
- /* determine the toplevel window we belong to */
- window = gtk_widget_get_toplevel (GTK_WIDGET (view));
-
- /* load the actions offered by the menu providers */
- for (lp = providers; lp != NULL; lp = lp->next)
- {
- tmp = thunarx_menu_provider_get_folder_actions (lp->data, window, THUNARX_FILE_INFO (file));
- actions = g_list_concat (actions, tmp);
- g_object_unref (G_OBJECT (lp->data));
- }
- g_list_free (providers);
-
- if (actions != NULL)
- {
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
- }
-
- /* add the actions to the menu */
- for (lp = actions; lp != NULL; lp = lp->next)
- {
- item = gtk_action_create_menu_item (GTK_ACTION (lp->data));
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* release the reference on the action */
- g_object_unref (G_OBJECT (lp->data));
- }
-
- /* cleanup */
- g_list_free (actions);
- }
- }
-
- /* append the remove menu item */
- if (group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
- {
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Shortcut"));
- g_object_set_data_full (G_OBJECT (item), I_("thunar-shortcuts-row"),
- gtk_tree_row_reference_new (model, path),
- (GDestroyNotify) gtk_tree_row_reference_free);
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_remove_activated), model);
- gtk_widget_set_sensitive (item, mutable);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* set the remove stock icon */
- image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
-
- /* append the rename menu item */
- item = gtk_image_menu_item_new_with_mnemonic (_("Re_name Shortcut"));
- g_object_set_data_full (G_OBJECT (item), I_("thunar-shortcuts-row"),
- gtk_tree_row_reference_new (model, path),
- (GDestroyNotify) gtk_tree_row_reference_free);
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_rename_activated), view);
- gtk_widget_set_sensitive (item, mutable);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- gtk_widget_show (item);
- }
-
- /* clean up */
- if (G_LIKELY (file != NULL))
- g_object_unref (G_OBJECT (file));
- if (G_UNLIKELY (device != NULL))
- g_object_unref (G_OBJECT (device));
- gtk_tree_path_free (path);
-
- /* run the menu on the view's screen (taking over the floating reference on menu) */
- thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (view), NULL, NULL, (event != NULL) ? event->button : 0,
- (event != NULL) ? event->time : gtk_get_current_event_time ());
-}
-
-
-
-static void
-thunar_shortcuts_view_remove_activated (GtkWidget *item,
- GtkTreeModel *model)
-{
- GtkTreeRowReference *row;
- GtkTreeModel *child_model;
- GtkTreePath *path;
- GtkTreePath *child_path;
-
- row = g_object_get_data (G_OBJECT (item), I_("thunar-shortcuts-row"));
- path = gtk_tree_row_reference_get_path (row);
- if (G_LIKELY (path != NULL))
- {
- child_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), path);
- gtk_tree_path_free (path);
-
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_remove (THUNAR_SHORTCUTS_MODEL (child_model), child_path);
- gtk_tree_path_free (child_path);
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_editing_canceled (GtkCellRenderer *renderer,
- ThunarShortcutsView *view)
-{
- g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
-
- g_signal_handlers_disconnect_by_func (G_OBJECT (renderer),
- G_CALLBACK (thunar_shortcuts_view_editing_canceled),
- view);
-}
-
-
-
-static void
-thunar_shortcuts_view_rename_activated (GtkWidget *item,
- ThunarShortcutsView *view)
-{
- GtkTreeRowReference *row;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkTreePath *path;
- GList *renderers;
-
- row = g_object_get_data (G_OBJECT (item), I_("thunar-shortcuts-row"));
- path = gtk_tree_row_reference_get_path (row);
- if (G_LIKELY (path != NULL))
- {
- /* determine the text renderer */
- column = gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0);
- renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
- renderer = g_list_nth_data (renderers, 3);
-
- /* make sure the text renderer is editable */
- g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
-
- /* set up signals for the cell renderer */
- g_signal_connect (G_OBJECT (renderer), "editing-canceled",
- G_CALLBACK (thunar_shortcuts_view_editing_canceled), view);
-
- /* tell the tree view to start editing the given row */
- gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (view), path, column, renderer, TRUE);
-
- /* cleanup */
- gtk_tree_path_free (path);
- g_list_free (renderers);
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_renamed (GtkCellRenderer *renderer,
- const gchar *path_string,
- const gchar *text,
- ThunarShortcutsView *view)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreeModel *child_model;
- GtkTreeIter child_iter;
-
- /* reset the editable flag */
- g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
-
- /* perform the rename */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- if (gtk_tree_model_get_iter_from_string (model, &iter, path_string))
- {
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, &iter);
- thunar_shortcuts_model_rename (THUNAR_SHORTCUTS_MODEL (child_model), &child_iter, text);
- }
-}
-
-
-
-static GdkDragAction
-thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView *view,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkTreePath **path_return,
- GdkDragAction *action_return,
- GtkTreeViewDropPosition *position_return)
-{
- GtkTreeViewColumn *column;
- GdkDragAction actions = 0;
- GdkRectangle cell_area;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- ThunarFile *file;
- gint cell_y;
-
- /* determine the shortcuts model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
-
- /* determine the path for x/y */
- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x, y, &path, &column, NULL, &cell_y))
- {
- /* determine the background area of the column */
- gtk_tree_view_get_background_area (GTK_TREE_VIEW (view), path, column, &cell_area);
-
- /* check if 1/6th inside the cell and the path is within the model */
- if ((cell_y > (cell_area.height / 6) && cell_y < (cell_area.height - cell_area.height / 6))
- && gtk_tree_model_get_iter (model, &iter, path))
- {
- /* determine the file for the iterator */
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, -1);
- if (G_LIKELY (file != NULL))
- {
- /* check if the file accepts the drop */
- actions = thunar_file_accepts_drop (file, view->drop_file_list, context, action_return);
- if (G_LIKELY (actions != 0))
- {
- /* we can drop into this location */
- *position_return = GTK_TREE_VIEW_DROP_INTO_OR_AFTER;
- *path_return = gtk_tree_path_copy (path);
-
- /* display a drop icon for the file */
- g_object_set (G_OBJECT (view->icon_renderer), "drop-file", file, NULL);
- }
-
- /* release the file */
- g_object_unref (G_OBJECT (file));
- }
- }
-
- /* release the path */
- gtk_tree_path_free (path);
- }
-
- /* check if we cannot drop into the shortcut */
- if (G_UNLIKELY (actions == 0))
- {
- /* check the action that should be performed */
- if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_LINK || (gdk_drag_context_get_actions (context) & GDK_ACTION_LINK) != 0)
- actions = GDK_ACTION_LINK;
- else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_COPY || (gdk_drag_context_get_actions (context) & GDK_ACTION_COPY) != 0)
- actions = GDK_ACTION_COPY;
- else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE || (gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) != 0)
- actions = GDK_ACTION_MOVE;
- else
- return 0;
-
- /* but maybe we can add as shortcut */
- path = thunar_shortcuts_view_compute_drop_position (view, x, y);
-
- if (path == NULL)
- return 0;
-
- /* check if path is about to append to the model */
- if (gtk_tree_path_get_indices (path)[0] >= gtk_tree_model_iter_n_children (model, NULL))
- {
- /* set the position to "after" and move the path to
- * point to the previous row instead; required to
- * get the highlighting in GtkTreeView correct.
- */
- *position_return = GTK_TREE_VIEW_DROP_AFTER;
- gtk_tree_path_prev (path);
- }
- else
- {
- /* drop before the path */
- *position_return = GTK_TREE_VIEW_DROP_BEFORE;
- }
-
- /* got it */
- *action_return = actions;
- *path_return = path;
- }
-
- return actions;
-}
-
-
-
-static GtkTreePath*
-thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView *view,
- gint x,
- gint y)
-{
- GtkTreeViewColumn *column;
- GtkTreeModel *model;
- GdkRectangle area;
- GtkTreePath *path;
- gint n_rows;
- gboolean result;
- GtkTreePath *child_path;
- GtkTreeModel *child_model;
-
- _thunar_return_val_if_fail (gtk_tree_view_get_model (GTK_TREE_VIEW (view)) != NULL, NULL);
- _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), NULL);
-
- /* query the number of rows in the model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- n_rows = gtk_tree_model_iter_n_children (model, NULL);
-
- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x, y,
- &path, &column, &x, &y))
- {
- /* determine the exact path of the row the user is trying to drop
- * (taking into account the relative y position)
- */
- gtk_tree_view_get_background_area (GTK_TREE_VIEW (view), path, column, &area);
- if (y >= area.height / 2)
- gtk_tree_path_next (path);
-
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-
- /* find a suitable drop path (we cannot drop into the default shortcuts list) */
- for (; gtk_tree_path_get_indices (path)[0] < n_rows; gtk_tree_path_next (path))
- {
- child_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), path);
- result = thunar_shortcuts_model_drop_possible (THUNAR_SHORTCUTS_MODEL (child_model), child_path);
- gtk_tree_path_free (child_path);
- if (result)
- return path;
- }
-
- gtk_tree_path_free (path);
- }
-
- return NULL;
-}
-
-
-
-static void
-thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view,
- GList *path_list,
- GtkTreePath *dst_path)
-{
- GtkTreeModel *model;
- GtkTreePath *path;
- ThunarFile *file;
- GError *error = NULL;
- GList *lp;
- GtkTreeModel *child_model;
- GtkTreePath *child_path;
-
- /* take a copy of the destination path */
- path = gtk_tree_path_copy (dst_path);
-
- /* process the URIs one-by-one and stop on error */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- for (lp = path_list; lp != NULL; lp = lp->next)
- {
- file = thunar_file_get (lp->data, &error);
- if (G_UNLIKELY (file == NULL))
- break;
-
- /* make sure, that only directories gets added to the shortcuts list */
- if (G_UNLIKELY (!thunar_file_is_directory (file)))
- {
- g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR,
- _("The path \"%s\" does not refer to a directory"),
- thunar_file_get_display_name (file));
- g_object_unref (file);
- break;
- }
-
- child_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), path);
- thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (child_model), child_path, file);
- gtk_tree_path_free (child_path);
-
- g_object_unref (file);
- gtk_tree_path_next (path);
- }
-
- /* release the tree path copy */
- gtk_tree_path_free (path);
-
- if (G_UNLIKELY (error != NULL))
- {
- /* display an error message to the user */
- thunar_dialogs_show_error (GTK_WIDGET (view), error, _("Failed to add new shortcut"));
-
- /* release the error */
- g_error_free (error);
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_open_clicked (ThunarShortcutsView *view)
-{
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
- thunar_shortcuts_view_open (view, OPEN_IN_VIEW);
-}
-
-
-
-static void
-thunar_shortcuts_view_poke_file_finish (ThunarBrowser *browser,
- ThunarFile *file,
- ThunarFile *target_file,
- GError *error,
- gpointer user_data)
-{
- ThunarApplication *application;
- OpenTarget open_in = GPOINTER_TO_UINT (user_data);
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
- _thunar_return_if_fail (THUNAR_IS_FILE (target_file));
-
- if (error == NULL)
- {
- if (open_in == OPEN_IN_WINDOW)
- {
- /* open a new window for the target folder */
- application = thunar_application_get ();
- thunar_application_open_window (application, target_file,
- gtk_widget_get_screen (GTK_WIDGET (browser)), NULL);
- g_object_unref (application);
- }
- else if (open_in == OPEN_IN_TAB)
- {
- /* invoke the signal to change to open folder in a new tab */
- g_signal_emit (browser, view_signals[SHORTCUT_ACTIVATED_TAB], 0, target_file);
- }
- else if (thunar_file_check_loaded (target_file))
- {
- /* invoke the signal to change to that folder */
- g_signal_emit (browser, view_signals[SHORTCUT_ACTIVATED], 0, target_file);
- }
- }
- else
- {
- thunar_dialogs_show_error (GTK_WIDGET (browser), error, _("Failed to open \"%s\""),
- thunar_file_get_display_name (file));
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_poke_location_finish (ThunarBrowser *browser,
- GFile *location,
- ThunarFile *file,
- ThunarFile *target_file,
- GError *error,
- gpointer user_data)
-{
- gchar *name;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
- _thunar_return_if_fail (G_IS_FILE (location));
-
- /* sotre the new file in the shortcuts model */
- if (error == NULL)
- {
- thunar_shortcuts_view_poke_file_finish (browser, file, target_file, error, user_data);
- }
- else
- {
- name = thunar_g_file_get_display_name_remote (location);
- thunar_dialogs_show_error (GTK_WIDGET (browser), error, _("Failed to open \"%s\""), name);
- g_free (name);
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_poke_device_finish (ThunarBrowser *browser,
- ThunarDevice *device,
- ThunarFile *mount_point,
- GError *error,
- gpointer user_data)
-{
- gchar *device_name;
- GtkTreeModel *model;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
-
- if (error == NULL)
- {
- thunar_browser_poke_file (browser, mount_point, GTK_WIDGET (browser),
- thunar_shortcuts_view_poke_file_finish,
- user_data);
- }
- else
- {
- device_name = thunar_device_get_name (device);
- thunar_dialogs_show_error (GTK_WIDGET (browser), error,
- _("Failed to mount \"%s\""), device_name);
- g_free (device_name);
- }
-
- /* stop the spinner */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (browser));
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, FALSE);
-}
-
-
-
-static void
-thunar_shortcuts_view_open (ThunarShortcutsView *view,
- OpenTarget open_in)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- ThunarFile *file;
- ThunarDevice *device;
- GFile *location;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* determine the selected item */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-
- /* avoid dealing with invalid selections */
- if (!GTK_IS_TREE_SELECTION (selection))
- return;
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* determine the file for the shortcut at the given tree iterator */
- gtk_tree_model_get (model, &iter,
- THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file,
- THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device,
- THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION, &location,
- -1);
-
- if (G_LIKELY (device != NULL))
- {
- /* start the spinner */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
-
- thunar_browser_poke_device (THUNAR_BROWSER (view), device, view,
- thunar_shortcuts_view_poke_device_finish,
- GUINT_TO_POINTER (open_in));
- }
- else if (file != NULL)
- {
- thunar_browser_poke_file (THUNAR_BROWSER (view), file, view,
- thunar_shortcuts_view_poke_file_finish,
- GUINT_TO_POINTER (open_in));
- }
- else if (location != NULL)
- {
- thunar_browser_poke_location (THUNAR_BROWSER (view), location, view,
- thunar_shortcuts_view_poke_location_finish,
- GUINT_TO_POINTER (open_in));
- }
-
- if (file != NULL)
- g_object_unref (file);
-
- if (device != NULL)
- g_object_unref (device);
-
- if (location != NULL)
- g_object_unref (location);
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_open_in_new_window_clicked (ThunarShortcutsView *view)
-{
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
- thunar_shortcuts_view_open (view, OPEN_IN_WINDOW);
-}
-
-
-
-static void
-thunar_shortcuts_view_open_in_new_tab_clicked (ThunarShortcutsView *view)
-{
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
- thunar_shortcuts_view_open (view, OPEN_IN_TAB);
-}
-
-
-
-static void
-thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view)
-{
- ThunarApplication *application;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* empty the trash bin (asking the user first) */
- application = thunar_application_get ();
- thunar_application_empty_trash (application, GTK_WIDGET (view), NULL);
- g_object_unref (G_OBJECT (application));
-}
-
-
-
-static void
-thunar_shortcuts_view_create_shortcut (ThunarShortcutsView *view)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- ThunarDevice *device;
- GFile *mount_point;
- GtkTreeModel *shortcuts_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* determine the selected item */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* determine the device/mount for the shortcut at the given tree iterator */
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
-
- /* add the mount point to the model */
- mount_point = thunar_device_get_root (device);
- if (mount_point != NULL)
- {
- shortcuts_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (shortcuts_model), NULL, mount_point);
- g_object_unref (mount_point);
- }
-
- g_object_unref (G_OBJECT (device));
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_eject_finish (ThunarDevice *device,
- const GError *error,
- gpointer user_data)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (user_data);
- gchar *device_name;
- GtkTreeModel *model;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* check if there was an error */
- if (error != NULL)
- {
- /* display an error dialog to inform the user */
- device_name = thunar_device_get_name (device);
- thunar_dialogs_show_error (GTK_WIDGET (view), error, _("Failed to eject \"%s\""), device_name);
- g_free (device_name);
- }
-
- /* stop the spinner */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, FALSE);
-
- g_object_unref (view);
-}
-
-
-
-static void
-thunar_shortcuts_view_eject (ThunarShortcutsView *view)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- ThunarDevice *device;
- GMountOperation *mount_operation;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* determine the selected item */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* determine the device/mount for the shortcut at the given tree iterator */
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
-
- /* prepare a mount operation */
- mount_operation = thunar_gtk_mount_operation_new (GTK_WIDGET (view));
-
- /* start the spinner */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
-
- /* try to unmount */
- thunar_device_eject (device,
- mount_operation,
- NULL,
- thunar_shortcuts_view_eject_finish,
- g_object_ref (view));
-
- g_object_unref (G_OBJECT (device));
- g_object_unref (G_OBJECT (mount_operation));
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_poke_device_mount_finish (ThunarBrowser *browser,
- ThunarDevice *device,
- ThunarFile *mount_point,
- GError *error,
- gpointer ignored)
-{
- gchar *device_name;
- GtkTreeModel *model;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
-
- if (error != NULL)
- {
- device_name = thunar_device_get_name (device);
- thunar_dialogs_show_error (GTK_WIDGET (browser), error,
- _("Failed to mount \"%s\""), device_name);
- g_free (device_name);
- }
-
- /* stop the spinner */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (browser));
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, FALSE);
-}
-
-
-
-static void
-thunar_shortcuts_view_mount (ThunarShortcutsView *view)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- ThunarDevice *device;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* determine the selected item */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-
- /* avoid dealing with invalid selections */
- if (!GTK_IS_TREE_SELECTION (selection))
- return;
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* determine the file for the shortcut at the given tree iterator */
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
-
- if (G_LIKELY (device != NULL))
- {
- /* start the spinner */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
-
- thunar_browser_poke_device (THUNAR_BROWSER (view), device, view,
- thunar_shortcuts_view_poke_device_mount_finish,
- NULL);
- g_object_unref (device);
- }
- }
-}
-
-
-
-static void
-thunar_shortcuts_view_unmount_finish (ThunarDevice *device,
- const GError *error,
- gpointer user_data)
-{
- ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (user_data);
- gchar *device_name;
- GtkTreeModel *model;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* check if there was an error */
- if (error != NULL)
- {
- /* display an error dialog to inform the user */
- device_name = thunar_device_get_name (device);
- thunar_dialogs_show_error (GTK_WIDGET (view), error, _("Failed to unmount \"%s\""), device_name);
- g_free (device_name);
- }
-
- /* stop the spinner */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, FALSE);
-
- g_object_unref (view);
-}
-
-
-
-static void
-thunar_shortcuts_view_unmount (ThunarShortcutsView *view)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- ThunarDevice *device;
- GMountOperation *mount_operation;
- GtkTreeModel *child_model;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
-
- /* determine the selected item */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- /* determine the device/mount for the shortcut at the given tree iterator */
- gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
- _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
-
- /* prepare a mount operation */
- mount_operation = thunar_gtk_mount_operation_new (GTK_WIDGET (view));
-
- /* start the spinner */
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
- thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
-
- /* try to unmount */
- thunar_device_unmount (device,
- mount_operation,
- NULL,
- thunar_shortcuts_view_unmount_finish,
- g_object_ref (view));
-
- g_object_unref (G_OBJECT (device));
- g_object_unref (G_OBJECT (mount_operation));
- }
-}
-
-
-
-/**
- * thunar_shortcuts_view_new:
- *
- * Allocates a new #ThunarShortcutsView instance and associates
- * it with the default #ThunarShortcutsModel instance.
- *
- * Return value: the newly allocated #ThunarShortcutsView instance.
- **/
-GtkWidget*
-thunar_shortcuts_view_new (void)
-{
- ThunarShortcutsModel *model;
- GtkWidget *view;
- GtkTreeModel *filter_model;
-
- model = thunar_shortcuts_model_get_default ();
- filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (model), NULL);
- gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE);
- g_object_unref (G_OBJECT (model));
-
- view = g_object_new (THUNAR_TYPE_SHORTCUTS_VIEW, "model", filter_model, NULL);
- g_object_unref (G_OBJECT (filter_model));
-
- return view;
-}
-
-
-
-/**
- * thunar_shortcuts_view_select_by_file:
- * @view : a #ThunarShortcutsView instance.
- * @file : a #ThunarFile instance.
- *
- * Looks up the first shortcut that refers to @file in @view and selects it.
- * If @file is not present in the underlying #ThunarShortcutsModel, no
- * shortcut will be selected afterwards.
- **/
-void
-thunar_shortcuts_view_select_by_file (ThunarShortcutsView *view,
- ThunarFile *file)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreeModel *child_model;
- GtkTreeIter child_iter;
-
- _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
- _thunar_return_if_fail (THUNAR_IS_FILE (file));
-
- /* get the selection */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-
- /* try to lookup a tree iter for the given file */
- if (thunar_shortcuts_model_iter_for_file (THUNAR_SHORTCUTS_MODEL (child_model), file, &child_iter)
- && gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (model), &iter, &child_iter))
- gtk_tree_selection_select_iter (selection, &iter);
- else
- gtk_tree_selection_unselect_all (selection);
-}
-
-
diff --git a/thunar/thunar-shortcuts-view.h b/thunar/thunar-shortcuts-view.h
deleted file mode 100644
index 5f81f0b..0000000
--- a/thunar/thunar-shortcuts-view.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __THUNAR_SHORTCUTS_VIEW_H__
-#define __THUNAR_SHORTCUTS_VIEW_H__
-
-#include <thunar/thunar-file.h>
-
-G_BEGIN_DECLS;
-
-typedef struct _ThunarShortcutsViewClass ThunarShortcutsViewClass;
-typedef struct _ThunarShortcutsView ThunarShortcutsView;
-
-#define THUNAR_TYPE_SHORTCUTS_VIEW (thunar_shortcuts_view_get_type ())
-#define THUNAR_SHORTCUTS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_SHORTCUTS_VIEW, ThunarShortcutsView))
-#define THUNAR_SHORTCUTS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_SHORTCUTS_VIEW, ThunarShortcutsViewClass))
-#define THUNAR_IS_SHORTCUTS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_SHORTCUTS_VIEW))
-#define THUNAR_IS_SHORTCUTS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SHORTCUTS_VIEW))
-#define THUNAR_SHORTCUTS_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_SHORTCUTS_VIEW, ThunarShortcutsViewClass))
-
-GType thunar_shortcuts_view_get_type (void) G_GNUC_CONST;
-
-GtkWidget *thunar_shortcuts_view_new (void) G_GNUC_MALLOC;
-
-void thunar_shortcuts_view_select_by_file (ThunarShortcutsView *view,
- ThunarFile *file);
-
-G_END_DECLS;
-
-#endif /* !__THUNAR_SHORTCUTS_VIEW_H__ */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list