[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Further work on ThunarShortcutsModel, add new ThunarShortcutRow widget.

Jannis Pohlmann noreply at xfce.org
Mon Jun 6 04:00:02 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 3d34ec850c15d8f17fab0b6ade07b026cfc4f260 (commit)
       from f4643b6c14f35ad9e567c828c8f9d45b1a623355 (commit)

commit 3d34ec850c15d8f17fab0b6ade07b026cfc4f260
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Mon Jun 6 03:55:50 2011 +0200

    Further work on ThunarShortcutsModel, add new ThunarShortcutRow widget.
    
    This commit introduces the new ThunarShortcutRow widget which has all
    the properties necessary to visualize a file, volume, mounted archive
    or remote location. The widget is used in the new ThunarShortcutsView to
    represent a single item.
    
    The communication between ThunarShortcutsModel and ThunarShortcutsView
    has been improved and ThunarShortcutsView now creates expanders for all
    categories and is able to insert new rows inside the correct expander.

 thunar/Makefile.am              |    2 +
 thunar/thunar-shortcut-row.c    |  519 +++++++++++++++++++++++++++++++++++++++
 thunar/thunar-shortcut-row.h    |   56 +++++
 thunar/thunar-shortcuts-model.c |  361 +++++++++++++++++++++++----
 thunar/thunar-shortcuts-model.h |    1 +
 thunar/thunar-shortcuts-view.c  |  169 ++++++++++++-
 6 files changed, 1043 insertions(+), 65 deletions(-)

diff --git a/thunar/Makefile.am b/thunar/Makefile.am
index b715fea..d6c8387 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-row.c						\
+	thunar-shortcut-row.h						\
 	thunar-shortcuts-icon-renderer.c				\
 	thunar-shortcuts-icon-renderer.h				\
 	thunar-shortcuts-model.c					\
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
new file mode 100644
index 0000000..be538b8
--- /dev/null
+++ b/thunar/thunar-shortcut-row.c
@@ -0,0 +1,519 @@
+/* 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 <exo/exo.h>
+
+#include <thunar/thunar-private.h>
+#include <thunar/thunar-shortcut-row.h>
+
+
+
+/* property identifiers */
+enum
+{
+  PROP_0,
+  PROP_ICON,
+  PROP_LABEL,
+  PROP_EJECT_ICON,
+  PROP_FILE,
+  PROP_VOLUME,
+};
+
+
+
+static void thunar_shortcut_row_constructed    (GObject           *object);
+static void thunar_shortcut_row_dispose        (GObject           *object);
+static void thunar_shortcut_row_finalize       (GObject           *object);
+static void thunar_shortcut_row_get_property   (GObject           *object,
+                                                guint              prop_id,
+                                                GValue            *value,
+                                                GParamSpec        *pspec);
+static void thunar_shortcut_row_set_property   (GObject           *object,
+                                                guint              prop_id,
+                                                const GValue      *value,
+                                                GParamSpec        *pspec);
+static void thunar_shortcut_row_icon_changed   (ThunarShortcutRow *row);
+static void thunar_shortcut_row_label_changed  (ThunarShortcutRow *row);
+static void thunar_shortcut_row_file_changed   (ThunarShortcutRow *row);
+static void thunar_shortcut_row_volume_changed (ThunarShortcutRow *row);
+
+
+
+struct _ThunarShortcutRowClass
+{
+  GtkEventBoxClass __parent__;
+};
+
+struct _ThunarShortcutRow
+{
+  GtkEventBox __parent__;
+
+  gchar      *label;
+
+  GIcon      *icon;
+  GIcon      *eject_icon;
+
+  GFile      *file;
+  GVolume    *volume;
+
+  GtkWidget  *label_widget;
+  GtkWidget  *icon_image;
+  GtkWidget  *action_button;
+};
+
+
+
+G_DEFINE_TYPE (ThunarShortcutRow, thunar_shortcut_row, GTK_TYPE_EVENT_BOX)
+
+
+
+static void
+thunar_shortcut_row_class_init (ThunarShortcutRowClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* determine the parent type class */
+  thunar_shortcut_row_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->constructed = thunar_shortcut_row_constructed; 
+  gobject_class->dispose = thunar_shortcut_row_dispose; 
+  gobject_class->finalize = thunar_shortcut_row_finalize; 
+  gobject_class->get_property = thunar_shortcut_row_get_property;
+  gobject_class->set_property = thunar_shortcut_row_set_property;
+
+  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_LABEL,
+                                   g_param_spec_string ("label",
+                                                        "label",
+                                                        "label",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_FILE,
+                                   g_param_spec_object ("file",
+                                                        "file",
+                                                        "file",
+                                                        G_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));
+}
+
+
+
+static void
+thunar_shortcut_row_init (ThunarShortcutRow *row)
+{
+  GtkWidget *alignment;
+  GtkWidget *box;
+
+  /* configure general widget behavior */
+  gtk_widget_set_can_focus (GTK_WIDGET (row), TRUE);
+  gtk_widget_set_sensitive (GTK_WIDGET (row), TRUE);
+
+  /* create the alignment for left and right padding */
+  alignment = gtk_alignment_new (0.0f, 0.0f, 1.0f, 1.0f);
+  /* TODO use expander arrow width instead of 16 here */
+  gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 16, 4);
+  gtk_container_add (GTK_CONTAINER (row), alignment);
+  gtk_widget_show (alignment);
+
+  /* create a box for the different sub-widgets */
+  box = gtk_hbox_new (FALSE, 4);
+  gtk_container_add (GTK_CONTAINER (alignment), box);
+  gtk_widget_show (box);
+
+  /* create the icon widget */
+  row->icon_image = gtk_image_new ();
+  gtk_box_pack_start (GTK_BOX (box), row->icon_image, FALSE, TRUE, 0);
+  gtk_widget_hide (row->icon_image);
+
+  /* create the label widget */
+  row->label_widget = gtk_label_new (NULL);
+  gtk_label_set_ellipsize (GTK_LABEL (row->label_widget), PANGO_ELLIPSIZE_END);
+  gtk_misc_set_alignment (GTK_MISC (row->label_widget), 0.0f, 0.5f);
+  gtk_container_add (GTK_CONTAINER (box), row->label_widget);
+  gtk_widget_hide (row->label_widget);
+
+  /* create the action button */
+  row->action_button = gtk_button_new ();
+  gtk_button_set_relief (GTK_BUTTON (row->action_button), GTK_RELIEF_NONE);
+  gtk_box_pack_start (GTK_BOX (box), row->action_button, FALSE, TRUE, 0);
+  gtk_widget_hide (row->action_button);
+}
+
+
+
+static void
+thunar_shortcut_row_constructed (GObject *object)
+{
+}
+
+
+
+static void
+thunar_shortcut_row_dispose (GObject *object)
+{
+  (*G_OBJECT_CLASS (thunar_shortcut_row_parent_class)->dispose) (object);
+}
+
+
+
+static void
+thunar_shortcut_row_finalize (GObject *object)
+{
+  ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (object);
+
+  g_free (row->label);
+
+  if (row->icon != NULL)
+    g_object_unref (row->icon);
+
+  if (row->eject_icon != NULL)
+    g_object_unref (row->eject_icon);
+
+  if (row->file != NULL)
+    g_object_unref (row->file);
+
+  if (row->volume != NULL)
+    g_object_unref (row->volume);
+
+  (*G_OBJECT_CLASS (thunar_shortcut_row_parent_class)->finalize) (object);
+}
+
+
+
+static void
+thunar_shortcut_row_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+  ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_ICON:
+      g_value_set_object (value, row->icon);
+      break;
+
+    case PROP_EJECT_ICON:
+      g_value_set_object (value, row->eject_icon);
+      break;
+
+    case PROP_LABEL:
+      g_value_set_string (value, row->label);
+      break;
+
+    case PROP_FILE:
+      g_value_set_object (value, row->file);
+      break;
+
+    case PROP_VOLUME:
+      g_value_set_object (value, row->volume);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+thunar_shortcut_row_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+  ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_ICON:
+      thunar_shortcut_row_set_icon (row, g_value_get_object (value));
+      break;
+
+    case PROP_EJECT_ICON:
+      thunar_shortcut_row_set_eject_icon (row, g_value_get_object (value));
+      break;
+
+    case PROP_LABEL:
+      thunar_shortcut_row_set_label (row, g_value_get_string (value));
+      break;
+
+    case PROP_FILE:
+      thunar_shortcut_row_set_file (row, g_value_get_object (value));
+      break;
+
+    case PROP_VOLUME:
+      thunar_shortcut_row_set_volume (row, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+thunar_shortcut_row_icon_changed (ThunarShortcutRow *row)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  /* update the icon image */
+  gtk_image_set_from_gicon (GTK_IMAGE (row->icon_image), row->icon, GTK_ICON_SIZE_MENU);
+  gtk_widget_set_visible (row->icon_image, row->icon != NULL);
+}
+
+
+
+static void
+thunar_shortcut_row_label_changed (ThunarShortcutRow *row)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  /* update the label widget */
+  gtk_label_set_markup (GTK_LABEL (row->label_widget), row->label);
+  gtk_widget_set_visible (row->label_widget, row->label != NULL && *row->label != '\0');
+}
+
+
+
+
+static void
+thunar_shortcut_row_file_changed (ThunarShortcutRow *row)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  /* volume has higher priority in affecting the appearance of 
+   * the shortcut, so if a volume is set, we will only adjust 
+   * the appearance based on that */
+  if (row->volume != NULL)
+    return;
+
+  if (row->file == NULL)
+    {
+    }
+  else
+    {
+    }
+}
+
+
+
+static void
+thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
+{
+  GMount *mount;
+  GIcon  *icon;
+  gchar  *name;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  if (row->volume == NULL)
+    {
+      /* update the appearance based on the file, if we have one */
+      thunar_shortcut_row_file_changed (row);
+    }
+  else
+    {
+      /* update the label widget */
+      name = g_volume_get_name (row->volume);
+      gtk_label_set_markup (GTK_LABEL (row->label_widget), name);
+      gtk_widget_set_visible (row->label_widget, name != NULL && *name != '\0');
+      g_free (name);
+
+      /* update the icon image */
+      icon = g_volume_get_icon (row->volume);
+      gtk_image_set_from_gicon (GTK_IMAGE (row->icon_image), icon, GTK_ICON_SIZE_MENU);
+      gtk_widget_set_visible (row->icon_image, icon != NULL);
+      g_object_unref (icon);
+
+      /* update the action button */
+      mount = g_volume_get_mount (row->volume);
+      gtk_widget_set_visible (row->action_button, mount != NULL);
+      if (mount != NULL)
+        g_object_unref (mount);
+    }
+}
+
+
+
+GtkWidget *
+thunar_shortcut_row_new (GIcon       *icon,
+                         const gchar *label,
+                         GIcon       *eject_icon)
+{
+  _thunar_return_val_if_fail (label != NULL && *label != '\0', NULL);
+
+  return g_object_new (THUNAR_TYPE_SHORTCUT_ROW,
+                       "icon", icon,
+                       "label", label,
+                       "eject-icon", eject_icon,
+                       NULL);
+}
+
+
+
+void
+thunar_shortcut_row_set_icon (ThunarShortcutRow *row,
+                              GIcon             *icon)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+  _thunar_return_if_fail (icon == NULL || G_IS_ICON (icon));
+
+  if (row->icon == icon)
+    return;
+
+  if (row->icon != NULL)
+    g_object_unref (row->icon);
+
+  if (icon != NULL)
+    row->icon = g_object_ref (icon);
+  else
+    row->icon = NULL;
+
+  thunar_shortcut_row_icon_changed (row);
+
+  g_object_notify (G_OBJECT (row), "icon");
+}
+
+
+
+void
+thunar_shortcut_row_set_eject_icon (ThunarShortcutRow *row,
+                                    GIcon             *eject_icon)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+  _thunar_return_if_fail (eject_icon == NULL || G_IS_ICON (eject_icon));
+
+  if (row->eject_icon == eject_icon)
+    return;
+
+  if (row->eject_icon != NULL)
+    g_object_unref (row->eject_icon);
+
+  if (eject_icon != NULL)
+    row->eject_icon = g_object_ref (eject_icon);
+  else
+    row->eject_icon = NULL;
+
+  g_object_notify (G_OBJECT (row), "eject-icon");
+}
+
+
+
+void
+thunar_shortcut_row_set_label (ThunarShortcutRow *row,
+                               const gchar       *label)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  if (g_strcmp0 (row->label, label) == 0)
+    return;
+
+  g_free (row->label);
+
+  row->label = g_strdup (label);
+
+  thunar_shortcut_row_label_changed (row);
+
+  g_object_notify (G_OBJECT (row), "label");
+}
+
+
+
+void
+thunar_shortcut_row_set_file (ThunarShortcutRow *row,
+                              GFile             *file)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+  _thunar_return_if_fail (file == NULL || G_IS_FILE (file));
+
+  if (row->file == file)
+    return;
+
+  if (row->file != NULL)
+    g_object_unref (row->file);
+
+  if (file != NULL)
+    row->file = g_object_ref (file);
+  else
+    row->file = NULL;
+
+  thunar_shortcut_row_file_changed (row);
+
+  g_object_notify (G_OBJECT (row), "file");
+}
+
+
+
+void
+thunar_shortcut_row_set_volume (ThunarShortcutRow *row,
+                                GVolume           *volume)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+  _thunar_return_if_fail (volume == NULL || G_IS_VOLUME (volume));
+
+  if (row->volume == volume)
+    return;
+
+  if (row->volume != NULL)
+    g_object_unref (row->volume);
+
+  if (volume != NULL)
+    row->volume = g_object_ref (volume);
+  else
+    row->volume = NULL;
+
+  thunar_shortcut_row_volume_changed (row);
+
+  g_object_notify (G_OBJECT (row), "volume");
+}
diff --git a/thunar/thunar-shortcut-row.h b/thunar/thunar-shortcut-row.h
new file mode 100644
index 0000000..b02110f
--- /dev/null
+++ b/thunar/thunar-shortcut-row.h
@@ -0,0 +1,56 @@
+/* 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_ROW_H__
+#define __THUNAR_SHORTCUT_ROW_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define THUNAR_TYPE_SHORTCUT_ROW            (thunar_shortcut_row_get_type ())
+#define THUNAR_SHORTCUT_ROW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_SHORTCUT_ROW, ThunarShortcutRow))
+#define THUNAR_SHORTCUT_ROW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_SHORTCUT_ROW, ThunarShortcutRowClass))
+#define THUNAR_IS_SHORTCUT_ROW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_SHORTCUT_ROW))
+#define THUNAR_IS_SHORTCUT_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SHORTCUT_ROW)
+#define THUNAR_SHORTCUT_ROW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_SHORTCUT_ROW, ThunarShortcutRowClass))
+
+typedef struct _ThunarShortcutRowClass ThunarShortcutRowClass;
+typedef struct _ThunarShortcutRow      ThunarShortcutRow;
+
+GType      thunar_shortcut_row_get_type (void) G_GNUC_CONST;
+
+GtkWidget *thunar_shortcut_row_new            (GIcon             *icon,
+                                               const gchar       *name,
+                                               GIcon             *eject_icon) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void       thunar_shortcut_row_set_icon       (ThunarShortcutRow *row,
+                                               GIcon             *icon);
+void       thunar_shortcut_row_set_eject_icon (ThunarShortcutRow *row,
+                                               GIcon             *eject_icon);
+void       thunar_shortcut_row_set_label      (ThunarShortcutRow *row,
+                                               const gchar       *label);
+void       thunar_shortcut_row_set_file       (ThunarShortcutRow *row,
+                                               GFile             *file);
+void       thunar_shortcut_row_set_volume     (ThunarShortcutRow *row,
+                                               GVolume           *volume);
+
+G_END_DECLS
+
+#endif /* !__THUNAR_SHORTCUT_ROW_H__ */
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index c5dd45f..b9594db 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -65,6 +65,13 @@ typedef struct _ThunarShortcut         ThunarShortcut;
 
 typedef enum
 {
+  THUNAR_SHORTCUT_CATEGORY_DEVICES,
+  THUNAR_SHORTCUT_CATEGORY_PLACES,
+  THUNAR_SHORTCUT_CATEGORY_NETWORK,
+} ThunarShortcutCategoryType;
+
+typedef enum
+{
   THUNAR_SHORTCUT_SYSTEM_VOLUME,
   THUNAR_SHORTCUT_VOLUME,
   THUNAR_SHORTCUT_USER_DIRECTORY,
@@ -74,48 +81,56 @@ typedef enum
 
 
 
-static void                    thunar_shortcuts_model_tree_model_init    (GtkTreeModelIface         *iface);
-static void                    thunar_shortcuts_model_finalize           (GObject                   *object);
-static GtkTreeModelFlags       thunar_shortcuts_model_get_flags          (GtkTreeModel              *tree_model);
-static gint                    thunar_shortcuts_model_get_n_columns      (GtkTreeModel              *tree_model);
-static GType                   thunar_shortcuts_model_get_column_type    (GtkTreeModel              *tree_model,
-                                                                          gint                       idx);
-static gboolean                thunar_shortcuts_model_get_iter           (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter,
-                                                                          GtkTreePath               *path);
-static GtkTreePath            *thunar_shortcuts_model_get_path           (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter);
-static void                    thunar_shortcuts_model_get_value          (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter,
-                                                                          gint                       column,
-                                                                          GValue                    *value);
-static gboolean                thunar_shortcuts_model_iter_next          (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter);
-static gboolean                thunar_shortcuts_model_iter_children      (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter,
-                                                                          GtkTreeIter               *parent);
-static gboolean                thunar_shortcuts_model_iter_has_child     (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter);
-static gint                    thunar_shortcuts_model_iter_n_children    (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter);
-static gboolean                thunar_shortcuts_model_iter_nth_child     (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter,
-                                                                          GtkTreeIter               *parent,
-                                                                          gint                       n);
-static gboolean                thunar_shortcuts_model_iter_parent        (GtkTreeModel              *tree_model,
-                                                                          GtkTreeIter               *iter,
-                                                                          GtkTreeIter               *child);
-static gboolean                thunar_shortcuts_model_parse_path         (ThunarShortcutsModel      *model,
-                                                                          GtkTreePath               *path,
-                                                                          gint                      *category_index,
-                                                                          gint                      *shortcut_index);
-static gboolean                thunar_shortcuts_model_parse_iter         (ThunarShortcutsModel      *model,
-                                                                          GtkTreeIter               *iter,
-                                                                          gint                      *category_index,
-                                                                          gint                      *shortcut_index);
-static ThunarShortcutCategory *thunar_shortcut_category_new              (const gchar               *name);
-static void                    thunar_shortcut_category_free             (ThunarShortcutCategory    *category);
-static void                    thunar_shortcut_free                      (ThunarShortcut            *shortcut);
+static void                    thunar_shortcuts_model_tree_model_init       (GtkTreeModelIface         *iface);
+static void                    thunar_shortcuts_model_finalize              (GObject                   *object);
+static GtkTreeModelFlags       thunar_shortcuts_model_get_flags             (GtkTreeModel              *tree_model);
+static gint                    thunar_shortcuts_model_get_n_columns         (GtkTreeModel              *tree_model);
+static GType                   thunar_shortcuts_model_get_column_type       (GtkTreeModel              *tree_model,
+                                                                             gint                       idx);
+static gboolean                thunar_shortcuts_model_get_iter              (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter,
+                                                                             GtkTreePath               *path);
+static GtkTreePath            *thunar_shortcuts_model_get_path              (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter);
+static void                    thunar_shortcuts_model_get_value             (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter,
+                                                                             gint                       column,
+                                                                             GValue                    *value);
+static gboolean                thunar_shortcuts_model_iter_next             (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter);
+static gboolean                thunar_shortcuts_model_iter_children         (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter,
+                                                                             GtkTreeIter               *parent);
+static gboolean                thunar_shortcuts_model_iter_has_child        (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter);
+static gint                    thunar_shortcuts_model_iter_n_children       (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter);
+static gboolean                thunar_shortcuts_model_iter_nth_child        (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter,
+                                                                             GtkTreeIter               *parent,
+                                                                             gint                       n);
+static gboolean                thunar_shortcuts_model_iter_parent           (GtkTreeModel              *tree_model,
+                                                                             GtkTreeIter               *iter,
+                                                                             GtkTreeIter               *child);
+static gboolean                thunar_shortcuts_model_parse_path            (ThunarShortcutsModel      *model,
+                                                                             GtkTreePath               *path,
+                                                                             gint                      *category_index,
+                                                                             gint                      *shortcut_index);
+static gboolean                thunar_shortcuts_model_parse_iter            (ThunarShortcutsModel      *model,
+                                                                             GtkTreeIter               *iter,
+                                                                             gint                      *category_index,
+                                                                             gint                      *shortcut_index);
+static gboolean                thunar_shortcuts_model_find_category         (ThunarShortcutsModel      *model,
+                                                                             GFile                     *file,
+                                                                             ThunarShortcutType         type,
+                                                                             ThunarShortcutCategory   **category,
+                                                                             gint                      *category_index);
+static void                    thunar_shortcuts_model_add_shortcut          (ThunarShortcutsModel      *model,
+                                                                             ThunarShortcut            *shortcut);
+static gboolean                thunar_shortcuts_model_load_system_shortcuts (gpointer                   user_data);
+static ThunarShortcutCategory *thunar_shortcut_category_new                 (ThunarShortcutCategoryType type);
+static void                    thunar_shortcut_category_free                (ThunarShortcutCategory    *category);
+static void                    thunar_shortcut_free                         (ThunarShortcut            *shortcut);
 
 
 
@@ -140,8 +155,10 @@ struct _ThunarShortcutsModel
 
 struct _ThunarShortcutCategory
 {
-  gchar     *name;
-  GPtrArray *shortcuts;
+  ThunarShortcutCategoryType type;
+  GPtrArray                 *shortcuts;
+  gchar                     *name;
+  guint                      visible : 1;
 };
 
 struct _ThunarShortcut
@@ -156,8 +173,8 @@ struct _ThunarShortcut
   GVolume            *volume;
 
   guint               mutable : 1;
-  guint               category : 1;
   guint               persistent : 1;
+  guint               visible : 1;
 };
 
 
