gtktreemodelsort.c 34.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* gtktreemodelsort.c
 * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

20 21

/* NOTE: There is a potential for confusion in this code as to whether an iter,
22 23
 * path or value refers to the GtkTreeModelSort model, or the child model being
 * sorted.  As a convention, variables referencing the child model will have an
24 25 26
 * s_ prefix before them (ie. s_iter, s_value, s_path);
 */

27
#include "gtktreemodelsort.h"
28
#include "gtktreesortable.h"
29
#include "gtksignal.h"
30
#include "gtktreedatalist.h"
31
#include <string.h>
32

33 34


35 36 37 38 39 40 41 42 43 44
typedef struct _SortElt SortElt;
struct _SortElt
{
  GtkTreeIter iter;
  SortElt *parent;
  GArray *children;
  gint ref;
  gint offset;
};

Jonathan Blandford's avatar
Jonathan Blandford committed
45 46 47 48 49 50 51 52
typedef struct _SortData SortData;
struct _SortData
{
  GtkTreeModel *model;
  gint sort_col;
  GValueCompareFunc func;
};

53 54 55

#define get_array(e,t) ((GArray *)((e)->parent?(e)->parent->children:GTK_TREE_MODEL_SORT(t)->root))

Jonathan Blandford's avatar
Jonathan Blandford committed
56

57 58 59
static void         gtk_tree_model_sort_init            (GtkTreeModelSort      *tree_model_sort);
static void         gtk_tree_model_sort_class_init      (GtkTreeModelSortClass *tree_model_sort_class);
static void         gtk_tree_model_sort_tree_model_init (GtkTreeModelIface     *iface);
60
static void         gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface   *iface);
61
static void         gtk_tree_model_sort_finalize        (GObject               *object);
62 63 64 65 66
static void         gtk_tree_model_sort_range_changed   (GtkTreeModel          *model,
							 GtkTreePath           *start_path,
							 GtkTreeIter           *start_iter,
							 GtkTreePath           *end_path,
							 GtkTreeIter           *end_iter,
67 68 69 70 71
							 gpointer               data);
static void         gtk_tree_model_sort_inserted        (GtkTreeModel          *model,
							 GtkTreePath           *path,
							 GtkTreeIter           *iter,
							 gpointer               data);
72 73 74 75
static void         gtk_tree_model_sort_has_child_toggled   (GtkTreeModel          *model,
							     GtkTreePath           *path,
							     GtkTreeIter           *iter,
							     gpointer               data);
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
static void         gtk_tree_model_sort_deleted         (GtkTreeModel          *model,
							 GtkTreePath           *path,
							 gpointer               data);
static gint         gtk_tree_model_sort_get_n_columns   (GtkTreeModel          *tree_model);
static GType        gtk_tree_model_sort_get_column_type (GtkTreeModel          *tree_model,
							 gint                   index);
static gboolean     gtk_tree_model_sort_get_iter        (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter,
							 GtkTreePath           *path);
static GtkTreePath *gtk_tree_model_sort_get_path        (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter);
static void         gtk_tree_model_sort_get_value       (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter,
							 gint                   column,
							 GValue                *value);
static gboolean     gtk_tree_model_sort_iter_next       (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter);
static gboolean     gtk_tree_model_sort_iter_children   (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter,
							 GtkTreeIter           *parent);
static gboolean     gtk_tree_model_sort_iter_has_child  (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter);
static gint         gtk_tree_model_sort_iter_n_children (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter);
static gboolean     gtk_tree_model_sort_iter_nth_child  (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter,
							 GtkTreeIter           *parent,
							 gint                   n);
static gboolean     gtk_tree_model_sort_iter_parent     (GtkTreeModel          *tree_model,
							 GtkTreeIter           *iter,
							 GtkTreeIter           *child);
107
static void         gtk_tree_model_sort_ref_node        (GtkTreeModel          *tree_model,
108
							 GtkTreeIter           *iter);
109
static void         gtk_tree_model_sort_unref_node      (GtkTreeModel          *tree_model,
110 111
							 GtkTreeIter           *iter);

112 113 114 115 116 117 118 119 120 121 122 123 124
/* sortable */
static gboolean gtk_tree_model_sort_get_sort_column_id      (GtkTreeSortable        *sortable,
							     gint                   *sort_column_id,
							     GtkTreeSortOrder       *order);
static void     gtk_tree_model_sort_set_sort_column_id      (GtkTreeSortable        *sortable,
							     gint                    sort_column_id,
							     GtkTreeSortOrder        order);
static void     gtk_tree_model_sort_sort_column_id_set_func (GtkTreeSortable        *sortable,
							     gint                    sort_column_id,
							     GtkTreeIterCompareFunc  func,
							     gpointer                data,
							     GtkDestroyNotify        destroy);

