[gtk+/wip/csoriano/bookmarks: 23/23] gtkplacesidebar: use GtkListBox



commit 4601ed5acfe1c63b854e177c3329188bac32968a
Author: Carlos Soriano <csoriano gnome org>
Date:   Wed May 6 23:07:17 2015 +0200

    gtkplacesidebar: use GtkListBox
    
    We were using GTkTreeView in a simple list. Also, as we know,
    GtkCellRenderers are not the best way to theme and manipulate
    widgets.
    
    So instead use a GtkListBox to modernize the GtkPlacesSidebar,
    and in the way clean up some parts of the code (like headings)
    which were not used anymore.
    Also we don't use a model anymore, since the data is simple
    enough to manage it in a subclass of the row itself.

 gtk/gtkplacessidebar.c |  658 ++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 549 insertions(+), 109 deletions(-)
---
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index 78720cf..ea19452 100644
--- a/gtk/gtkplacessidebar.c
+++ b/gtk/gtkplacessidebar.c
@@ -44,6 +44,7 @@
 #include "config.h"
 
 #include <gio/gio.h>
+#include <gtk/gtk.h>
 
 #include "gdk/gdkkeysyms.h"
 #include "gtkbookmarksmanager.h"
@@ -70,6 +71,7 @@
 #include "gtkgrid.h"
 #include "gtklabel.h"
 #include "gtkbutton.h"