@@ -211,16 +228,19 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model)
     g_ptr_array_new_with_free_func ((GDestroyNotify) thunar_shortcut_category_free);
 
   /* create the devices category */
-  category = thunar_shortcut_category_new (_("DEVICES"));
+  category = thunar_shortcut_category_new (THUNAR_SHORTCUT_CATEGORY_DEVICES);
   g_ptr_array_add (model->categories, category);
 
   /* create the places category */
-  category = thunar_shortcut_category_new (_("PLACES"));
+  category = thunar_shortcut_category_new (THUNAR_SHORTCUT_CATEGORY_PLACES);
   g_ptr_array_add (model->categories, category);
 
   /* create the network category */
-  category = thunar_shortcut_category_new (_("NETWORK"));
+  category = thunar_shortcut_category_new (THUNAR_SHORTCUT_CATEGORY_NETWORK);
   g_ptr_array_add (model->categories, category);
+
+  /* start the load chain */
+  g_idle_add (thunar_shortcuts_model_load_system_shortcuts, model);
 }
 
 
@@ -285,6 +305,9 @@ thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model,
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_PERSISTENT:
       return G_TYPE_BOOLEAN;
+
+    case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
+      return G_TYPE_BOOLEAN;
     }
 
   _thunar_assert_not_reached ();
