/* * Copyright © 2019 Benjamin Otte * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * * Authors: Benjamin Otte */ #include "config.h" #include "gtkfilter.h" #include "gtkintl.h" #include "gtktypebuiltins.h" /** * GtkFilter: * * A `GtkFilter` object describes the filtering to be performed by a * `GtkFilterListModel`. * * The model will use the filter to determine if it should include items * or not by calling [method@Gtk.Filter.match] for each item and only * keeping the ones that the function returns %TRUE for. * * Filters may change what items they match through their lifetime. In that * case, they will emit the [signal@Gtk.Filter::changed] signal to notify * that previous filter results are no longer valid and that items should * be checked again via [method@Gtk.Filter.match]. * * GTK provides various pre-made filter implementations for common filtering * operations. These filters often include properties that can be linked to * various widgets to easily allow searches. * * However, in particular for large lists or complex search methods, it is * also possible to subclass `GtkFilter` and provide one's own filter. */ enum { CHANGED, LAST_SIGNAL }; G_DEFINE_TYPE (GtkFilter, gtk_filter, G_TYPE_OBJECT) static guint signals[LAST_SIGNAL] = { 0 }; static gboolean gtk_filter_default_match (GtkFilter *self, gpointer item) { g_critical ("Filter of type '%s' does not implement GtkFilter::match", G_OBJECT_TYPE_NAME (self)); return FALSE; } static GtkFilterMatch gtk_filter_default_get_strictness (GtkFilter *self) { return GTK_FILTER_MATCH_SOME; } static void gtk_filter_class_init (GtkFilterClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); class->match = gtk_filter_default_match; class->get_strictness = gtk_filter_default_get_strictness; /** * GtkFilter::changed: * @self: The `GtkFilter` * @change: how the filter changed * * Emitted whenever the filter changed. * * Users of the filter should then check items again via * [method@Gtk.Filter.match]. * * `GtkFilterListModel` handles this signal automatically. * * Depending on the @change parameter, not all items need * to be checked, but only some. Refer to the [enum@Gtk.FilterChange] * documentation for details. */ signals[CHANGED] = g_signal_new (I_("changed"), G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__ENUM, G_TYPE_NONE, 1, GTK_TYPE_FILTER_CHANGE); g_signal_set_va_marshaller (signals[CHANGED], G_TYPE_FROM_CLASS (gobject_class), g_cclosure_marshal_VOID__ENUMv); } static void gtk_filter_init (GtkFilter *self) { } /** * gtk_filter_match: * @self: a `GtkFilter` * @item: (type GObject) (transfer none): The item to check * * Checks if the given @item is matched by the filter or not. * * Returns: %TRUE if the filter matches the item and a filter model should * keep it, %FALSE if not. */ gboolean gtk_filter_match (GtkFilter *self, gpointer item) { g_return_val_if_fail (GTK_IS_FILTER (self), FALSE); g_return_val_if_fail (item != NULL, FALSE); return GTK_FILTER_GET_CLASS (self)->match (self, item); } /** * gtk_filter_get_strictness: * @self: a `GtkFilter` * * Gets the known strictness of @filters. * * If the strictness is not known, %GTK_FILTER_MATCH_SOME is returned. * * This value may change after emission of the [signal@Gtk.Filter::changed] * signal. * * This function is meant purely for optimization purposes, filters can * choose to omit implementing it, but `GtkFilterListModel` uses it. * * Returns: the strictness of @self */ GtkFilterMatch gtk_filter_get_strictness (GtkFilter *self) { g_return_val_if_fail (GTK_IS_FILTER (self), GTK_FILTER_MATCH_SOME); return GTK_FILTER_GET_CLASS (self)->get_strictness (self); } /** * gtk_filter_changed: * @self: a `GtkFilter` * @change: How the filter changed * * Notifies all users of the filter that it has changed. * * This emits the [signal@Gtk.Filter::changed] signal. Users * of the filter should then check items again via * [method@Gtk.Filter.match]. * * Depending on the @change parameter, not all items need to * be changed, but only some. Refer to the [enum@Gtk.FilterChange] * documentation for details. * * This function is intended for implementors of `GtkFilter` * subclasses and should not be called from other functions. */ void gtk_filter_changed (GtkFilter *self, GtkFilterChange change) { g_return_if_fail (GTK_IS_FILTER (self)); g_signal_emit (self, signals[CHANGED], 0, change); }