+#include "gtklistbox.h"
 
 /**
  * SECTION:gtkplacessidebar
@@ -129,6 +131,8 @@ typedef enum {
 struct _GtkPlacesSidebar {
   GtkScrolledWindow parent;
 
+  GtkWidget *list_box;
+
   GtkTreeView       *tree_view;
   GtkCellRenderer   *eject_icon_cell_renderer;
   GtkCellRenderer   *text_cell_renderer;
@@ -230,6 +234,7 @@ enum {
 };
 
 typedef enum {
+  PLACES_0,
   PLACES_BUILT_IN,
   PLACES_XDG_DIR,
   PLACES_MOUNTED_VOLUME,
@@ -237,14 +242,17 @@ typedef enum {
   PLACES_HEADING,
   PLACES_CONNECT_TO_SERVER,
   PLACES_ENTER_LOCATION,
-  PLACES_DROP_FEEDBACK
+  PLACES_DROP_FEEDBACK,
+  N_PLACES
 } PlaceType;
 
 typedef enum {
+  SECTION_0,
   SECTION_DEVICES,
   SECTION_BOOKMARKS,
   SECTION_COMPUTER,
-  SECTION_NETWORK
+  SECTION_NETWORK,
+  N_SECTIONS
 } SectionType;
 
 enum {
@@ -347,6 +355,384 @@ static GtkListStore *shortcuts_model_new (GtkPlacesSidebar *sidebar);
 
 G_DEFINE_TYPE (GtkPlacesSidebar, gtk_places_sidebar, GTK_TYPE_SCROLLED_WINDOW);
 
+#define SIDEBAR_TYPE_ROW (sidebar_row_get_type ())
+G_DECLARE_DERIVABLE_TYPE (SidebarRow, sidebar_row, SIDEBAR, ROW, GtkListBoxRow)
+
+struct _SidebarRowClass
+{
+  GtkListBoxRowClass parent_class;
+};
+
+typedef struct
+{
+  GIcon *icon;
+  GtkWidget *icon_widget;
+  gchar *label;
+  GtkWidget *label_widget;
+  gboolean ejectable;
+  GtkWidget *eject_button;
+  gint order_index;
+  gint section_type;
+  gint place_type;
+  gchar *uri;
+  GDrive *drive;
+  GVolume *volume;
+  GMount *mount;
+} SidebarRowPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (SidebarRow, sidebar_row, GTK_TYPE_LIST_BOX_ROW)
+
+enum
+{
+  PROP_0,
+  PROP_ICON,
+  PROP_LABEL,
+  PROP_EJECTABLE,
+  PROP_ORDER_INDEX,
+  PROP_SECTION_TYPE,
+  PROP_PLACE_TYPE,
+  PROP_URI,
+  PROP_DRIVE,
+  PROP_VOLUME,
+  PROP_MOUNT,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+static void
+sidebar_row_get_property (GObject    *object,
+                          guint       prop_id,
+                          GValue     *value,
+                          GParamSpec *pspec)
+{
+  SidebarRow *self = SIDEBAR_ROW (object);
+  SidebarRowPrivate *priv = sidebar_row_get_instance_private (self);
+
+  switch (prop_id)
+    {
+    case PROP_ICON:
+      {
+        g_value_set_object (value, priv->icon);
+        break;
+      }
+
+    case PROP_LABEL:
+      {
+        g_value_set_string (value, priv->label);
+        break;
+      }
+
+    case PROP_EJECTABLE:
+      {
+        g_value_set_boolean (value, priv->ejectable);
+        break;
+      }
+
+    case PROP_ORDER_INDEX:
+      {
+        g_value_set_int (value, priv->order_index);
+          break;
+      }
+
+    case PROP_SECTION_TYPE:
+      {
+        g_value_set_int (value, priv->section_type);
+        break;
+      }
+
+    case PROP_PLACE_TYPE:
+      {
+        g_value_set_int (value, priv->place_type);
+        break;
+      }
+
+    case PROP_URI:
+      {
+        g_value_set_string (value, priv->uri);
+        break;
+      }
+
+    case PROP_DRIVE:
+      {
+        g_value_set_object (value, priv->drive);
+        break;
+      }
+
+    case PROP_VOLUME:
+      {
+        g_value_set_object (value, priv->volume);
+        break;
+      }
+
+    case PROP_MOUNT:
+      {
+        g_value_set_object (value, priv->mount);
+        break;
+      }
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+sidebar_row_set_property (GObject      *object,
+                          guint         prop_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  SidebarRow *self = SIDEBAR_ROW (object);
+  SidebarRowPrivate *priv = sidebar_row_get_instance_private (self);
+
+  switch (prop_id)
+    {
+    case PROP_ICON:
+      {
+        g_clear_object (&priv->icon);
+        if (value != NULL)
+          {
+            priv->icon = g_object_ref (g_value_get_object (value));
+            gtk_image_set_from_gicon (GTK_IMAGE (priv->icon_widget), priv->icon, GTK_ICON_SIZE_MENU);
+          }
+        else
+          {
+            priv->icon = NULL;
+            gtk_image_clear (GTK_IMAGE (priv->icon_widget));
+          }
+        break;
+      }
+
+    case PROP_LABEL:
+      {
+        g_free (priv->label);
+        priv->label = g_strdup (g_value_get_string (value));
+        gtk_label_set_text (GTK_LABEL (priv->label_widget), priv->label);
+        break;
+      }
+
+    case PROP_EJECTABLE:
+      {
+        priv->ejectable = g_value_get_boolean (value);
+        if (priv->ejectable)
+          {
+            gtk_widget_set_sensitive (priv->eject_button, TRUE);
+            gtk_widget_set_opacity (priv->eject_button, 1);
+          }
+        else
+          {
+            gtk_widget_set_sensitive (priv->eject_button, FALSE);
+            gtk_widget_set_opacity (priv->eject_button, 0);
+          }
+        break;
+      }
+
+    case PROP_ORDER_INDEX:
+      {
+        priv->order_index = g_value_get_int (value);
+        break;
+      }
+
+    case PROP_SECTION_TYPE:
+      {
+        priv->section_type = g_value_get_int (value);
+        if (priv->section_type != SECTION_COMPUTER)
+          gtk_label_set_ellipsize (GTK_LABEL (priv->label_widget), PANGO_ELLIPSIZE_MIDDLE);
+        else
+          gtk_label_set_ellipsize (GTK_LABEL (priv->label_widget), PANGO_ELLIPSIZE_NONE);
+        break;
+      }
+
+    case PROP_PLACE_TYPE:
+      {
+        priv->place_type = g_value_get_int (value);
+        break;
+      }
+
+    case PROP_URI:
+      {
+        g_free (priv->uri);
+        priv->uri = g_strdup (g_value_get_string (value));
+        break;
+      }
+
+    case PROP_DRIVE:
+      {
+        gpointer *object;
+
+        g_clear_object (&priv->drive);
+        object = g_value_get_object (value);
+        if (object != NULL)
+          priv->drive = g_object_ref (object);
+        break;
+      }
+
+    case PROP_VOLUME:
+      {
+        gpointer *object;
+
+        g_clear_object (&priv->volume);
+        object = g_value_get_object (value);
+        if (object != NULL)
+          priv->volume = g_object_ref (object);
+        break;
+      }
+
+    case PROP_MOUNT:
+      {
+        gpointer *object;
+
+        g_clear_object (&priv->mount);
+        object = g_value_get_object (value);
+        if (object != NULL)
+          priv->mount = g_object_ref (object);
+        break;
+      }
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+sidebar_row_init (SidebarRow *self)
+{
+  GtkWidget *hbox;
+  SidebarRowPrivate *priv = sidebar_row_get_instance_private (self);
+  GtkStyleContext *css_context;
+
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  priv->icon_widget = gtk_image_new ();
+  gtk_widget_set_margin_start (priv->icon_widget, 10);
+  gtk_container_add (GTK_CONTAINER (hbox), priv->icon_widget);
+  priv->label_widget = gtk_label_new (NULL);
+  gtk_widget_set_margin_start (priv->label_widget, 7);
+  gtk_container_add (GTK_CONTAINER (hbox), priv->label_widget);
+  priv->eject_button = gtk_button_new_from_icon_name ("media-eject-symbolic", GTK_ICON_SIZE_MENU);
+  css_context = gtk_widget_get_style_context (priv->eject_button);
+  gtk_style_context_add_class (css_context, "flat");
+  gtk_widget_set_margin_start (priv->eject_button, 15);
+  gtk_widget_set_hexpand (priv->eject_button, TRUE);
+  gtk_widget_set_halign (priv->eject_button, GTK_ALIGN_END);
+  gtk_widget_set_valign (priv->eject_button, GTK_ALIGN_CENTER);
+  gtk_container_add (GTK_CONTAINER (hbox), priv->eject_button);
+
+  gtk_container_add (GTK_CONTAINER (self), hbox);
+}
+
+static void
+sidebar_row_class_init (SidebarRowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = sidebar_row_get_property;
+  object_class->set_property = sidebar_row_set_property;
+
+  gParamSpecs [PROP_ICON] =
+    g_param_spec_object ("icon",
+                         "icon",
+                         "The place icon.",
+                         G_TYPE_ICON,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_ICON,
+                                   gParamSpecs [PROP_ICON]);
+
+  gParamSpecs [PROP_LABEL] =
+    g_param_spec_string ("label",
+                         "label",
+                         "The label text.",
+                         NULL,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_LABEL,
+                                   gParamSpecs [PROP_LABEL]);
+
+  gParamSpecs [PROP_EJECTABLE] =
+    g_param_spec_boolean ("ejectable",
+                          "Ejectable",
+                          "Ejectable",
+                          TRUE,
+                          (G_PARAM_READWRITE |
+                           G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_EJECTABLE,
+                                   gParamSpecs [PROP_EJECTABLE]);
+
+  gParamSpecs [PROP_ORDER_INDEX] =
+    g_param_spec_int ("order-index",
+                      "OrderIndex",
+                      "Order Index",
+                      0, G_MAXINT, 0,
+                      (G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_ORDER_INDEX,
+                                   gParamSpecs [PROP_ORDER_INDEX]);
+
+  gParamSpecs [PROP_SECTION_TYPE] =
+    g_param_spec_int ("section-type",
+                      "section type",
+                      "The section type.",
+                      SECTION_0, N_SECTIONS, SECTION_0,
+                      (G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS |
+                       G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_SECTION_TYPE,
+                                   gParamSpecs [PROP_SECTION_TYPE]);
+
+  gParamSpecs [PROP_PLACE_TYPE] =
+    g_param_spec_int ("place-type",
+                      "place type",
+                      "The place type.",
+                      PLACES_0, N_PLACES, PLACES_0,
+                      (G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS |
+                       G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_PLACE_TYPE,
+                                   gParamSpecs [PROP_PLACE_TYPE]);
+
+ gParamSpecs [PROP_URI] =
+   g_param_spec_string ("uri",
+                        "Uri",
+                        "Uri",
+                        NULL,
+                        (G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_URI,
+                                  gParamSpecs [PROP_URI]);
+  gParamSpecs [PROP_DRIVE] =
+    g_param_spec_object ("drive",
+                         "Drive",
+                         "Drive",
+                         G_TYPE_DRIVE,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_DRIVE,
+                                   gParamSpecs [PROP_DRIVE]);
+
+  gParamSpecs [PROP_VOLUME] =
+    g_param_spec_object ("volume",
+                         "Volume",
+                         "Volume",
+                         G_TYPE_VOLUME,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_VOLUME,
+                                   gParamSpecs [PROP_VOLUME]);
+
+  gParamSpecs [PROP_MOUNT] =
+    g_param_spec_object ("mount",
+                         "Mount",
+                         "Mount",
+                         G_TYPE_MOUNT,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_MOUNT,
+                                   gParamSpecs [PROP_MOUNT]);
+}
+
 static void
 emit_open_location (GtkPlacesSidebar   *sidebar,
                     GFile              *location,
@@ -457,23 +843,35 @@ add_heading (GtkPlacesSidebar *sidebar,
 }
 
 static void
-check_heading_for_section (GtkPlacesSidebar *sidebar,
-                           SectionType       section_type)
+add_separator (GtkListBoxRow *row,
+               GtkListBoxRow    *before,
+               gpointer       user_data)
 {
-  switch (section_type)
+  SectionType row_section_type;
+  SectionType before_section_type;
+  gchar *name, *name2 = NULL;
+  GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
+
+  g_object_get (row, "section-type", &row_section_type, "label", &name, NULL);
+  if (before)
+    g_object_get (before, "section-type", &before_section_type, "label", &name2, NULL);
+  else
+    before_section_type = SECTION_0;
+
+  switch (row_section_type)
     {
     case SECTION_DEVICES:
-      if (!sidebar->devices_header_added)
+      if (!sidebar->devices_header_added && before && before_section_type != row_section_type)
         {
-          add_heading (sidebar, SECTION_DEVICES, _("Devices"));
+          gtk_list_box_row_set_header (row, gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
           sidebar->devices_header_added = TRUE;
         }
       break;
 
     case SECTION_BOOKMARKS:
-      if (!sidebar->bookmarks_header_added)
+      if (!sidebar->bookmarks_header_added && before && before_section_type != row_section_type)
         {
-          add_heading (sidebar, SECTION_BOOKMARKS, _("Bookmarks"));
+          gtk_list_box_row_set_header (row, gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
           sidebar->bookmarks_header_added = TRUE;
         }
       break;
@@ -496,11 +894,9 @@ add_place (GtkPlacesSidebar *sidebar,
            const gint        index,
            const gchar      *tooltip)
 {
-  GtkTreeIter iter;
   gboolean show_eject, show_unmount;
   gboolean show_eject_button;
-
-  check_heading_for_section (sidebar, section_type);
+  SidebarRow *row;
 
   check_unmount_and_eject (mount, volume, drive,
                            &show_unmount, &show_eject);
@@ -513,23 +909,21 @@ add_place (GtkPlacesSidebar *sidebar,
   else
     show_eject_button = (show_unmount || show_eject);
 
-  gtk_list_store_append (sidebar->store, &iter);
-  gtk_list_store_set (sidebar->store, &iter,
-                      PLACES_SIDEBAR_COLUMN_GICON, icon,
-                      PLACES_SIDEBAR_COLUMN_NAME, name,
-                      PLACES_SIDEBAR_COLUMN_URI, uri,
-                      PLACES_SIDEBAR_COLUMN_DRIVE, drive,
-                      PLACES_SIDEBAR_COLUMN_VOLUME, volume,
-                      PLACES_SIDEBAR_COLUMN_MOUNT, mount,
-                      PLACES_SIDEBAR_COLUMN_ROW_TYPE, place_type,
-                      PLACES_SIDEBAR_COLUMN_INDEX, index,
-                      PLACES_SIDEBAR_COLUMN_EJECT, show_eject_button,
-                      PLACES_SIDEBAR_COLUMN_NO_EJECT, !show_eject_button,
-                      PLACES_SIDEBAR_COLUMN_BOOKMARK, place_type != PLACES_BOOKMARK,
-                      PLACES_SIDEBAR_COLUMN_TOOLTIP, tooltip,
-                      PLACES_SIDEBAR_COLUMN_SECTION_TYPE, section_type,
-                      PLACES_SIDEBAR_COLUMN_SENSITIVE, TRUE,
-                      -1);
+  row = g_object_new (SIDEBAR_TYPE_ROW,
+                      "icon", icon,
+                      "label", name,
+                      "ejectable", show_eject_button,
+                      "order-index", index,
+                      "section-type", section_type,
+                      "place-type", place_type,
+                      "uri", uri,
+                      "drive", drive,
+                      "volume", volume,
+                      "mount", mount,
+                      NULL);
+
+  gtk_container_add (GTK_CONTAINER (sidebar->list_box), GTK_WIDGET (row));
+  gtk_widget_show_all (GTK_WIDGET (row));
 }
 
 static GIcon *
@@ -666,7 +1060,6 @@ add_special_dirs (GtkPlacesSidebar *sidebar)
           path_is_home_dir (path) ||
           g_list_find_custom (dirs, path, (GCompareFunc) g_strcmp0) != NULL)
         continue;
-          
 
       root = g_file_new_for_path (path);
 
@@ -922,8 +1315,6 @@ out:
 static void
 update_places (GtkPlacesSidebar *sidebar)
 {
-  GtkTreeIter iter;
-  GVolumeMonitor *volume_monitor;
   GList *mounts, *l, *ll;
   GMount *mount;
   GList *drives;
@@ -933,6 +1324,7 @@ update_places (GtkPlacesSidebar *sidebar)
   GSList *bookmarks, *sl;
   gint index;
   gchar *original_uri, *mount_uri, *name, *identifier;
+  GtkListBoxRow *selected;
   gchar *home_uri;
   GIcon *icon;
   GFile *root;
@@ -940,10 +1332,9 @@ update_places (GtkPlacesSidebar *sidebar)
   GList *network_mounts, *network_volumes;
 
   /* save original selection */