125
/* Internal functions */
Jonathan Blandford's avatar
Jonathan Blandford committed
126 127 128 129
static gint         gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort,
							   GArray           *array,
							   GtkTreeIter      *iter,
							   gboolean          skip_sort_elt);
Jonathan Blandford's avatar
Jonathan Blandford committed
130 131 132 133 134 135 136
static GtkTreePath *gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort,
							   GtkTreePath      *child_path,
							   gboolean          build_children);
static void         gtk_tree_model_sort_build_level       (GtkTreeModelSort *tree_model_sort,
							   SortElt          *place);
static void         gtk_tree_model_sort_free_level        (GArray           *array);

137 138


139
GType
140 141
gtk_tree_model_sort_get_type (void)
{
142
  static GType tree_model_sort_type = 0;
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165

  if (!tree_model_sort_type)
    {
      static const GTypeInfo tree_model_sort_info =
      {
        sizeof (GtkTreeModelSortClass),
	NULL,		/* base_init */
	NULL,		/* base_finalize */
        (GClassInitFunc) gtk_tree_model_sort_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
        sizeof (GtkTreeModelSort),
	0,              /* n_preallocs */
        (GInstanceInitFunc) gtk_tree_model_sort_init
      };

      static const GInterfaceInfo tree_model_info =
      {
	(GInterfaceInitFunc) gtk_tree_model_sort_tree_model_init,
	NULL,
	NULL
      };

166 167 168 169 170 171 172
      static const GInterfaceInfo sortable_info =
      {
	(GInterfaceInitFunc) gtk_tree_model_sort_tree_sortable_init,
	NULL,
	NULL
      };

173
      tree_model_sort_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeModelSort", &tree_model_sort_info, 0);
174 175 176
      g_type_add_interface_static (tree_model_sort_type,
				   GTK_TYPE_TREE_MODEL,
				   &tree_model_info);
177 178 179 180

      g_type_add_interface_static (tree_model_sort_type,
				   GTK_TYPE_TREE_SORTABLE,
				   &sortable_info);
181 182 183 184 185 186 187 188 189 190 191 192
    }

  return tree_model_sort_type;
}

static void
gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class)
{
  GObjectClass *object_class;

  object_class = (GObjectClass *) tree_model_sort_class;

193
  object_class->finalize = gtk_tree_model_sort_finalize;
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
}

static void
gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
{
  iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
  iface->get_column_type = gtk_tree_model_sort_get_column_type;
  iface->get_iter = gtk_tree_model_sort_get_iter;
  iface->get_path = gtk_tree_model_sort_get_path;
  iface->get_value = gtk_tree_model_sort_get_value;
  iface->iter_next = gtk_tree_model_sort_iter_next;
  iface->iter_children = gtk_tree_model_sort_iter_children;
  iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
  iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
  iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
  iface->iter_parent = gtk_tree_model_sort_iter_parent;
210 211
  iface->ref_node = gtk_tree_model_sort_ref_node;
  iface->unref_node = gtk_tree_model_sort_unref_node;
212 213
}

214 215 216 217 218 219 220 221
static void
gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
{
  iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
  iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
  iface->sort_column_id_set_func = gtk_tree_model_sort_sort_column_id_set_func;
}

222 223 224
static void
gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
{
225
  tree_model_sort->sort_column_id = -1;
226 227 228 229 230 231
  tree_model_sort->stamp = g_random_int ();
}

GtkTreeModel *
gtk_tree_model_sort_new (void)
{
232
  return GTK_TREE_MODEL (g_object_new (gtk_tree_model_sort_get_type (), NULL));
233 234 235
}

GtkTreeModel *
236
gtk_tree_model_sort_new_with_model (GtkTreeModel      *child_model)
237 238 239 240
{
  GtkTreeModel *retval;

  retval = gtk_tree_model_sort_new ();
241
  gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
242 243 244 245 246 247 248

  return retval;
}

/**
 * gtk_tree_model_sort_set_model:
 * @tree_model_sort: The #GtkTreeModelSort.
249
 * @child_model: A #GtkTreeModel, or NULL.
250 251 252 253 254 255
 * 
 * Sets the model of @tree_model_sort to be @model.  If @model is NULL, then the
 * old model is unset.
 **/
void
gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
256
			       GtkTreeModel     *child_model)
257 258 259 260
{
  g_return_if_fail (tree_model_sort != NULL);
  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));

261 262
  if (child_model)
    g_object_ref (G_OBJECT (child_model));
263

264
  if (tree_model_sort->child_model)
265
    {
266 267 268 269 270
      g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
				   tree_model_sort->changed_id);
      g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
				   tree_model_sort->inserted_id);
      g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
271
				   tree_model_sort->has_child_toggled_id);
272 273
      g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
				   tree_model_sort->deleted_id);
274

275
      g_object_unref (G_OBJECT (tree_model_sort->child_model));