@@ -417,7 +440,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_CATEGORY:
       g_value_init (value, G_TYPE_BOOLEAN);
-      g_value_set_boolean (value, shortcut != NULL);
+      g_value_set_boolean (value, shortcut == NULL);
       break;
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_PERSISTENT:
@@ -428,6 +451,14 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
         g_value_set_boolean (value, FALSE);
       break;
 
+    case THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE:
+      g_value_init (value, G_TYPE_BOOLEAN);
+      if (shortcut != NULL)
+        g_value_set_boolean (value, shortcut->visible);
+      else
+        g_value_set_boolean (value, category->visible);
+      break;
+
     default:
       _thunar_assert_not_reached ();
       break;
@@ -790,16 +821,244 @@ thunar_shortcuts_model_parse_iter (ThunarShortcutsModel *model,
 
 
 
+static gboolean
+thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
+                                      GFile                   *file,
+                                      ThunarShortcutType       type,
+                                      ThunarShortcutCategory **category,
+                                      gint                    *category_index)
+{
+  ThunarShortcutCategory *current_category = NULL;
+  gboolean                item_belongs_here = FALSE;
+  guint                   n;
+
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
+
+  /* reset category return parameter */
+  if (category != NULL)
+    *category = NULL;
+
+  /* reset category index return parameter */
+  if (category_index != NULL)
+    *category_index = -1;
+
+  /* iterate over all available categories */
+  for (n = 0; !item_belongs_here && n < model->categories->len; ++n)
+    {
+      /* get the nth category */
+      current_category = g_ptr_array_index (model->categories, n);
+
+      switch (current_category->type)
+        {
+        case THUNAR_SHORTCUT_CATEGORY_DEVICES:
+          /* system volumes belong into devices */
+          if (type == THUNAR_SHORTCUT_SYSTEM_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;
+          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)
+            item_belongs_here = TRUE;
+
+          /* check whether we have a local file */
+          if (file != NULL && g_file_has_uri_scheme (file, "file"))
+            item_belongs_here = TRUE;
+          break;
+
+        case THUNAR_SHORTCUT_CATEGORY_NETWORK:
+          /* remote files belong here */
+          if (type == THUNAR_SHORTCUT_REMOTE_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;
+          break;
+
+        default:
+          _thunar_assert_not_reached ();
+          break;
+        }
+
+      /* check if the item belongs into this category */
+      if (item_belongs_here)
+        {
+          /* return the category if requested */
+          if (category != NULL)
+            *category = current_category;
+
+          /* return the category index if requested */
+          if (category_index != NULL)
+            *category_index = n;
+        }
+    }
+
+  return item_belongs_here;
+}
+
+
+
+static void
+thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
+                                     ThunarShortcut       *shortcut)
+{
+  ThunarShortcutCategory *category;
+  GtkTreePath            *path;
+  GtkTreeIter             iter;
+  gint                    category_index;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  _thunar_return_if_fail (shortcut != NULL);
+
+  /* find the destination category for the shortcut */
+  if (!thunar_shortcuts_model_find_category (model, 
+                                             shortcut->file, shortcut->type,
+                                             &category, &category_index))
+    {
+      return;
+    }
+
+  /* insert the shortcut into the category if we have one for it */
+  if (category != NULL)
+    {
+      /* add the shortcut to the category */
+      g_ptr_array_add (category->shortcuts, shortcut);
+
+      /* create a tree path for the new row */
+      path = gtk_tree_path_new_from_indices (category_index, 
+                                             category->shortcuts->len - 1,
+                                             -1);
+
+      /* create a tree iter for the new row */
+#ifndef NDEBUG
+      iter.stamp = model->stamp;
+#endif
+      iter.user_data = GINT_TO_POINTER (category_index);
+      iter.user_data2 = GINT_TO_POINTER (category->shortcuts->len - 1);
+
+      /* create a tree path for the new row */
+      g_signal_emit_by_name (model, "row-inserted", path, &iter, NULL);
+
+      /* release the tree path */
+      gtk_tree_path_free (path);
+    }
+}
+
+
+
+static gboolean
+thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
+{
+  ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
+  ThunarShortcut       *shortcut;
+  GFile                *desktop_file;
+  GFile                *home_file;
+  gchar                *path;
+
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
+  
+  /* 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");
+  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;
+
+  /* add the shortcut */
+  thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+  /* request a GFile for the desktop directory */
+  desktop_file = 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))
+    {
+      /* 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;
+
+      /* add the shortcut */
+      thunar_shortcuts_model_add_shortcut (model, shortcut);
+    }
+
+  /* release desktop and home files */
+  g_object_unref (desktop_file);
+  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_root ();
+  shortcut->icon = g_themed_icon_new ("harddrive");
+  shortcut->name = g_strdup (g_get_host_name ());
+  shortcut->type = THUNAR_SHORTCUT_SYSTEM_VOLUME;
+  shortcut->visible = TRUE;
+  shortcut->mutable = FALSE;
+  shortcut->persistent = TRUE;
+
+  /* add the shortcut */
+  thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+  return FALSE;
+}
+
+
+
 static ThunarShortcutCategory *