-  if (get_selected_iter (sidebar, &iter))
-    gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store),
-                        &iter,
-                        PLACES_SIDEBAR_COLUMN_URI, &original_uri, -1);
+  selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box));
+  if (selected)
+    g_object_get (SIDEBAR_ROW (selected), "uri", &original_uri, NULL);
   else
     original_uri = NULL;
 
@@ -952,16 +1343,16 @@ update_places (GtkPlacesSidebar *sidebar)
   g_object_unref (sidebar->cancellable);
   sidebar->cancellable = g_cancellable_new ();
 
-  gtk_list_store_clear (sidebar->store);
+  gtk_container_foreach (GTK_CONTAINER (sidebar->list_box),
+                         (GtkCallback) gtk_widget_destroy,
+                         NULL);
 
   sidebar->devices_header_added = FALSE;
   sidebar->bookmarks_header_added = FALSE;
 
   network_mounts = network_volumes = NULL;
-  volume_monitor = sidebar->volume_monitor;
-
-  /* add built-in bookmarks */
 
+  /* add built-in places */
   if (should_show_recent (sidebar))
     {
       mount_uri = "recent:///";
@@ -1033,7 +1424,7 @@ update_places (GtkPlacesSidebar *sidebar)
   add_application_shortcuts (sidebar);
 
   /* go through all connected drives */
-  drives = g_volume_monitor_get_connected_drives (volume_monitor);
+  drives = g_volume_monitor_get_connected_drives (sidebar->volume_monitor);
 
   for (l = drives; l != NULL; l = l->next)
     {
@@ -1132,7 +1523,7 @@ update_places (GtkPlacesSidebar *sidebar)
   g_list_free (drives);
 
   /* add all volumes that is not associated with a drive */
-  volumes = g_volume_monitor_get_volumes (volume_monitor);
+  volumes = g_volume_monitor_get_volumes (sidebar->volume_monitor);
   for (l = volumes; l != NULL; l = l->next)
     {
       volume = l->data;
@@ -1184,13 +1575,12 @@ update_places (GtkPlacesSidebar *sidebar)
                      NULL, volume, NULL, 0, name);
           g_object_unref (icon);
           g_free (name);
-        } 
+        }
       g_object_unref (volume);
     }
   g_list_free (volumes);
 
   /* file system root */
