gint height;
gint flags;
gint order;
+ gint invert_order;
} GtkRBReorder;
static int
return ((GtkRBReorder *) a)->order > ((GtkRBReorder *) b)->order;
}
+static int
+gtk_rbtree_reorder_invert_func (gconstpointer a,
+ gconstpointer b)
+{
+ return ((GtkRBReorder *) a)->invert_order > ((GtkRBReorder *) b)->invert_order;
+}
+
static void
gtk_rbtree_reorder_fixup (GtkRBTree *tree,
GtkRBNode *node)
GtkRBNode *node;
gint i;
- node = tree->root;
- while (node && node->left != tree->nil)
- node = node->left;
/* Sort the trees values in the new tree. */
array = g_array_sized_new (FALSE, FALSE, sizeof (GtkRBReorder), length);
for (i = 0; i < length; i++)
{
- g_assert (node != tree->nil);
- reorder.children = node->children;
- reorder.flags = GTK_RBNODE_NON_COLORS & node->flags;
- reorder.height = GTK_RBNODE_GET_HEIGHT (node);
reorder.order = new_order[i];
+ reorder.invert_order = i;
g_array_append_val (array, reorder);
+ }
+
+ g_array_sort(array, gtk_rbtree_reorder_sort_func);
+
+ /* rewind node*/
+ node = tree->root;
+ while (node && node->left != tree->nil)
+ node = node->left;
+
+ for (i = 0; i < length; i++)
+ {
+ g_assert (node != tree->nil);
+ g_array_index (array, GtkRBReorder, i).children = node->children;
+ g_array_index (array, GtkRBReorder, i).flags = GTK_RBNODE_NON_COLORS & node->flags;
+ g_array_index (array, GtkRBReorder, i).height = GTK_RBNODE_GET_HEIGHT (node);
node = _gtk_rbtree_next (tree, node);
}
- g_array_sort (array, gtk_rbtree_reorder_sort_func);
-
+ g_array_sort (array, gtk_rbtree_reorder_invert_func);
+
/* rewind node*/
node = tree->root;
while (node && node->left != tree->nil)
for (i = 0; i < length; i++)
{
reorder = g_array_index (array, GtkRBReorder, i);
-
node->children = reorder.children;
node->flags = GTK_RBNODE_GET_COLOR (node) | reorder.flags;
/* We temporarily set the height to this. */
node->offset = reorder.height;
node = _gtk_rbtree_next (tree, node);
}
-
gtk_rbtree_reorder_fixup (tree, tree->root);
}
#include "gtkhbox.h"
#include "gtkarrow.h"
#include "gtkintl.h"
-
+#include <string.h>
enum
{
PROP_0,
GValue *value,
GParamSpec *pspec);
static void gtk_tree_view_column_finalize (GObject *object);
+static void gtk_tree_view_column_sort_column_changed (GtkTreeSortable *sortable,
+ GtkTreeViewColumn *column);
+static void update_button_contents (GtkTreeViewColumn *tree_column);
static GtkObjectClass *parent_class = NULL;
tree_column->width = 1;
tree_column->min_width = -1;
tree_column->max_width = -1;
+ tree_column->model_changed_signal = 0;
tree_column->cell = NULL;
tree_column->attributes = NULL;
tree_column->column_type = GTK_TREE_VIEW_COLUMN_AUTOSIZE;
tree_column->dirty = TRUE;
tree_column->sort_order = GTK_TREE_SORT_ASCENDING;
tree_column->show_sort_indicator = FALSE;
- tree_column->sort_signal = 0;
+ tree_column->sort_clicked_signal = 0;
+ tree_column->sort_column_changed_signal = 0;
tree_column->sort_column_id = -1;
}
gtk_widget_show (hbox);
gtk_widget_show (column->alignment);
+ update_button_contents (column);
}
void
column->window = NULL;
}
+static void
+gtk_tree_view_column_model_changed (GtkTreeView *view,
+ guint n_pspecs,
+ GParamSpec **pspecs,
+ GtkTreeViewColumn *column)
+{
+ gint i;
+
+ for (i = 0; i < n_pspecs; i++)
+ {
+ if (! strcmp (pspecs[i]->name, "model") &&
+ (column->sort_clicked_signal))
+ {
+ GtkTreeModel *model;
+ if (column->sort_column_changed_signal)
+ g_signal_handler_disconnect (G_OBJECT (column),
+ column->sort_column_changed_signal);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (column->tree_view));
+ if (model)
+ column->sort_column_changed_signal =
+ g_signal_connectc (G_OBJECT (model), "sort_column_changed",
+ GTK_SIGNAL_FUNC (gtk_tree_view_column_sort_column_changed),
+ column, FALSE);
+ else
+ column->sort_column_changed_signal = 0;
+ }
+ }
+}
+
void
_gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
GtkTreeView *tree_view)
{
column->tree_view = GTK_WIDGET (tree_view);
+ column->model_changed_signal =
+ gtk_signal_connect (GTK_OBJECT (tree_view),
+ "properties_changed",
+ GTK_SIGNAL_FUNC (gtk_tree_view_column_model_changed),
+ column);
+
+ if (column->sort_clicked_signal)
+ {
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (column->tree_view));
+
+ if (GTK_IS_TREE_SORTABLE (model))
+ {
+ gint real_sort_column_id;
+ GtkTreeSortOrder real_order;
+
+ if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
+ &real_sort_column_id,
+ &real_order) &&
+ (real_sort_column_id == column->sort_column_id))
+ {
+ gtk_tree_view_column_set_sort_indicator (column, TRUE);
+ gtk_tree_view_column_set_sort_order (column, real_order);
+ }
+ column->sort_column_changed_signal =
+ g_signal_connectc (G_OBJECT (model), "sort_column_changed",
+ GTK_SIGNAL_FUNC (gtk_tree_view_column_sort_column_changed),
+ column, FALSE);
+
+ }
+ }
}
void
{
gtk_container_remove (GTK_CONTAINER (column->tree_view), column->button);
}
-
+ g_signal_handler_disconnect (G_OBJECT (column->tree_view),
+ column->model_changed_signal);
+ column->model_changed_signal = 0;
column->tree_view = NULL;
column->button = NULL;
}
static void
update_button_contents (GtkTreeViewColumn *tree_column)
{
- if (tree_column->button)
- {
- GtkWidget *hbox = GTK_BIN (tree_column->button)->child;
- GtkWidget *alignment = tree_column->alignment;
- GtkWidget *arrow = tree_column->arrow;
- GtkWidget *current_child = GTK_BIN (alignment)->child;
+ GtkWidget *hbox;
+ GtkWidget *alignment;
+ GtkWidget *arrow;
+ GtkWidget *current_child;
- gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
- 0.5, 0.0, 0.0);
+ if (! tree_column->button)
+ return;
+
+ hbox = GTK_BIN (tree_column->button)->child;
+ alignment = tree_column->alignment;
+ arrow = tree_column->arrow;
+ current_child = GTK_BIN (alignment)->child;
+
+ gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
+ 0.5, 0.0, 0.0);
- if (tree_column->child)
- {
- if (current_child != tree_column->child)
- {
- gtk_container_remove (GTK_CONTAINER (alignment),
- current_child);
-
- gtk_container_add (GTK_CONTAINER (alignment),
- tree_column->child);
- }
- }
- else
- {
- if (current_child == NULL)
- {
- current_child = gtk_label_new (NULL);
+ if (tree_column->child)
+ {
+ if (current_child != tree_column->child)
+ {
+ gtk_container_remove (GTK_CONTAINER (alignment),
+ current_child);
+
+ gtk_container_add (GTK_CONTAINER (alignment),
+ tree_column->child);
+ }
+ }
+ else
+ {
+ if (current_child == NULL)
+ {
+ current_child = gtk_label_new (NULL);
- gtk_widget_show (current_child);
+ gtk_widget_show (current_child);
- gtk_container_add (GTK_CONTAINER (alignment),
- current_child);
- }
-
- g_return_if_fail (GTK_IS_LABEL (current_child));
-
- if (tree_column->title)
- gtk_label_set_text (GTK_LABEL (current_child),
- tree_column->title);
- else
- gtk_label_set_text (GTK_LABEL (current_child),
- "");
- }
+ gtk_container_add (GTK_CONTAINER (alignment),
+ current_child);
+ }
- switch (tree_column->sort_order)
- {
- case GTK_TREE_SORT_ASCENDING:
- gtk_arrow_set (GTK_ARROW (arrow),
- GTK_ARROW_DOWN,
- GTK_SHADOW_IN);
- break;
-
- case GTK_TREE_SORT_DESCENDING:
- gtk_arrow_set (GTK_ARROW (arrow),
- GTK_ARROW_UP,
- GTK_SHADOW_IN);
- break;
+ g_return_if_fail (GTK_IS_LABEL (current_child));
+
+ if (tree_column->title)
+ gtk_label_set_text (GTK_LABEL (current_child),
+ tree_column->title);
+ else
+ gtk_label_set_text (GTK_LABEL (current_child),
+ "");
+ }
+
+ switch (tree_column->sort_order)
+ {
+ case GTK_TREE_SORT_ASCENDING:
+ gtk_arrow_set (GTK_ARROW (arrow),
+ GTK_ARROW_DOWN,
+ GTK_SHADOW_IN);
+ break;
+
+ case GTK_TREE_SORT_DESCENDING:
+ gtk_arrow_set (GTK_ARROW (arrow),
+ GTK_ARROW_UP,
+ GTK_SHADOW_IN);
+ break;
- default:
- g_warning (G_STRLOC": bad sort order");
- break;
- }
+ default:
+ g_warning (G_STRLOC": bad sort order");
+ break;
+ }
- /* Put arrow on the right if the text is left-or-center justified,
+ /* Put arrow on the right if the text is left-or-center justified,
* and on the left otherwise; do this by packing boxes, so flipping
* text direction will reverse things
*/
- gtk_widget_ref (arrow);
- gtk_container_remove (GTK_CONTAINER (hbox), arrow);
+ gtk_widget_ref (arrow);
+ gtk_container_remove (GTK_CONTAINER (hbox), arrow);
- if (tree_column->xalign <= 0.5)
- {
- gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
- }
- else
- {
- gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
- /* move it to the front */
- gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
- }
+ if (tree_column->xalign <= 0.5)
+ {
+ gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+ }
+ else
+ {
+ gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+ /* move it to the front */
+ gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
+ }
- gtk_widget_unref (arrow);
+ gtk_widget_unref (arrow);
- if (tree_column->show_sort_indicator)
- gtk_widget_show (arrow);
- else
- gtk_widget_hide (arrow);
- }
+ if (tree_column->show_sort_indicator)
+ gtk_widget_show (arrow);
+ else
+ gtk_widget_hide (arrow);
}
/**
return tree_column->xalign;
}
+static void
+gtk_tree_view_column_sort_column_changed (GtkTreeSortable *sortable,
+ GtkTreeViewColumn *column)
+{
+ gint sort_column_id;
+ GtkTreeSortOrder order;
+
+ if (gtk_tree_sortable_get_sort_column_id (sortable,
+ &sort_column_id,
+ &order))
+ {
+ if (sort_column_id == column->sort_column_id)
+ {
+ gtk_tree_view_column_set_sort_indicator (column, TRUE);
+ gtk_tree_view_column_set_sort_order (column, order);
+ }
+ else
+ {
+ gtk_tree_view_column_set_sort_indicator (column, FALSE);
+ }
+ }
+}
static void
sort_clicked_func (GtkTreeViewColumn *tree_column,
if (sort_column_id == -1)
{
- if (tree_column->sort_signal)
- g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_signal);
+ if (tree_column->sort_clicked_signal)
+ g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_clicked_signal);
return;
}
- if (! tree_column->sort_signal)
- tree_column->sort_signal = g_signal_connectc (G_OBJECT (tree_column),
+ if (! tree_column->sort_clicked_signal)
+ tree_column->sort_clicked_signal = g_signal_connectc (G_OBJECT (tree_column),
"clicked",
G_CALLBACK (sort_clicked_func),
NULL, FALSE);
tree_column->sort_column_id = sort_column_id;
+
+ if (tree_column->tree_view)
+ {
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
+
+ if (GTK_IS_TREE_SORTABLE (model))
+ {
+ gint real_sort_column_id;
+ GtkTreeSortOrder real_order;
+
+ if (tree_column->sort_column_changed_signal == 0)
+ tree_column->sort_column_changed_signal =
+ g_signal_connectc (G_OBJECT (model), "sort_column_changed",
+ GTK_SIGNAL_FUNC (gtk_tree_view_column_sort_column_changed),
+ tree_column, FALSE);
+
+ if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
+ &real_sort_column_id,
+ &real_order) &&
+ (real_sort_column_id == sort_column_id))
+ {
+ gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
+ gtk_tree_view_column_set_sort_order (tree_column, real_order);
+
+ return;
+ }
+ }
+ }
+
gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
gtk_tree_view_column_set_sort_order (tree_column, GTK_TREE_SORT_ASCENDING);
}
tree_column->show_sort_indicator = setting;
update_button_contents (tree_column);
-
+
g_object_notify (G_OBJECT (tree_column), "sort_indicator");
if (GTK_WIDGET_REALIZED (tree_column->tree_view))
gtk_widget_queue_draw (tree_column->tree_view);
{ "Apples", "Transmorgrify", "Exculpatory", "Gesundheit"},
{ "Oranges", "Wicker", "Adamantine", "Convivial" },
{ "Bovine Spongiform Encephilopathy", "Sleazebucket", "Mountaineer", "Pander" },
- { "Foot and Mouth", "Lampshade", "Skim Milk Full Milk", "Viewless" },
+ { "Foot and Mouth", "Lampshade", "Skim Milk\nFull Milk", "Viewless" },
{ "Blood,\nsweat,\ntears", "The Man", "Horses", "Muckety-Muck" },
{ "Rare Steak", "Siam", "Watchdog", "Xantippe" },
{ "SIGINT", "Rabbit Breath", "Alligator", "Bloodstained" },
enum
{
- WORD_COLUMN = 0,
+ WORD_COLUMN_1 = 0,
WORD_COLUMN_2,
WORD_COLUMN_3,
WORD_COLUMN_4,
{
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- WORD_COLUMN, data[i].word_1,
+ WORD_COLUMN_1, data[i].word_1,
WORD_COLUMN_2, data[i].word_2,
WORD_COLUMN_3, data[i].word_3,
WORD_COLUMN_4, data[i].word_4,
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("First Word", renderer,
- "text", WORD_COLUMN,
+ "text", WORD_COLUMN_1,
NULL);
- gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+ gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN_1);
+
g_object_unref (column);
g_object_unref (renderer);
column = gtk_tree_view_column_new_with_attributes ("Third Word", renderer,
"text", WORD_COLUMN_3,
NULL);
- gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN_3);
+ gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN_1);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
g_object_unref (column);
g_object_unref (renderer);
g_object_unref (renderer);
gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+ gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
gtk_widget_show_all (window);
gtk_main ();