-thunar_shortcut_category_new (const gchar *name)
+thunar_shortcut_category_new (ThunarShortcutCategoryType type)
 {
   ThunarShortcutCategory *category;
 
   /* allocate a new category */
   category = g_slice_new0 (ThunarShortcutCategory);
 
+  /* set its type */
+  category->type = type;
+
   /* set its name */
-  category->name = g_strdup (name);
+  switch (type)
+    {
+    case THUNAR_SHORTCUT_CATEGORY_DEVICES:
+      category->name = g_strdup (_("DEVICES"));
+      break;
+
+    case THUNAR_SHORTCUT_CATEGORY_PLACES:
+      category->name = g_strdup (_("PLACES"));
+      break;
+
+    case THUNAR_SHORTCUT_CATEGORY_NETWORK:
+      category->name = g_strdup (_("NETWORK"));
+      break;
+
+    default:
+      _thunar_assert_not_reached ();
+      break;
+    }
+
+  /* assume the category is visible by default */
+  category->visible = TRUE;
 
   /* allocate an empty array for the shortcuts in the category */
   category->shortcuts = 
diff --git a/thunar/thunar-shortcuts-model.h b/thunar/thunar-shortcuts-model.h
index 43d03b3..e56747d 100644
--- a/thunar/thunar-shortcuts-model.h
+++ b/thunar/thunar-shortcuts-model.h
@@ -60,6 +60,7 @@ typedef enum
   THUNAR_SHORTCUTS_MODEL_COLUMN_EJECT_ICON,
   THUNAR_SHORTCUTS_MODEL_COLUMN_CATEGORY,
   THUNAR_SHORTCUTS_MODEL_COLUMN_PERSISTENT,
+  THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE,
   THUNAR_SHORTCUTS_MODEL_N_COLUMNS,
 } ThunarShortcutsModelColumn;
 
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 3341e63..98b9358 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -41,6 +41,7 @@
 #include <thunar/thunar-gtk-extensions.h>
 #include <thunar/thunar-preferences.h>
 #include <thunar/thunar-private.h>
