[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Add new ThunarShortcut class. Improve the shortcuts model.

Jannis Pohlmann noreply at xfce.org
Wed Jun 8 00:10:01 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 1f4442041960739076ee2f9a8d44b630cc916935 (commit)
       from f7c19b6f18c046ea11690309f146066dc24147c0 (commit)

commit 1f4442041960739076ee2f9a8d44b630cc916935
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Wed Jun 8 00:07:27 2011 +0200

    Add new ThunarShortcut class. Improve the shortcuts model.
    
    A new feature that slips in with this commit: newly created mounts are
    now displayed in one of the categories, e.g. when an archive or a
    network location is mounted.

 thunar/Makefile.am              |    2 +
 thunar/thunar-enum-types.c      |   52 +++-
 thunar/thunar-enum-types.h      |   51 ++-
 thunar/thunar-shortcut-row.c    |    1 +
 thunar/thunar-shortcut.c        |  701 +++++++++++++++++++++++++++++++++++++++
 thunar/thunar-shortcut.h        |   78 +++++
 thunar/thunar-shortcuts-model.c |  456 ++++++++++++++-----------
 7 files changed, 1112 insertions(+), 229 deletions(-)

diff --git a/thunar/Makefile.am b/thunar/Makefile.am
index d6c8387..383c439 100644
--- a/thunar/Makefile.am
+++ b/thunar/Makefile.am
@@ -171,6 +171,8 @@ Thunar_SOURCES =							\
 	thunar-sendto-model.h						\
 	thunar-session-client.c						\
 	thunar-session-client.h						\
+	thunar-shortcut.c						\
+	thunar-shortcut.h						\
 	thunar-shortcut-row.c						\
 	thunar-shortcut-row.h						\
 	thunar-shortcuts-icon-renderer.c				\
diff --git a/thunar/thunar-enum-types.c b/thunar/thunar-enum-types.c
index b9303b6..573c364 100644
--- a/thunar/thunar-enum-types.c
+++ b/thunar/thunar-enum-types.c
@@ -1,21 +1,22 @@
-/* $Id$ */
+/* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
  * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2011 Jannis Pohlmann <jannis 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 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.
+ * 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
+ * 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
@@ -329,3 +330,28 @@ thunar_file_mode_get_type (void)
     }
 	return type;
 }
+
+
+
+GType
+thunar_shortcut_type_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GEnumValue values[] =
+      {
+        { THUNAR_SHORTCUT_REGULAR_FILE,     "THUNAR_SHORTCUT_REGULAR_FILE",     "regular-file",     },
+        { THUNAR_SHORTCUT_NETWORK_FILE,     "THUNAR_SHORTCUT_NETWORK_FILE",     "network-file",     },
+        { THUNAR_SHORTCUT_STANDALONE_MOUNT, "THUNAR_SHORTCUT_STANDALONE_MOUNT", "standalone-mount", },
+        { THUNAR_SHORTCUT_EJECTABLE_VOLUME, "THUNAR_SHORTCUT_EJECTABLE_VOLUME", "ejectable-volume", },
+        { THUNAR_SHORTCUT_REGULAR_VOLUME,   "THUNAR_SHORTCUT_REGULAR_VOLUME",   "regular-volume",   },
+        { 0,                                NULL,                               NULL,               },
+      };
+
+      type = g_enum_register_static (I_("ThunarShortcutType"), values);
+    }
+
+  return type;
+}
diff --git a/thunar/thunar-enum-types.h b/thunar/thunar-enum-types.h
index c5f78ba..75c61c2 100644
--- a/thunar/thunar-enum-types.h
+++ b/thunar/thunar-enum-types.h
@@ -1,21 +1,22 @@
-/* $Id$ */
+/* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
  * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2011 Jannis Pohlmann <jannis 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 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.
+ * 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
+ * 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.
  */
 
 #ifndef __THUNAR_ENUM_TYPES_H__
@@ -23,7 +24,7 @@
 
 #include <exo/exo.h>
 
-G_BEGIN_DECLS;
+G_BEGIN_DECLS
 
 #define THUNAR_TYPE_RENAMER_MODE (thunar_renamer_mode_get_type ())
 
@@ -290,6 +291,26 @@ typedef enum /*< flags >*/
 
 GType thunar_file_mode_get_type (void) G_GNUC_CONST;
 
-G_END_DECLS;
+
+#define THUNAR_TYPE_SHORTCUT_TYPE (thunar_shortcut_type_get_type ())
+
+/**
+ * ThunarShortcutType:
+ *
+ * Enumeration used for classifying the different shortcuts
+ * in #ThunarShortcutsModel.
+ **/
+typedef enum
+{
+  THUNAR_SHORTCUT_REGULAR_FILE,
+  THUNAR_SHORTCUT_NETWORK_FILE,
+  THUNAR_SHORTCUT_STANDALONE_MOUNT,
+  THUNAR_SHORTCUT_EJECTABLE_VOLUME,
+  THUNAR_SHORTCUT_REGULAR_VOLUME,
+} ThunarShortcutType;
+
+GType thunar_shortcut_type_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
 
 #endif /* !__THUNAR_ENUM_TYPES_H__ */
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index 4ebaf45..2de9d1c 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -385,6 +385,7 @@ thunar_shortcut_row_finalize (GObject *object)
     g_object_unref (row->volume);
 
   /* release the cancellable */
+  g_cancellable_cancel (row->cancellable);
   g_object_unref (row->cancellable);
 
   /* release the preferences */
diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c
new file mode 100644
index 0000000..216618c
--- /dev/null
+++ b/thunar/thunar-shortcut.c
@@ -0,0 +1,701 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2011 Jannis Pohlmann <jannis 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
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gio/gio.h>
+
+#include <thunar/thunar-enum-types.h>
+#include <thunar/thunar-file.h>
+#include <thunar/thunar-private.h>
+#include <thunar/thunar-shortcut.h>
+
+
+
+/* property identifiers */
+enum
+{
+  PROP_0,
+  PROP_LOCATION,
+  PROP_FILE,
+  PROP_VOLUME,
+  PROP_MOUNT,
+  PROP_ICON,
+  PROP_EJECT_ICON,
+  PROP_NAME,
+  PROP_SHORTCUT_TYPE,
+  PROP_HIDDEN,
+  PROP_MUTABLE,
+  PROP_PERSISTENT,
+};
+
+/* signal identifiers */
+enum
+{
+  LAST_SIGNAL,
+};
+
+
+
+static void thunar_shortcut_constructed  (GObject      *object);
+static void thunar_shortcut_finalize     (GObject      *object);
+static void thunar_shortcut_get_property (GObject      *object,
+                                          guint         prop_id,
+                                          GValue       *value,
+                                          GParamSpec   *pspec);
+static void thunar_shortcut_set_property (GObject      *object,
+                                          guint         prop_id,
+                                          const GValue *value,
+                                          GParamSpec   *pspec);
+
+
+
+struct _ThunarShortcutClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarShortcut
+{
+  GObject __parent__;
+
+  GFile             *location;
+
+  ThunarFile        *file;
+  GVolume           *volume;
+  GMount            *mount;
+  
+  GIcon             *icon;
+  GIcon             *eject_icon;
+  
+  gchar             *name;
+  
+  ThunarShortcutType type;
+
+  guint              hidden : 1;
+  guint              mutable : 1;
+  guint              persistent : 1;
+
+};
+
+
+
+G_DEFINE_TYPE (ThunarShortcut, thunar_shortcut, G_TYPE_OBJECT)
+
+
+
+static void
+thunar_shortcut_class_init (ThunarShortcutClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine the parent type class */
+  thunar_shortcut_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->constructed = thunar_shortcut_constructed; 
+  gobject_class->finalize = thunar_shortcut_finalize; 
+  gobject_class->get_property = thunar_shortcut_get_property;
+  gobject_class->set_property = thunar_shortcut_set_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_LOCATION,
+                                   g_param_spec_object ("location",
+                                                        "location",
+                                                        "location",
+                                                        G_TYPE_FILE,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FILE,
+                                   g_param_spec_object ("file",
+                                                        "file",
+                                                        "file",
+                                                        THUNAR_TYPE_FILE,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_VOLUME,
+                                   g_param_spec_object ("volume",
+                                                        "volume",
+                                                        "volume",
+                                                        G_TYPE_VOLUME,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MOUNT,
+                                   g_param_spec_object ("mount",
+                                                        "mount",
+                                                        "mount",
+                                                        G_TYPE_MOUNT,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_ICON,
+                                   g_param_spec_object ("icon",
+                                                        "icon",
+                                                        "icon",
+                                                        G_TYPE_ICON,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_EJECT_ICON,
+                                   g_param_spec_object ("eject-icon",
+                                                        "eject-icon",
+                                                        "eject-icon",
+                                                        G_TYPE_ICON,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_NAME,
+                                   g_param_spec_string ("name",
+                                                        "name",
+                                                        "name",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_SHORTCUT_TYPE,
+                                   g_param_spec_enum ("shortcut-type",
+                                                      "shortcut-type",
+                                                      "shortcut-type",
+                                                      THUNAR_TYPE_SHORTCUT_TYPE,
+                                                      THUNAR_SHORTCUT_REGULAR_FILE,
+                                                      EXO_PARAM_READWRITE));
+
+  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_MUTABLE,
+                                   g_param_spec_boolean ("mutable",
+                                                         "mutable",
+                                                         "mutable",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_PERSISTENT,
+                                   g_param_spec_boolean ("persistent",
+                                                         "persistent",
+                                                         "persistent",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+}
+
+
+
+static void
+thunar_shortcut_init (ThunarShortcut *shortcut)
+{
+}
+
+
+
+static void
+thunar_shortcut_constructed (GObject *object)
+{
+#if 0
+  ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
+#endif
+}
+
+
+
+static void
+thunar_shortcut_finalize (GObject *object)
+{
+  ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
+
+  if (shortcut->location != NULL)
+    g_object_unref (shortcut->location);
+
+  if (shortcut->file != NULL)
+    g_object_unref (shortcut->file);
+
+  if (shortcut->volume != NULL)
+    g_object_unref (shortcut->volume);
+
+  if (shortcut->mount != NULL)
+    g_object_unref (shortcut->mount);
+
+  if (shortcut->icon != NULL)
+    g_object_unref (shortcut->icon);
+
+  if (shortcut->eject_icon != NULL)
+    g_object_unref (shortcut->eject_icon);
+
+  g_free (shortcut->name);
+
+  (*G_OBJECT_CLASS (thunar_shortcut_parent_class)->finalize) (object);
+}
+
+
+
+static void
+thunar_shortcut_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
+
+  switch (prop_id)
+    {
+    case PROP_LOCATION:
+      g_value_set_object (value, thunar_shortcut_get_location (shortcut));
+      break;
+
+    case PROP_FILE:
+      g_value_set_object (value, thunar_shortcut_get_file (shortcut));
+      break;
+
+    case PROP_VOLUME:
+      g_value_set_object (value, thunar_shortcut_get_volume (shortcut));
+      break;
+
+    case PROP_MOUNT:
+      g_value_set_object (value, thunar_shortcut_get_mount (shortcut));
+      break;
+
+    case PROP_ICON:
+      g_value_set_object (value, thunar_shortcut_get_icon (shortcut));
+      break;
+
+    case PROP_EJECT_ICON:
+      g_value_set_object (value, thunar_shortcut_get_eject_icon (shortcut));
+      break;
+
+    case PROP_NAME:
+      g_value_set_string (value, thunar_shortcut_get_name (shortcut));
+      break;
+
+    case PROP_SHORTCUT_TYPE:
+      g_value_set_enum (value, thunar_shortcut_get_shortcut_type (shortcut));
+      break;
+
+    case PROP_HIDDEN:
+      g_value_set_boolean (value, thunar_shortcut_get_hidden (shortcut));
+      break;
+
+    case PROP_MUTABLE:
+      g_value_set_boolean (value, thunar_shortcut_get_mutable (shortcut));
+      break;
+
+    case PROP_PERSISTENT:
+      g_value_set_boolean (value, thunar_shortcut_get_persistent (shortcut));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+thunar_shortcut_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
+
+  switch (prop_id)
+    {
+    case PROP_LOCATION:
+      thunar_shortcut_set_location (shortcut, g_value_get_object (value));
+      break;
+
+    case PROP_FILE:
+      thunar_shortcut_set_file (shortcut, g_value_get_object (value));
+      break;
+
+    case PROP_VOLUME:
+      thunar_shortcut_set_volume (shortcut, g_value_get_object (value));
+      break;
+
+    case PROP_MOUNT:
+      thunar_shortcut_set_mount (shortcut, g_value_get_object (value));
+      break;
+
+    case PROP_ICON:
+      thunar_shortcut_set_icon (shortcut, g_value_get_object (value));
+      break;
+
+    case PROP_EJECT_ICON:
+      thunar_shortcut_set_eject_icon (shortcut, g_value_get_object (value));
+      break;
+
+    case PROP_NAME:
+      thunar_shortcut_set_name (shortcut, g_value_get_string (value));
+      break;
+
+    case PROP_SHORTCUT_TYPE:
+      thunar_shortcut_set_shortcut_type (shortcut, g_value_get_enum (value));
+      break;
+
+    case PROP_HIDDEN:
+      thunar_shortcut_set_hidden (shortcut, g_value_get_boolean (value));
+      break;
+
+    case PROP_MUTABLE:
+      thunar_shortcut_set_mutable (shortcut, g_value_get_boolean (value));
+      break;
+
+    case PROP_PERSISTENT:
+      thunar_shortcut_set_persistent (shortcut, g_value_get_boolean (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+GFile *
+thunar_shortcut_get_location (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->location;
+}
+
+
+
+void
+thunar_shortcut_set_location (ThunarShortcut *shortcut,
+                              GFile          *location)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (location == NULL || G_IS_FILE (location));
+
+  if (shortcut->location == location)
+    return;
+
+  if (shortcut->location != NULL)
+    g_object_unref (shortcut->location);
+
+  if (location != NULL)
+    shortcut->location = g_object_ref (location);
+  else
+    shortcut->location = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "location");
+}
+
+
+
+ThunarFile *
+thunar_shortcut_get_file (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->file;
+}
+
+
+
+void
+thunar_shortcut_set_file (ThunarShortcut *shortcut,
+                          ThunarFile     *file)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+
+  if (shortcut->file == file)
+    return;
+
+  if (shortcut->file != NULL)
+    g_object_unref (shortcut->file);
+
+  if (file != NULL)
+    shortcut->file = g_object_ref (file);
+  else
+    shortcut->file = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "file");
+}
+
+
+
+GVolume *
+thunar_shortcut_get_volume (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->volume;
+}
+
+
+
+void
+thunar_shortcut_set_volume (ThunarShortcut *shortcut,
+                            GVolume        *volume)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (volume == NULL || G_IS_VOLUME (volume));
+
+  if (shortcut->volume == volume)
+    return;
+
+  if (shortcut->volume != NULL)
+    g_object_unref (shortcut->volume);
+
+  if (volume != NULL)
+    shortcut->volume = g_object_ref (volume);
+  else
+    shortcut->volume = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "volume");
+}
+
+
+
+GMount *
+thunar_shortcut_get_mount (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->mount;
+}
+
+
+
+void
+thunar_shortcut_set_mount (ThunarShortcut *shortcut,
+                           GMount         *mount)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (mount == NULL || G_IS_MOUNT (mount));
+
+  if (shortcut->mount == mount)
+    return;
+
+  if (shortcut->mount != NULL)
+    g_object_unref (shortcut->mount);
+
+  if (mount != NULL)
+    shortcut->mount = g_object_ref (mount);
+  else
+    shortcut->mount = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "mount");
+}
+
+
+
+GIcon *
+thunar_shortcut_get_icon (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->icon;
+}
+
+
+
+void
+thunar_shortcut_set_icon (ThunarShortcut *shortcut,
+                          GIcon          *icon)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (icon == NULL || G_IS_ICON (icon));
+
+  if (shortcut->icon == icon)
+    return;
+
+  if (shortcut->icon != NULL)
+    g_object_unref (shortcut->icon);
+
+  if (icon != NULL)
+    shortcut->icon = g_object_ref (icon);
+  else
+    shortcut->icon = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "icon");
+}
+
+
+
+GIcon *
+thunar_shortcut_get_eject_icon (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->eject_icon;
+}
+
+
+
+void
+thunar_shortcut_set_eject_icon (ThunarShortcut *shortcut,
+                                GIcon          *eject_icon)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (eject_icon == NULL || G_IS_ICON (eject_icon));
+
+  if (shortcut->eject_icon == eject_icon)
+    return;
+
+  if (shortcut->eject_icon != NULL)
+    g_object_unref (shortcut->eject_icon);
+
+  if (eject_icon != NULL)
+    shortcut->eject_icon = g_object_ref (eject_icon);
+  else
+    shortcut->eject_icon = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "eject-icon");
+}
+
+
+
+const gchar *
+thunar_shortcut_get_name (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->name;
+}
+
+
+
+void
+thunar_shortcut_set_name (ThunarShortcut *shortcut,
+                          const gchar    *name)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  if (g_strcmp0 (shortcut->name, name) == 0)
+    return;
+
+  g_free (shortcut->name);
+
+  shortcut->name = g_strdup (name);
+
+  g_object_notify (G_OBJECT (shortcut), "name");
+}
+
+
+
+ThunarShortcutType
+thunar_shortcut_get_shortcut_type (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), 0);
+  return shortcut->type;
+}
+
+
+
+void
+thunar_shortcut_set_shortcut_type (ThunarShortcut    *shortcut,
+                                   ThunarShortcutType shortcut_type)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  if (shortcut->type == shortcut_type)
+    return;
+
+  shortcut->type = shortcut_type;
+
+  g_object_notify (G_OBJECT (shortcut), "shortcut-type");
+}
+
+
+
+gboolean
+thunar_shortcut_get_hidden (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), FALSE);
+  return shortcut->hidden;
+}
+
+
+
+void
+thunar_shortcut_set_hidden (ThunarShortcut *shortcut,
+                            gboolean        hidden)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  if (shortcut->hidden == hidden)
+    return;
+
+  shortcut->hidden = hidden;
+
+  g_object_notify (G_OBJECT (shortcut), "hidden");
+}
+
+
+
+gboolean
+thunar_shortcut_get_mutable (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), FALSE);
+  return shortcut->mutable;
+}
+
+
+
+void
+thunar_shortcut_set_mutable (ThunarShortcut *shortcut,
+                             gboolean        mutable)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  if (shortcut->mutable == mutable)
+    return;
+
+  shortcut->mutable = mutable;
+
+  g_object_notify (G_OBJECT (shortcut), "mutable");
+}
+
+
+
+gboolean
+thunar_shortcut_get_persistent (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), FALSE);
+  return shortcut->persistent;
+}
+
+
+
+void
+thunar_shortcut_set_persistent (ThunarShortcut *shortcut,
+                                gboolean        persistent)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  if (shortcut->persistent == persistent)
+    return;
+
+  shortcut->persistent = persistent;
+
+  g_object_notify (G_OBJECT (shortcut), "persistent");
+}
diff --git a/thunar/thunar-shortcut.h b/thunar/thunar-shortcut.h
new file mode 100644
index 0000000..4a1c8d6
--- /dev/null
+++ b/thunar/thunar-shortcut.h
@@ -0,0 +1,78 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2011 Jannis Pohlmann <jannis 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.
+ */
+
+#ifndef __THUNAR_SHORTCUT_H__
+#define __THUNAR_SHORTCUT_H__
+
+#include <gio/gio.h>
+
+#include <thunar/thunar-file.h>
+
+G_BEGIN_DECLS
+
+#define THUNAR_TYPE_SHORTCUT            (thunar_shortcut_get_type ())
+#define THUNAR_SHORTCUT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_SHORTCUT, ThunarShortcut))
+#define THUNAR_SHORTCUT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_SHORTCUT, ThunarShortcutClass))
+#define THUNAR_IS_SHORTCUT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_SHORTCUT))
+#define THUNAR_IS_SHORTCUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SHORTCUT)
+#define THUNAR_SHORTCUT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_SHORTCUT, ThunarShortcutClass))
+
+typedef struct _ThunarShortcutClass ThunarShortcutClass;
+typedef struct _ThunarShortcut      ThunarShortcut;
+
+GType              thunar_shortcut_get_type          (void) G_GNUC_CONST;
+
+GFile             *thunar_shortcut_get_location      (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_location      (ThunarShortcut    *shortcut,
+                                                      GFile             *location);
+ThunarFile        *thunar_shortcut_get_file          (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_file          (ThunarShortcut    *shortcut,
+                                                      ThunarFile        *file);
+GVolume           *thunar_shortcut_get_volume        (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_volume        (ThunarShortcut    *shortcut,
+                                                      GVolume           *volume);
+GMount            *thunar_shortcut_get_mount         (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_mount         (ThunarShortcut    *shortcut,
+                                                      GMount            *mount);
+GIcon             *thunar_shortcut_get_icon          (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_icon          (ThunarShortcut    *shortcut,
+                                                      GIcon             *icon);
+GIcon             *thunar_shortcut_get_eject_icon    (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_eject_icon    (ThunarShortcut    *shortcut,
+                                                      GIcon             *eject_icon);
+const gchar       *thunar_shortcut_get_name          (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_name          (ThunarShortcut    *shortcut,
+                                                      const gchar       *name);
+ThunarShortcutType thunar_shortcut_get_shortcut_type (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_shortcut_type (ThunarShortcut    *shortcut,
+                                                      ThunarShortcutType shortcut_type);
+gboolean           thunar_shortcut_get_hidden        (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_hidden        (ThunarShortcut    *shortcut,
+                                                      gboolean           hidden);
+gboolean           thunar_shortcut_get_mutable       (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_mutable       (ThunarShortcut    *shortcut,
+                                                      gboolean           mutable);
+gboolean           thunar_shortcut_get_persistent    (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_persistent    (ThunarShortcut    *shortcut,
+                                                      gboolean           persistent);
+
+G_END_DECLS
+
+#endif /* !__THUNAR_SHORTCUT_H__ */
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index a6f53fa..6d1b748 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -40,12 +40,9 @@
 #include <glib/gstdio.h>
 
 #include <thunar/thunar-file.h>
-#include <thunar/thunar-shortcuts-model.h>
 #include <thunar/thunar-private.h>
-
-
-
-#define THUNAR_SHORTCUT(obj) ((ThunarShortcut *) (obj))
+#include <thunar/thunar-shortcuts-model.h>
+#include <thunar/thunar-shortcut.h>
 
 
 
@@ -59,7 +56,6 @@ const gchar *_thunar_user_directory_names[9] = {
 
 
 typedef struct _ThunarShortcutCategory ThunarShortcutCategory;
-typedef struct _ThunarShortcut         ThunarShortcut;
 
 
 
@@ -70,15 +66,6 @@ typedef enum
   THUNAR_SHORTCUT_CATEGORY_NETWORK,
 } ThunarShortcutCategoryType;
 
-typedef enum
-{
-  THUNAR_SHORTCUT_SYSTEM_VOLUME,
-  THUNAR_SHORTCUT_VOLUME,
-  THUNAR_SHORTCUT_USER_DIRECTORY,
-  THUNAR_SHORTCUT_LOCAL_FILE,
-  THUNAR_SHORTCUT_REMOTE_FILE,
-} ThunarShortcutType;
-
 
 
 static void                    thunar_shortcuts_model_tree_model_init       (GtkTreeModelIface         *iface);
@@ -121,9 +108,7 @@ static gboolean                thunar_shortcuts_model_parse_iter            (Thu
                                                                              gint                      *category_index,
                                                                              gint                      *shortcut_index);
 static gboolean                thunar_shortcuts_model_find_category         (ThunarShortcutsModel      *model,
-                                                                             GFile                     *file,
-                                                                             GVolume                   *volume,
-                                                                             ThunarShortcutType         type,
+                                                                             ThunarShortcut            *shortcut,
                                                                              ThunarShortcutCategory   **category,
                                                                              gint                      *category_index);
 static gboolean                thunar_shortcuts_model_find_volume           (ThunarShortcutsModel      *model,
@@ -142,9 +127,11 @@ static void                    thunar_shortcuts_model_volume_added          (Thu
 static void                    thunar_shortcuts_model_volume_removed        (ThunarShortcutsModel      *model,
                                                                              GVolume                   *volume,
                                                                              GVolumeMonitor            *monitor);
+static void                    thunar_shortcuts_model_mount_added           (ThunarShortcutsModel      *model,
+                                                                             GMount                    *mount,
+                                                                             GVolumeMonitor            *monitor);
 static ThunarShortcutCategory *thunar_shortcut_category_new                 (ThunarShortcutCategoryType type);
 static void                    thunar_shortcut_category_free                (ThunarShortcutCategory    *category);
-static void                    thunar_shortcut_free                         (ThunarShortcut            *shortcut);
 
 
 
@@ -179,26 +166,11 @@ struct _ThunarShortcutCategory
   guint                      visible : 1;
 };
 
-struct _ThunarShortcut
-{
-  ThunarShortcutType type;
-
-  GIcon              *icon;
-  GIcon              *eject_icon;
-
-  gchar              *name;
-  GFile              *file;
-  GVolume            *volume;
-
-  guint               mutable : 1;
-  guint               persistent : 1;
-  guint               visible : 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_MODEL, 
+                                                thunar_shortcuts_model_tree_model_init))
 
 
     
@@ -273,10 +245,15 @@ thunar_shortcuts_model_finalize (GObject *object)
   if (model->load_idle_id != 0)
     g_source_remove (model->load_idle_id);
   
-  /* release the volume monitor */
+  /* check if we have a volume monitor */
   if (model->volume_monitor != NULL)
     {
-      /* TODO disconnect from the monitor signals */
+      /* disconnect from the monitor signals */
+      g_signal_handlers_disconnect_matched (model->volume_monitor, 
+                                            G_SIGNAL_MATCH_DATA,
+                                            0, 0, 0, NULL, model);
+
+      /* release the volume monitor */
       g_object_unref (model->volume_monitor);
     }
 
@@ -423,7 +400,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_ICON:
       g_value_init (value, G_TYPE_ICON);
       if (shortcut != NULL)
-        g_value_set_object (value, shortcut->icon);
+        g_value_set_object (value, thunar_shortcut_get_icon (shortcut));
       else
         g_value_set_object (value, NULL);
       break;
@@ -431,7 +408,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
       g_value_init (value, G_TYPE_STRING);
       if (shortcut != NULL)
-        g_value_set_static_string (value, shortcut->name);
+        g_value_set_static_string (value, thunar_shortcut_get_name (shortcut));
       else
         g_value_set_static_string (value, category->name);
       break;
@@ -439,7 +416,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_FILE:
       g_value_init (value, G_TYPE_FILE);
       if (shortcut != NULL)
-        g_value_set_object (value, shortcut->file);
+        g_value_set_object (value, thunar_shortcut_get_location (shortcut));
       else
         g_value_set_object (value, NULL);
       break;
@@ -447,7 +424,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME:
       g_value_init (value, G_TYPE_VOLUME);
       if (shortcut != NULL)
-        g_value_set_object (value, shortcut->volume);
+        g_value_set_object (value, thunar_shortcut_get_volume (shortcut));
       else
         g_value_set_object (value, NULL);
       break;
@@ -455,7 +432,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_MUTABLE:
       g_value_init (value, G_TYPE_BOOLEAN);
       if (shortcut != NULL)
-        g_value_set_boolean (value, shortcut->mutable);
+        g_value_set_boolean (value, thunar_shortcut_get_mutable (shortcut));
       else
         g_value_set_boolean (value, FALSE);
       break;
@@ -463,7 +440,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_EJECT_ICON:
       g_value_init (value, G_TYPE_ICON);
       if (shortcut != NULL)
-        g_value_set_object (value, shortcut->eject_icon);
+        g_value_set_object (value, thunar_shortcut_get_eject_icon (shortcut));
       else
         g_value_set_object (value, NULL);
       break;
@@ -476,7 +453,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_PERSISTENT:
       g_value_init (value, G_TYPE_BOOLEAN);
       if (shortcut != NULL)
-        g_value_set_boolean (value, shortcut->persistent);
+        g_value_set_boolean (value, thunar_shortcut_get_persistent (shortcut));
       else
         g_value_set_boolean (value, FALSE);
       break;
@@ -484,7 +461,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
       g_value_init (value, G_TYPE_BOOLEAN);
       if (shortcut != NULL)
-        g_value_set_boolean (value, shortcut->visible);
+        g_value_set_boolean (value, !thunar_shortcut_get_hidden (shortcut));
       else
         g_value_set_boolean (value, category->visible);
       break;
@@ -853,14 +830,14 @@ thunar_shortcuts_model_parse_iter (ThunarShortcutsModel *model,
 
 static gboolean
 thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
-                                      GFile                   *file,
-                                      GVolume                 *volume,
-                                      ThunarShortcutType       type,
+                                      ThunarShortcut          *shortcut,
                                       ThunarShortcutCategory **category,
                                       gint                    *category_index)
 {
   ThunarShortcutCategory *current_category = NULL;
+  ThunarShortcutType      type;
   gboolean                item_belongs_here = FALSE;
+  GFile                  *file;
   guint                   n;
 
   _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
@@ -873,6 +850,13 @@ thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
   if (category_index != NULL)
     *category_index = -1;
 
+  /* read information needed to find the category from the shortcut */
+  type = thunar_shortcut_get_shortcut_type (shortcut);
+  file = thunar_shortcut_get_location (shortcut);
+  
+  g_debug ("%s:", thunar_shortcut_get_name (shortcut));
+  g_debug ("type = %d", type);
+
   /* iterate over all available categories */
   for (n = 0; !item_belongs_here && n < model->categories->len; ++n)
     {
@@ -882,45 +866,47 @@ thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
       switch (current_category->type)
         {
         case THUNAR_SHORTCUT_CATEGORY_DEVICES:
-          /* system volumes belong into devices */
-          if (type == THUNAR_SHORTCUT_SYSTEM_VOLUME)
-            item_belongs_here = TRUE;
-
-          /* regular volumes belong into devices as well */
-          if (type == THUNAR_SHORTCUT_VOLUME)
+          /* regular volumes belong here */
+          if (type == THUNAR_SHORTCUT_REGULAR_VOLUME)
             item_belongs_here = TRUE;
 
-          /* items with volumes belong here too */
-          if (volume != NULL)
+          /* directly ejectable volumes belong here */
+          if (type == THUNAR_SHORTCUT_EJECTABLE_VOLUME)
             item_belongs_here = TRUE;
 
-          /* check whether we have an archive mountable */
-          if (file != NULL && g_file_has_uri_scheme (file, "archive"))
-            item_belongs_here = TRUE;
+          /* mounts with mount points that are in archive:// belong here */
+          if (type == THUNAR_SHORTCUT_STANDALONE_MOUNT 
+              && file != NULL 
+              && g_file_has_uri_scheme (file, "archive"))
+            {
+              item_belongs_here = TRUE;
+            }
           break;
 
         case THUNAR_SHORTCUT_CATEGORY_PLACES:
-          /* user directories belong into places */
-          if (type == THUNAR_SHORTCUT_USER_DIRECTORY)
-            item_belongs_here = TRUE;
-
-          /* local files belong into places */
-          if (type == THUNAR_SHORTCUT_LOCAL_FILE)
+          /* regular files belong here */
+          if (type == THUNAR_SHORTCUT_REGULAR_FILE)
             item_belongs_here = TRUE;
 
-          /* check whether we have a local file */
-          if (file != NULL && g_file_has_uri_scheme (file, "file"))
+          /* trash directories belong here */
+          if (file != NULL && g_file_has_uri_scheme (file, "trash"))
             item_belongs_here = TRUE;
           break;
 
         case THUNAR_SHORTCUT_CATEGORY_NETWORK:
           /* remote files belong here */
-          if (type == THUNAR_SHORTCUT_REMOTE_FILE)
+          if (type == THUNAR_SHORTCUT_NETWORK_FILE)
             item_belongs_here = TRUE;
 
-          /* check whether we have a remote file */
-          if (file != NULL && !g_file_has_uri_scheme (file, "file"))
-            item_belongs_here = TRUE;
+          /* remote mounts belong here */
+          if (type == THUNAR_SHORTCUT_STANDALONE_MOUNT
+              && file != NULL 
+              && !g_file_has_uri_scheme (file, "archive")
+              && !g_file_has_uri_scheme (file, "file")
+              && !g_file_has_uri_scheme (file, "trash"))
+            {
+              item_belongs_here = TRUE;
+            }
           break;
 
         default:
@@ -955,6 +941,7 @@ thunar_shortcuts_model_find_volume (ThunarShortcutsModel *model,
   ThunarShortcutCategory *category;
   ThunarShortcut         *shortcut;
   gboolean                shortcut_found = FALSE;
+  GVolume                *shortcut_volume;
   gint                    category_index;
   gint                    shortcut_index;
 
@@ -972,8 +959,9 @@ thunar_shortcuts_model_find_volume (ThunarShortcutsModel *model,
            ++shortcut_index)
         {
           shortcut = g_ptr_array_index (category->shortcuts, shortcut_index);
+          shortcut_volume = thunar_shortcut_get_volume (shortcut);
 
-          if (shortcut->volume == volume)
+          if (shortcut_volume == volume)
             {
               if (iter != NULL)
                 {
@@ -1010,14 +998,14 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
   gint                    category_index;
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
-  _thunar_return_if_fail (shortcut != NULL);
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
 
   /* find the destination category for the shortcut */
-  if (!thunar_shortcuts_model_find_category (model, shortcut->file, shortcut->volume,
-                                             shortcut->type, &category, &category_index))
+  if (!thunar_shortcuts_model_find_category (model, shortcut, 
+                                             &category, &category_index))
     {
       g_debug ("failed to add shortcut \"%s\": no category found",
-               shortcut->name);
+               thunar_shortcut_get_name (shortcut));
       return;
     }
 
@@ -1054,8 +1042,10 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
 {
   ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
   ThunarShortcut       *shortcut;
-  GFile                *desktop_file;
   GFile                *home_file;
+  GFile                *location;
+  GIcon                *icon;
+  gchar                *name;
   gchar                *path;
 
   _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
@@ -1063,58 +1053,90 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
   /* request a GFile for the home directory */
   home_file = thunar_g_file_new_for_home ();
 
-  /* create a shortcut for the HOME folder */
-  shortcut = g_slice_new0 (ThunarShortcut);
-  shortcut->file = g_object_ref (home_file);
-  shortcut->icon = g_themed_icon_new ("user-home");
+  /* create $HOME information */
+  icon = g_themed_icon_new ("user-home");
   path = g_file_get_path (home_file);
-  shortcut->name = g_filename_display_basename (path);
-  g_free (path);
-  shortcut->type = THUNAR_SHORTCUT_USER_DIRECTORY;
-  shortcut->visible = TRUE;
-  shortcut->mutable = FALSE;
-  shortcut->persistent = TRUE;
+  name = g_filename_display_basename (path);
+  
+  /* create the $HOME shortcut */
+  shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                           "shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
+                           "location", home_file,
+                           "icon", icon,
+                           "eject-icon", NULL,
+                           "name", name,
+                           "hidden", FALSE,
+                           "mutable", FALSE,
+                           "persistent", TRUE,
+                           NULL);
 
   /* add the shortcut */
   thunar_shortcuts_model_add_shortcut (model, shortcut);
 
+  /* release $HOME information */
+  g_free (name);
+  g_free (path);
+  g_object_unref (icon);
+
   /* request a GFile for the desktop directory */
-  desktop_file = thunar_g_file_new_for_desktop ();
+  location = thunar_g_file_new_for_desktop ();
 
   /* check if desktop is set to home (in that case, ignore it) */
-  if (!g_file_equal (home_file, desktop_file))
+  if (!g_file_equal (home_file, location))
     {
-      /* create a shortcut for the desktop folder */
-      shortcut = g_slice_new0 (ThunarShortcut);
-      shortcut->file = g_object_ref (desktop_file);
-      shortcut->icon = g_themed_icon_new ("user-desktop");
-      shortcut->name = g_strdup (_("Desktop"));
-      shortcut->type = THUNAR_SHORTCUT_USER_DIRECTORY;
-      shortcut->visible = TRUE;
-      shortcut->mutable = FALSE;
-      shortcut->persistent = TRUE;
+      /* create desktop information */
+      icon = g_themed_icon_new ("user-desktop");
+      name = g_strdup (_("Desktop"));
+
+      /* create the desktop shortcut */
+      shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                               "shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
+                               "location", location,
+                               "icon", icon,
+                               "eject-icon", NULL,
+                               "name", name,
+                               "hidden", FALSE,
+                               "mutable", FALSE,
+                               "persistent", TRUE,
+                               NULL);
 
       /* add the shortcut */
       thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+      /* release desktop information */
+      g_free (name);
+      g_object_unref (icon);
     }
 
   /* release desktop and home files */
-  g_object_unref (desktop_file);
+  g_object_unref (location);
   g_object_unref (home_file);
 
-  /* create a shortcut for the root file system */
-  shortcut = g_slice_new0 (ThunarShortcut);
-  shortcut->file = thunar_g_file_new_for_trash ();
-  shortcut->icon = g_themed_icon_new ("user-trash");
-  shortcut->name = g_strdup (_("Trash"));
-  shortcut->type = THUNAR_SHORTCUT_USER_DIRECTORY;
-  shortcut->visible = TRUE;
-  shortcut->mutable = FALSE;
-  shortcut->persistent = TRUE;
+  /* create trash information */
+  location = thunar_g_file_new_for_trash ();
+  icon = g_themed_icon_new ("user-trash");
+  name = g_strdup (_("Trash"));
+
+  /* create the trash shortcut */
+  shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                           "shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
+                           "location", location,
+                           "icon", icon,
+                           "eject-icon", NULL,
+                           "name", name,
+                           "hidden", FALSE,
+                           "mutable", FALSE,
+                           "persistent", TRUE,
+                           NULL);
 
   /* add the shortcut */
   thunar_shortcuts_model_add_shortcut (model, shortcut);
 
+  /* release trash information */
+  g_free (name);
+  g_object_unref (icon);
+  g_object_unref (location);
+
   /* load rest of the user dirs next */
   model->load_idle_id = g_idle_add (thunar_shortcuts_model_load_user_dirs, model);
 
@@ -1142,10 +1164,14 @@ static gboolean
 thunar_shortcuts_model_load_bookmarks (gpointer user_data)
 {
   ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
+  ThunarShortcutType    type;
   ThunarShortcut       *shortcut;
   gboolean              is_local;
   GFile                *bookmarks_file;
   GFile                *home_file;
+  GFile                *location;
+  GIcon                *eject_icon;
+  GIcon                *icon;
   gchar                *bookmarks_path;
   gchar                 line[2048];
   gchar                *name;
@@ -1154,6 +1180,9 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
 
   _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
 
+  /* create an eject icon */
+  eject_icon = g_themed_icon_new ("media-eject");
+
   /* resolve the bookmarks file */
   home_file = thunar_g_file_new_for_home ();
   bookmarks_file = g_file_resolve_relative_path (home_file, ".gtk-bookmarks");
@@ -1184,41 +1213,53 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
           /* check if we have something that looks like a URI */
           if (exo_str_looks_like_an_uri (line))
             {
-              
-              /* create a shortcut for the desktop folder */
-              shortcut = g_slice_new0 (ThunarShortcut);
-              shortcut->file = g_file_new_for_uri (line);
+              /* parse the URI */
+              location = g_file_new_for_uri (line);
 
+              /* use the base name as a fallback for the display name */
               if (*name != '\0')
                 {
-                  shortcut->name = g_strdup (name);
+                  name = g_strdup (name);
                 }
               else
                 {
                   unescaped_uri = g_uri_unescape_string (line, NULL);
-                  shortcut->name = g_filename_display_basename (unescaped_uri);
+                  name = g_filename_display_basename (unescaped_uri);
                   g_free (unescaped_uri);
                 }
 
-              is_local = g_file_has_uri_scheme (shortcut->file, "file");
-
+              /* set initial icon and type based on the URI scheme */
+              is_local = g_file_has_uri_scheme (location, "file");
               if (is_local)
                 {
-                  shortcut->icon = g_themed_icon_new ("folder");
-                  shortcut->type = THUNAR_SHORTCUT_LOCAL_FILE;
+                  icon = g_themed_icon_new ("folder");
+                  type = THUNAR_SHORTCUT_REGULAR_FILE;
                 }
               else
                 {
-                  shortcut->icon = g_themed_icon_new ("folder-remote");
-                  shortcut->type = THUNAR_SHORTCUT_REMOTE_FILE;
+                  icon = g_themed_icon_new ("folder-remote");
+                  type = THUNAR_SHORTCUT_NETWORK_FILE;
                 }
 
-              shortcut->visible = TRUE;
-              shortcut->mutable = FALSE;
-              shortcut->persistent = TRUE;
+              /* create the shortcut */
+              shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                                       "shortcut-type", type,
+                                       "location", location,
+                                       "icon", icon,
+                                       "eject-icon", eject_icon,
+                                       "name", name,
+                                       "hidden", FALSE,
+                                       "mutable", TRUE,
+                                       "persistent", TRUE,
+                                       NULL);
 
               /* add the shortcut */
               thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+              /* release file information */
+              g_free (name);
+              g_object_unref (icon);
+              g_object_unref (location);
             }
         }
 
@@ -1229,6 +1270,9 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
   /* free the bookmarks file path */
   g_free (bookmarks_path);
 
+  /* release the eject icon */
+  g_object_unref (eject_icon);
+
   /* TODO monitor the bookmarks file for changes */
 
   /* load volumes next */
@@ -1243,8 +1287,6 @@ static gboolean
 thunar_shortcuts_model_load_volumes (gpointer user_data)
 {
   ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
-  ThunarShortcut       *shortcut;
-  GVolume              *volume;
   GList                *mounts;
   GList                *volumes;
   GList                *lp;
@@ -1260,19 +1302,8 @@ thunar_shortcuts_model_load_volumes (gpointer user_data)
   /* create shortcuts for the volumes */
   for (lp = volumes; lp != NULL; lp = lp->next)
     {
-      /* create the shortcut */
-      shortcut = g_slice_new0 (ThunarShortcut);
-      shortcut->volume = lp->data;
-      shortcut->icon = g_volume_get_icon (shortcut->volume);
-      shortcut->eject_icon = g_themed_icon_new ("media-eject");
-      shortcut->name = g_volume_get_name (shortcut->volume);
-      shortcut->type = THUNAR_SHORTCUT_VOLUME;
-      shortcut->visible = TRUE;
-      shortcut->mutable = TRUE;
-      shortcut->persistent = FALSE;
-
-      /* add the shortcut */
-      thunar_shortcuts_model_add_shortcut (model, shortcut);
+      /* add a new volume shortcut */
+      thunar_shortcuts_model_volume_added (model, lp->data, model->volume_monitor);
     }
 
   /* release the volume list */
@@ -1284,29 +1315,8 @@ thunar_shortcuts_model_load_volumes (gpointer user_data)
   /* create shortcuts for the mounts */
   for (lp = mounts; lp != NULL; lp = lp->next)
     {
-      /* only create the shortcut if it has no volume */
-      volume = g_mount_get_volume (lp->data);
-      if (volume == NULL)
-        {
-          /* create the shortcut */
-          shortcut = g_slice_new0 (ThunarShortcut);
-          shortcut->file = g_mount_get_root (lp->data);
-          shortcut->icon = g_mount_get_icon (lp->data);
-          shortcut->eject_icon = g_themed_icon_new ("media-eject");
-          shortcut->name = g_mount_get_name (lp->data);
-          shortcut->type = THUNAR_SHORTCUT_REMOTE_FILE;
-          shortcut->visible = TRUE;
-          shortcut->mutable = TRUE;
-          shortcut->persistent = FALSE;
-
-          /* add the shortcut */
-          thunar_shortcuts_model_add_shortcut (model, shortcut);
-        }
-      else
-        {
-          /* release the volume again */
-          g_object_unref (volume);
-        }
+      /* add a new mount shortcut */
+      thunar_shortcuts_model_mount_added (model, lp->data, model->volume_monitor);
     }
 
   /* release the mount list */
@@ -1317,6 +1327,8 @@ thunar_shortcuts_model_load_volumes (gpointer user_data)
                             G_CALLBACK (thunar_shortcuts_model_volume_added), model);
   g_signal_connect_swapped (model->volume_monitor, "volume-removed",
                             G_CALLBACK (thunar_shortcuts_model_volume_removed), model);
+  g_signal_connect_swapped (model->volume_monitor, "mount-added",
+                            G_CALLBACK (thunar_shortcuts_model_mount_added), model);
 
   /* reset the load idle ID */
   model->load_idle_id = 0;
@@ -1332,24 +1344,38 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
                                      GVolumeMonitor       *monitor)
 {
   ThunarShortcut *shortcut;
+  GIcon          *eject_icon;
+  GIcon          *icon;
+  gchar          *name;
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
   _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (G_IS_VOLUME_MONITOR (monitor));
 
+  /* read information from the volume */
+  icon = g_volume_get_icon (volume);
+  eject_icon = g_themed_icon_new ("media-eject");
+  name = g_volume_get_name (volume);
+
   /* create a shortcut for the volume */
-  shortcut = g_slice_new0 (ThunarShortcut);
-  shortcut->volume = g_object_ref (volume);
-  shortcut->icon = g_volume_get_icon (shortcut->volume);
-  shortcut->eject_icon = g_themed_icon_new ("media-eject");
-  shortcut->name = g_volume_get_name (shortcut->volume);
-  shortcut->type = THUNAR_SHORTCUT_VOLUME;
-  shortcut->visible = TRUE;
-  shortcut->mutable = TRUE;
-  shortcut->persistent = FALSE;
+  shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                           "shortcut-type", THUNAR_SHORTCUT_REGULAR_VOLUME,
+                           "volume", volume,
+                           "icon", icon,
+                           "eject-icon", eject_icon,
+                           "name", name,
+                           "hidden", FALSE,
+                           "mutable", FALSE,
+                           "persistent", FALSE,
+                           NULL);
 
   /* add the shortcut to the model */
   thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+  /* release volume information */
+  g_free (name);
+  g_object_unref (eject_icon);
+  g_object_unref (icon);
 }
 
 
@@ -1388,6 +1414,63 @@ thunar_shortcuts_model_volume_removed (ThunarShortcutsModel *model,
 
 
 
+static void
+thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
+                                    GMount               *mount,
+                                    GVolumeMonitor       *monitor)
+{
+  ThunarShortcut *shortcut;
+  GVolume        *volume;
+  GFile          *location;
+  GIcon          *eject_icon;
+  GIcon          *icon;
+  gchar          *name;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  _thunar_return_if_fail (G_IS_MOUNT (mount));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (monitor));
+
+  /* only create the shortcut if it has no volume */
+  volume = g_mount_get_volume (mount);
+  if (volume != NULL)
+    {
+      /* release the volume again */
+      g_object_unref (volume);
+    }
+  else
+    {
+      /* read information from the mount */
+      location = g_mount_get_root (mount);
+      icon = g_mount_get_icon (mount);
+      eject_icon = g_themed_icon_new ("media-eject");
+      name = g_mount_get_name (mount);
+
+      /* create a shortcut for the mount */
+      shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                               "shortcut-type", THUNAR_SHORTCUT_STANDALONE_MOUNT,
+                               "location", location,
+                               "mount", mount,
+                               "icon", icon,
+                               "eject-icon", eject_icon,
+                               "name", name,
+                               "hidden", FALSE,
+                               "mutable", FALSE,
+                               "persistent", FALSE,
+                               NULL);
+
+      /* add the shortcut to the model */
+      thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+      /* release volume information */
+      g_free (name);
+      g_object_unref (eject_icon);
+      g_object_unref (icon);
+      g_object_unref (location);
+    }
+}
+
+
+
 static ThunarShortcutCategory *
 thunar_shortcut_category_new (ThunarShortcutCategoryType type)
 {
@@ -1423,8 +1506,7 @@ thunar_shortcut_category_new (ThunarShortcutCategoryType type)
   category->visible = TRUE;
 
   /* allocate an empty array for the shortcuts in the category */
-  category->shortcuts = 
-    g_ptr_array_new_with_free_func ((GDestroyNotify) thunar_shortcut_free);
+  category->shortcuts = g_ptr_array_new_with_free_func (g_object_unref);
 
   return category;
 }
@@ -1483,34 +1565,6 @@ _thunar_get_xdg_user_dirs_locale (void)
 
 
 
-static void
-thunar_shortcut_free (ThunarShortcut *shortcut)
-{
-  /* release the shortcut icon */
-  if (shortcut->icon != NULL)
-    g_object_unref (shortcut->icon);
-
-  /* release the eject icon */
-  if (shortcut->eject_icon != NULL)
-    g_object_unref (shortcut->eject_icon);
-
-  /* release the shortcut name */
-  g_free (shortcut->name);
-
-  /* release the shortcut file */
-  if (shortcut->file != NULL)
-    g_object_unref (shortcut->file);
-
-  /* release the shortcut volume */
-  if (shortcut->volume != NULL)
-    g_object_unref (shortcut->volume);
-
-  /* release the shortcut itself */
-  g_slice_free (ThunarShortcut, shortcut);
-}
-
-
-
 /**
  * thunar_shortcuts_model_get_default:
  *



More information about the Xfce4-commits mailing list