276 277
    }

278 279 280 281 282 283 284 285 286 287 288
  if (tree_model_sort->root)
    {
      gtk_tree_model_sort_free_level (tree_model_sort->root);
      tree_model_sort->root;
    }

  if (tree_model_sort->sort_list)
    {
      _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
      tree_model_sort->sort_list = NULL;
    }
289

290
  tree_model_sort->child_model = child_model;
291
  if (child_model)
292
    {
293 294 295
      GType *types;
      gint i, n_columns;

296
      tree_model_sort->changed_id =
297
	g_signal_connectc (child_model,
298
			   "range_changed",
299
			   G_CALLBACK (gtk_tree_model_sort_range_changed),
300 301
			   tree_model_sort,
			   FALSE);
302
      tree_model_sort->inserted_id = 
303
	g_signal_connectc (child_model,
304 305
			   "inserted",
			   G_CALLBACK (gtk_tree_model_sort_inserted),
306 307
			   tree_model_sort,
			   FALSE);
308
      tree_model_sort->has_child_toggled_id = 
309 310
	g_signal_connectc (child_model,
			   "has_child_toggled",
311
			   G_CALLBACK (gtk_tree_model_sort_has_child_toggled),
312 313
			   tree_model_sort,
			   FALSE);
314
      tree_model_sort->deleted_id =
315 316
	g_signal_connectc (child_model,
			   "deleted",
317
			   G_CALLBACK (gtk_tree_model_sort_deleted),
318 319
			   tree_model_sort,
			   FALSE);
320

321
      tree_model_sort->flags = gtk_tree_model_get_flags (child_model);
322 323 324 325 326 327
      n_columns = gtk_tree_model_get_n_columns (child_model);
      types = g_new (GType, n_columns);
      for (i = 0; i < n_columns; i++)
	types[i] = gtk_tree_model_get_column_type (child_model, i);
      tree_model_sort->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
      g_free (types);
328 329 330
    }
}

331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
/**
 * gtk_tree_model_sort_get_model:
 * @tree_model: a #GtkTreeModelSort
 * 
 * Returns the model the #GtkTreeModelSort is sorting.
 * 
 * Return value: the "child model" being sorted
 **/
GtkTreeModel*
gtk_tree_model_sort_get_model (GtkTreeModelSort  *tree_model)
{
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);

  return tree_model->child_model;
}

347 348 349
/**
 * gtk_tree_model_sort_convert_path:
 * @tree_model_sort: The #GtkTreeModelSort.
Owen Taylor's avatar
Owen Taylor committed
350
 * @child_path: A #GtkTreePath, relative to the child model.
351
 * 
Owen Taylor's avatar
Owen Taylor committed
352 353
 * Converts the @child_path to a new path, relative to the sorted position.  In other
 * words, the value found in the @tree_model_sort ->child_model at the @child_path, is
354 355
 * identical to that found in the @tree_model_sort and the return value.
 * 
Owen Taylor's avatar
Owen Taylor committed
356
 * Return value: A new path, or NULL if @child_path does not exist in @tree_model_sort
357
 * ->child_model.
358 359 360
 **/
GtkTreePath *
gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
361
				  GtkTreePath      *child_path)
362
{
Jonathan Blandford's avatar
Jonathan Blandford committed
363 364 365
  g_return_val_if_fail (tree_model_sort != NULL, NULL);
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
  g_return_val_if_fail (child_path != NULL, NULL);
366

Jonathan Blandford's avatar
Jonathan Blandford committed
367
  return gtk_tree_model_sort_convert_path_real (tree_model_sort, child_path, TRUE);
368 369 370 371 372 373 374 375 376 377
}

static void
gtk_tree_model_sort_finalize (GObject *object)
{
  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;

  if (tree_model_sort->root)
    gtk_tree_model_sort_free_level (tree_model_sort->root);

378 379 380 381 382
  if (tree_model_sort->child_model)
    {
      g_object_unref (G_OBJECT (tree_model_sort->child_model));
      tree_model_sort->child_model = NULL;
    }
383 384 385 386 387
  if (tree_model_sort->sort_list)
    {
      _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
      tree_model_sort->sort_list = NULL;
    }
388 389 390
}

static void
391 392 393 394 395 396
gtk_tree_model_sort_range_changed (GtkTreeModel *s_model,
				   GtkTreePath  *s_start_path,
				   GtkTreeIter  *s_start_iter,
				   GtkTreePath  *s_end_path,
				   GtkTreeIter  *s_end_iter,
				   gpointer      data)