-
   mount_uri = "file:///"; /* No need to strdup */
   icon = g_themed_icon_new_with_default_fallbacks (ICON_NAME_FILESYSTEM);
   add_place (sidebar, PLACES_BUILT_IN,
@@ -1201,7 +1591,7 @@ update_places (GtkPlacesSidebar *sidebar)
   g_object_unref (icon);
 
   /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
-  mounts = g_volume_monitor_get_mounts (volume_monitor);
+  mounts = g_volume_monitor_get_mounts (sidebar->volume_monitor);
 
   for (l = mounts; l != NULL; l = l->next)
     {
@@ -1245,7 +1635,6 @@ update_places (GtkPlacesSidebar *sidebar)
   g_list_free (mounts);
 
   /* add bookmarks */
-
   bookmarks = _gtk_bookmarks_manager_list_bookmarks (sidebar->bookmarks_manager);
 
   for (sl = bookmarks, index = 0; sl; sl = sl->next, index++)
@@ -1360,6 +1749,8 @@ update_places (GtkPlacesSidebar *sidebar)
   g_list_free_full (network_volumes, g_object_unref);
   g_list_free_full (network_mounts, g_object_unref);
 
+  gtk_widget_show_all (GTK_WIDGET (sidebar));
+
   /* restore original selection */
   if (original_uri)
     {
@@ -2466,27 +2857,12 @@ mount_volume (GtkPlacesSidebar *sidebar,
 }
 
 static void
-open_selected_volume (GtkPlacesSidebar   *sidebar,
-                      GtkTreeModel       *model,
-                      GtkTreeIter        *iter,
-                      GtkPlacesOpenFlags  open_flags)
+open_drive (GtkPlacesSidebar   *sidebar,
+            GDrive             *drive,
+            GtkPlacesOpenFlags  open_flags)
 {
-  GDrive *drive;
-  GVolume *volume;
-
-  gtk_tree_model_get (model, iter,
-                      PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
-                      PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
-                      -1);
-
-  if (volume != NULL && !sidebar->mounting)
-    {
-      sidebar->mounting = TRUE;
-      sidebar->go_to_after_mount_open_flags = open_flags;
-      mount_volume (sidebar, volume);
-    }
-  else if (volume == NULL && drive != NULL &&
-           (g_drive_can_start (drive) || g_drive_can_start_degraded (drive)))
+  if (drive != NULL &&
+      (g_drive_can_start (drive) || g_drive_can_start_degraded (drive)))
     {
       GMountOperation *mount_op;
 
@@ -2494,18 +2870,25 @@ open_selected_volume (GtkPlacesSidebar   *sidebar,
       g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, NULL);
       g_object_unref (mount_op);
     }
+}
 
-  if (drive != NULL)
-    g_object_unref (drive);
-
-  if (volume != NULL)
-    g_object_unref (volume);
+static void
+open_volume (GtkPlacesSidebar   *sidebar,
+             GVolume            *volume,
+             GtkPlacesOpenFlags  open_flags)
+{
+  if (volume != NULL && !sidebar->mounting)
+    {
+      sidebar->mounting = TRUE;
+      sidebar->go_to_after_mount_open_flags = open_flags;
+      mount_volume (sidebar, volume);
+    }
 }
 
 static void
-open_selected_uri (GtkPlacesSidebar   *sidebar,
-                   const gchar        *uri,
-                   GtkPlacesOpenFlags  open_flags)
+open_uri (GtkPlacesSidebar   *sidebar,
+          const gchar        *uri,
+          GtkPlacesOpenFlags  open_flags)
 {
   GFile *location;
 
@@ -2515,9 +2898,53 @@ open_selected_uri (GtkPlacesSidebar   *sidebar,
 }
 
 static void
+open_selected_row (GtkPlacesSidebar   *sidebar,
+                   GtkPlacesOpenFlags  open_flags)
+{
+  gchar *uri;
+  GDrive *drive;
+  GVolume *volume;
+  PlaceType place_type;
+  GtkListBoxRow  *selected;
+
+  selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box));
+  g_object_get (selected,
+                "uri", &uri,
+                "place-type", &place_type,
+                "drive", &drive,
+                "volume", &volume,
+                NULL);
+
+  if (uri != NULL)
+    {
+      open_uri (sidebar, uri, open_flags);
+      g_free (uri);
+    }
+  else if (place_type == PLACES_CONNECT_TO_SERVER)
+    {
+      emit_show_connect_to_server (sidebar);
+    }
+  else if (place_type == PLACES_ENTER_LOCATION)
+    {
+      emit_show_enter_location (sidebar);
+    }
+  else if (volume != NULL)
+    {
+      open_volume (sidebar, volume, open_flags);
+    }
+  else if (drive != NULL)
+    {
+      open_drive (sidebar, drive, open_flags);
+    }
+
+  g_clear_object (&volume);
+  g_clear_object (&drive);
+}
+
+static void
 open_selected_bookmark (GtkPlacesSidebar   *sidebar,
-                        GtkTreeModel       *model,
-                        GtkTreeIter        *iter,
+                        GtkTreeModel *model,
+                        GtkTreeIter *iter,
                         GtkPlacesOpenFlags  open_flags)
 {
   gchar *uri;
@@ -2533,7 +2960,7 @@ open_selected_bookmark (GtkPlacesSidebar   *sidebar,
 
   if (uri != NULL)
     {
-      open_selected_uri (sidebar, uri, open_flags);
+      //open_selected_uri (sidebar, uri, open_flags);
       g_free (uri);
     }
   else if (place_type == PLACES_CONNECT_TO_SERVER)
@@ -2546,7 +2973,7 @@ open_selected_bookmark (GtkPlacesSidebar   *sidebar,
     }
   else
     {
-      open_selected_volume (sidebar, model, iter, open_flags);
+      //open_selected_volume (sidebar, model, iter, open_flags);
     }
 }
 
@@ -2562,7 +2989,7 @@ open_shortcut_from_menu (GtkPlacesSidebar   *sidebar,
   gtk_tree_view_get_cursor (sidebar->tree_view, &path, NULL);
 
   if (path != NULL && gtk_tree_model_get_iter (model, &iter, path))
-    open_selected_bookmark (sidebar, model, &iter, open_flags);
+    open_selected_bookmark (sidebar, GTK_TREE_MODEL (sidebar->store), &iter, open_flags);
 
   gtk_tree_path_free (path);
 }
@@ -3834,6 +4261,14 @@ bookmarks_popup_menu_cb (GtkWidget        *widget,
 }
 
 static void
+on_row_activated (GtkListBox    *list_box,
+                  GtkListBoxRow *row,
+                  gpointer       user_data)
+{
+  open_selected_row (GTK_PLACES_SIDEBAR (user_data), 0);
+}
+
+static void
 bookmarks_row_activated_cb (GtkWidget         *widget,
                             GtkTreePath       *path,
                             GtkTreeViewColumn *column,
@@ -4229,6 +4664,21 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
   gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (sidebar)),
                                         GTK_JUNCTION_RIGHT | GTK_JUNCTION_LEFT);
 
+  /* list box */
+  sidebar->list_box = gtk_list_box_new ();
+  gtk_list_box_set_header_func (GTK_LIST_BOX (sidebar->list_box),
+                                add_separator, sidebar, NULL);
+  gtk_list_box_set_selection_mode (GTK_LIST_BOX (sidebar->list_box),
+                                   GTK_SELECTION_BROWSE);
+  gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (sidebar),
+                                             TRUE);
+  g_signal_connect (sidebar->list_box,
+                    "row-activated",
+                    (GCallback) on_row_activated,
+                    sidebar);
+  gtk_container_add (GTK_CONTAINER (sidebar), sidebar->list_box);
+  gtk_widget_show (GTK_WIDGET (sidebar));
+
   /* tree view */
   tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
   gtk_tree_view_set_headers_visible (tree_view, FALSE);
@@ -4318,7 +4768,7 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
                                    sidebar, NULL);
 
   gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (sidebar->store));
