[gtk+/wip/csoriano/bookmarks: 13/14] gtkplacesidebar: use GtkListBox
- From: Carlos Soriano Sánchez <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/csoriano/bookmarks: 13/14] gtkplacesidebar: use GtkListBox
- Date: Tue, 12 May 2015 16:59:00 +0000 (UTC)
commit f56163eff8875b607bc423b6bfc753a2c2789e61
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/Makefile.am | 3 +-
gtk/gtkplacessidebar.c | 882 ++++++++++++++++++++++++++++++++++--------------
gtk/ui/sidebarrow.ui | 47 +++
3 files changed, 673 insertions(+), 259 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 9e8b2a8..5cb6858 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -1085,7 +1085,8 @@ templates = \
ui/gtksearchbar.ui \
ui/gtkscalebutton.ui \
ui/gtkstatusbar.ui \
- ui/gtkvolumebutton.ui
+ ui/gtkvolumebutton.ui \
+ ui/sidebarrow.ui
#
# rules to generate built sources
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index 8828381..b202e1a 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 {
@@ -292,19 +300,6 @@ enum {
static guint places_sidebar_signals [LAST_SIGNAL] = { 0 };
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
-static void open_selected_bookmark (GtkPlacesSidebar *sidebar,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkPlacesOpenFlags open_flags);
-static gboolean eject_or_unmount_bookmark (GtkPlacesSidebar *sidebar,
- GtkTreePath *path);
-static gboolean eject_or_unmount_selection (GtkPlacesSidebar *sidebar);
-static void check_unmount_and_eject (GMount *mount,
- GVolume *volume,
- GDrive *drive,
- gboolean *show_unmount,
- gboolean *show_eject);
-static int bookmarks_get_first_index (GtkPlacesSidebar *sidebar);
/* Identifiers for target types */
enum {
@@ -347,6 +342,417 @@ 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;
+ GtkPlacesSidebar *sidebar;
+} SidebarRowPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (SidebarRow, sidebar_row, GTK_TYPE_LIST_BOX_ROW)
+
+static void open_selected_bookmark (GtkPlacesSidebar *sidebar,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkPlacesOpenFlags open_flags);
+static gboolean eject_or_unmount_bookmark (GtkPlacesSidebar *sidebar,
+ SidebarRow *row);
+static gboolean eject_or_unmount_selection (GtkPlacesSidebar *sidebar);
+static void check_unmount_and_eject (GMount *mount,
+ GVolume *volume,
+ GDrive *drive,
+ gboolean *show_unmount,
+ gboolean *show_eject);
+static int bookmarks_get_first_index (GtkPlacesSidebar *sidebar);
+
+enum
+{
+ PROP_0,
+ PROP_ICON,
+ PROP_LABEL,
+ PROP_EJECTABLE,
+ PROP_SIDEBAR,
+ 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_SIDEBAR:
+ {
+ priv->sidebar = g_value_get_object (value);
+ break;
+ }
+
+ 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
+on_eject_button_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ SidebarRow *self = SIDEBAR_ROW (user_data);
+ SidebarRowPrivate *priv = sidebar_row_get_instance_private (self);
+
+ eject_or_unmount_bookmark (priv->sidebar, self);
+}
+
+static void
+sidebar_row_init (SidebarRow *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+static void
+sidebar_row_class_init (SidebarRowClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = sidebar_row_get_property;
+ object_class->set_property = sidebar_row_set_property;
+
+ gParamSpecs [PROP_SIDEBAR] =
+ g_param_spec_object ("sidebar",
+ "Sidebar",
+ "Sidebar",
+ GTK_TYPE_PLACES_SIDEBAR,
+ (G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_SIDEBAR,
+ gParamSpecs [PROP_SIDEBAR]);
+ 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]);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gtk/libgtk/ui/sidebarrow.ui");
+
+ gtk_widget_class_bind_template_child_private (widget_class, SidebarRow, icon_widget);
+ gtk_widget_class_bind_template_child_private (widget_class, SidebarRow, label_widget);
+ gtk_widget_class_bind_template_child_private (widget_class, SidebarRow, eject_button);
+
+ gtk_widget_class_bind_template_callback (widget_class, on_eject_button_clicked);
+}
+
static void
emit_open_location (GtkPlacesSidebar *sidebar,
GFile *location,
@@ -457,27 +863,52 @@ 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);
+ GtkWidget *separator;
+
+ 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"));
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_set_margin_top (separator, 4);
+ gtk_widget_set_margin_bottom (separator, 4);
+ gtk_list_box_row_set_header (row, separator);
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"));
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_set_margin_top (separator, 4);
+ gtk_widget_set_margin_bottom (separator, 4);
+ gtk_list_box_row_set_header (row, separator);
sidebar->bookmarks_header_added = TRUE;
}
break;
+ case SECTION_0:
+ {
+ if (before == NULL)
+ gtk_widget_set_margin_top (GTK_WIDGET (row), 4);
+ }
+
default:
break;
}
@@ -496,11 +927,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 +942,22 @@ 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,
+ "sidebar", sidebar,
+ "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 +1094,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 +1349,6 @@ out:
static void
update_places (GtkPlacesSidebar *sidebar)
{
- GtkTreeIter iter;
- GVolumeMonitor *volume_monitor;
GList *mounts, *l, *ll;
GMount *mount;
GList *drives;
@@ -933,6 +1358,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 +1366,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 +1377,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 +1458,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 +1557,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 +1609,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 +1625,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 +1669,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 +1783,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)
{
@@ -1374,79 +1799,6 @@ update_places (GtkPlacesSidebar *sidebar)
}
static gboolean
-over_eject_button (GtkPlacesSidebar *sidebar,
- gint x,
- gint y,
- GtkTreePath **path)
-{
- GtkTreeViewColumn *column;
- gint width, x_offset, hseparator;
- gint eject_button_size;
- gboolean show_eject;
- GtkTreeIter iter;
- GtkTreeModel *model;
-
- *path = NULL;
- model = gtk_tree_view_get_model (sidebar->tree_view);
-
- if (gtk_tree_view_get_path_at_pos (sidebar->tree_view,
- x, y, path, &column, NULL, NULL))
- {
- gtk_tree_model_get_iter (model, &iter, *path);
- gtk_tree_model_get (model, &iter,
- PLACES_SIDEBAR_COLUMN_EJECT, &show_eject,
- -1);
-
- if (!show_eject)
- goto out;
-
- gtk_widget_style_get (GTK_WIDGET (sidebar->tree_view),
- "horizontal-separator", &hseparator,
- NULL);
-
- /* Reload cell attributes for this particular row */
- gtk_tree_view_column_cell_set_cell_data (column,
- model, &iter, FALSE, FALSE);
-
- gtk_tree_view_column_cell_get_position (column,
- sidebar->eject_icon_cell_renderer,
- &x_offset, &width);
-
- eject_button_size = get_icon_size (sidebar);
-
- /* This is kinda weird, but we have to do it to workaround expanding
- * the eject cell renderer (even thought we told it not to) and we
- * then had to set it right-aligned
- */
- x_offset += width - hseparator - EJECT_BUTTON_XPAD - eject_button_size;
-
- if (x - x_offset >= 0 && x - x_offset <= eject_button_size)
- return TRUE;
- }
-
- out:
- g_clear_pointer (path, gtk_tree_path_free);
-
- return FALSE;
-}
-
-static gboolean
-clicked_eject_button (GtkPlacesSidebar *sidebar,
- GtkTreePath **path)
-{
- GdkEvent *event;
-
- event = gtk_get_current_event ();
-
- if (event &&
- (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) &&
- over_eject_button (sidebar, ((GdkEventButton *)event)->x, ((GdkEventButton *)event)->y, path))
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean
pos_is_into_or_before (GtkTreeViewDropPosition pos)
{
return (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
@@ -2466,27 +2818,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 +2831,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 +2859,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 +2921,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 +2934,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 +2950,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);
}
@@ -3299,30 +3687,19 @@ eject_shortcut_cb (GtkMenuItem *item,
static gboolean
eject_or_unmount_bookmark (GtkPlacesSidebar *sidebar,
- GtkTreePath *path)
+ SidebarRow *row)
{
- GtkTreeModel *model;
- GtkTreeIter iter;
gboolean can_unmount, can_eject;
GMount *mount;
GVolume *volume;
GDrive *drive;
gboolean ret;
- model = GTK_TREE_MODEL (sidebar->store);
-
- if (!path)
- return FALSE;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- return FALSE;
-
- gtk_tree_model_get (model, &iter,
- PLACES_SIDEBAR_COLUMN_MOUNT, &mount,
- PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
- PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
- -1);
-
+ g_object_get (row,
+ "mount", &mount,
+ "volume", &volume,
+ "drive", &drive,
+ NULL);
ret = FALSE;
check_unmount_and_eject (mount, volume, drive, &can_unmount, &can_eject);
@@ -3338,30 +3715,17 @@ eject_or_unmount_bookmark (GtkPlacesSidebar *sidebar,
ret = TRUE;
}
- g_clear_object (&mount);
- g_clear_object (&volume);
- g_clear_object (&drive);
-
return ret;
}
static gboolean
eject_or_unmount_selection (GtkPlacesSidebar *sidebar)
{
- GtkTreeIter iter;
- GtkTreePath *path;
gboolean ret;
+ GtkListBoxRow *row;
- if (!get_selected_iter (sidebar, &iter))
- return FALSE;
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (sidebar->store), &iter);
- if (path == NULL)
- return FALSE;
-
- ret = eject_or_unmount_bookmark (sidebar, path);
-
- gtk_tree_path_free (path);
+ row = gtk_list_box_get_selected_row (GTK_LIST_BOX (sidebar->list_box));
+ ret = eject_or_unmount_bookmark (sidebar, SIDEBAR_ROW (row));
return ret;
}
@@ -3834,40 +4198,36 @@ bookmarks_popup_menu_cb (GtkWidget *widget,
}
static void
-bookmarks_row_activated_cb (GtkWidget *widget,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GtkPlacesSidebar *sidebar)
+on_row_activated (GtkListBox *list_box,
+ GtkListBoxRow *row,
+ gpointer user_data)
{
- GtkTreeIter iter;
- GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
- GtkTreePath *dummy;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- return;
-
- dummy = NULL;
- if (!clicked_eject_button (sidebar, &dummy))
- {
- open_selected_bookmark (sidebar, model, &iter, 0);
- gtk_tree_path_free (dummy);
- }
+ open_selected_row (GTK_PLACES_SIDEBAR (user_data), 0);
}
static gboolean
-bookmarks_button_release_event_cb (GtkWidget *widget,
- GdkEventButton *event,
- GtkPlacesSidebar *sidebar)
+on_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ GtkPlacesSidebar *sidebar)
{
- GtkTreePath *path;
- GtkTreeIter iter;
- GtkTreeModel *model;
- GtkTreeView *tree_view;
gboolean ret = FALSE;
- gboolean res;
+ GtkListBoxRow *row;
+ gchar *label;
- path = NULL;
+ if (event)
+ {
+ row = gtk_list_box_get_row_at_y (GTK_LIST_BOX (sidebar->list_box),
+ (gint) event->y);
+ if (row)
+ {
+ g_object_get (row, "label", &label, NULL);
+ g_print ("row %s\n", label);
+ }
+ }
+ g_print ("release event\n");
+ return ret;
+/*
if (event->type != GDK_BUTTON_RELEASE)
return TRUE;
@@ -3926,6 +4286,7 @@ bookmarks_button_release_event_cb (GtkWidget *widget,
gtk_tree_path_free (path);
return ret;
+ **/
}
static gboolean
@@ -4229,6 +4590,25 @@ 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->list_box),
+ TRUE);
+ g_signal_connect (sidebar->list_box,
+ "row-activated",
+ (GCallback) on_row_activated,
+ sidebar);
+ g_signal_connect (sidebar->list_box,
+ "button-release-event",
+ G_CALLBACK (on_button_release_event),
+ 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 +4698,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);
@@ -4361,10 +4741,6 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
g_signal_connect (tree_view, "popup-menu",
G_CALLBACK (bookmarks_popup_menu_cb), sidebar);
- g_signal_connect (tree_view, "button-release-event",
- G_CALLBACK (bookmarks_button_release_event_cb), sidebar);
- g_signal_connect (tree_view, "row-activated",
- G_CALLBACK (bookmarks_row_activated_cb), sidebar);
gtk_tree_view_set_activate_on_single_click (sidebar->tree_view, TRUE);
@@ -4833,7 +5209,7 @@ gtk_places_sidebar_new (void)
return GTK_WIDGET (g_object_new (gtk_places_sidebar_get_type (), NULL));
}
-
+
/* Drag and drop interfaces */
@@ -4911,7 +5287,7 @@ shortcuts_model_new (GtkPlacesSidebar *sidebar)
return GTK_LIST_STORE (model);
}
-
+
/* Public methods for GtkPlacesSidebar */
@@ -4986,16 +5362,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 +5382,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 +5422,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);
}
diff --git a/gtk/ui/sidebarrow.ui b/gtk/ui/sidebarrow.ui
new file mode 100644
index 0000000..0093f51
--- /dev/null
+++ b/gtk/ui/sidebarrow.ui
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="SidebarRow" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <property name="margin-top">1</property>
+ <property name="margin-bottom">1</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImage" id="icon_widget">
+ <property name="visible">True</property>
+ <property name="margin-start">10</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_widget">
+ <property name="visible">True</property>
+ <property name="margin-start">10</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="eject_button">
+ <property name="visible">True</property>
+ <property name="margin-start">15</property>
+ <property name="hexpand">True</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="on_eject_button_clicked" swapped="no" />
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">media-eject-symbolic</property>
+ <property name="icon_size">1</property>
+ </object>
+ </child>
+ <style>
+ <class name="image-button"/>
+ <class name="sidebar-button"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]