397 398
{
  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
399 400
  GtkTreePath *path;
  GtkTreeIter iter;
Jonathan Blandford's avatar
Jonathan Blandford committed
401 402
  SortElt *elt;
  GArray *array;
403
  gboolean free_s_path = FALSE;
Jonathan Blandford's avatar
Jonathan Blandford committed
404
  gint index;
405

406
  g_return_if_fail (s_start_path != NULL || s_start_iter != NULL);
407

408
  if (s_start_path == NULL)
409 410
    {
      free_s_path = TRUE;
411
      s_start_path = gtk_tree_model_get_path (s_model, s_start_iter);
412
    }
413

414
  path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_start_path, FALSE);
Jonathan Blandford's avatar
Jonathan Blandford committed
415 416 417
  if (path == NULL)
    {
      if (free_s_path)
418
	gtk_tree_path_free (s_start_path);
Jonathan Blandford's avatar
Jonathan Blandford committed
419 420
      return;
    }
Jonathan Blandford's avatar
Jonathan Blandford committed
421

422
  gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
Havoc Pennington's avatar
Havoc Pennington committed
423
  elt = (SortElt *) iter.user_data;
Jonathan Blandford's avatar
Jonathan Blandford committed
424 425 426 427 428 429 430 431 432 433 434 435
  array = get_array (elt, tree_model_sort);

  /* FIXME: as an optimization for when the column other then the one we're
   * sorting is changed, we can check the prev and next element to see if
   * they're different.
   */
  
  /* Now we need to resort things. */
  index = gtk_tree_model_sort_array_find_insert (tree_model_sort,
						 array,
						 (GtkTreeIter *) elt,
						 TRUE);
436

437
  gtk_tree_model_range_changed (GTK_TREE_MODEL (data), path, &iter, path, &iter);
438

439 440
  gtk_tree_path_free (path);
  if (free_s_path)
441
    gtk_tree_path_free (s_start_path);
442 443
}

Jonathan Blandford's avatar
Jonathan Blandford committed
444 445
/* FALSE if the value was inserted, TRUE otherwise */
static gboolean
446
gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
447 448
				  GtkTreePath      *s_path,
				  GtkTreeIter      *s_iter)
449
{
450
  GtkTreePath *tmp_path;
451
  GArray *array;
Jonathan Blandford's avatar
Jonathan Blandford committed
452
  gint index;
453
  GtkTreeIter iter;
454
  SortElt elt;
455
  gint offset;
456
  gint j;
Jonathan Blandford's avatar
Jonathan Blandford committed
457
  SortElt *tmp_elt;
458 459
  offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];

460 461 462
  elt.iter = *s_iter;
  elt.ref = 0;
  elt.children = NULL;
463
  elt.offset = offset;
Jonathan Blandford's avatar
Jonathan Blandford committed
464

465
  tmp_path = gtk_tree_path_copy (s_path);
Jonathan Blandford's avatar
Jonathan Blandford committed
466

467 468 469 470
  if (gtk_tree_path_up (tmp_path))
    {
      GtkTreePath *parent_path;

Jonathan Blandford's avatar
Jonathan Blandford committed
471 472 473 474 475 476
      parent_path = gtk_tree_model_sort_convert_path_real (sort, tmp_path, FALSE);
      if (parent_path == NULL)
	{
	  gtk_tree_path_free (tmp_path);
	  return FALSE;
	}
477
      gtk_tree_model_get_iter (GTK_TREE_MODEL (sort), &iter, parent_path);
Havoc Pennington's avatar
Havoc Pennington committed
478 479
      elt.parent = ((SortElt *) iter.user_data);
      array = ((SortElt *) iter.user_data)->children;
Jonathan Blandford's avatar
Jonathan Blandford committed
480
      gtk_tree_path_free (parent_path);
481 482
      if (array == NULL)
	{
Jonathan Blandford's avatar
Jonathan Blandford committed
483 484
	  gtk_tree_path_free (tmp_path);
	  return FALSE;
485 486 487 488 489 490 491 492 493 494
	}
    }
  else
    {
      if (sort->root == NULL)
	sort->root = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), 1);
      array = sort->root;
      elt.parent = NULL;
    }
  gtk_tree_path_free (tmp_path);
495

Jonathan Blandford's avatar
Jonathan Blandford committed
496
  index = gtk_tree_model_sort_array_find_insert (sort, array, (GtkTreeIter *) &elt, FALSE);
497

Jonathan Blandford's avatar
Jonathan Blandford committed
498
  g_array_insert_vals (array, index, &elt, 1);
499 500 501 502 503 504

  /* update all the larger offsets */
  tmp_elt = (SortElt *) array->data;
  for (j = 0; j < array->len; j++, tmp_elt++)
	{
	  if ((tmp_elt->offset >= offset) &&
Jonathan Blandford's avatar
Jonathan Blandford committed
505
	      j != index)
506 507
	    tmp_elt->offset ++;
	}
Jonathan Blandford's avatar
Jonathan Blandford committed
508 509

  return TRUE;
510 511 512
}

