[Xfce4-commits] <thunar:nick/new-shortcuts-pane-model> Make hiding items in the sidepane work.
Nick Schermer
noreply at xfce.org
Thu Oct 11 21:22:02 CEST 2012
Updating branch refs/heads/nick/new-shortcuts-pane-model
to 674980f42b30e2c23a8bba6327b0a28d46a35eb1 (commit)
from 84e148d3d35a3dd07d29d244328b84957ec9a876 (commit)
commit 674980f42b30e2c23a8bba6327b0a28d46a35eb1
Author: Nick Schermer <nick at xfce.org>
Date: Thu Oct 11 21:20:04 2012 +0200
Make hiding items in the sidepane work.
Make the model work on top of a filter model and implement
hiding including related code and some small related
improvements.
thunar/thunar-device-monitor.c | 204 +++++++++++-
thunar/thunar-device-monitor.h | 4 +
thunar/thunar-device.c | 65 ++++-
thunar/thunar-device.h | 4 +
thunar/thunar-launcher-ui.xml | 2 +
thunar/thunar-launcher.c | 31 ++-
thunar/thunar-preferences.c | 83 ++++-
thunar/thunar-shortcuts-model.c | 700 ++++++++++++++++++++++++++-------------
thunar/thunar-shortcuts-model.h | 69 +++--
thunar/thunar-shortcuts-pane.c | 10 +-
thunar/thunar-shortcuts-view.c | 278 +++++++++++++---
11 files changed, 1104 insertions(+), 346 deletions(-)
diff --git a/thunar/thunar-device-monitor.c b/thunar/thunar-device-monitor.c
index c8dd712..a704bd0 100644
--- a/thunar/thunar-device-monitor.c
+++ b/thunar/thunar-device-monitor.c
@@ -29,6 +29,7 @@
#include <thunar/thunar-device-monitor.h>
#include <thunar/thunar-private.h>
#include <thunar/thunar-marshal.h>
+#include <thunar/thunar-preferences.h>
@@ -42,9 +43,26 @@ enum
LAST_SIGNAL
};
+enum
+{
+ PROP_0,
+ PROP_HIDDEN_DEVICES
+};
+
static void thunar_device_monitor_finalize (GObject *object);
+static void thunar_device_monitor_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void thunar_device_monitor_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void thunar_device_monitor_update_hidden (gpointer key,
+ gpointer value,
+ gpointer data);
static void thunar_device_monitor_volume_added (GVolumeMonitor *volume_monitor,
GVolume *volume,
ThunarDeviceMonitor *monitor);
@@ -89,12 +107,17 @@ struct _ThunarDeviceMonitor
{
GObject __parent__;
- GVolumeMonitor *volume_monitor;
+ GVolumeMonitor *volume_monitor;
/* GVolume/GMount -> ThunarDevice */
- GHashTable *devices;
+ GHashTable *devices;
+
+ /* GVolumes from GVolumeMonitor that are currently invisible */
+ GList *hidden_volumes;
- GList *hidden_volumes;
+ /* user defined hidden volumes */
+ ThunarPreferences *preferences;
+ gchar **hidden_devices;
};
@@ -114,6 +137,16 @@ thunar_device_monitor_class_init (ThunarDeviceMonitorClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = thunar_device_monitor_finalize;
+ gobject_class->get_property = thunar_device_monitor_get_property;
+ gobject_class->set_property = thunar_device_monitor_set_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_HIDDEN_DEVICES,
+ g_param_spec_boxed ("hidden-devices",
+ NULL,
+ NULL,
+ G_TYPE_STRV,
+ EXO_PARAM_READWRITE));
device_monitor_signals[DEVICE_ADDED] =
g_signal_new (I_("device-added"),
@@ -161,6 +194,10 @@ thunar_device_monitor_init (ThunarDeviceMonitor *monitor)
GList *list;
GList *lp;
+ monitor->preferences = thunar_preferences_get ();
+ exo_binding_new (G_OBJECT (monitor->preferences), "hidden-devices",
+ G_OBJECT (monitor), "hidden-devices");
+
/* table for GVolume/GMount (key) -> ThunarDevice (value) */
monitor->devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, g_object_unref);
@@ -202,6 +239,10 @@ thunar_device_monitor_finalize (GObject *object)
{
ThunarDeviceMonitor *monitor = THUNAR_DEVICE_MONITOR (object);
+ /* release properties */
+ g_object_unref (monitor->preferences);
+ g_strfreev (monitor->hidden_devices);
+
/* detatch from the monitor */
g_signal_handlers_disconnect_matched (monitor->volume_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, monitor);
g_object_unref (monitor->volume_monitor);
@@ -217,6 +258,99 @@ thunar_device_monitor_finalize (GObject *object)
+static void
+thunar_device_monitor_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThunarDeviceMonitor *monitor = THUNAR_DEVICE_MONITOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_HIDDEN_DEVICES:
+ g_value_set_boxed (value, monitor->hidden_devices);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+thunar_device_monitor_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThunarDeviceMonitor *monitor = THUNAR_DEVICE_MONITOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_HIDDEN_DEVICES:
+ /* set */
+ g_strfreev (monitor->hidden_devices);
+ monitor->hidden_devices = g_value_dup_boxed (value);
+
+ /* update the devices */
+ if (monitor->devices != NULL)
+ g_hash_table_foreach (monitor->devices, thunar_device_monitor_update_hidden, monitor);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static gboolean
+thunar_device_monitor_id_is_hidden (ThunarDeviceMonitor *monitor,
+ const gchar *id)
+{
+ guint n;
+
+ if (id == NULL || monitor->hidden_devices == NULL)
+ return FALSE;
+
+ /* check if the uuid is in the hidden list */
+ for (n = 0; monitor->hidden_devices[n] != NULL; n++)
+ if (g_strcmp0 (monitor->hidden_devices[n], id)== 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+static void
+thunar_device_monitor_update_hidden (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ ThunarDeviceMonitor *monitor = THUNAR_DEVICE_MONITOR (data);
+ ThunarDevice *device = THUNAR_DEVICE (value);
+ gchar *id;
+ gboolean hidden;
+
+ /* get state of the device */
+ id = thunar_device_get_identifier (device);
+ hidden = thunar_device_monitor_id_is_hidden (monitor, id);
+ g_free (id);
+
+ if (thunar_device_get_hidden (device) != hidden)
+ {g_message ("update device");
+ g_object_set (G_OBJECT (device), "hidden", hidden, NULL);
+ g_signal_emit (G_OBJECT (monitor), device_monitor_signals[DEVICE_CHANGED], 0, device);
+ }
+}
+
+
+
#ifdef HAVE_GIO_UNIX
static gboolean
thunar_device_monitor_mount_is_internal (GMount *mount)
@@ -401,6 +535,7 @@ thunar_device_monitor_volume_changed (GVolumeMonitor *volume_monitor,
{
GList *lp;
ThunarDevice *device;
+ gchar *id;
_thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor));
_thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (monitor));
@@ -422,6 +557,13 @@ thunar_device_monitor_volume_changed (GVolumeMonitor *volume_monitor,
"kind", THUNAR_DEVICE_KIND_VOLUME,
NULL);
+ /* set visibility */
+ id = thunar_device_get_identifier (device);
+ g_object_set (G_OBJECT (device),
+ "hidden", thunar_device_monitor_id_is_hidden (monitor, id),
+ NULL);
+ g_free (id);
+
/* insert to list (takes ref from hidden list) */
g_hash_table_insert (monitor->devices, volume, device);
@@ -472,6 +614,7 @@ thunar_device_monitor_mount_added (GVolumeMonitor *volume_monitor,
GFile *location;
ThunarDeviceKind kind = THUNAR_DEVICE_KIND_MOUNT_LOCAL;
GVolume *volume;
+ gchar *id;
_thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor));
_thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (monitor));
@@ -511,6 +654,13 @@ thunar_device_monitor_mount_added (GVolumeMonitor *volume_monitor,
"kind", kind,
NULL);
+ /* set visibility */
+ id = thunar_device_get_identifier (device);
+ g_object_set (G_OBJECT (device),
+ "hidden", thunar_device_monitor_id_is_hidden (monitor, id),
+ NULL);
+ g_free (id);
+
/* insert to list */
g_hash_table_insert (monitor->devices, g_object_ref (mount), device);
@@ -688,3 +838,51 @@ thunar_device_monitor_get_devices (ThunarDeviceMonitor *monitor)
return list;
}
+
+
+
+void
+thunar_device_monitor_set_hidden (ThunarDeviceMonitor *monitor,
+ ThunarDevice *device,
+ gboolean hidden)
+{
+ gchar *id;
+ gchar **devices;
+ guint length;
+ guint n;
+ guint pos;
+
+ _thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (monitor));
+ _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
+
+ id = thunar_device_get_identifier (device);
+ if (id == NULL)
+ return;
+
+ /* update device */
+ g_object_set (G_OBJECT (device), "hidden", hidden, NULL);
+ g_signal_emit (G_OBJECT (monitor), device_monitor_signals[DEVICE_CHANGED], 0, device);
+
+ /* update the device list */
+ length = monitor->hidden_devices != NULL ? g_strv_length (monitor->hidden_devices) : 0;
+ devices = g_new0 (gchar *, length + 2);
+ pos = 0;
+
+ /* copy other identifiers in the new list */
+ if (monitor->hidden_devices != NULL)
+ {
+ for (n = 0; monitor->hidden_devices[n] != NULL; n++)
+ if (g_strcmp0 (monitor->hidden_devices[n], id) != 0)
+ devices[pos++] = g_strdup (monitor->hidden_devices[n]);
+ }
+
+ /* add the new identifiers if it should hide */
+ if (hidden)
+ devices[pos++] = id;
+ else
+ g_free (id);
+
+ /* store new list */
+ g_object_set (G_OBJECT (monitor->preferences), "hidden-devices", devices, NULL);
+ g_strfreev (devices);
+}
diff --git a/thunar/thunar-device-monitor.h b/thunar/thunar-device-monitor.h
index 4932c41..6c0c369 100644
--- a/thunar/thunar-device-monitor.h
+++ b/thunar/thunar-device-monitor.h
@@ -39,6 +39,10 @@ ThunarDeviceMonitor *thunar_device_monitor_get (void);
GList *thunar_device_monitor_get_devices (ThunarDeviceMonitor *monitor);
+void thunar_device_monitor_set_hidden (ThunarDeviceMonitor *monitor,
+ ThunarDevice *device,
+ gboolean hidden);
+
G_END_DECLS
#endif /* !__THUNAR_DEVICE_MONITOR_H__ */
diff --git a/thunar/thunar-device.c b/thunar/thunar-device.c
index 0047aa5..45d382e 100644
--- a/thunar/thunar-device.c
+++ b/thunar/thunar-device.c
@@ -32,6 +32,7 @@ enum
{
PROP_0,
PROP_DEVICE,
+ PROP_HIDDEN,
PROP_KIND
};
@@ -62,6 +63,8 @@ struct _ThunarDevice
gpointer device;
ThunarDeviceKind kind;
+
+ guint hidden : 1;
};
typedef struct
@@ -98,6 +101,14 @@ thunar_device_class_init (ThunarDeviceClass *klass)
| G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
+ PROP_HIDDEN,
+ g_param_spec_boolean ("hidden",
+ "hidden",
+ "hidden",
+ FALSE,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
PROP_KIND,
g_param_spec_uint ("kind",
"kind",
@@ -146,6 +157,10 @@ thunar_device_get_property (GObject *object,
g_value_set_object (value, device->device);
break;
+ case PROP_HIDDEN:
+ g_value_set_boolean (value, device->hidden);
+ break;
+
case PROP_KIND:
g_value_set_uint (value, device->kind);
break;
@@ -173,6 +188,10 @@ thunar_device_set_property (GObject *object,
_thunar_assert (G_IS_VOLUME (device->device) || G_IS_MOUNT (device->device));
break;
+ case PROP_HIDDEN:
+ device->hidden = g_value_get_boolean (value);
+ break;
+
case PROP_KIND:
device->kind = g_value_get_uint (value);
break;
@@ -290,7 +309,7 @@ thunar_device_volume_mount_finished (GObject *object,
_thunar_return_if_fail (G_IS_VOLUME (object));
_thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
-
+
/* finish the eject */
if (!g_volume_eject_with_operation_finish (G_VOLUME (object), result, &error))
{
@@ -389,6 +408,44 @@ thunar_device_get_kind (const ThunarDevice *device)
+gchar *
+thunar_device_get_identifier (const ThunarDevice *device)
+{
+ gchar *ident = NULL;
+
+ _thunar_return_val_if_fail (THUNAR_IS_DEVICE (device), NULL);
+
+ if (G_IS_VOLUME (device->device))
+ {
+ ident = g_volume_get_uuid (device->device);
+ if (ident == NULL)
+ ident = g_volume_get_identifier (device->device, G_VOLUME_IDENTIFIER_KIND_UUID);
+ if (ident == NULL)
+ ident = g_volume_get_name (device->device);
+ }
+ else if (G_IS_MOUNT (device->device))
+ {
+ ident = g_mount_get_uuid (device->device);
+ if (ident == NULL)
+ ident = g_mount_get_name (device->device);
+ }
+ else
+ _thunar_assert_not_reached ();
+
+ return ident;
+}
+
+
+
+gboolean
+thunar_device_get_hidden (const ThunarDevice *device)
+{
+ _thunar_return_val_if_fail (THUNAR_IS_DEVICE (device), FALSE);
+ return device->hidden;
+}
+
+
+
/**
* thunar_device_can_eject:
*
@@ -509,7 +566,7 @@ thunar_device_is_mounted (const ThunarDevice *device)
GMount *volume_mount;
_thunar_return_val_if_fail (THUNAR_IS_DEVICE (device), FALSE);
-
+
if (G_IS_VOLUME (device->device))
{
/* a volume with a mount point is mounted */
@@ -590,12 +647,12 @@ thunar_device_mount (ThunarDevice *device,
gpointer user_data)
{
ThunarDeviceOperation *operation;
-
+
_thunar_return_if_fail (THUNAR_IS_DEVICE (device));
_thunar_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
_thunar_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
_thunar_return_if_fail (callback != NULL);
-
+
if (G_IS_VOLUME (device->device))
{
operation = thunar_device_operation_new (device, callback, user_data);
diff --git a/thunar/thunar-device.h b/thunar/thunar-device.h
index f4de610..614fd51 100644
--- a/thunar/thunar-device.h
+++ b/thunar/thunar-device.h
@@ -53,6 +53,10 @@ GIcon *thunar_device_get_icon (const ThunarDevice *devic
ThunarDeviceKind thunar_device_get_kind (const ThunarDevice *device) G_GNUC_PURE;
+gchar *thunar_device_get_identifier (const ThunarDevice *device) G_GNUC_MALLOC;
+
+gboolean thunar_device_get_hidden (const ThunarDevice *device);
+
gboolean thunar_device_can_eject (const ThunarDevice *device);
gboolean thunar_device_can_mount (const ThunarDevice *device);
diff --git a/thunar/thunar-launcher-ui.xml b/thunar/thunar-launcher-ui.xml
index ecf2432..2567ff8 100644
--- a/thunar/thunar-launcher-ui.xml
+++ b/thunar/thunar-launcher-ui.xml
@@ -28,6 +28,7 @@
<menu action="sendto-menu">
<placeholder name="placeholder-sendto-actions">
<menuitem action="sendto-desktop" />
+ <separator />
</placeholder>
</menu>
</menu>
@@ -50,6 +51,7 @@
<menu action="sendto-menu">
<placeholder name="placeholder-sendto-actions">
<menuitem action="sendto-desktop" />
+ <separator />
</placeholder>
</menu>
</popup>
diff --git a/thunar/thunar-launcher.c b/thunar/thunar-launcher.c
index 72cdf62..644b7b6 100644
--- a/thunar/thunar-launcher.c
+++ b/thunar/thunar-launcher.c
@@ -1462,6 +1462,9 @@ thunar_launcher_sendto_idle (gpointer user_data)
gchar *device_name;
gint n_selected_files;
gint n = 0;
+ gboolean got_devices = FALSE;
+ const gchar *file_menu_path;
+ const gchar *context_menu_path;
/* verify that we have an UI manager */
if (launcher->ui_manager == NULL)
@@ -1505,6 +1508,11 @@ thunar_launcher_sendto_idle (gpointer user_data)
/* determine the currently active devices */
devices = thunar_device_monitor_get_devices (launcher->device_monitor);
+ got_devices = (devices != NULL);
+
+ /* paths in ui */
+ file_menu_path = "/main-menu/file-menu/sendto-menu/placeholder-sendto-actions";
+ context_menu_path = "/file-context-menu/sendto-menu/placeholder-sendto-actions";
/* add removable (and writable) drives and media */
for (lp = devices; lp != NULL; lp = lp->next, ++n)
@@ -1522,11 +1530,9 @@ thunar_launcher_sendto_idle (gpointer user_data)
g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_sendto_device), launcher);
gtk_action_group_add_action (launcher->action_group, action);
gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
- "/main-menu/file-menu/sendto-menu/placeholder-sendto-actions",
- name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
+ file_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
- "/file-context-menu/sendto-menu/placeholder-sendto-actions",
- name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
+ context_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
g_object_unref (action);
icon = thunar_device_get_icon (lp->data);
@@ -1549,6 +1555,17 @@ thunar_launcher_sendto_idle (gpointer user_data)
handlers = thunar_sendto_model_get_matching (launcher->sendto_model, launcher->selected_files);
if (G_LIKELY (handlers != NULL))
{
+ if (got_devices)
+ {
+ /* add separator between the devices and actions action */
+ gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
+ file_menu_path, "separator", NULL,
+ GTK_UI_MANAGER_SEPARATOR, FALSE);
+ gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
+ context_menu_path, "separator", NULL,
+ GTK_UI_MANAGER_SEPARATOR, FALSE);
+ }
+
/* add all handlers to the user interface */
for (lp = handlers; lp != NULL; lp = lp->next, ++n)
{
@@ -1566,11 +1583,9 @@ thunar_launcher_sendto_idle (gpointer user_data)
g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher);
gtk_action_group_add_action (launcher->action_group, action);
gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
- "/main-menu/file-menu/sendto-menu/placeholder-sendto-actions",
- name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
+ file_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
- "/file-context-menu/sendto-menu/placeholder-sendto-actions",
- name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
+ context_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
g_object_unref (G_OBJECT (action));
/* cleanup */
diff --git a/thunar/thunar-preferences.c b/thunar/thunar-preferences.c
index ea5bdc8..4e1de11 100644
--- a/thunar/thunar-preferences.c
+++ b/thunar/thunar-preferences.c
@@ -50,6 +50,8 @@ enum
{
PROP_0,
PROP_DEFAULT_VIEW,
+ PROP_HIDDEN_DEVICES,
+ PROP_HIDDEN_BOOKMARKS,
PROP_LAST_COMPACT_VIEW_ZOOM_LEVEL,
PROP_LAST_DETAILS_VIEW_COLUMN_ORDER,
PROP_LAST_DETAILS_VIEW_COLUMN_WIDTHS,
@@ -118,6 +120,8 @@ struct _ThunarPreferences
GObject __parent__;
XfconfChannel *channel;
+
+ gulong property_changed_id;
};
@@ -152,6 +156,35 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass)
EXO_PARAM_READWRITE));
/**
+ * ThunarPreferences:hidden-bookmarks:
+ *
+ * List of URI's that are hidden in the bookmarks (obtained from ~/.gtk-bookmarks).
+ * If an URI is not in the bookmarks file it will be removed from this list.
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_HIDDEN_BOOKMARKS,
+ g_param_spec_boxed ("hidden-bookmarks",
+ NULL,
+ NULL,
+ G_TYPE_STRV,
+ EXO_PARAM_READWRITE));
+
+ /**
+ * ThunarPreferences:hidden-devices:
+ *
+ * List of hidden devices. The value could be an UUID or name.
+ * Visibility of the device can be obtained with
+ * thunar_device_get_hidden().
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_HIDDEN_DEVICES,
+ g_param_spec_boxed ("hidden-devices",
+ NULL,
+ NULL,
+ G_TYPE_STRV,
+ EXO_PARAM_READWRITE));
+
+ /**
* ThunarPreferences:last-compact-view-zoom-level:
*
* The last selected #ThunarZoomLevel for the #ThunarCompactView.
@@ -666,7 +699,7 @@ thunar_preferences_init (ThunarPreferences *preferences)
const gchar check_prop[] = "/last-view";
/* load the channel */
- preferences->channel = xfconf_channel_new ("thunar");
+ preferences->channel = xfconf_channel_get ("thunar");
/* check one of the property to see if there are values */
if (!xfconf_channel_has_property (preferences->channel, check_prop))
@@ -679,8 +712,9 @@ thunar_preferences_init (ThunarPreferences *preferences)
xfconf_channel_set_string (preferences->channel, check_prop, "ThunarIconView");
}
- g_signal_connect (G_OBJECT (preferences->channel), "property-changed",
- G_CALLBACK (thunar_preferences_prop_changed), preferences);
+ preferences->property_changed_id =
+ g_signal_connect (G_OBJECT (preferences->channel), "property-changed",
+ G_CALLBACK (thunar_preferences_prop_changed), preferences);
}
@@ -690,8 +724,8 @@ thunar_preferences_finalize (GObject *object)
{
ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
- /* release the channel */
- g_object_unref (G_OBJECT (preferences->channel));
+ /* disconnect from the updates */
+ g_signal_handler_disconnect (preferences->channel, preferences->property_changed_id);
(*G_OBJECT_CLASS (thunar_preferences_parent_class)->finalize) (object);
}
@@ -704,19 +738,26 @@ thunar_preferences_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
- GValue src = { 0, };
- gchar prop_name[64];
+ ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
+ GValue src = { 0, };
+ gchar prop_name[64];
+ gchar **array;
/* build property name */
g_snprintf (prop_name, sizeof (prop_name), "/%s", g_param_spec_get_name (pspec));
- if (xfconf_channel_get_property (preferences->channel, prop_name, &src))
+ if (G_VALUE_TYPE (value) == G_TYPE_STRV)
+ {
+ /* handle arrays directly since we cannot transform those */
+ array = xfconf_channel_get_string_list (preferences->channel, prop_name);
+ g_value_take_boxed (value, array);
+ }
+ else if (xfconf_channel_get_property (preferences->channel, prop_name, &src))
{
if (G_VALUE_TYPE (value) == G_VALUE_TYPE (&src))
g_value_copy (&src, value);
else if (!g_value_transform (&src, value))
- g_printerr ("Thunar: Failed to transform property %s", prop_name);
+ g_printerr ("Thunar: Failed to transform property %s\n", prop_name);
g_value_unset (&src);
}
else
@@ -734,13 +775,17 @@ thunar_preferences_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
- GValue dst = { 0, };
- gchar prop_name[64];
+ ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
+ GValue dst = { 0, };
+ gchar prop_name[64];
+ gchar **array;
/* build property name */
g_snprintf (prop_name, sizeof (prop_name), "/%s", g_param_spec_get_name (pspec));
+ /* freeze */
+ g_signal_handler_block (preferences->channel, preferences->property_changed_id);
+
if (G_VALUE_HOLDS_ENUM (value))
{
/* convert into a string */
@@ -749,11 +794,23 @@ thunar_preferences_set_property (GObject *object,
xfconf_channel_set_property (preferences->channel, prop_name, &dst);
g_value_unset (&dst);
}
+ else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
+ {
+ /* convert to a GValue GPtrArray in xfconf */
+ array = g_value_get_boxed (value);
+ if (array != NULL && *array != NULL)
+ xfconf_channel_set_string_list (preferences->channel, prop_name, (const gchar * const *) array);
+ else
+ xfconf_channel_reset_property (preferences->channel, prop_name, FALSE);
+ }
else
{
/* other types we support directly */
xfconf_channel_set_property (preferences->channel, prop_name, value);
}
+
+ /* thaw */
+ g_signal_handler_unblock (preferences->channel, preferences->property_changed_id);
}
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index 84fdc30..15c0cb5 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -2,6 +2,7 @@
/*-
* 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
@@ -41,6 +42,7 @@
#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-private.h>
#define SPINNER_CYCLE_DURATION 1000
@@ -56,8 +58,24 @@ typedef struct _ThunarShortcut ThunarShortcut;
+enum
+{
+ PROP_0,
+ PROP_HIDDEN_BOOKMARKS
+};
+
+
+
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);
@@ -95,6 +113,11 @@ static gboolean thunar_shortcuts_model_drag_data_get (GtkTreeDrag
GtkSelectionData *selection_data);
static gboolean thunar_shortcuts_model_drag_data_delete (GtkTreeDragSource *source,
GtkTreePath *path);
+static void thunar_shortcuts_model_shortcut_places (ThunarShortcutsModel *model);
+static void thunar_shortcuts_model_shortcut_network (ThunarShortcutsModel *model);
+static gboolean thunar_shortcuts_model_devices_load (gpointer data);
+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,
@@ -139,26 +162,29 @@ struct _ThunarShortcutsModel
* generated by another model.
*/
#ifndef NDEBUG
- gint stamp;
+ gint stamp;
#endif
- GList *shortcuts;
+ GList *shortcuts;
+
+ ThunarPreferences *preferences;
+ gchar **hidden_bookmarks;
- ThunarDeviceMonitor *device_monitor;
- guint devices_monitor_idle_id;
+ ThunarDeviceMonitor *device_monitor;
+ guint devices_monitor_idle_id;
- GFileMonitor *monitor;
- guint load_idle_id;
+ gint64 bookmarks_time;
+ GFile *bookmarks_file;
+ GFileMonitor *bookmarks_monitor;
+ guint bookmarks_idle_id;
- guint busy_timeout_id;
+ guint busy_timeout_id;
};
struct _ThunarShortcut
{
ThunarShortcutGroup group;
- guint is_header : 1;
-
gchar *name;
GIcon *gicon;
gint sort_id;
@@ -169,6 +195,8 @@ struct _ThunarShortcut
GFile *location;
ThunarFile *file;
ThunarDevice *device;
+
+ guint hidden : 1;
};
@@ -186,6 +214,16 @@ thunar_shortcuts_model_class_init (ThunarShortcutsModelClass *klass)
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));
}
@@ -219,161 +257,6 @@ thunar_shortcuts_model_drag_source_init (GtkTreeDragSourceIface *iface)
-static gboolean
-thunar_shortcuts_model_devices_load (gpointer data)
-{
- ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (data);
- ThunarShortcut *shortcut;
- GList *devices;
- GList *lp;
-
- GDK_THREADS_ENTER ();
-
- /* add the devices heading */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES;
- shortcut->name = g_strdup (_("DEVICES"));
- shortcut->is_header = TRUE;
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* the filesystem entry */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES;
- shortcut->name = g_strdup (_("File System"));
- shortcut->file = thunar_file_get_for_uri ("file:///", NULL);
- shortcut->gicon = g_themed_icon_new (GTK_STOCK_HARDDISK);
- 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 (model->device_monitor, lp->data, model);
- g_object_unref (G_OBJECT (lp->data));
- }
- g_list_free (devices);
-
- GDK_THREADS_LEAVE ();
-
- /* 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);
-
- model->devices_monitor_idle_id = 0;
-
- return FALSE;
-}
-
-
-
-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;
- shortcut->name = g_strdup (_("NETWORK"));
- shortcut->is_header = TRUE;
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-
- /* the browse network entry */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_NETWORK;
- shortcut->name = g_strdup (_("Browse Network"));
- shortcut->location = g_file_new_for_uri ("network://");
- shortcut->gicon = g_themed_icon_new (GTK_STOCK_NETWORK);
- thunar_shortcuts_model_add_shortcut (model, shortcut);
-}
-
-
-
-static void
-thunar_shortcuts_model_shortcut_places (ThunarShortcutsModel *model)
-{
- ThunarShortcut *shortcut;
- GFile *home;
- GFile *bookmarks;
- GFile *desktop;
- GFile *trash;
- ThunarFile *file;
-
- /* add the places heading */
- shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES;
- shortcut->name = g_strdup (_("PLACES"));
- shortcut->is_header = TRUE;
- 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;
- shortcut->file = file;
- shortcut->sort_id = 0;
- 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;
- shortcut->file = file;
- shortcut->sort_id = 1;
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
- }
- g_object_unref (desktop);
-
- /* 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_TRASH;
- shortcut->file = file;
- thunar_shortcuts_model_add_shortcut (model, shortcut);
- }
- }
-
- /* determine the URI to the Gtk+ bookmarks file */
- bookmarks = g_file_resolve_relative_path (home, ".gtk-bookmarks");
-
- /* register with the alteration monitor for the bookmarks file */
- model->monitor = g_file_monitor_file (bookmarks, G_FILE_MONITOR_NONE, NULL, NULL);
- if (G_LIKELY (model->monitor != NULL))
- g_signal_connect (model->monitor, "changed", G_CALLBACK (thunar_shortcuts_model_monitor), model);
-
- /* read the Gtk+ bookmarks file */
- model->load_idle_id = g_idle_add (thunar_shortcuts_model_load, model);
-
- g_object_unref (home);
- g_object_unref (bookmarks);
-}
-
-
-
-
static void
thunar_shortcuts_model_init (ThunarShortcutsModel *model)
{
@@ -381,8 +264,13 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model)
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");
+
/* load volumes */
- model->devices_monitor_idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_shortcuts_model_devices_load, model, NULL);
+ model->devices_monitor_idle_id = g_idle_add (thunar_shortcuts_model_devices_load, model);
/* add network */
thunar_shortcuts_model_shortcut_network (model);
@@ -405,8 +293,8 @@ thunar_shortcuts_model_finalize (GObject *object)
g_source_remove (model->busy_timeout_id);
/* stop bookmark load idle */
- if (model->load_idle_id != 0)
- g_source_remove (model->load_idle_id);
+ if (model->bookmarks_idle_id != 0)
+ g_source_remove (model->bookmarks_idle_id);
/* stop device monitor loading */
if (model->devices_monitor_idle_id != 0)
@@ -416,13 +304,19 @@ thunar_shortcuts_model_finalize (GObject *object)
g_list_foreach (model->shortcuts, (GFunc) thunar_shortcut_free, model);
g_list_free (model->shortcuts);
+ /* free hidden list */
+ g_strfreev (model->hidden_bookmarks);
+
/* detach from the file monitor */
- if (model->monitor != NULL)
+ if (model->bookmarks_monitor != NULL)
{
- g_file_monitor_cancel (model->monitor);
- g_object_unref (model->monitor);
+ 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);
@@ -432,6 +326,81 @@ thunar_shortcuts_model_finalize (GObject *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;
+
+ 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);
+ }
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
static GtkTreeModelFlags
thunar_shortcuts_model_get_flags (GtkTreeModel *tree_model)
{
@@ -455,7 +424,12 @@ thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model,
switch (idx)
{
case THUNAR_SHORTCUTS_MODEL_COLUMN_HEADER:
- case THUNAR_SHORTCUTS_MODEL_COLUMN_NOT_HEADER:
+ return G_TYPE_BOOLEAN;
+
+ case THUNAR_SHORTCUTS_MODEL_COLUMN_ITEM:
+ return G_TYPE_BOOLEAN;
+
+ case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
return G_TYPE_BOOLEAN;
case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
@@ -553,17 +527,27 @@ thunar_shortcuts_model_get_value (GtkTreeModel *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_HEADER:
g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, shortcut->is_header);
+ g_value_set_boolean (value, (shortcut->group & THUNAR_SHORTCUT_GROUP_HEADER) != 0);
+ break;
+
+ case THUNAR_SHORTCUTS_MODEL_COLUMN_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_NOT_HEADER:
+ case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, !shortcut->is_header);
+ if (shortcut->device == NULL)
+ g_value_set_boolean (value, !shortcut->hidden);
+ else
+ g_value_set_boolean (value, !thunar_device_get_hidden (shortcut->device));
break;
case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
@@ -605,7 +589,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
case THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE:
g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, shortcut->group == THUNAR_SHORTCUT_GROUP_BOOKMARKS);
+ g_value_set_boolean (value, shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
break;
case THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT:
@@ -740,7 +724,7 @@ thunar_shortcuts_model_row_draggable (GtkTreeDragSource *source,
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_BOOKMARKS);
+ return (shortcut != NULL && shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
}
@@ -771,6 +755,198 @@ thunar_shortcuts_model_drag_data_delete (GtkTreeDragSource *source,
+static gboolean
+thunar_shortcuts_model_devices_load (gpointer data)
+{
+ ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (data);
+ ThunarShortcut *shortcut;
+ GList *devices;
+ GList *lp;
+
+ GDK_THREADS_ENTER ();
+
+ /* 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 (GTK_STOCK_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 (model->device_monitor, lp->data, model);
+ g_object_unref (G_OBJECT (lp->data));
+ }
+ g_list_free (devices);
+
+ GDK_THREADS_LEAVE ();
+
+ /* 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);
+
+ model->devices_monitor_idle_id = 0;
+
+ return FALSE;
+}
+
+
+
+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 (GTK_STOCK_NETWORK);
+ 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->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);
+
+ /* 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 = g_file_resolve_relative_path (home, ".gtk-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 (thunar_shortcuts_model_load, model);
+
+ g_object_unref (home);
+}
+
+
+
+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)
@@ -782,10 +958,6 @@ thunar_shortcuts_model_sort_func (gconstpointer shortcut_a,
if (a->group != b->group)
return a->group - b->group;
- /* sort header at the top of a group */
- if (a->is_header != b->is_header)
- return b->is_header ? 1 : -1;
-
/* use sort order */
if (a->sort_id != b->sort_id)
return a->sort_id > b->sort_id ? 1 : -1;
@@ -894,7 +1066,6 @@ thunar_shortcuts_model_load (gpointer data)
ThunarShortcut *shortcut;
ThunarFile *file;
GFile *file_path;
- GFile *home;
gchar *bookmarks_path;
gchar line[2048];
gchar *name;
@@ -903,10 +1074,8 @@ thunar_shortcuts_model_load (gpointer data)
_thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
- home = thunar_g_file_new_for_home ();
-
/* determine the path to the GTK+ bookmarks file */
- bookmarks_path = xfce_get_homefile (".gtk-bookmarks", NULL);
+ bookmarks_path = g_file_get_path (model->bookmarks_file);
/* append the GTK+ bookmarks (if any) */
fp = fopen (bookmarks_path, "r");
@@ -950,9 +1119,10 @@ thunar_shortcuts_model_load (gpointer data)
{
/* create the shortcut entry */
shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_BOOKMARKS;
+ shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
shortcut->file = file;
shortcut->sort_id = ++sort_id;
+ shortcut->hidden = thunar_shortcuts_model_get_hidden (model, shortcut);
shortcut->name = (*name != '\0') ? g_strdup (name) : NULL;
/* append the shortcut to the list */
@@ -967,7 +1137,7 @@ thunar_shortcuts_model_load (gpointer data)
{
/* create the shortcut entry */
shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_BOOKMARKS;
+ shortcut->group = THUNAR_SHORTCUT_GROUP_NETWORK_BOOKMARKS;
shortcut->gicon = g_themed_icon_new ("folder-remote");
shortcut->location = file_path;
shortcut->sort_id = ++sort_id;
@@ -985,10 +1155,9 @@ thunar_shortcuts_model_load (gpointer data)
}
/* clean up */
- g_object_unref (home);
g_free (bookmarks_path);
- model->load_idle_id = 0;
+ model->bookmarks_idle_id = 0;
return FALSE;
}
@@ -1018,7 +1187,7 @@ thunar_shortcuts_model_reload (gpointer data)
lp = g_list_next (lp);
/* drop the shortcut if it is user-defined */
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_BOOKMARKS)
+ if (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
{
/* unlink the shortcut from the model */
model->shortcuts = g_list_remove (model->shortcuts, shortcut);
@@ -1055,11 +1224,15 @@ thunar_shortcuts_model_monitor (GFileMonitor *monitor,
ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
_thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- _thunar_return_if_fail (model->monitor == monitor);
+ _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->load_idle_id == 0)
- model->load_idle_id = g_idle_add (thunar_shortcuts_model_reload, model);
+ if (model->bookmarks_idle_id == 0)
+ model->bookmarks_idle_id = g_idle_add (thunar_shortcuts_model_reload, model);
}
@@ -1067,33 +1240,21 @@ thunar_shortcuts_model_monitor (GFileMonitor *monitor,
static void
thunar_shortcuts_model_save (ThunarShortcutsModel *model)
{
+ GString *contents;
ThunarShortcut *shortcut;
gchar *bookmarks_path;
- gchar *tmp_path;
gchar *uri;
GList *lp;
- FILE *fp;
- gint fd;
+ GError *err = NULL;
_thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
- /* open a temporary file for writing */
- tmp_path = xfce_get_homefile (".gtk-bookmarks.XXXXXX", NULL);
- fd = g_mkstemp (tmp_path);
- if (G_UNLIKELY (fd < 0))
- {
- g_warning ("Failed to open `%s' for writing: %s",
- tmp_path, g_strerror (errno));
- g_free (tmp_path);
- return;
- }
+ contents = g_string_new (NULL);
- /* write the uris of user customizable shortcuts */
- fp = fdopen (fd, "w");
for (lp = model->shortcuts; lp != NULL; lp = lp->next)
{
shortcut = THUNAR_SHORTCUT (lp->data);
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_BOOKMARKS)
+ if (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
{
if (shortcut->file != NULL)
uri = thunar_file_dup_uri (shortcut->file);
@@ -1103,28 +1264,25 @@ thunar_shortcuts_model_save (ThunarShortcutsModel *model)
continue;
if (G_LIKELY (shortcut->name != NULL))
- fprintf (fp, "%s %s\n", uri, shortcut->name);
+ g_string_append_printf (contents, "%s %s\n", uri, shortcut->name);
else
- fprintf (fp, "%s\n", uri);
+ g_string_append_printf (contents, "%s\n", uri);
g_free (uri);
}
}
- /* we're done writing the temporary file */
- fclose (fp);
-
- /* move the temporary file to it's final location (atomic writing) */
- bookmarks_path = xfce_get_homefile (".gtk-bookmarks", NULL);
- if (rename (tmp_path, bookmarks_path) < 0)
+ /* 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, g_strerror (errno));
- g_unlink (tmp_path);
+ g_warning ("Failed to write \"%s\": %s", bookmarks_path, err->message);
+ g_error_free (err);
}
-
- /* cleanup */
g_free (bookmarks_path);
- g_free (tmp_path);
+ g_string_free (contents, TRUE);
+
+ /* store the save time */
+ model->bookmarks_time = g_get_real_time ();
}
@@ -1212,15 +1370,16 @@ thunar_shortcuts_model_device_added (ThunarDeviceMonitor *device_monitor,
/* 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_VOLUMES;
+ shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES_VOLUMES;
break;
case THUNAR_DEVICE_KIND_MOUNT_LOCAL:
- shortcut->group = THUNAR_SHORTCUT_GROUP_MOUNTS;
+ shortcut->group = THUNAR_SHORTCUT_GROUP_DEVICES_MOUNTS;
break;
case THUNAR_DEVICE_KIND_MOUNT_REMOTE:
@@ -1547,11 +1706,11 @@ thunar_shortcuts_model_drop_possible (ThunarShortcutsModel *model,
return FALSE;
/* cannot drop before special shortcuts! */
- if (shortcut->group == THUNAR_SHORTCUT_GROUP_BOOKMARKS)
+ 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 && shortcut->is_header)
+ if (shortcut->group == THUNAR_SHORTCUT_GROUP_NETWORK_HEADER)
return TRUE;
return FALSE;
@@ -1589,7 +1748,7 @@ thunar_shortcuts_model_add (ThunarShortcutsModel *model,
/* create the new shortcut that will be inserted */
shortcut = g_slice_new0 (ThunarShortcut);
- shortcut->group = THUNAR_SHORTCUT_GROUP_BOOKMARKS;
+ shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
shortcut->file = g_object_ref (G_OBJECT (file));
/* add the shortcut to the list at the given position */
@@ -1616,12 +1775,13 @@ thunar_shortcuts_model_move (ThunarShortcutsModel *model,
GtkTreePath *dst_path)
{
ThunarShortcut *shortcut;
- GtkTreePath *path;
- GList *lp;
- gint *order;
- gint index_src;
- gint index_dst;
- gint idx;
+ 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);
@@ -1637,7 +1797,8 @@ thunar_shortcuts_model_move (ThunarShortcutsModel *model,
return;
/* generate the order for the rows prior the dst/src rows */
- order = g_newa (gint, g_list_length (model->shortcuts));
+ 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;
@@ -1679,11 +1840,11 @@ thunar_shortcuts_model_move (ThunarShortcutsModel *model,
}
/* generate the remaining order */
- for (; idx < (gint) g_list_length (model->shortcuts); ++idx)
+ for (; idx < n_shortcuts; ++idx)
order[idx] = idx;
/* tell all listeners about the reordering just performed */
- path = gtk_tree_path_new ();
+ path = gtk_tree_path_new_first ();
gtk_tree_model_rows_reordered (GTK_TREE_MODEL (model), path, NULL, order);
gtk_tree_path_free (path);
@@ -1718,7 +1879,7 @@ thunar_shortcuts_model_remove (ThunarShortcutsModel *model,
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_BOOKMARKS);
+ _thunar_assert (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
/* remove the shortcut (using the file destroy handler) */
thunar_shortcuts_model_remove_shortcut (model, shortcut);
@@ -1756,7 +1917,7 @@ thunar_shortcuts_model_rename (ThunarShortcutsModel *model,
shortcut = THUNAR_SHORTCUT (((GList *) iter->user_data)->data);
/* verify the shortcut */
- _thunar_assert (shortcut->group == THUNAR_SHORTCUT_GROUP_BOOKMARKS);
+ _thunar_assert (shortcut->group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS);
_thunar_assert (THUNAR_IS_FILE (shortcut->file));
/* perform the rename */
@@ -1828,3 +1989,66 @@ thunar_shortcuts_model_set_busy (ThunarShortcutsModel *model,
}
}
}
+
+
+
+
+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);
+}
diff --git a/thunar/thunar-shortcuts-model.h b/thunar/thunar-shortcuts-model.h
index 5932ad9..f09cbec 100644
--- a/thunar/thunar-shortcuts-model.h
+++ b/thunar/thunar-shortcuts-model.h
@@ -27,6 +27,7 @@ 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))
@@ -35,25 +36,11 @@ typedef struct _ThunarShortcutsModel ThunarShortcutsModel;
#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))
-/**
- * ThunarShortcutsModelColumn:
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_TYPE : #ThunarShortcutType.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_NAME : the index of the name column.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_FILE : the index of the file column.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION : file of the location.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_GICON : custom image.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE : the index of the device column.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE : tells whether a row is mutable.
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_EJECT : stock icon name for eject symbol
- * @THUNAR_SHORTCUTS_MODEL_COLUMN_SEPARATOR : tells whether a row is a separator.
- *
- * Columns exported by #ThunarShortcutsModel using the
- * #GtkTreeModel interface.
- **/
typedef enum
{
THUNAR_SHORTCUTS_MODEL_COLUMN_HEADER,
- THUNAR_SHORTCUTS_MODEL_COLUMN_NOT_HEADER,
+ THUNAR_SHORTCUTS_MODEL_COLUMN_ITEM,
+ THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE,
THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
THUNAR_SHORTCUTS_MODEL_COLUMN_FILE,
THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION,
@@ -67,23 +54,48 @@ typedef enum
THUNAR_SHORTCUTS_MODEL_N_COLUMNS,
} ThunarShortcutsModelColumn;
-typedef enum
+#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 \
+ | THUNAR_SHORTCUT_GROUP_NETWORK_BOOKMARKS)
+#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_VOLUMES,
- THUNAR_SHORTCUT_GROUP_MOUNTS,
- THUNAR_SHORTCUT_GROUP_PLACES,
- THUNAR_SHORTCUT_GROUP_TRASH,
- THUNAR_SHORTCUT_GROUP_BOOKMARKS,
- THUNAR_SHORTCUT_GROUP_NETWORK,
- THUNAR_SHORTCUT_GROUP_NETWORK_MOUNTS
-} 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), /* local 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 */
+ THUNAR_SHORTCUT_GROUP_NETWORK_BOOKMARKS = (1 << 11), /* remote bookmarks */
+};
GType thunar_shortcuts_model_get_type (void) G_GNUC_CONST;
-ThunarShortcutsModel *thunar_shortcuts_model_get_default (void);
+ThunarShortcutsModel *thunar_shortcuts_model_get_default (void);
gboolean thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model,
ThunarFile *file,
@@ -110,6 +122,9 @@ void thunar_shortcuts_model_rename (ThunarShortcutsMode
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;
diff --git a/thunar/thunar-shortcuts-pane.c b/thunar/thunar-shortcuts-pane.c
index 6cbb72f..ca32dba 100644
--- a/thunar/thunar-shortcuts-pane.c
+++ b/thunar/thunar-shortcuts-pane.c
@@ -325,6 +325,7 @@ thunar_shortcuts_pane_set_selected_files (ThunarComponent *component,
{
ThunarShortcutsPane *shortcuts_pane = THUNAR_SHORTCUTS_PANE (component);
GtkTreeModel *model;
+ GtkTreeModel *child_model;
GtkTreeIter iter;
GtkAction *action;
GList *lp;
@@ -350,8 +351,9 @@ thunar_shortcuts_pane_set_selected_files (ThunarComponent *component,
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_iter_for_file (THUNAR_SHORTCUTS_MODEL (model), lp->data, &iter))
+ if (!thunar_shortcuts_model_iter_for_file (THUNAR_SHORTCUTS_MODEL (child_model), lp->data, &iter))
break;
}
@@ -436,6 +438,7 @@ thunar_shortcuts_pane_action_shortcuts_add (GtkAction *action,
ThunarShortcutsPane *shortcuts_pane)
{
GtkTreeModel *model;
+ GtkTreeModel *child_model;
GtkTreePath *path;
GList *lp;
@@ -447,12 +450,13 @@ thunar_shortcuts_pane_action_shortcuts_add (GtkAction *action,
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)))
{
/* append the folder to the shortcuts model */
- path = gtk_tree_path_new_from_indices (gtk_tree_model_iter_n_children (model, NULL), -1);
- thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (model), path, lp->data);
+ path = gtk_tree_path_new_from_indices (gtk_tree_model_iter_n_children (child_model, NULL), -1);
+ thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (child_model), path, lp->data);
gtk_tree_path_free (path);
}
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index b8d19a3..831ccb5 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -2,6 +2,7 @@
/*-
* 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
@@ -96,12 +97,17 @@ static gboolean thunar_shortcuts_view_popup_menu (GtkWid
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 (ThunarShortcutsView *view,
GdkEventButton *event,
GtkTreeModel *model,
GtkTreeIter *iter);
static void thunar_shortcuts_view_remove_activated (GtkWidget *item,
- ThunarShortcutsView *view);
+ GtkTreeModel *model);
static void thunar_shortcuts_view_rename_activated (GtkWidget *item,
ThunarShortcutsView *view);
static void thunar_shortcuts_view_renamed (GtkCellRenderer *renderer,
@@ -226,22 +232,6 @@ thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass)
}
-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_HEADER, &is_header, -1);
- return !is_header;
-}
-
static void
thunar_shortcuts_view_init (ThunarShortcutsView *view)
@@ -294,7 +284,7 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
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_NOT_HEADER,
+ "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_ITEM,
NULL);
/* allocate the special icon renderer */
@@ -304,7 +294,7 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
"gicon", THUNAR_SHORTCUTS_MODEL_COLUMN_GICON,
"file", THUNAR_SHORTCUTS_MODEL_COLUMN_FILE,
"device", THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE,
- "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_NOT_HEADER,
+ "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_ITEM,
NULL);
/* sync the "emblems" property of the icon renderer with the "shortcuts-icon-emblems" preference
@@ -322,7 +312,7 @@ thunar_shortcuts_view_init (ThunarShortcutsView *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_NOT_HEADER,
+ "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_ITEM,
NULL);
/* spinner to indicate (un)mount/eject delay */
@@ -649,6 +639,9 @@ thunar_shortcuts_view_drag_drop (GtkWidget *widget,
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);
@@ -673,18 +666,29 @@ thunar_shortcuts_view_drag_drop (GtkWidget *widget,
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
- /* we need to adjust the destination path here, because the path returned by
- * the drop position computation effectively points after the insert position,
- * which can led to unexpected results.
- */
- gtk_tree_path_prev (dst_path);
- if (!thunar_shortcuts_model_drop_possible (THUNAR_SHORTCUTS_MODEL (model), dst_path))
- gtk_tree_path_next (dst_path);
+ /* get the source path */
+ src_path = gtk_tree_model_get_path (model, &iter);
- /* perform the move */
+ /* 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);
- thunar_shortcuts_model_move (THUNAR_SHORTCUTS_MODEL (model), src_path, dst_path);
+ 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 */
@@ -866,6 +870,134 @@ thunar_shortcuts_view_row_activated (GtkTreeView *tree_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_HEADER, &is_header, -1);
+ return !is_header;
+}
+
+
+
+static void
+thunar_shortcuts_view_context_menu_header_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_header (ThunarShortcutsView *view,
+ GdkEventButton *event,
+ GtkTreeModel *model,
+ GtkTreeIter *header_iter)
+{
+ GtkTreeIter iter;
+ guint mask = 0;
+ ThunarShortcutGroup group;
+ GtkWidget *menu;
+ GtkWidget *mi;
+ gchar *label;
+ GtkTreeSelection *selection;
+ gboolean visible;
+ GtkTreePath *path;
+ GtkTreeModel *child_model;
+
+ /* 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 = gtk_menu_new ();
+
+ /* process all items below the header */
+ 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), &iter, header_iter);
+ 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 (mask == 0 && (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_set_sensitive (mi, FALSE);
+ gtk_widget_show (mi);
+
+ mi = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+ gtk_widget_show (mi);
+ }
+ else if ((group & mask) != 0)
+ {
+ mi = gtk_check_menu_item_new_with_label (label);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), 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_header_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,
@@ -883,6 +1015,15 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
GList *providers, *lp;
GList *actions = NULL, *tmp;
ThunarShortcutGroup group;
+ gboolean is_header;
+
+ /* check if this is an item menu or a header menu */
+ gtk_tree_model_get (model, iter, THUNAR_SHORTCUTS_MODEL_COLUMN_HEADER, &is_header, -1);
+ if (is_header)
+ {
+ thunar_shortcuts_view_context_menu_header (view, event, model, iter);
+ return;
+ }
/* determine the tree path for the given iter */
path = gtk_tree_model_get_path (model, iter);
@@ -918,7 +1059,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
switch (group)
{
- case THUNAR_SHORTCUT_GROUP_VOLUMES:
+ case THUNAR_SHORTCUT_GROUP_DEVICES_VOLUMES:
/* append a menu separator */
item = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
@@ -943,7 +1084,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_eject), view);
break;
- case THUNAR_SHORTCUT_GROUP_MOUNTS:
+ case THUNAR_SHORTCUT_GROUP_DEVICES_MOUNTS:
case THUNAR_SHORTCUT_GROUP_NETWORK_MOUNTS:
/* append a menu separator */
item = gtk_separator_menu_item_new ();
@@ -958,7 +1099,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
gtk_widget_show (item);
break;
- case THUNAR_SHORTCUT_GROUP_TRASH:
+ 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);
@@ -1020,7 +1161,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
}
/* append the remove menu item */
- if (group == THUNAR_SHORTCUT_GROUP_BOOKMARKS)
+ if (group == THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS)
{
/* append a menu separator */
item = gtk_separator_menu_item_new ();
@@ -1031,7 +1172,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
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), view);
+ 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);
@@ -1067,20 +1208,24 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view,
static void
-thunar_shortcuts_view_remove_activated (GtkWidget *item,
- ThunarShortcutsView *view)
+thunar_shortcuts_view_remove_activated (GtkWidget *item,
+ GtkTreeModel *model)
{
GtkTreeRowReference *row;
- GtkTreeModel *model;
+ 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))
{
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- thunar_shortcuts_model_remove (THUNAR_SHORTCUTS_MODEL (model), path);
+ 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);
}
}
@@ -1127,6 +1272,8 @@ thunar_shortcuts_view_renamed (GtkCellRenderer *renderer,
{
GtkTreeModel *model;
GtkTreeIter iter;
+ GtkTreeModel *child_model;
+ GtkTreeIter child_iter;
/* reset the editable flag */
g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
@@ -1134,7 +1281,11 @@ thunar_shortcuts_view_renamed (GtkCellRenderer *renderer,
/* 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))
- thunar_shortcuts_model_rename (THUNAR_SHORTCUTS_MODEL (model), &iter, text);
+ {
+ 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);
+ }
}
@@ -1248,8 +1399,11 @@ thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView *view,
GtkTreeViewColumn *column;
GtkTreeModel *model;
GdkRectangle area;
- GtkTreePath *path = NULL;
+ 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);
@@ -1268,10 +1422,17 @@ thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView *view,
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))
- if (thunar_shortcuts_model_drop_possible (THUNAR_SHORTCUTS_MODEL (model), path))
- return 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);
}
@@ -1291,12 +1452,15 @@ thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view,
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);
@@ -1313,7 +1477,10 @@ thunar_shortcuts_view_drop_uri_list (ThunarShortcutsView *view,
break;
}
- thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (model), path, file);
+ 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);
}
@@ -1755,12 +1922,17 @@ GtkWidget*
thunar_shortcuts_view_new (void)
{
ThunarShortcutsModel *model;
- GtkWidget *view;
+ GtkWidget *view;
+ GtkTreeModel *filter_model;
model = thunar_shortcuts_model_get_default ();
- view = g_object_new (THUNAR_TYPE_SHORTCUTS_VIEW, "model", model, NULL);
+ 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;
}
@@ -1782,18 +1954,24 @@ thunar_shortcuts_view_select_by_file (ThunarShortcutsView *view,
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));
- /* clear the selection */
+ /* get the selection */
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- gtk_tree_selection_unselect_all (selection);
- /* try to lookup a tree iter for the given file */
model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- if (thunar_shortcuts_model_iter_for_file (THUNAR_SHORTCUTS_MODEL (model), file, &iter))
+ 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);
}
More information about the Xfce4-commits
mailing list