+#include <thunar/thunar-shortcut-row.h>
 #include <thunar/thunar-shortcuts-model.h>
 #include <thunar/thunar-shortcuts-view.h>
 
@@ -66,16 +67,22 @@ enum
 
 
 
-static void thunar_shortcuts_view_constructed  (GObject      *object);
-static void thunar_shortcuts_view_finalize     (GObject      *object);
-static void thunar_shortcuts_view_get_property (GObject      *object,
-                                                guint         prop_id,
-                                                GValue       *value,
-                                                GParamSpec   *pspec);
-static void thunar_shortcuts_view_set_property (GObject      *object,
-                                                guint         prop_id,
-                                                const GValue *value,
-                                                GParamSpec   *pspec);
+static void       thunar_shortcuts_view_constructed     (GObject             *object);
+static void       thunar_shortcuts_view_finalize        (GObject             *object);
+static void       thunar_shortcuts_view_get_property    (GObject             *object,
+                                                         guint                prop_id,
+                                                         GValue              *value,
+                                                         GParamSpec          *pspec);
+static void       thunar_shortcuts_view_set_property    (GObject             *object,
+                                                         guint                prop_id,
+                                                         const GValue        *value,
+                                                         GParamSpec          *pspec);
+static void       thunar_shortcuts_view_row_inserted    (ThunarShortcutsView *view,
+                                                         GtkTreePath         *path,
+                                                         GtkTreeIter         *iter,
+                                                         GtkTreeModel        *model);
+static GtkWidget *thunar_shortcuts_view_get_expander_at (ThunarShortcutsView *view, 
+                                                         gint                 index);
 
 
 