static void
513 514 515
gtk_tree_model_sort_inserted (GtkTreeModel *s_model,
			      GtkTreePath  *s_path,
			      GtkTreeIter  *s_iter,
516 517 518
			      gpointer      data)
{
  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
519 520
  GtkTreePath *path;
  GtkTreeIter iter;
521

522
  g_return_if_fail (s_path != NULL || s_iter != NULL);
523

524 525 526
  if (s_path == NULL)
    s_path = gtk_tree_model_get_path (s_model, s_iter);

527
  if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST))
528
    {
529
      gtk_tree_model_sort_free_level ((GArray *) tree_model_sort->root);
530 531
      tree_model_sort->root = NULL;
    }
532 533
  else
    {
534
      GtkTreeIter real_s_iter;
535

536 537 538
      if (s_iter == NULL)
	gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
      else
539
	real_s_iter = (* s_iter);
540

Jonathan Blandford's avatar
Jonathan Blandford committed
541 542
      if (!gtk_tree_model_sort_insert_value (tree_model_sort, s_path, &real_s_iter))
	return;
543
    }
544

Jonathan Blandford's avatar
Jonathan Blandford committed
545 546 547
  path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE);
  if (path == NULL)
    return;
548

549
  gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
550
  g_signal_emit_by_name (G_OBJECT (data), "inserted", path, &iter);
551
  gtk_tree_path_free (path);
552 553 554
}

static void
555 556 557 558
gtk_tree_model_sort_has_child_toggled (GtkTreeModel *s_model,
				       GtkTreePath  *s_path,
				       GtkTreeIter  *s_iter,
				       gpointer      data)
559 560
{
  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
561 562 563
  GtkTreePath *path;
  GtkTreeIter iter;
  gboolean free_s_path = FALSE;
564

565
  g_return_if_fail (s_path != NULL || s_iter != NULL);
566

567
  if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST))
568 569 570 571 572
    {
      gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
      tree_model_sort->root = NULL;
    }

573 574 575 576 577
  if (s_path == NULL)
    {
      s_path = gtk_tree_model_get_path (s_model, s_iter);
      free_s_path = TRUE;
    }
578

Jonathan Blandford's avatar
Jonathan Blandford committed
579 580 581
  path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE);
  if (path == NULL)
    return;
582
  gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
583
  g_signal_emit_by_name (G_OBJECT (data),
584
			   "has_child_toggled",
585 586 587 588
			   path, &iter);
  gtk_tree_path_free (path);
  if (free_s_path)
    gtk_tree_path_free (s_path);
589 590 591
}

static void
592 593
gtk_tree_model_sort_deleted (GtkTreeModel *s_model,
			     GtkTreePath  *s_path,
594 595 596
			     gpointer      data)
{
  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
597
  GtkTreePath *path;
598

599 600
  g_return_if_fail (s_path != NULL);
  path = gtk_tree_model_sort_convert_path (tree_model_sort, s_path);
601 602
  g_return_if_fail (path != NULL);

603
  if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST))
604 605 606 607
    {
      gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
      tree_model_sort->root = NULL;
    }
608 609 610 611 612 613 614 615 616
  else
    {
      GArray *array;
      GtkTreeIter iter;
      SortElt *elt;
      gint offset;
      gint i;

      gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort), &iter, path);
Havoc Pennington's avatar
Havoc Pennington committed
617
      elt = (SortElt *) iter.user_data;
618 619 620 621 622 623 624 625 626 627 628 629 630
      offset = elt->offset;
      array = get_array (elt, tree_model_sort);
      if (array->len == 1)
	{
	  if (((SortElt *)array->data)->parent == NULL)
	    tree_model_sort->root = NULL;
	  else
	    (((SortElt *)array->data)->parent)->children = NULL;
	  gtk_tree_model_sort_free_level (array);
	}
      else
	{
	  g_array_remove_index (array, elt - ((SortElt *) array->data));
631

632 633 634 635 636 637 638 639 640 641
	  for (i = 0; i < array->len; i++)
	    {
	      elt = & (g_array_index (array, SortElt, i));
	      if (elt->offset > offset)
		elt->offset--;
	    }
	}
    }

  tree_model_sort->stamp++;
642
  g_signal_emit_by_name (G_OBJECT (data), "deleted", path);
643
  gtk_tree_path_free (path);
644 645 646 647 648
}

static gint
gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
{
649 650
  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;

651
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
652 653 654

  if (tree_model_sort->child_model == 0)
    return 0;
655

656
  return gtk_tree_model_get_n_columns (GTK_TREE_MODEL_SORT (tree_model)->child_model);
657 658 659 660 661 662 663
}

static GType
gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
				     gint          index)
{
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), G_TYPE_INVALID);
664
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, G_TYPE_INVALID);
665

666
  return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->child_model, index);
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
}

