[gnome-builder] recent-projects: implement GListModel
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] recent-projects: implement GListModel
- Date: Wed, 22 Apr 2015 21:52:32 +0000 (UTC)
commit e4914e8970ead39d7a5b6ef7c7a031d2d48bde19
Author: Christian Hergert <christian hergert me>
Date: Wed Apr 22 14:52:15 2015 -0700
recent-projects: implement GListModel
Implement GListModel from IdeRecentProjects. This simplifies the code
in IdeProjectSelector a bit to remove the list management details.
libide/ide-recent-projects.c | 93 ++++++++++++++++++++++++-------------
src/dialogs/gb-projects-dialog.c | 87 +++++++-----------------------------
2 files changed, 76 insertions(+), 104 deletions(-)
---
diff --git a/libide/ide-recent-projects.c b/libide/ide-recent-projects.c
index b996781..dcba064 100644
--- a/libide/ide-recent-projects.c
+++ b/libide/ide-recent-projects.c
@@ -28,7 +28,7 @@ struct _IdeRecentProjects
GCancellable *cancellable;
GPtrArray *miners;
- GPtrArray *projects;
+ GSequence *projects;
GHashTable *recent_uris;
gint active;
@@ -36,14 +36,11 @@ struct _IdeRecentProjects
guint discovered : 1;
};
-G_DEFINE_TYPE (IdeRecentProjects, ide_recent_projects, G_TYPE_OBJECT)
+static void list_model_iface_init (GListModelInterface *iface);
-enum {
- ADDED,
- LAST_SIGNAL
-};
-
-static guint gSignals [LAST_SIGNAL];
+G_DEFINE_TYPE_WITH_CODE (IdeRecentProjects, ide_recent_projects, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
+ list_model_iface_init))
IdeRecentProjects *
ide_recent_projects_new (void)
@@ -66,8 +63,15 @@ ide_recent_projects_added (IdeRecentProjects *self,
if (!g_hash_table_contains (self->recent_uris, uri))
{
- g_ptr_array_add (self->projects, g_object_ref (project_info));
- g_signal_emit (self, gSignals [ADDED], 0, project_info);
+ GSequenceIter *iter;
+ gint position;
+
+ iter = g_sequence_insert_sorted (self->projects,
+ g_object_ref (project_info),
+ (GCompareDataFunc)ide_project_info_compare,
+ NULL);
+ position = g_sequence_iter_get_position (iter);
+ g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
}
}
@@ -178,13 +182,44 @@ ide_recent_projects_load_recent (IdeRecentProjects *self,
g_list_free_full (list, (GDestroyNotify)gtk_recent_info_unref);
}
+static GType
+ide_recent_projects_get_item_type (GListModel *model)
+{
+ return IDE_TYPE_PROJECT_INFO;
+}
+
+static guint
+ide_recent_projects_get_n_items (GListModel *model)
+{
+ IdeRecentProjects *self = (IdeRecentProjects *)model;
+
+ g_assert (IDE_IS_RECENT_PROJECTS (self));
+
+ return g_sequence_get_length (self->projects);
+}
+
+static gpointer
+ide_recent_projects_get_item (GListModel *model,
+ guint position)
+{
+ IdeRecentProjects *self = (IdeRecentProjects *)model;
+ GSequenceIter *iter;
+
+ g_assert (IDE_IS_RECENT_PROJECTS (self));
+
+ if ((iter = g_sequence_get_iter_at_pos (self->projects, position)))
+ return g_object_ref (g_sequence_get (iter));
+
+ return NULL;
+}
+
static void
ide_recent_projects_finalize (GObject *object)
{
IdeRecentProjects *self = (IdeRecentProjects *)object;
g_clear_pointer (&self->miners, g_ptr_array_unref);
- g_clear_pointer (&self->projects, g_ptr_array_unref);
+ g_clear_pointer (&self->projects, g_sequence_free);
g_clear_pointer (&self->recent_uris, g_hash_table_unref);
g_clear_object (&self->cancellable);
@@ -192,29 +227,19 @@ ide_recent_projects_finalize (GObject *object)
}
static void
+list_model_iface_init (GListModelInterface *iface)
+{
+ iface->get_item_type = ide_recent_projects_get_item_type;
+ iface->get_n_items = ide_recent_projects_get_n_items;
+ iface->get_item = ide_recent_projects_get_item;
+}
+
+static void
ide_recent_projects_class_init (IdeRecentProjectsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = ide_recent_projects_finalize;
-
- /**
- * IdeRecentProjects::added:
- * @self: An #IdeRecentProjects
- * @project_info: An #IdeProjectInfo.
- *
- * The "added" signal is emitted when a new #IdeProjectInfo has been discovered.
- */
- gSignals [ADDED] =
- g_signal_new ("added",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- IDE_TYPE_PROJECT_INFO);
}
static void
@@ -223,7 +248,7 @@ ide_recent_projects_init (IdeRecentProjects *self)
GIOExtensionPoint *extension_point;
GList *extensions;
- self->projects = g_ptr_array_new_with_free_func (g_object_unref);
+ self->projects = g_sequence_new (g_object_unref);
self->miners = g_ptr_array_new_with_free_func (g_object_unref);
self->cancellable = g_cancellable_new ();
self->recent_uris = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -261,18 +286,20 @@ ide_recent_projects_init (IdeRecentProjects *self)
GPtrArray *
ide_recent_projects_get_projects (IdeRecentProjects *self)
{
+ GSequenceIter *iter;
GPtrArray *ret;
- gsize i;
g_return_val_if_fail (IDE_IS_RECENT_PROJECTS (self), NULL);
ret = g_ptr_array_new_with_free_func (g_object_unref);
- for (i = 0; i < self->projects->len; i++)
+ for (iter = g_sequence_get_begin_iter (self->projects);
+ !g_sequence_iter_is_end (iter);
+ g_sequence_iter_next (iter))
{
IdeProjectInfo *project_info;
- project_info = g_ptr_array_index (self->projects, i);
+ project_info = g_sequence_get (iter);
g_ptr_array_add (ret, g_object_ref (project_info));
}
diff --git a/src/dialogs/gb-projects-dialog.c b/src/dialogs/gb-projects-dialog.c
index 36ea900..9ebefc5 100644
--- a/src/dialogs/gb-projects-dialog.c
+++ b/src/dialogs/gb-projects-dialog.c
@@ -16,10 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
#define G_LOG_DOMAIN "gb-projects-dialog"
#include <glib/gi18n.h>
@@ -138,16 +134,16 @@ gb_projects_dialog__listbox_row_activated_cb (GbProjectsDialog *self,
g_object_ref (self));
}
-static void
-gb_projects_dialog__recent_projects_added (GbProjectsDialog *self,
- IdeProjectInfo *project_info,
- IdeRecentProjects *recent_projects)
+static GtkWidget *
+create_project_row (gpointer item,
+ gpointer user_data)
{
+ IdeProjectInfo *project_info = item;
+ GbProjectsDialog *self = user_data;
GtkWidget *row;
- g_assert (GB_IS_PROJECTS_DIALOG (self));
g_assert (IDE_IS_PROJECT_INFO (project_info));
- g_assert (IDE_IS_RECENT_PROJECTS (recent_projects));
+ g_assert (GB_IS_PROJECTS_DIALOG (self));
row = g_object_new (GB_TYPE_RECENT_PROJECT_ROW,
"project-info", project_info,
@@ -158,9 +154,11 @@ gb_projects_dialog__recent_projects_added (GbProjectsDialog *self,
G_CALLBACK (gb_projects_dialog_update_delete_sensitivity),
self,
G_CONNECT_SWAPPED);
- g_object_bind_property (self->select_button, "active", row, "selection-mode",
+ g_object_bind_property (self->select_button, "active",
+ row, "selection-mode",
G_BINDING_SYNC_CREATE);
- gtk_container_add (GTK_CONTAINER (self->listbox), row);
+
+ return row;
}
static void
@@ -202,55 +200,6 @@ gb_projects_dialog__listbox_header_cb (GtkListBoxRow *row,
}
}
-static gint
-gb_projects_dialog__listbox_sort_cb (GtkListBoxRow *row1,
- GtkListBoxRow *row2,
- gpointer user_data)
-{
- IdeProjectInfo *info1;
- IdeProjectInfo *info2;
- const gchar *name1;
- const gchar *name2;
- GDateTime *dt1;
- GDateTime *dt2;
- gint ret;
- gint prio1;
- gint prio2;
-
- g_assert (GB_IS_RECENT_PROJECT_ROW (row1));
- g_assert (GB_IS_RECENT_PROJECT_ROW (row2));
-
- info1 = gb_recent_project_row_get_project_info (GB_RECENT_PROJECT_ROW (row1));
- info2 = gb_recent_project_row_get_project_info (GB_RECENT_PROJECT_ROW (row2));
-
- g_assert (IDE_IS_PROJECT_INFO (info1));
- g_assert (IDE_IS_PROJECT_INFO (info2));
-
- prio1 = ide_project_info_get_priority (info1);
- prio2 = ide_project_info_get_priority (info2);
-
- if (prio1 != prio2)
- return prio1 - prio2;
-
- dt1 = ide_project_info_get_last_modified_at (info1);
- dt2 = ide_project_info_get_last_modified_at (info2);
-
- ret = g_date_time_compare (dt2, dt1);
-
- if (ret != 0)
- return ret;
-
- name1 = ide_project_info_get_name (info1);
- name2 = ide_project_info_get_name (info2);
-
- if (name1 == NULL)
- return 1;
- else if (name2 == NULL)
- return -1;
- else
- return strcasecmp (name1, name2);
-}
-
static gboolean
gb_projects_dialog__listbox_filter_cb (GtkListBoxRow *row,
gpointer user_data)
@@ -482,12 +431,6 @@ gb_projects_dialog_constructed (GObject *object)
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (self->recent_projects,
- "added",
- G_CALLBACK (gb_projects_dialog__recent_projects_added),
- self,
- G_CONNECT_SWAPPED);
-
g_object_bind_property (self->search_button, "active",
self->search_bar, "search-mode-enabled",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
@@ -526,14 +469,16 @@ gb_projects_dialog_constructed (GObject *object)
gb_projects_dialog__listbox_header_cb,
NULL, NULL);
- gtk_list_box_set_sort_func (self->listbox,
- gb_projects_dialog__listbox_sort_cb,
- NULL, NULL);
-
gtk_list_box_set_filter_func (self->listbox,
gb_projects_dialog__listbox_filter_cb,
self, NULL);
+ gtk_list_box_bind_model (self->listbox,
+ G_LIST_MODEL (self->recent_projects),
+ create_project_row,
+ self,
+ NULL);
+
ide_recent_projects_discover_async (self->recent_projects,
NULL, /* TODO: cancellable */
gb_projects_dialog__recent_projects_discover_cb,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]