@@ -197,7 +204,13 @@ thunar_shortcuts_view_constructed (GObject *object)
 {
   ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (object);
   GtkTreeIter          iter;
+  const gchar         *markup_format = "<span size='medium' weight='bold' color='#353535'>%s</span>";
+  GtkWidget           *box;
+  GtkWidget           *expander;
+  gboolean             category;
   gboolean             valid_iter = FALSE;
+  gchar               *markup;
+  gchar               *name;
 
   /* chain up to the parent class */
   (*G_OBJECT_CLASS (thunar_shortcuts_view_parent_class)->constructed) (object);
@@ -210,21 +223,50 @@ thunar_shortcuts_view_constructed (GObject *object)
   valid_iter = gtk_tree_model_get_iter_first (view->model, &iter);
   while (valid_iter)
     {
-      gchar *name = NULL;
-
       /* TODO read values from the row and create an expander, 
        * shortcut row or drop placeholder, depending on the 
        * row values */
       gtk_tree_model_get (view->model, &iter,
+                          THUNAR_SHORTCUTS_MODEL_COLUMN_CATEGORY, &category,
                           THUNAR_SHORTCUTS_MODEL_COLUMN_NAME, &name,
                           -1);
 
-      g_debug ("name: %s", name);
-      g_free (name);
+      if (category)
+        {
+          /* create the category expander */
+          expander = gtk_expander_new (NULL);
+          markup = g_markup_printf_escaped (markup_format, name);
+          gtk_expander_set_label (GTK_EXPANDER (expander), markup);
+          g_free (markup);
+          gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
+          gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
+          gtk_container_set_border_width (GTK_CONTAINER (expander), 0);
+          gtk_expander_set_spacing (GTK_EXPANDER (expander), 0);
+
+          /* add it to the expander box and show it */
+          gtk_box_pack_start (GTK_BOX (view->expander_box), expander, FALSE, TRUE, 0);
+          gtk_widget_show (expander);
+
+          /* create a box for the shortcuts of the category */
+          box = gtk_vbox_new (FALSE, 0);
+          gtk_container_add (GTK_CONTAINER (expander), box);
+          gtk_widget_show (box);
+        }
+      else
+        {
+          /* we will have to implement this at some point but right now, the
+           * model data is loaded in an idle handler, so there is no data other
+           * than categories during construction */
+          _thunar_assert_not_reached ();
+        }
 
       /* advance to the next row */
       valid_iter = gtk_tree_model_iter_next (view->model, &iter);
     }
+
+  /* be notified when a new shortcut is added to the model */
+  g_signal_connect_swapped (view->model, "row-inserted",
+                            G_CALLBACK (thunar_shortcuts_view_row_inserted), view);
 }
 
 