static gboolean
gtk_tree_model_sort_get_iter_helper (GtkTreeModelSort *tree_model_sort,
				     GArray       *array,
				     GtkTreeIter  *iter,
				     gint          depth,
				     GtkTreePath  *path)
{
  SortElt *elt;

  if (array == NULL)
    return FALSE;

  if (gtk_tree_path_get_indices (path)[depth] > array->len)
    return FALSE;

  elt = & (g_array_index (array, SortElt, gtk_tree_path_get_indices (path)[depth]));

  if (depth == gtk_tree_path_get_depth (path) - 1)
    {
      iter->stamp = tree_model_sort->stamp;
Havoc Pennington's avatar
Havoc Pennington committed
689
      iter->user_data = elt;
690 691 692 693 694 695 696 697 698 699
      return TRUE;
    }

  if (elt->children != NULL)
    return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
						elt->children,
						iter,
						depth + 1,
						path);

700
  if (gtk_tree_model_iter_has_child (tree_model_sort->child_model,
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717
				     &(elt->iter)))

    gtk_tree_model_sort_build_level (tree_model_sort, elt);

  return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
					      elt->children,
					      iter,
					      depth + 1,
					      path);
}

static gboolean
gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
			      GtkTreeIter  *iter,
			      GtkTreePath  *path)
{
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
718
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
719 720 721 722 723 724 725 726 727 728 729 730 731 732

  if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
    gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);

  return gtk_tree_model_sort_get_iter_helper (GTK_TREE_MODEL_SORT (tree_model),
					      GTK_TREE_MODEL_SORT (tree_model)->root,
					      iter, 0, path);
}

static GtkTreePath *
gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
			      GtkTreeIter  *iter)
{
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
733
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, NULL);
734

735
  return gtk_tree_model_get_path (GTK_TREE_MODEL_SORT (tree_model)->child_model, iter);
736 737 738 739 740 741 742 743 744 745 746
}

static void
gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
			       GtkTreeIter  *iter,
			       gint          column,
			       GValue        *value)
{
  SortElt *elt;

  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
747
  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
748 749
  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);

Havoc Pennington's avatar
Havoc Pennington committed
750
  elt = iter->user_data;
751

752
  gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->child_model, (GtkTreeIter *)elt, column, value);
753 754 755 756 757 758 759 760 761 762
}

static gboolean
gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
			       GtkTreeIter  *iter)
{
  GArray *array;
  SortElt *elt;

  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
763
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
764 765
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);

Havoc Pennington's avatar
Havoc Pennington committed
766
  elt = iter->user_data;
767 768 769 770 771 772 773
  array = get_array (elt, tree_model);

  if (elt - ((SortElt*) array->data) >=  array->len - 1)
    {
      iter->stamp = 0;
      return FALSE;
    }
Havoc Pennington's avatar
Havoc Pennington committed
774
  iter->user_data = elt + 1;
775 776 777 778 779 780 781 782 783 784 785
  return TRUE;
}

static gboolean
gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
				   GtkTreeIter  *iter,
				   GtkTreeIter  *parent)
{
  SortElt *elt;

  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
786
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
Jonathan Blandford's avatar
Jonathan Blandford committed
787

788 789 790 791
  if (parent)
    g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);

  if (parent)
Havoc Pennington's avatar
Havoc Pennington committed
792
    elt = parent->user_data;
793 794 795 796 797 798 799
  else
    elt = (SortElt *) ((GArray *)GTK_TREE_MODEL_SORT (tree_model)->root)->data;

  if (elt == NULL)
    return FALSE;

  if (elt->children == NULL &&
800
      gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->child_model, (GtkTreeIter *)elt))
801 802 803 804 805 806
    gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);

  if (elt->children == NULL)
    return FALSE;

  iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
Havoc Pennington's avatar
Havoc Pennington committed
807
  iter->user_data = elt->children->data;
808 809 810 811 812 813 814 815 816 817 818

  return TRUE;
}

static gboolean
gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
				    GtkTreeIter  *iter)
{
  SortElt *elt;

  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
819
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
820 821
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);

Havoc Pennington's avatar
Havoc Pennington committed
822
  elt = iter->user_data;
823 824 825
  if (elt->children)
    return TRUE;

826
  return gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->child_model, (GtkTreeIter *) elt);
827 828 829 830 831 832 833 834 835
}

static gint
gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
				     GtkTreeIter  *iter)
{
  SortElt *elt;

  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
836
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, 0);
837 838
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);

Havoc Pennington's avatar
Havoc Pennington committed
839
  elt = iter->user_data;
840 841 842
  if (elt->children)
    return elt->children->len;

843
  return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->child_model, (GtkTreeIter *) elt);
844 845 846 847 848 849 850 851 852 853 854 855
}


static gboolean
gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
				    GtkTreeIter  *iter,
				    GtkTreeIter  *parent,
				    gint          n)
{
  SortElt *elt;

  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
856
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
857 858 859
  if (parent)
    g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);

