forked from AuroraMiddleware/gtk
columnview: Add sorting
This is a somewhat large commit that: - Adds GtkColumnViewSorter This is a special-purpose, private sorter implementation which sorts according to multiple sorters, allowing each individual sorter to be inverted. This will be used with clickable column view headers. - Adds a read-only GtkColumnView::sorter property The GtkColumnView creates a GtkColumnViewSorter at startup that it uses for this property. - Adds a writable GtkColumnViewColumn::sorter property This allows defining per-column sorters. Whenever an application sets a sorter for a column, the header becomes clickable and whenever a header is clicked, that column's sorter is prepended to the list of sorters, unless it is already the first sorter, in which case we invert its order. No column can be in the list more than once.
This commit is contained in:
parent
2c4c07c96d
commit
66500a6882
@ -500,6 +500,7 @@ gtk_column_view_remove_column
|
||||
gtk_column_view_get_columns
|
||||
gtk_column_view_get_model
|
||||
gtk_column_view_set_model
|
||||
gtk_column_view_get_sorter
|
||||
gtk_column_view_get_show_separators
|
||||
gtk_column_view_set_show_separators
|
||||
<SUBSECTION Standard>
|
||||
@ -524,6 +525,8 @@ gtk_column_view_column_set_factory
|
||||
gtk_column_view_column_get_factory
|
||||
gtk_column_view_column_set_title
|
||||
gtk_column_view_column_get_title
|
||||
gtk_column_view_column_set_sorter
|
||||
gtk_column_view_column_get_sorter
|
||||
<SUBSECTION Standard>
|
||||
GTK_COLUMN_VIEW_COLUMN
|
||||
GTK_COLUMN_VIEW_COLUMN_CLASS
|
||||
|
@ -29,6 +29,7 @@ private_headers = [
|
||||
'gtkcolumnviewcolumnprivate.h',
|
||||
'gtkcolumnviewlayoutprivate.h',
|
||||
'gtkcolumnviewprivate.h',
|
||||
'gtkcolumnviewsorterprivate.h',
|
||||
'gtkcolumnviewtitleprivate.h',
|
||||
'gtkcomboboxprivate.h',
|
||||
'gtkconstraintexpressionprivate.h',
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "gtkcolumnlistitemfactoryprivate.h"
|
||||
#include "gtkcolumnviewcolumnprivate.h"
|
||||
#include "gtkcolumnviewlayoutprivate.h"
|
||||
#include "gtkcolumnviewsorterprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtklistview.h"
|
||||
@ -42,6 +43,12 @@
|
||||
*
|
||||
* GtkColumnView is a widget to present a view into a large dynamic list of items
|
||||
* using multiple columns.
|
||||
*
|
||||
* It supports sorting that can be customized by the user by clicking on column
|
||||
* view headers. To set this up, the #GtkSorter returned by gtk_column_view_get_sorter()
|
||||
* must be attached to a sort model for the data that the view is showing, and the
|
||||
* columns must have sorters attached to them by calling gtk_column_view_column_set_sorter().
|
||||
* The initial sort order can be set with gtk_column_view_sort_by_column().
|
||||
*/
|
||||
|
||||
struct _GtkColumnView
|
||||
@ -54,6 +61,8 @@ struct _GtkColumnView
|
||||
|
||||
GtkListView *listview;
|
||||
GtkColumnListItemFactory *factory;
|
||||
|
||||
GtkSorter *sorter;
|
||||
};
|
||||
|
||||
struct _GtkColumnViewClass
|
||||
@ -69,6 +78,7 @@ enum
|
||||
PROP_HSCROLL_POLICY,
|
||||
PROP_MODEL,
|
||||
PROP_SHOW_SEPARATORS,
|
||||
PROP_SORTER,
|
||||
PROP_VADJUSTMENT,
|
||||
PROP_VSCROLL_POLICY,
|
||||
|
||||
@ -250,6 +260,8 @@ gtk_column_view_dispose (GObject *object)
|
||||
g_clear_pointer ((GtkWidget **) &self->listview, gtk_widget_unparent);
|
||||
g_clear_object (&self->factory);
|
||||
|
||||
g_clear_object (&self->sorter);
|
||||
|
||||
G_OBJECT_CLASS (gtk_column_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -301,6 +313,10 @@ gtk_column_view_get_property (GObject *object,
|
||||
g_value_set_enum (value, gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (self->listview)));
|
||||
break;
|
||||
|
||||
case PROP_SORTER:
|
||||
g_value_set_object (value, self->sorter);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -429,6 +445,18 @@ gtk_column_view_class_init (GtkColumnViewClass *klass)
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkColumnView:sorter:
|
||||
*
|
||||
* Sorter with the sorting choices of the user
|
||||
*/
|
||||
properties[PROP_SORTER] =
|
||||
g_param_spec_object ("sorter",
|
||||
P_("Sorter"),
|
||||
P_("Sorter with sorting choices of the user"),
|
||||
GTK_TYPE_SORTER,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
|
||||
/**
|
||||
@ -468,6 +496,7 @@ gtk_column_view_init (GtkColumnView *self)
|
||||
gtk_widget_set_layout_manager (self->header, gtk_column_view_layout_new (self));
|
||||
gtk_widget_set_parent (self->header, GTK_WIDGET (self));
|
||||
|
||||
self->sorter = gtk_column_view_sorter_new ();
|
||||
self->factory = gtk_column_list_item_factory_new (self);
|
||||
self->listview = GTK_LIST_VIEW (gtk_list_view_new_with_factory (
|
||||
GTK_LIST_ITEM_FACTORY (g_object_ref (self->factory))));
|
||||
@ -643,6 +672,7 @@ gtk_column_view_remove_column (GtkColumnView *self,
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_column_view_sorter_remove_column (GTK_COLUMN_VIEW_SORTER (self->sorter), column);
|
||||
gtk_column_view_column_set_column_view (column, NULL);
|
||||
g_list_store_remove (self->columns, i);
|
||||
}
|
||||
@ -681,3 +711,28 @@ gtk_column_view_get_header_widget (GtkColumnView *self)
|
||||
return GTK_LIST_ITEM_WIDGET (self->header);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_column_view_get_sorter:
|
||||
* @self: a #GtkColumnView
|
||||
*
|
||||
* Returns the sorter associated with users sorting choices in
|
||||
* the column view.
|
||||
*
|
||||
* To allow users to customizable sorting by clicking on column
|
||||
* headers, this sorter needs to be set on the sort
|
||||
* model(s) underneath the model that is displayed
|
||||
* by the view.
|
||||
*
|
||||
* See gtk_column_view_column_get_sorter() for setting up
|
||||
* per-column sorting.
|
||||
*
|
||||
* Returns: (transfer none): the #GtkSorter of @self
|
||||
*/
|
||||
GtkSorter *
|
||||
gtk_column_view_get_sorter (GtkColumnView *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW (self), NULL);
|
||||
|
||||
return self->sorter;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtksortlistmodel.h>
|
||||
#include <gtk/gtksorter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -65,12 +67,16 @@ GListModel * gtk_column_view_get_model (GtkColumnView
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_column_view_set_model (GtkColumnView *self,
|
||||
GListModel *model);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_column_view_get_show_separators (GtkColumnView *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_column_view_set_show_separators (GtkColumnView *self,
|
||||
gboolean show_separators);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSorter * gtk_column_view_get_sorter (GtkColumnView *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_COLUMN_VIEW_H__ */
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcolumnviewcolumnprivate.h"
|
||||
#include "gtkcolumnviewsorterprivate.h"
|
||||
|
||||
#include "gtkcolumnviewprivate.h"
|
||||
#include "gtkcolumnviewtitleprivate.h"
|
||||
@ -32,6 +33,7 @@
|
||||
#include "gtksizegroup.h"
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtksorter.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkcolumnviewcolumn
|
||||
@ -48,6 +50,7 @@ struct _GtkColumnViewColumn
|
||||
|
||||
GtkListItemFactory *factory;
|
||||
char *title;
|
||||
GtkSorter *sorter;
|
||||
|
||||
/* data for the view */
|
||||
GtkColumnView *view;
|
||||
@ -73,6 +76,7 @@ enum
|
||||
PROP_COLUMN_VIEW,
|
||||
PROP_FACTORY,
|
||||
PROP_TITLE,
|
||||
PROP_SORTER,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@ -90,6 +94,7 @@ gtk_column_view_column_dispose (GObject *object)
|
||||
g_assert (self->first_cell == NULL); /* no view = no children */
|
||||
|
||||
g_clear_object (&self->factory);
|
||||
g_clear_object (&self->sorter);
|
||||
g_clear_pointer (&self->title, g_free);
|
||||
|
||||
G_OBJECT_CLASS (gtk_column_view_column_parent_class)->dispose (object);
|
||||
@ -117,6 +122,10 @@ gtk_column_view_column_get_property (GObject *object,
|
||||
g_value_set_string (value, self->title);
|
||||
break;
|
||||
|
||||
case PROP_SORTER:
|
||||
g_value_set_object (value, self->sorter);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -141,6 +150,10 @@ gtk_column_view_column_set_property (GObject *object,
|
||||
gtk_column_view_column_set_title (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SORTER:
|
||||
gtk_column_view_column_set_sorter (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -192,6 +205,18 @@ gtk_column_view_column_class_init (GtkColumnViewColumnClass *klass)
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkColumnViewColumn:sorter:
|
||||
*
|
||||
* Sorter for sorting items according to this column
|
||||
*/
|
||||
properties[PROP_SORTER] =
|
||||
g_param_spec_object ("sorter",
|
||||
P_("Sorter"),
|
||||
P_("Sorter for sorting items according to this column"),
|
||||
GTK_TYPE_SORTER,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@ -552,3 +577,73 @@ gtk_column_view_column_get_title (GtkColumnViewColumn *self)
|
||||
return self->title;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
gtk_column_view_column_add_to_sorter (GtkColumnViewColumn *self)
|
||||
{
|
||||
if (self->view == NULL)
|
||||
return;
|
||||
|
||||
gtk_column_view_sorter_add_column (GTK_COLUMN_VIEW_SORTER (gtk_column_view_get_sorter (self->view)), self);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_column_view_column_remove_from_sorter (GtkColumnViewColumn *self)
|
||||
{
|
||||
if (self->view == NULL)
|
||||
return;
|
||||
|
||||
gtk_column_view_sorter_remove_column (GTK_COLUMN_VIEW_SORTER (gtk_column_view_get_sorter (self->view)), self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_column_view_column_set_sorter:
|
||||
* @self: a #GtkColumnViewColumn
|
||||
* @sorter: (nullable): the #GtkSorter to associate with @column
|
||||
*
|
||||
* Associates a sorter with the column.
|
||||
*
|
||||
* This sorter can be made active by clicking on the column
|
||||
* header, or by calling gtk_column_view_sort_by_column().
|
||||
*/
|
||||
void
|
||||
gtk_column_view_column_set_sorter (GtkColumnViewColumn *self,
|
||||
GtkSorter *sorter)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self));
|
||||
g_return_if_fail (sorter == NULL || GTK_IS_SORTER (sorter));
|
||||
|
||||
if (!g_set_object (&self->sorter, sorter))
|
||||
return;
|
||||
|
||||
gtk_column_view_column_remove_from_sorter (self);
|
||||
|
||||
if (self->header)
|
||||
gtk_column_view_title_update (GTK_COLUMN_VIEW_TITLE (self->header));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTER]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_column_view_column_get_sorter:
|
||||
* @self: a #GtkColumnViewColumn
|
||||
*
|
||||
* Returns the sorter that is associated with the column.
|
||||
*
|
||||
* Returns: (transfer none): the #GtkSorter of @self
|
||||
*/
|
||||
GtkSorter *
|
||||
gtk_column_view_column_get_sorter (GtkColumnViewColumn *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL);
|
||||
|
||||
return self->sorter;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_column_view_column_notify_sort (GtkColumnViewColumn *self)
|
||||
{
|
||||
if (self->header)
|
||||
gtk_column_view_title_update (GTK_COLUMN_VIEW_TITLE (self->header));
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkcolumnview.h>
|
||||
#include <gtk/gtksorter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -65,6 +66,12 @@ void gtk_column_view_column_set_title (GtkColu
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gtk_column_view_column_get_title (GtkColumnViewColumn *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_column_view_column_set_sorter (GtkColumnViewColumn *self,
|
||||
GtkSorter *sorter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSorter * gtk_column_view_column_get_sorter (GtkColumnViewColumn *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_COLUMN_VIEW_COLUMN_H__ */
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "gtk/gtkcolumnviewcellprivate.h"
|
||||
|
||||
|
||||
void gtk_column_view_column_set_column_view (GtkColumnViewColumn *self,
|
||||
GtkColumnView *view);
|
||||
|
||||
@ -44,4 +45,6 @@ void gtk_column_view_column_get_allocation (GtkColu
|
||||
int *offset,
|
||||
int *size);
|
||||
|
||||
void gtk_column_view_column_notify_sort (GtkColumnViewColumn *self);
|
||||
|
||||
#endif /* __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ */
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "gtk/gtkcolumnview.h"
|
||||
|
||||
#include "gtk/gtkcolumnviewsorterprivate.h"
|
||||
#include "gtk/gtklistitemwidgetprivate.h"
|
||||
|
||||
GtkListItemWidget * gtk_column_view_get_header_widget (GtkColumnView *self);
|
||||
|
282
gtk/gtkcolumnviewsorter.c
Normal file
282
gtk/gtkcolumnviewsorter.c
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright © 2019 Matthias Clasen
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcolumnviewsorterprivate.h"
|
||||
|
||||
#include "gtkcolumnviewcolumnprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkColumnViewColumn *column;
|
||||
GtkSorter *sorter;
|
||||
gboolean inverted;
|
||||
gulong changed_id;
|
||||
} Sorter;
|
||||
|
||||
static void
|
||||
free_sorter (gpointer data)
|
||||
{
|
||||
Sorter *s = data;
|
||||
|
||||
g_signal_handler_disconnect (s->sorter, s->changed_id);
|
||||
g_object_unref (s->sorter);
|
||||
g_object_unref (s->column);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
struct _GtkColumnViewSorter
|
||||
{
|
||||
GtkSorter parent_instance;
|
||||
|
||||
GSequence *sorters;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkColumnViewSorter, gtk_column_view_sorter, GTK_TYPE_SORTER)
|
||||
|
||||
static GtkOrdering
|
||||
gtk_column_view_sorter_compare (GtkSorter *sorter,
|
||||
gpointer item1,
|
||||
gpointer item2)
|
||||
{
|
||||
GtkColumnViewSorter *self = GTK_COLUMN_VIEW_SORTER (sorter);
|
||||
GtkOrdering result = GTK_ORDERING_EQUAL;
|
||||
GSequenceIter *iter;
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->sorters);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
Sorter *s = g_sequence_get (iter);
|
||||
|
||||
result = gtk_sorter_compare (s->sorter, item1, item2);
|
||||
if (s->inverted)
|
||||
result = - result;
|
||||
|
||||
if (result != GTK_ORDERING_EQUAL)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GtkSorterOrder
|
||||
gtk_column_view_sorter_get_order (GtkSorter *sorter)
|
||||
{
|
||||
GtkColumnViewSorter *self = GTK_COLUMN_VIEW_SORTER (sorter);
|
||||
GtkSorterOrder result = GTK_SORTER_ORDER_NONE;
|
||||
GSequenceIter *iter;
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->sorters);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
Sorter *s = g_sequence_get (iter);
|
||||
|
||||
switch (gtk_sorter_get_order (s->sorter))
|
||||
{
|
||||
case GTK_SORTER_ORDER_PARTIAL:
|
||||
result = GTK_SORTER_ORDER_PARTIAL;
|
||||
break;
|
||||
case GTK_SORTER_ORDER_NONE:
|
||||
break;
|
||||
case GTK_SORTER_ORDER_TOTAL:
|
||||
return GTK_SORTER_ORDER_TOTAL;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_sorter_dispose (GObject *object)
|
||||
{
|
||||
GtkColumnViewSorter *self = GTK_COLUMN_VIEW_SORTER (object);
|
||||
|
||||
g_clear_pointer (&self->sorters, g_sequence_free);
|
||||
|
||||
G_OBJECT_CLASS (gtk_column_view_sorter_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_sorter_class_init (GtkColumnViewSorterClass *class)
|
||||
{
|
||||
GtkSorterClass *sorter_class = GTK_SORTER_CLASS (class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
sorter_class->compare = gtk_column_view_sorter_compare;
|
||||
sorter_class->get_order = gtk_column_view_sorter_get_order;
|
||||
|
||||
object_class->dispose = gtk_column_view_sorter_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_sorter_init (GtkColumnViewSorter *self)
|
||||
{
|
||||
self->sorters = g_sequence_new (free_sorter);
|
||||
}
|
||||
|
||||
GtkSorter *
|
||||
gtk_column_view_sorter_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_COLUMN_VIEW_SORTER, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_sorter_changed_cb (GtkSorter *sorter, int change, gpointer data)
|
||||
{
|
||||
gtk_sorter_changed (GTK_SORTER (data), GTK_SORTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remove_column (GtkColumnViewSorter *self,
|
||||
GtkColumnViewColumn *column)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->sorters);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
Sorter *s = g_sequence_get (iter);
|
||||
|
||||
if (s->column == column)
|
||||
{
|
||||
g_sequence_remove (iter);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_column_view_sorter_add_column (GtkColumnViewSorter *self,
|
||||
GtkColumnViewColumn *column)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
GtkSorter *sorter;
|
||||
Sorter *s, *first;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_SORTER (self), FALSE);
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (column), FALSE);
|
||||
|
||||
sorter = gtk_column_view_column_get_sorter (column);
|
||||
if (sorter == NULL)
|
||||
return FALSE;
|
||||
|
||||
iter = g_sequence_get_begin_iter (self->sorters);
|
||||
if (!g_sequence_iter_is_end (iter))
|
||||
{
|
||||
first = g_sequence_get (iter);
|
||||
if (first->column == column)
|
||||
{
|
||||
first->inverted = !first->inverted;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
first = NULL;
|
||||
|
||||
remove_column (self, column);
|
||||
|
||||
s = g_new (Sorter, 1);
|
||||
s->column = g_object_ref (column);
|
||||
s->sorter = g_object_ref (sorter);
|
||||
s->changed_id = g_signal_connect (sorter, "changed", G_CALLBACK (gtk_column_view_sorter_changed_cb), self);
|
||||
s->inverted = FALSE;
|
||||
|
||||
g_sequence_insert_before (iter, s);
|
||||
|
||||
/* notify the previous first column to stop drawing an arrow */
|
||||
if (first)
|
||||
gtk_column_view_column_notify_sort (first->column);
|
||||
|
||||
out:
|
||||
gtk_sorter_changed (GTK_SORTER (self), GTK_SORTER_CHANGE_DIFFERENT);
|
||||
|
||||
gtk_column_view_column_notify_sort (column);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_column_view_sorter_remove_column (GtkColumnViewSorter *self,
|
||||
GtkColumnViewColumn *column)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_SORTER (self), FALSE);
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (column), FALSE);
|
||||
|
||||
if (remove_column (self, column))
|
||||
{
|
||||
gtk_sorter_changed (GTK_SORTER (self), GTK_SORTER_CHANGE_DIFFERENT);
|
||||
gtk_column_view_column_notify_sort (column);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_column_view_sorter_clear (GtkColumnViewSorter *self)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
Sorter *s;
|
||||
GtkColumnViewColumn *column;
|
||||
|
||||
g_return_if_fail (GTK_IS_COLUMN_VIEW_SORTER (self));
|
||||
|
||||
if (g_sequence_is_empty (self->sorters))
|
||||
return;
|
||||
|
||||
iter = g_sequence_get_begin_iter (self->sorters);
|
||||
s = g_sequence_get (iter);
|
||||
column = s->column;
|
||||
g_sequence_remove_range (iter, g_sequence_get_end_iter (self->sorters));
|
||||
|
||||
gtk_sorter_changed (GTK_SORTER (self), GTK_SORTER_CHANGE_DIFFERENT);
|
||||
|
||||
gtk_column_view_column_notify_sort (column);
|
||||
}
|
||||
|
||||
GtkColumnViewColumn *
|
||||
gtk_column_view_sorter_get_sort_column (GtkColumnViewSorter *self,
|
||||
gboolean *inverted)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
Sorter *s;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_SORTER (self), NULL);
|
||||
|
||||
if (g_sequence_is_empty (self->sorters))
|
||||
return NULL;
|
||||
|
||||
iter = g_sequence_get_begin_iter (self->sorters);
|
||||
s = g_sequence_get (iter);
|
||||
|
||||
*inverted = s->inverted;
|
||||
|
||||
return s->column;
|
||||
}
|
53
gtk/gtkcolumnviewsorterprivate.h
Normal file
53
gtk/gtkcolumnviewsorterprivate.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright © 2019 Matthias Clasen
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_COLUMN_VIEW_SORTER_H__
|
||||
#define __GTK_COLUMN_VIEW_SORTER_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtksorter.h>
|
||||
#include <gtk/gtkcolumnviewcolumn.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_COLUMN_VIEW_SORTER (gtk_column_view_sorter_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkColumnViewSorter, gtk_column_view_sorter, GTK, COLUMN_VIEW_SORTER, GtkSorter)
|
||||
|
||||
GtkSorter * gtk_column_view_sorter_new (void);
|
||||
|
||||
gboolean gtk_column_view_sorter_add_column (GtkColumnViewSorter *self,
|
||||
GtkColumnViewColumn *column);
|
||||
gboolean gtk_column_view_sorter_remove_column (GtkColumnViewSorter *self,
|
||||
GtkColumnViewColumn *column);
|
||||
|
||||
void gtk_column_view_sorter_clear (GtkColumnViewSorter *self);
|
||||
|
||||
GtkColumnViewColumn * gtk_column_view_sorter_get_sort_column (GtkColumnViewSorter *self,
|
||||
gboolean *inverted);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SORTER_H__ */
|
||||
|
@ -199,6 +199,7 @@ gtk_public_sources = files([
|
||||
'gtkcolorutils.c',
|
||||
'gtkcolumnview.c',
|
||||
'gtkcolumnviewcolumn.c',
|
||||
'gtkcolumnviewsorter.c',
|
||||
'gtkcombobox.c',
|
||||
'gtkcomboboxtext.c',
|
||||
'gtkcomposetable.c',
|
||||
|
@ -240,7 +240,8 @@ test_type (gconstpointer data)
|
||||
continue;
|
||||
|
||||
if (g_type_is_a (type, GTK_TYPE_COLUMN_VIEW) &&
|
||||
strcmp (pspec->name, "columns") == 0)
|
||||
(strcmp (pspec->name, "columns") == 0 ||
|
||||
strcmp (pspec->name, "sorter") == 0))
|
||||
continue;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
Loading…
Reference in New Issue
Block a user