summaryrefslogtreecommitdiff
path: root/src/trg-sortable-filtered-model.c
blob: 198a72360fe1d8414a505e8b935bebfb809a1621 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * transmission-remote-gtk - Transmission RPC client for GTK
 * Copyright (C) 2011  Alan Fitton

 * 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 2 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <gtk/gtk.h>

#include "trg-sortable-filtered-model.h"

/* This class extends GtkTreeModelFilter, so it can implement the
 * GtkTreeSortable interface. All of the sortable functions are passed on to
 * a child GtkTreeModelSort. Also proxy the sort-column-changed signal
 * so that a TreeViewColumn can track changes for indicators.
 */

static void
trg_sortable_filtered_model_tree_sortable_init(GtkTreeSortableIface *iface);

/* TreeSortable interface */
static GtkTreeSortable *trg_sortable_filtered_model_get_real_sortable(GtkTreeSortable *sortable);
static gboolean trg_sortable_filtered_model_sort_get_sort_column_id(
        GtkTreeSortable *sortable, gint *sort_column_id, GtkSortType *order);
static void trg_sortable_filtered_model_sort_set_sort_column_id(
        GtkTreeSortable *sortable, gint sort_column_id, GtkSortType order);
static void trg_sortable_filtered_model_sort_set_sort_func(
        GtkTreeSortable *sortable, gint sort_column_id,
        GtkTreeIterCompareFunc func, gpointer data, GDestroyNotify destroy);
static void trg_sortable_filtered_model_sort_set_default_sort_func(
        GtkTreeSortable *sortable, GtkTreeIterCompareFunc func, gpointer data,
        GDestroyNotify destroy);
static gboolean trg_sortable_filtered_model_sort_has_default_sort_func(
        GtkTreeSortable *sortable);
static void trg_sortable_filtered_model_sort_column_changed(GtkTreeSortable *realSortable,
        GtkTreeSortable *fakeSortable);

G_DEFINE_TYPE_WITH_CODE(
        TrgSortableFilteredModel,
        trg_sortable_filtered_model,
        GTK_TYPE_TREE_MODEL_FILTER,
        G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE, trg_sortable_filtered_model_tree_sortable_init))

static void trg_sortable_filtered_model_class_init(
        TrgSortableFilteredModelClass *klass) {
}

static void trg_sortable_filtered_model_init(TrgSortableFilteredModel *self) {
}

static void trg_sortable_filtered_model_tree_sortable_init(
        GtkTreeSortableIface *iface) {
    iface->get_sort_column_id =
            trg_sortable_filtered_model_sort_get_sort_column_id;
    iface->set_sort_column_id =
            trg_sortable_filtered_model_sort_set_sort_column_id;
    iface->set_sort_func = trg_sortable_filtered_model_sort_set_sort_func;
    iface->set_default_sort_func =
            trg_sortable_filtered_model_sort_set_default_sort_func;
    iface->has_default_sort_func =
            trg_sortable_filtered_model_sort_has_default_sort_func;
}

static void trg_sortable_filtered_model_sort_column_changed(GtkTreeSortable *realSortable G_GNUC_UNUSED,
        GtkTreeSortable *fakeSortable)
{
    g_signal_emit_by_name (fakeSortable, "sort-column-changed");
}

GtkTreeModel *
trg_sortable_filtered_model_new (GtkTreeSortable *child_model,
                           GtkTreePath  *root)
{
  g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
  g_return_val_if_fail (GTK_IS_TREE_SORTABLE (child_model), NULL);

  GObject *obj = g_object_new (TRG_TYPE_SORTABLE_FILTERED_MODEL,
                         "child-model", GTK_TREE_MODEL(child_model),
                         "virtual-root", root,
                         NULL);

  g_signal_connect (child_model, "sort-column-changed",
                    G_CALLBACK (trg_sortable_filtered_model_sort_column_changed),
                    obj);

  return GTK_TREE_MODEL(obj);
}

static GtkTreeSortable *trg_sortable_filtered_model_get_real_sortable(GtkTreeSortable *sortable)
{
    return GTK_TREE_SORTABLE(gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(sortable)));
}

static gboolean trg_sortable_filtered_model_sort_get_sort_column_id(
        GtkTreeSortable *sortable, gint *sort_column_id, GtkSortType *order) {
    GtkTreeSortable *realSortable = trg_sortable_filtered_model_get_real_sortable(sortable);
    return gtk_tree_sortable_get_sort_column_id(realSortable, sort_column_id, order);
}

static void trg_sortable_filtered_model_sort_set_sort_column_id(
        GtkTreeSortable *sortable, gint sort_column_id, GtkSortType order)
{
    GtkTreeSortable *realSortable = trg_sortable_filtered_model_get_real_sortable(sortable);
    gtk_tree_sortable_set_sort_column_id(realSortable, sort_column_id, order);
}

static void trg_sortable_filtered_model_sort_set_sort_func(
        GtkTreeSortable *sortable, gint sort_column_id,
        GtkTreeIterCompareFunc func, gpointer data, GDestroyNotify destroy)
{
    GtkTreeSortable *realSortable = trg_sortable_filtered_model_get_real_sortable(sortable);
    gtk_tree_sortable_set_sort_func(realSortable, sort_column_id, func, data, destroy);
}

static void trg_sortable_filtered_model_sort_set_default_sort_func(
        GtkTreeSortable *sortable, GtkTreeIterCompareFunc func, gpointer data,
        GDestroyNotify destroy)
{
    GtkTreeSortable *realSortable = trg_sortable_filtered_model_get_real_sortable(sortable);
    gtk_tree_sortable_set_default_sort_func(realSortable, func, data, destroy);
}

static gboolean trg_sortable_filtered_model_sort_has_default_sort_func(
        GtkTreeSortable *sortable)
{
    GtkTreeSortable *realSortable = trg_sortable_filtered_model_get_real_sortable(sortable);
    return gtk_tree_sortable_has_default_sort_func(realSortable);
}