Havoc Pennington's avatar
Havoc Pennington committed
860
  elt = iter->user_data;
861 862 863 864


  if (elt->children == NULL)
    {
865
      if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->child_model, (GtkTreeIter *)elt))
866 867 868 869 870 871 872 873 874 875 876 877
	gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
      else
	return FALSE;
    }

  if (elt->children == NULL)
    return FALSE;

  if (n >= elt->children->len)
    return FALSE;

  iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
Havoc Pennington's avatar
Havoc Pennington committed
878
  iter->user_data = &g_array_index (elt->children, SortElt, n);
879 880 881 882 883 884 885 886 887 888 889 890

  return TRUE;
}

static gboolean
gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
				 GtkTreeIter  *iter,
				 GtkTreeIter  *child)
{
  SortElt *elt;

  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
891
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
892 893
  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);

Havoc Pennington's avatar
Havoc Pennington committed
894
  elt = iter->user_data;
895 896 897
  if (elt->parent)
    {
      iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
Havoc Pennington's avatar
Havoc Pennington committed
898
      iter->user_data = elt->parent;
899 900 901 902 903 904 905

      return TRUE;
    }
  return FALSE;
}

static void
906
gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
907 908 909 910 911
			      GtkTreeIter  *iter)
{
}

static void
912
gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
913 914 915
				GtkTreeIter  *iter)
{

916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
 
}

static gboolean
gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable  *sortable,
					gint             *sort_column_id,
					GtkTreeSortOrder *order)
{
  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;

  g_return_val_if_fail (sortable != NULL, FALSE);
  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);

  if (tree_model_sort->sort_column_id == -1)
    return FALSE;

  if (sort_column_id)
    *sort_column_id = tree_model_sort->sort_column_id;
  if (order)
    *order = tree_model_sort->order;

  return TRUE;
}

static void
gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable  *sortable,
					gint              sort_column_id,
					GtkTreeSortOrder  order)
{
  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
  GList *list;

  g_return_if_fail (sortable != NULL);
  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));

  for (list = tree_model_sort->sort_list; list; list = list->next)
    {
      GtkTreeDataSortHeader *header = (GtkTreeDataSortHeader*) list->data;
      if (header->sort_column_id == sort_column_id)
	break;
    }
  g_return_if_fail (list != NULL);

  if ((tree_model_sort->sort_column_id == sort_column_id) &&
      (tree_model_sort->order == order))
    return;

  tree_model_sort->sort_column_id = sort_column_id;
  tree_model_sort->order = order;

  /*  if (tree_model_sort->sort_column_id >= 0)
      gtk_list_store_sort (tree_model_sort);*/

  gtk_tree_sortable_sort_column_changed (sortable);

}

static void
gtk_tree_model_sort_sort_column_id_set_func (GtkTreeSortable        *sortable,
					     gint                    sort_column_id,
					     GtkTreeIterCompareFunc  func,
					     gpointer                data,
					     GtkDestroyNotify        destroy)
{
  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
  GtkTreeDataSortHeader *header = NULL;
  GList *list;

  g_return_if_fail (sortable != NULL);
  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
  g_return_if_fail (func != NULL);

  for (list = tree_model_sort->sort_list; list; list = list->next)
    {
      header = (GtkTreeDataSortHeader*) list->data;
      if (header->sort_column_id == sort_column_id)
	break;
    }

  if (header == NULL)
    {
      header = g_new0 (GtkTreeDataSortHeader, 1);
      header->sort_column_id = sort_column_id;
      tree_model_sort->sort_list = g_list_append (tree_model_sort->sort_list, header);
    }

  if (header->destroy)
    (* header->destroy) (header->data);

  header->func = func;
  header->data = data;
  header->destroy = destroy;
1008 1009 1010
}

/* Internal functions */
Jonathan Blandford's avatar
Jonathan Blandford committed
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024

static gint
gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort,
				       GArray           *array,
				       GtkTreeIter      *iter,
				       gboolean          skip_sort_elt)
{
  gint middle;
  gint cmp;
  GValueCompareFunc func;
  GValue value = {0, };
  GValue tmp_value = {0, };
  SortElt *tmp_elt;

1025
  func = NULL; //(GValueCompareFunc) gtk_tree_model_sort_get_func (tree_model_sort);
Jonathan Blandford's avatar
Jonathan Blandford committed
1026 1027 1028

  g_return_val_if_fail (func != NULL, 0);

1029
  gtk_tree_model_get_value (tree_model_sort->child_model, iter, tree_model_sort->sort_column_id, &value);
Jonathan Blandford's avatar
Jonathan Blandford committed
1030 1031 1032 1033 1034 1035 1036 1037 1038

  for (middle = 0; middle < array->len; middle++)
    {
      tmp_elt = &(g_array_index (array, SortElt, middle));
      if (!skip_sort_elt &&
	  (SortElt *) iter == tmp_elt)
	  continue;
      gtk_tree_model_get_value (tree_model_sort->child_model,
				(GtkTreeIter *) tmp_elt,
1039
				tree_model_sort->sort_column_id,
Jonathan Blandford's avatar
Jonathan Blandford committed
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
				&tmp_value);

      cmp = ((func) (&value, &tmp_value));
      g_value_unset (&tmp_value);

      if (cmp >= 0)
	break;
    }
  return middle;
}