@@ -287,6 +329,105 @@ thunar_shortcuts_view_set_property (GObject      *object,
 
 
 
+static void
+thunar_shortcuts_view_row_inserted (ThunarShortcutsView *view,
+                                    GtkTreePath         *path,
+                                    GtkTreeIter         *iter,
+                                    GtkTreeModel        *model)
+{
+  GtkWidget *box;
+  GtkWidget *expander;
+  GtkWidget *shortcut_row;
+  gboolean   category;
+  gboolean   visible;
+  GVolume   *volume;
+  GFile     *file;
+  GIcon     *eject_icon;
+  GIcon     *icon;
+  gchar     *name;
+  gint       category_index;
+  gint       shortcut_index;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
+  _thunar_return_if_fail (path != NULL);
+  _thunar_return_if_fail (iter != NULL);
+  _thunar_return_if_fail (GTK_IS_TREE_MODEL (model) && model == view->model);
+
+  /* read information from the new row */
+  gtk_tree_model_get (model, iter,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_CATEGORY, &category,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_ICON, &icon,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_NAME, &name,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_EJECT_ICON, &eject_icon,
+                      THUNAR_SHORTCUTS_MODEL_COLUMN_VISIBLE, &visible,
+                      -1);
+
+  if (category)
+    {
+      /* we will have to implement this at some point but right now the
+       * categories are hard-coded and will not change */
+      _thunar_assert_not_reached ();
+    }
+  else
+    {
+      /* create a row widget for the shortcut */
+      shortcut_row = thunar_shortcut_row_new (icon, name, eject_icon);
+      thunar_shortcut_row_set_file (THUNAR_SHORTCUT_ROW (shortcut_row), file);
+      thunar_shortcut_row_set_volume (THUNAR_SHORTCUT_ROW (shortcut_row), volume);
+
+      /* get the category and shortcut index */
+      category_index = gtk_tree_path_get_indices (path)[0];
+      shortcut_index = gtk_tree_path_get_indices (path)[1];
+
+      /* find the expander for the row widget */
+      expander = thunar_shortcuts_view_get_expander_at (view, category_index);
+      
+      /* if this fails then we are out of sync with the model */
+      g_assert (expander != NULL);
+
+      /* get the box widget for placing the row */
+      box = gtk_bin_get_child (GTK_BIN (expander));
+
+      /* add the new row to the box and show it */
+      gtk_container_add (GTK_CONTAINER (box), shortcut_row);
+
+      /* move the row to the correct location */
+      gtk_box_reorder_child (GTK_BOX (box), shortcut_row, shortcut_index);
+      
+      /* show the row now (unless it was hidden by the user) */
+      if (visible)
+        gtk_widget_show (shortcut_row);
+    }
+}
+
+
+
+static GtkWidget *
+thunar_shortcuts_view_get_expander_at (ThunarShortcutsView *view, 
+                                       gint                 expander_index)
+{
+  GtkWidget *expander = NULL;
+  GList     *expanders;
+  GList     *lp = NULL;
+
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), NULL);
+  _thunar_return_val_if_fail (expander_index >= 0, NULL);
+
+  expanders = gtk_container_get_children (GTK_CONTAINER (view->expander_box));
+  
+  lp = g_list_nth (expanders, expander_index);
+  if (lp != NULL)
+    expander = lp->data;
+
+  g_list_free (expanders);
+
+  return expander;
+}
+
+
+
 /**
  * thunar_shortcuts_view_new:
  *



More information about the Xfce4-commits mailing list