-  gtk_container_add (GTK_CONTAINER (sidebar), GTK_WIDGET (tree_view));
+//  gtk_container_add (GTK_CONTAINER (sidebar), GTK_WIDGET (tree_view));
   gtk_widget_show (GTK_WIDGET (tree_view));
   gtk_tree_view_set_enable_search (tree_view, FALSE);
 
@@ -4833,7 +5283,7 @@ gtk_places_sidebar_new (void)
   return GTK_WIDGET (g_object_new (gtk_places_sidebar_get_type (), NULL));
 }
 
-
+
 
 /* Drag and drop interfaces */
 
@@ -4911,7 +5361,7 @@ shortcuts_model_new (GtkPlacesSidebar *sidebar)
   return GTK_LIST_STORE (model);
 }
 
-
+
 
 /* Public methods for GtkPlacesSidebar */
 
@@ -4986,16 +5436,14 @@ void
 gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar,
                                  GFile            *location)
 {
-  GtkTreeSelection *selection;
-  GtkTreeIter      iter;
-  gboolean         valid;
-  gchar            *iter_uri;
-  gchar            *uri;
+  GList *children;
+  GList *child;
+  gchar *row_uri;
+  gchar *uri;
 
   g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
 
-  selection = gtk_tree_view_get_selection (sidebar->tree_view);
-  gtk_tree_selection_unselect_all (selection);
+  gtk_list_box_unselect_all (GTK_LIST_BOX (sidebar->list_box));
 
   if (sidebar->current_location != NULL)
     g_object_unref (sidebar->current_location);
@@ -5008,23 +5456,16 @@ gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar,
 
   uri = g_file_get_uri (location);
 
-  valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (sidebar->store), &iter);
-  while (valid)
+  children = gtk_container_get_children (GTK_CONTAINER (sidebar->list_box));
+  for (child = children; child != NULL; child = child->next)
     {
-      gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
-                          PLACES_SIDEBAR_COLUMN_URI, &iter_uri,
-                          -1);
-      if (iter_uri != NULL)
+      g_object_get (SIDEBAR_ROW (child->data), "uri", &row_uri, NULL);
+      if (row_uri != NULL && g_strcmp0 (row_uri, uri) == 0)
         {
-          if (strcmp (iter_uri, uri) == 0)
-            {
-              g_free (iter_uri);
-              gtk_tree_selection_select_iter (selection, &iter);
-              break;
-            }
-          g_free (iter_uri);
+          gtk_list_box_select_row (GTK_LIST_BOX (sidebar->list_box),
+                                   GTK_LIST_BOX_ROW (child->data));
+          break;
         }
-      valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (sidebar->store), &iter);
     }
 
   g_free (uri);
@@ -5055,22 +5496,21 @@ gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar,
 GFile *
 gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar)
 {
-  GtkTreeIter iter;
+  GtkListBoxRow *selected;
   GFile *file;
 
   g_return_val_if_fail (sidebar != NULL, NULL);
 
   file = NULL;
+  selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box));
 
-  if (get_selected_iter (sidebar, &iter))
+  if (selected)
     {
       gchar *uri;
 
-      gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store), &iter,
-                          PLACES_SIDEBAR_COLUMN_URI, &uri,
-                          -1);
-
+      g_object_get (SIDEBAR_ROW (selected), "uri", &uri, NULL);
       file = g_file_new_for_uri (uri);
+
       g_free (uri);
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]