Jonathan Blandford's avatar
Jonathan Blandford committed
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
static GtkTreePath *
gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort,
				       GtkTreePath      *child_path,
				       gboolean          build_children)
{
  GtkTreePath *retval;
  GArray *array;
  gint *indices;
  gint i = 0;

  if (tree_model_sort->root == NULL)
    {
      if (build_children)
	gtk_tree_model_sort_build_level (tree_model_sort, NULL);
      else
	return FALSE;
    }

  retval = gtk_tree_path_new ();
  array = (GArray *) tree_model_sort->root;
  indices = gtk_tree_path_get_indices (child_path);

  do
    {
      SortElt *elt;
      gboolean found = FALSE;
      gint j;

      if ((array->len < indices[i]) || (array == NULL))
	{
	  gtk_tree_path_free (retval);
	  return NULL;
	}

      elt = (SortElt *) array->data;
      for (j = 0; j < array->len; j++, elt++)
	{
	  if (elt->offset == indices[i])
	    {
	      found = TRUE;
	      break;
	    }
	}
      if (! found)
	{
	  gtk_tree_path_free (retval);
	  return NULL;
	}

      gtk_tree_path_prepend_index (retval, j);

      i++;

      if (i == gtk_tree_path_get_depth (child_path))
	break;

      if (elt->children == NULL)
	{
	  if (build_children)
	    {
	      gtk_tree_path_prepend_index (retval, j);
	      gtk_tree_model_sort_build_level (tree_model_sort, elt);
	    }
	  else
	    {
	      gtk_tree_path_free (retval);
	      return NULL;
	    }
	}
    }
  while (TRUE);

  return retval;
}
  
1127 1128 1129 1130
static void
gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
				 SortElt          *place)
{
1131
  gint n, i = 0;
1132 1133 1134 1135
  GArray *children;
  GtkTreeIter *parent_iter = NULL;
  GtkTreeIter iter;
  SortElt elt;
Jonathan Blandford's avatar
Jonathan Blandford committed
1136
  SortData sort_data;
1137 1138 1139 1140 1141

  if (place)
    parent_iter = & (place->iter);

      
1142
  n = gtk_tree_model_iter_n_children (tree_model_sort->child_model, parent_iter);
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153

  if (n == 0)
    return;

  children = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), n);

  if (place)
    place->children = children;
  else
    tree_model_sort->root = children;

1154
  gtk_tree_model_iter_children (tree_model_sort->child_model,
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
				&iter,
				parent_iter);

  do
    {
      elt.iter = iter;
      elt.parent = place;
      elt.children = NULL;
      elt.ref = 0;
      elt.offset = i;

      g_array_append_vals (children, &elt, 1);
      i++;
    }
1169
  while (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter));
1170 1171 1172 1173 1174 1175 1176
}

static void
gtk_tree_model_sort_free_level (GArray *array)
{
  gint i;

1177 1178 1179
  if (array == NULL)
    return;

1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
  for (i = 0; i < array->len; i++)
    {
      SortElt *elt;

      elt = &g_array_index (array, SortElt, i);
      if (elt->children)
	gtk_tree_model_sort_free_level (array);
    }

  g_array_free (array, TRUE);
}

Jonathan Blandford's avatar
Jonathan Blandford committed
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
/* DEAD CODE */

#if 0
  /* FIXME: we can, as we are an array, do binary search to find the correct
   * location to insert the element.  However, I'd rather get it working.  The
   * below is quite wrong, but a step in the right direction.
   */
  low = 0;
  high = array->len;
  middle = (low + high)/2;

  /* Insert the value into the array */
  while (low != high)
    {
      gint cmp;
      tmp_elt = &(g_array_index (array, SortElt, middle));
      gtk_tree_model_get_value (sort->child_model,
				(GtkTreeIter *) tmp_elt,
1210
				sort->sort_column_id,
Jonathan Blandford's avatar
Jonathan Blandford committed
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
				&tmp_value);

      cmp = ((func) (&tmp_value, &s_value));
      g_value_unset (&tmp_value);

      if (cmp < 0)
	high = middle;
      else if (cmp > 0)
	low = middle;
      else if (cmp == 0)
	break;
      middle = (low + high)/2;
    }
#endif