diff options
author | Jamie Murphy <hello@itsjamie.dev> | 2023-01-12 15:28:40 -0800 |
---|---|---|
committer | Jamie Murphy <hello@itsjamie.dev> | 2023-02-12 07:14:41 +0000 |
commit | cfc3f862c6a0a77fe08b2a17fd3a86cad11ec8f1 (patch) | |
tree | 2186c1d91df7c9fd5d87aaf784da14a29ca90bca | |
parent | 39d63bf2fd9a9f752e4136aa3574265a8953a971 (diff) | |
download | gnome-todo-cfc3f862c6a0a77fe08b2a17fd3a86cad11ec8f1.tar.gz |
gtd-list-model: Remove unused models
-rw-r--r-- | src/models/gtd-list-model-filter.c | 569 | ||||
-rw-r--r-- | src/models/gtd-list-model-filter.h | 44 | ||||
-rw-r--r-- | src/models/gtd-list-model-sort.c | 500 | ||||
-rw-r--r-- | src/models/gtd-list-model-sort.h | 46 |
4 files changed, 0 insertions, 1159 deletions
diff --git a/src/models/gtd-list-model-filter.c b/src/models/gtd-list-model-filter.c deleted file mode 100644 index 632c2279..00000000 --- a/src/models/gtd-list-model-filter.c +++ /dev/null @@ -1,569 +0,0 @@ -/* gtd-list-model-filter.c - * - * Copyright (C) 2016 Christian Hergert <christian@hergert.me> - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - */ - -#define G_LOG_DOMAIN "GtdListModelFilter" - -#include "gtd-debug.h" -#include "gtd-list-model-filter.h" -#include "gtd-task-list.h" - -typedef struct -{ - GSequenceIter *child_iter; - GSequenceIter *filter_iter; -} GtdListModelFilterItem; - -typedef struct -{ - /* The list we are filtering */ - GListModel *child_model; - - /* - * Both sequences point to the same GtdListModelFilterItem which - * contains cross-referencing stable GSequenceIter pointers. - * The child_seq is considered the "owner" and used to release - * allocated resources. - */ - GSequence *child_seq; - GSequence *filter_seq; - - /* - * Typical set of callback/closure/free function pointers and data. - * Called for child items to determine visibility state. - */ - GtdListModelFilterFunc filter_func; - gpointer filter_func_data; - GDestroyNotify filter_func_data_destroy; - - /* cache */ - gint64 length; - gint64 last_position; - GSequenceIter *last_iter; - - /* - * If set, we will not emit items-changed. This is useful during - * invalidation so that we can do a single emission for all items - * that have changed. - */ - gboolean supress_items_changed : 1; -} GtdListModelFilterPrivate; - -struct _GtdListModelFilter -{ - GObject parent_instance; -}; - -static void list_model_iface_init (GListModelInterface *iface); - -G_DEFINE_TYPE_EXTENDED (GtdListModelFilter, gtd_list_model_filter, G_TYPE_OBJECT, 0, - G_ADD_PRIVATE (GtdListModelFilter) - G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, - list_model_iface_init)) - -enum -{ - PROP_0, - PROP_CHILD_MODEL, - N_PROPS -}; - -static GParamSpec *properties [N_PROPS]; -static guint signal_id; - -static void -gtd_list_model_filter_item_free (gpointer data) -{ - GtdListModelFilterItem *item = data; - - g_clear_pointer (&item->filter_iter, g_sequence_remove); - item->child_iter = NULL; - g_slice_free (GtdListModelFilterItem, item); -} - -static gboolean -gtd_list_model_filter_default_filter_func (GObject *item, - gpointer user_data) -{ - return TRUE; -} - -/* - * Locates the next item in the filter sequence starting from - * the cross-reference found at @iter. If none are found, the - * end_iter for the filter sequence is returned. - * - * This returns an iter in the filter_sequence, not the child_seq. - * - * Returns: a #GSequenceIter from the filter sequence. - */ -static GSequenceIter * -find_next_visible_filter_iter (GtdListModelFilter *self, - GSequenceIter *iter) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - g_assert (GTD_IS_LIST_MODEL_FILTER (self)); - g_assert (iter != NULL); - - for (; !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) - { - GtdListModelFilterItem *item = g_sequence_get (iter); - - g_assert (item->child_iter == iter); - g_assert (item->filter_iter == NULL || - g_sequence_iter_get_sequence (item->filter_iter) == priv->filter_seq); - - if (item->filter_iter != NULL) - return item->filter_iter; - } - - return g_sequence_get_end_iter (priv->filter_seq); -} - -static void -invalidate_cache (GtdListModelFilter *self) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - GTD_TRACE_MSG ("Invalidating cache"); - - priv->last_iter = NULL; - priv->last_position = -1u; -} - -static void -emit_items_changed (GtdListModelFilter *self, - guint position, - guint n_removed, - guint n_added) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - if (position <= priv->last_position) - invalidate_cache (self); - - priv->length -= n_removed; - priv->length += n_added; - - GTD_TRACE_MSG ("Emitting items-changed(%u, %u, %u)", position, n_removed, n_added); - - g_list_model_items_changed (G_LIST_MODEL (self), position, n_removed, n_added); -} - -static void -child_model_items_changed (GtdListModelFilter *self, - guint position, - guint n_removed, - guint n_added, - GListModel *child_model) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - gboolean unblocked; - guint i; - - GTD_ENTRY; - - g_assert (GTD_IS_LIST_MODEL_FILTER (self)); - g_assert (G_IS_LIST_MODEL (child_model)); - g_assert (priv->child_model == child_model); - g_assert (position <= (guint)g_sequence_get_length (priv->child_seq)); - g_assert ((g_sequence_get_length (priv->child_seq) - n_removed + n_added) == - g_list_model_get_n_items (child_model)); - - GTD_TRACE_MSG ("Received items-changed(%u, %u, %u)", position, n_removed, n_added); - - unblocked = !priv->supress_items_changed; - - if (n_removed > 0) - { - GSequenceIter *iter = g_sequence_get_iter_at_pos (priv->child_seq, position); - gint64 first_position = -1; - guint count = 0; - - g_assert (!g_sequence_iter_is_end (iter)); - - /* Small shortcut when all items are removed */ - if (n_removed == (guint)g_sequence_get_length (priv->child_seq)) - { - g_sequence_remove_range (g_sequence_get_begin_iter (priv->child_seq), - g_sequence_get_end_iter (priv->child_seq)); - g_assert (g_sequence_is_empty (priv->child_seq)); - g_assert (g_sequence_is_empty (priv->filter_seq)); - - if (unblocked) - emit_items_changed (self, 0, priv->length, 0); - - GTD_TRACE_MSG ("Removed all items"); - - GTD_GOTO (add_new_items); - } - - for (i = 0; i < n_removed; i++) - { - GSequenceIter *to_remove = iter; - GtdListModelFilterItem *item = g_sequence_get (iter); - - g_assert (item != NULL); - g_assert (item->child_iter == iter); - g_assert (item->filter_iter == NULL || - g_sequence_iter_get_sequence (item->filter_iter) == priv->filter_seq); - - /* If this is visible, we need to notify about removal */ - if (unblocked && item->filter_iter != NULL) - { - if (first_position < 0) - first_position = g_sequence_iter_get_position (item->filter_iter); - - count++; - } - - /* Fetch the next while the iter is still valid */ - iter = g_sequence_iter_next (iter); - - /* Cascades into also removing from filter_seq. */ - g_sequence_remove (to_remove); - } - - GTD_TRACE_MSG ("Removed %u items", count); - - if (unblocked && first_position >= 0) - emit_items_changed (self, first_position, count, 0); - } - -add_new_items: - - if (n_added > 0) - { - GSequenceIter *iter = g_sequence_get_iter_at_pos (priv->child_seq, position); - GSequenceIter *filter_iter = find_next_visible_filter_iter (self, iter); - guint filter_position = g_sequence_iter_get_position (filter_iter); - guint count = 0; - - /* Walk backwards to insert items into the filter list so that - * we can use the same filter_position for each items-changed - * signal emission. - */ - for (i = position + n_added; i > position; i--) - { - GtdListModelFilterItem *item; - g_autoptr (GObject) instance = NULL; - - item = g_slice_new0 (GtdListModelFilterItem); - item->filter_iter = NULL; - item->child_iter = g_sequence_insert_before (iter, item); - - instance = g_list_model_get_item (child_model, i - 1); - g_assert (G_IS_OBJECT (instance)); - - /* Check if this item is visible */ - if (priv->filter_func (instance, priv->filter_func_data)) - { - item->filter_iter = g_sequence_insert_before (filter_iter, item); - count++; - - /* Use this in the future for relative positioning */ - filter_iter = item->filter_iter; - } - - /* Insert next item before this */ - iter = item->child_iter; - } - - GTD_TRACE_MSG ("Added %u items (%u were filtered)", count, n_added - count); - - if (unblocked && count) - emit_items_changed (self, filter_position, 0, count); - } - - g_assert ((guint)g_sequence_get_length (priv->child_seq) == g_list_model_get_n_items (child_model)); - - GTD_EXIT; -} - -static void -gtd_list_model_filter_finalize (GObject *object) -{ - GtdListModelFilter *self = (GtdListModelFilter *)object; - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - g_clear_pointer (&priv->child_seq, g_sequence_free); - g_clear_pointer (&priv->filter_seq, g_sequence_free); - - if (priv->filter_func_data_destroy) - { - g_clear_pointer (&priv->filter_func_data, priv->filter_func_data_destroy); - priv->filter_func_data_destroy = NULL; - } - - g_clear_object (&priv->child_model); - - G_OBJECT_CLASS (gtd_list_model_filter_parent_class)->finalize (object); -} - -static void -gtd_list_model_filter_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtdListModelFilter *self = GTD_LIST_MODEL_FILTER (object); - - switch (prop_id) - { - case PROP_CHILD_MODEL: - g_value_set_object (value, gtd_list_model_filter_get_child_model (self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -gtd_list_model_filter_class_init (GtdListModelFilterClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gtd_list_model_filter_finalize; - object_class->get_property = gtd_list_model_filter_get_property; - - properties [PROP_CHILD_MODEL] = - g_param_spec_object ("child-model", - "Child Model", - "The child model being filtered.", - G_TYPE_LIST_MODEL, - (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_properties (object_class, N_PROPS, properties); - - signal_id = g_signal_lookup ("items-changed", GTD_TYPE_LIST_MODEL_FILTER); -} - -static void -gtd_list_model_filter_init (GtdListModelFilter *self) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - priv->filter_func = gtd_list_model_filter_default_filter_func; - priv->child_seq = g_sequence_new (gtd_list_model_filter_item_free); - priv->filter_seq = g_sequence_new (NULL); - priv->last_position = -1; -} - -static GType -gtd_list_model_filter_get_item_type (GListModel *model) -{ - GtdListModelFilter *self = (GtdListModelFilter *)model; - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - g_assert (GTD_IS_LIST_MODEL_FILTER (self)); - - return g_list_model_get_item_type (priv->child_model); -} - -static guint -gtd_list_model_filter_get_n_items (GListModel *model) -{ - GtdListModelFilter *self = (GtdListModelFilter *)model; - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - g_assert (GTD_IS_LIST_MODEL_FILTER (self)); - g_assert (priv->filter_seq != NULL); - - return priv->length; -} - -static gpointer -gtd_list_model_filter_get_item (GListModel *model, - guint position) -{ - GtdListModelFilter *self = (GtdListModelFilter *)model; - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - GtdListModelFilterItem *item; - GSequenceIter *iter; - guint child_position; - - g_assert (GTD_IS_LIST_MODEL_FILTER (self)); - - iter = NULL; - - if (priv->last_position != -1) - { - if (priv->last_position == position + 1) - iter = g_sequence_iter_prev (priv->last_iter); - else if (priv->last_position == position - 1) - iter = g_sequence_iter_next (priv->last_iter); - else if (priv->last_position == position) - iter = priv->last_iter; - } - - if (!iter) - iter = g_sequence_get_iter_at_pos (priv->filter_seq, position); - - if (g_sequence_iter_is_end (iter)) - return NULL; - - item = g_sequence_get (iter); - g_assert (item != NULL); - g_assert (item->filter_iter == iter); - g_assert (item->child_iter != NULL); - g_assert (g_sequence_iter_get_sequence (item->child_iter) == priv->child_seq); - - child_position = g_sequence_iter_get_position (item->child_iter); - - return g_list_model_get_item (priv->child_model, child_position); -} - -static void -list_model_iface_init (GListModelInterface *iface) -{ - iface->get_item_type = gtd_list_model_filter_get_item_type; - iface->get_n_items = gtd_list_model_filter_get_n_items; - iface->get_item = gtd_list_model_filter_get_item; -} - -GtdListModelFilter * -gtd_list_model_filter_new (GListModel *child_model) -{ - GtdListModelFilter *ret; - GtdListModelFilterPrivate *priv; - - g_return_val_if_fail (G_IS_LIST_MODEL (child_model), NULL); - - ret = g_object_new (GTD_TYPE_LIST_MODEL_FILTER, NULL); - priv = gtd_list_model_filter_get_instance_private (ret); - priv->child_model = g_object_ref (child_model); - - g_signal_connect_object (child_model, - "items-changed", - G_CALLBACK (child_model_items_changed), - ret, - G_CONNECT_SWAPPED); - - gtd_list_model_filter_invalidate (ret); - - return ret; -} - -/** - * gtd_list_model_filter_get_child_model: - * @self: A #GtdListModelFilter - * - * Gets the child model that is being filtered. - * - * Returns: (transfer none): A #GListModel. - */ -GListModel * -gtd_list_model_filter_get_child_model (GtdListModelFilter *self) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - g_return_val_if_fail (GTD_IS_LIST_MODEL_FILTER (self), NULL); - - return priv->child_model; -} - -void -gtd_list_model_filter_invalidate (GtdListModelFilter *self) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - guint n_items; - - GTD_ENTRY; - - g_return_if_fail (GTD_IS_LIST_MODEL_FILTER (self)); - - /* We block emission while in invalidate so that we can use - * a single larger items-changed rather lots of small emissions. - */ - priv->supress_items_changed = TRUE; - - /* First determine how many items we need to synthesize as a removal */ - n_items = g_sequence_get_length (priv->filter_seq); - - /* - * If we have a child store, we want to rebuild our list of items - * from scratch, so just remove everything. - */ - if (!g_sequence_is_empty (priv->child_seq)) - g_sequence_remove_range (g_sequence_get_begin_iter (priv->child_seq), - g_sequence_get_end_iter (priv->child_seq)); - - g_assert (g_sequence_is_empty (priv->child_seq)); - g_assert (g_sequence_is_empty (priv->filter_seq)); - g_assert (!priv->child_model || G_IS_LIST_MODEL (priv->child_model)); - - /* - * Now add the new items by synthesizing the addition of all the - * items in the list. - */ - if (priv->child_model != NULL) - { - guint child_n_items; - - /* - * Now add all the items as one shot to our list so that - * we get populate our sequence and filter sequence. - */ - child_n_items = g_list_model_get_n_items (priv->child_model); - child_model_items_changed (self, 0, 0, child_n_items, priv->child_model); - - g_assert ((guint)g_sequence_get_length (priv->child_seq) == child_n_items); - g_assert ((guint)g_sequence_get_length (priv->filter_seq) <= child_n_items); - } - - priv->supress_items_changed = FALSE; - - /* Now that we've updated our sequences, notify of all the changes - * as a single series of updates to the consumers. - */ - if (n_items > 0 || !g_sequence_is_empty (priv->filter_seq)) - emit_items_changed (self, 0, n_items, g_sequence_get_length (priv->filter_seq)); - - GTD_EXIT; -} - -void -gtd_list_model_filter_set_filter_func (GtdListModelFilter *self, - GtdListModelFilterFunc filter_func, - gpointer filter_func_data, - GDestroyNotify filter_func_data_destroy) -{ - GtdListModelFilterPrivate *priv = gtd_list_model_filter_get_instance_private (self); - - g_return_if_fail (GTD_IS_LIST_MODEL_FILTER (self)); - g_return_if_fail (filter_func || (!filter_func_data && !filter_func_data_destroy)); - - if (priv->filter_func_data_destroy != NULL) - g_clear_pointer (&priv->filter_func_data, priv->filter_func_data_destroy); - - if (filter_func != NULL) - { - priv->filter_func = filter_func; - priv->filter_func_data = filter_func_data; - priv->filter_func_data_destroy = filter_func_data_destroy; - } - else - { - priv->filter_func = gtd_list_model_filter_default_filter_func; - priv->filter_func_data = NULL; - priv->filter_func_data_destroy = NULL; - } - - gtd_list_model_filter_invalidate (self); -} diff --git a/src/models/gtd-list-model-filter.h b/src/models/gtd-list-model-filter.h deleted file mode 100644 index f5c2a426..00000000 --- a/src/models/gtd-list-model-filter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* gtd-list-model-filter.h - * - * Copyright © 2016 Christian Hergert <christian@hergert.me> - * 2018 Georges Basile Stavracas Neto <gbsneto@gnome.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 3 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, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define GTD_TYPE_LIST_MODEL_FILTER (gtd_list_model_filter_get_type()) - -typedef gboolean (*GtdListModelFilterFunc) (GObject *object, - gpointer user_data); - -G_DECLARE_FINAL_TYPE (GtdListModelFilter, gtd_list_model_filter, GTD, LIST_MODEL_FILTER, GObject) - -GtdListModelFilter* gtd_list_model_filter_new (GListModel *child_model); - -GListModel* gtd_list_model_filter_get_child_model (GtdListModelFilter *self); - -void gtd_list_model_filter_invalidate (GtdListModelFilter *self); - -void gtd_list_model_filter_set_filter_func (GtdListModelFilter *self, - GtdListModelFilterFunc filter_func, - gpointer filter_func_data, - GDestroyNotify filter_func_data_destroy); - -G_END_DECLS diff --git a/src/models/gtd-list-model-sort.c b/src/models/gtd-list-model-sort.c deleted file mode 100644 index dedbb6d1..00000000 --- a/src/models/gtd-list-model-sort.c +++ /dev/null @@ -1,500 +0,0 @@ -/* gtd-list-model-sort.c - * - * Copyright 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#define G_LOG_DOMAIN "GtdListModelSort" - -#include "gtd-debug.h" -#include "gtd-list-model-sort.h" -#include "gtd-task.h" -#include "gtd-task-list.h" - -struct _GtdListModelSort -{ - GObject parent; - - GListModel *child_model; - - GSequence *child_seq; - GSequence *sort_seq; - - GtdListModelCompareFunc compare_func; - gpointer compare_func_data; - GDestroyNotify compare_func_data_destroy; - - gboolean supress_items_changed : 1; - - /* cache */ - gint64 length; - gint64 last_position; - GSequenceIter *last_iter; -}; - -static void list_model_iface_init (GListModelInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (GtdListModelSort, gtd_list_model_sort, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init)) - -enum -{ - PROP_0, - PROP_CHILD_MODEL, - N_PROPS -}; - -static GParamSpec *properties [N_PROPS]; - -static void -gtd_list_model_sort_item_free (gpointer data) -{ - GSequenceIter *iter = data; - - g_clear_pointer (&iter, g_sequence_remove); -} - -static gint -seq_compare_func (gconstpointer a, - gconstpointer b, - gpointer user_data) -{ - GtdListModelSort *self = (GtdListModelSort*) user_data; - - return self->compare_func (G_OBJECT (a), G_OBJECT (b), self->compare_func_data); -} - -static gint -default_compare_func (GObject *a, - GObject *b, - gpointer user_data) -{ - return 0; -} - - -static void -invalidate_cache (GtdListModelSort *self) -{ - GTD_TRACE_MSG ("Invalidating cache"); - - self->last_iter = NULL; - self->last_position = -1; -} - -static void -emit_items_changed (GtdListModelSort *self, - guint position, - guint n_removed, - guint n_added) -{ - if (position <= self->last_position) - invalidate_cache (self); - - self->length -= n_removed; - self->length += n_added; - - GTD_TRACE_MSG ("Emitting items-changed(%u, %u, %u)", position, n_removed, n_added); - - g_list_model_items_changed (G_LIST_MODEL (self), position, n_removed, n_added); -} - - -static void -child_model_items_changed (GtdListModelSort *self, - guint position, - guint n_removed, - guint n_added, - GListModel *child_model) -{ - guint i; - - GTD_ENTRY; - - g_assert (GTD_IS_LIST_MODEL_SORT (self)); - g_assert (G_IS_LIST_MODEL (child_model)); - g_assert (self->child_model == child_model); - g_assert (position <= (guint)g_sequence_get_length (self->child_seq)); - g_assert (g_sequence_get_length (self->child_seq) - n_removed + n_added == g_list_model_get_n_items (child_model)); - - GTD_TRACE_MSG ("Received items-changed(%u, %u, %u)", position, n_removed, n_added); - - if (n_removed > 0) - { - GSequenceIter *iter; - gint64 previous_sort_position = -1; - gint64 first_position = -1; - gint64 counter = 0; - - /* Small shortcut when all items are removed */ - if (n_removed == (guint)g_sequence_get_length (self->child_seq)) - { - g_sequence_remove_range (g_sequence_get_begin_iter (self->child_seq), - g_sequence_get_end_iter (self->child_seq)); - - g_assert (g_sequence_is_empty (self->child_seq)); - g_assert (g_sequence_is_empty (self->sort_seq)); - - emit_items_changed (self, 0, n_removed, 0); - - goto add_new_items; - } - - iter = g_sequence_get_iter_at_pos (self->child_seq, position); - g_assert (!g_sequence_iter_is_end (iter)); - - for (i = 0; i < n_removed; i++) - { - GSequenceIter *sort_iter = g_sequence_get (iter); - GSequenceIter *to_remove = iter; - guint sort_position; - - g_assert (g_sequence_iter_get_sequence (sort_iter) == self->sort_seq); - - sort_position = g_sequence_iter_get_position (sort_iter); - - /* Fetch the next while the iter is still valid */ - iter = g_sequence_iter_next (iter); - - /* Cascades into also removing from sort_seq. */ - g_sequence_remove (to_remove); - - if (first_position == -1) - first_position = sort_position; - - /* - * This happens when the position in the sorted sequence is different - * from the position in the child sequence. We try to accumulate as many - * items-changed() signals as possible, but we can't do that when the - * order doesn't match. - */ - if (previous_sort_position != -1 && sort_position != previous_sort_position + 1) - { - emit_items_changed (self, first_position, counter, 0); - - first_position = sort_position; - counter = 0; - } - - previous_sort_position = sort_position; - counter++; - } - - /* - * Last items-changed() - if the child model is already sorted, - * only this one will be fired. - */ - if (counter > 0) - emit_items_changed (self, first_position, counter, 0); - } - -add_new_items: - - if (n_added > 0) - { - GSequenceIter *iter = g_sequence_get_iter_at_pos (self->child_seq, position); - gint64 previous_sort_position = -1; - gint64 first_position = -1; - gint64 counter = 0; - - for (i = 0; i < n_added; i++) - { - g_autoptr (GObject) instance = NULL; - GSequenceIter *sort_iter; - guint new_sort_position; - - instance = g_list_model_get_item (child_model, position + i); - g_assert (G_IS_OBJECT (instance)); - - sort_iter = g_sequence_insert_sorted (self->sort_seq, - g_steal_pointer (&instance), - seq_compare_func, - self); - - new_sort_position = g_sequence_iter_get_position (sort_iter); - - /* Insert next item before this */ - iter = g_sequence_insert_before (iter, sort_iter); - iter = g_sequence_iter_next (iter); - - if (first_position == -1) - first_position = new_sort_position; - - /* - * This happens when the position in the sorted sequence is different - * from the position in the child sequence. We try to accumulate as many - * items-changed() signals as possible, but we can't do that when the - * order doesn't match. - */ - if (previous_sort_position != -1 && new_sort_position != previous_sort_position + 1) - { - emit_items_changed (self, first_position, 0, counter); - - first_position = new_sort_position; - counter = 0; - } - - previous_sort_position = new_sort_position; - counter++; - } - - /* - * Last items-changed() - if the child model is already sorted, - * only this one will be fired. - */ - if (counter > 0) - emit_items_changed (self, first_position, 0, counter); - } - - g_assert ((guint)g_sequence_get_length (self->child_seq) == g_list_model_get_n_items (child_model)); - g_assert ((guint)g_sequence_get_length (self->sort_seq) == g_list_model_get_n_items (child_model)); - - GTD_EXIT; -} - - -/* - * GListModel iface - */ - -static GType -gtd_list_model_sort_get_item_type (GListModel *model) -{ - GtdListModelSort *self = (GtdListModelSort*) model; - - g_assert (GTD_IS_LIST_MODEL_SORT (self)); - - return g_list_model_get_item_type (self->child_model); -} - -static guint -gtd_list_model_sort_get_n_items (GListModel *model) -{ - GtdListModelSort *self = (GtdListModelSort*) model; - - g_assert (GTD_IS_LIST_MODEL_SORT (self)); - g_assert (self->sort_seq != NULL); - - return self->length; -} - -static gpointer -gtd_list_model_sort_get_item (GListModel *model, - guint position) -{ - GtdListModelSort *self; - GSequenceIter *iter; - gpointer item; - - g_assert (GTD_IS_LIST_MODEL_SORT (model)); - - self = (GtdListModelSort*) model; - iter = NULL; - - if (self->last_position != -1) - { - if (self->last_position == position + 1) - iter = g_sequence_iter_prev (self->last_iter); - else if (self->last_position == position - 1) - iter = g_sequence_iter_next (self->last_iter); - else if (self->last_position == position) - iter = self->last_iter; - } - - if (!iter) - iter = g_sequence_get_iter_at_pos (self->sort_seq, position); - - if (g_sequence_iter_is_end (iter)) - return NULL; - - self->last_iter = iter; - self->last_position = position; - - item = g_sequence_get (iter); - g_assert (item != NULL); - - return g_object_ref (G_OBJECT (item)); -} - -static void -list_model_iface_init (GListModelInterface *iface) -{ - iface->get_item_type = gtd_list_model_sort_get_item_type; - iface->get_n_items = gtd_list_model_sort_get_n_items; - iface->get_item = gtd_list_model_sort_get_item; -} - - -/* - * GObject overrides - */ - -static void -gtd_list_model_sort_finalize (GObject *object) -{ - GtdListModelSort *self = (GtdListModelSort*) object; - - g_clear_pointer (&self->child_seq, g_sequence_free); - g_clear_pointer (&self->sort_seq, g_sequence_free); - - if (self->compare_func_data_destroy) - { - g_clear_pointer (&self->compare_func_data, self->compare_func_data_destroy); - self->compare_func_data_destroy = NULL; - } - - g_clear_object (&self->child_model); - - G_OBJECT_CLASS (gtd_list_model_sort_parent_class)->finalize (object); -} - -static void -gtd_list_model_sort_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtdListModelSort *self = GTD_LIST_MODEL_SORT (object); - - switch (prop_id) - { - case PROP_CHILD_MODEL: - g_value_set_object (value, gtd_list_model_sort_get_child_model (self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -gtd_list_model_sort_class_init (GtdListModelSortClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gtd_list_model_sort_finalize; - object_class->get_property = gtd_list_model_sort_get_property; - - properties [PROP_CHILD_MODEL] = g_param_spec_object ("child-model", - "Child Model", - "The child model being sorted.", - G_TYPE_LIST_MODEL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPS, properties); -} - -static void -gtd_list_model_sort_init (GtdListModelSort *self) -{ - self->compare_func = default_compare_func; - self->child_seq = g_sequence_new (gtd_list_model_sort_item_free); - self->sort_seq = g_sequence_new (g_object_unref); - self->last_position = -1; -} - -GtdListModelSort * -gtd_list_model_sort_new (GListModel *child_model) -{ - GtdListModelSort *self; - - g_return_val_if_fail (G_IS_LIST_MODEL (child_model), NULL); - - self = g_object_new (GTD_TYPE_LIST_MODEL_SORT, NULL); - self->child_model = g_object_ref (child_model); - - g_signal_connect_object (child_model, - "items-changed", - G_CALLBACK (child_model_items_changed), - self, - G_CONNECT_SWAPPED); - - child_model_items_changed (self, 0, 0, g_list_model_get_n_items (child_model), child_model); - - return self; -} - -/** - * gtd_list_model_sort_get_child_model: - * @self: A #GtdListModelSort - * - * Gets the child model that is being sorted. - * - * Returns: (transfer none): A #GListModel. - */ -GListModel * -gtd_list_model_sort_get_child_model (GtdListModelSort *self) -{ - g_return_val_if_fail (GTD_IS_LIST_MODEL_SORT (self), NULL); - - return self->child_model; -} - -void -gtd_list_model_sort_invalidate (GtdListModelSort *self) -{ - guint n_items; - - g_return_if_fail (GTD_IS_LIST_MODEL_SORT (self)); - - /* First determine how many items we need to synthesize as a removal */ - n_items = g_sequence_get_length (self->child_seq); - - g_assert (G_IS_LIST_MODEL (self->child_model)); - - invalidate_cache (self); - - g_sequence_sort (self->sort_seq, seq_compare_func, self); - - g_assert ((guint)g_sequence_get_length (self->child_seq) == n_items); - g_assert ((guint)g_sequence_get_length (self->sort_seq) == n_items); - - if (n_items > 0) - emit_items_changed (self, 0, n_items, n_items); -} - -void -gtd_list_model_sort_set_sort_func (GtdListModelSort *self, - GtdListModelCompareFunc compare_func, - gpointer compare_func_data, - GDestroyNotify compare_func_data_destroy) -{ - g_return_if_fail (GTD_IS_LIST_MODEL_SORT (self)); - g_return_if_fail (compare_func || (!compare_func_data && !compare_func_data_destroy)); - - GTD_ENTRY; - - if (self->compare_func_data_destroy != NULL) - g_clear_pointer (&self->compare_func_data, self->compare_func_data_destroy); - - if (compare_func != NULL) - { - self->compare_func = compare_func; - self->compare_func_data = compare_func_data; - self->compare_func_data_destroy = compare_func_data_destroy; - } - else - { - self->compare_func = default_compare_func; - self->compare_func_data = NULL; - self->compare_func_data_destroy = NULL; - } - - gtd_list_model_sort_invalidate (self); - - GTD_EXIT; -} diff --git a/src/models/gtd-list-model-sort.h b/src/models/gtd-list-model-sort.h deleted file mode 100644 index c95db29c..00000000 --- a/src/models/gtd-list-model-sort.h +++ /dev/null @@ -1,46 +0,0 @@ -/* gtd-list-model-sort.h - * - * Copyright 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#pragma once - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define GTD_TYPE_LIST_MODEL_SORT (gtd_list_model_sort_get_type()) - -typedef gboolean (*GtdListModelCompareFunc) (GObject *a, - GObject *b, - gpointer user_data); - -G_DECLARE_FINAL_TYPE (GtdListModelSort, gtd_list_model_sort, GTD, LIST_MODEL_SORT, GObject) - -GtdListModelSort* gtd_list_model_sort_new (GListModel *child_model); - -GListModel* gtd_list_model_sort_get_child_model (GtdListModelSort *self); - -void gtd_list_model_sort_invalidate (GtdListModelSort *self); - -void gtd_list_model_sort_set_sort_func (GtdListModelSort *self, - GtdListModelCompareFunc compare_func, - gpointer compare_func_data, - GDestroyNotify compare_func_data_destroy); - -G_END_DECLS |