Blame tests/testtreeview.c

Packit 98cdb6
/* testtreeview.c
Packit 98cdb6
 * Copyright (C) 2001 Red Hat, Inc
Packit 98cdb6
 * Author: Jonathan Blandford
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Library General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Library General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Library General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#undef GTK_DISABLE_DEPRECATED
Packit 98cdb6
#include <string.h>
Packit 98cdb6
#include "prop-editor.h"
Packit 98cdb6
#include <gtk/gtk.h>
Packit 98cdb6
#include <stdlib.h>
Packit 98cdb6
Packit 98cdb6
/* Don't copy this bad example; inline RGB data is always a better
Packit 98cdb6
 * idea than inline XPMs.
Packit 98cdb6
 */
Packit 98cdb6
static char  *book_closed_xpm[] = {
Packit 98cdb6
"16 16 6 1",
Packit 98cdb6
"       c None s None",
Packit 98cdb6
".      c black",
Packit 98cdb6
"X      c red",
Packit 98cdb6
"o      c yellow",
Packit 98cdb6
"O      c #808080",
Packit 98cdb6
"#      c white",
Packit 98cdb6
"                ",
Packit 98cdb6
"       ..       ",
Packit 98cdb6
"     ..XX.      ",
Packit 98cdb6
"   ..XXXXX.     ",
Packit 98cdb6
" ..XXXXXXXX.    ",
Packit 98cdb6
".ooXXXXXXXXX.   ",
Packit 98cdb6
"..ooXXXXXXXXX.  ",
Packit 98cdb6
".X.ooXXXXXXXXX. ",
Packit 98cdb6
".XX.ooXXXXXX..  ",
Packit 98cdb6
" .XX.ooXXX..#O  ",
Packit 98cdb6
"  .XX.oo..##OO. ",
Packit 98cdb6
"   .XX..##OO..  ",
Packit 98cdb6
"    .X.#OO..    ",
Packit 98cdb6
"     ..O..      ",
Packit 98cdb6
"      ..        ",
Packit 98cdb6
"                "
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static void run_automated_tests (void);
Packit 98cdb6
Packit 98cdb6
/* This custom model is to test custom model use. */
Packit 98cdb6
Packit 98cdb6
#define GTK_TYPE_MODEL_TYPES				(gtk_tree_model_types_get_type ())
Packit 98cdb6
#define GTK_TREE_MODEL_TYPES(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypes))
Packit 98cdb6
#define GTK_TREE_MODEL_TYPES_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypesClass))
Packit 98cdb6
#define GTK_IS_TREE_MODEL_TYPES(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MODEL_TYPES))
Packit 98cdb6
#define GTK_IS_TREE_MODEL_TYPES_GET_CLASS(klass)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MODEL_TYPES))
Packit 98cdb6
Packit 98cdb6
typedef struct _GtkTreeModelTypes       GtkTreeModelTypes;
Packit 98cdb6
typedef struct _GtkTreeModelTypesClass  GtkTreeModelTypesClass;
Packit 98cdb6
Packit 98cdb6
struct _GtkTreeModelTypes
Packit 98cdb6
{
Packit 98cdb6
  GObject parent;
Packit 98cdb6
Packit 98cdb6
  gint stamp;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
struct _GtkTreeModelTypesClass
Packit 98cdb6
{
Packit 98cdb6
  GObjectClass parent_class;
Packit 98cdb6
Packit 98cdb6
  guint        (* get_flags)       (GtkTreeModel *tree_model);   
Packit 98cdb6
  gint         (* get_n_columns)   (GtkTreeModel *tree_model);
Packit 98cdb6
  GType        (* get_column_type) (GtkTreeModel *tree_model,
Packit 98cdb6
				    gint          index);
Packit 98cdb6
  gboolean     (* get_iter)        (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter,
Packit 98cdb6
				    GtkTreePath  *path);
Packit 98cdb6
  GtkTreePath *(* get_path)        (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  void         (* get_value)       (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter,
Packit 98cdb6
				    gint          column,
Packit 98cdb6
				    GValue       *value);
Packit 98cdb6
  gboolean     (* iter_next)       (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  gboolean     (* iter_children)   (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter,
Packit 98cdb6
				    GtkTreeIter  *parent);
Packit 98cdb6
  gboolean     (* iter_has_child)  (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  gint         (* iter_n_children) (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  gboolean     (* iter_nth_child)  (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter,
Packit 98cdb6
				    GtkTreeIter  *parent,
Packit 98cdb6
				    gint          n);
Packit 98cdb6
  gboolean     (* iter_parent)     (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter,
Packit 98cdb6
				    GtkTreeIter  *child);
Packit 98cdb6
  void         (* ref_iter)        (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  void         (* unref_iter)      (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
Packit 98cdb6
  /* These will be moved into the GtkTreeModelIface eventually */
Packit 98cdb6
  void         (* changed)         (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreePath  *path,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  void         (* inserted)        (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreePath  *path,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  void         (* child_toggled)   (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreePath  *path,
Packit 98cdb6
				    GtkTreeIter  *iter);
Packit 98cdb6
  void         (* deleted)         (GtkTreeModel *tree_model,
Packit 98cdb6
				    GtkTreePath  *path);
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
GType              gtk_tree_model_types_get_type      (void) G_GNUC_CONST;
Packit 98cdb6
GtkTreeModelTypes *gtk_tree_model_types_new           (void);
Packit 98cdb6
Packit 98cdb6
typedef enum
Packit 98cdb6
{
Packit 98cdb6
  COLUMNS_NONE,
Packit 98cdb6
  COLUMNS_ONE,
Packit 98cdb6
  COLUMNS_LOTS,
Packit 98cdb6
  COLUMNS_LAST
Packit 98cdb6
} ColumnsType;
Packit 98cdb6
Packit 98cdb6
static gchar *column_type_names[] = {
Packit 98cdb6
  "No columns",
Packit 98cdb6
  "One column",
Packit 98cdb6
  "Many columns"
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
#define N_COLUMNS 9
Packit 98cdb6
Packit 98cdb6
static GType*
Packit 98cdb6
get_model_types (void)
Packit 98cdb6
{
Packit 98cdb6
  static GType column_types[N_COLUMNS] = { 0 };
Packit 98cdb6
  
Packit 98cdb6
  if (column_types[0] == 0)
Packit 98cdb6
    {
Packit 98cdb6
      column_types[0] = G_TYPE_STRING;
Packit 98cdb6
      column_types[1] = G_TYPE_STRING;
Packit 98cdb6
      column_types[2] = GDK_TYPE_PIXBUF;
Packit 98cdb6
      column_types[3] = G_TYPE_FLOAT;
Packit 98cdb6
      column_types[4] = G_TYPE_UINT;
Packit 98cdb6
      column_types[5] = G_TYPE_UCHAR;
Packit 98cdb6
      column_types[6] = G_TYPE_CHAR;
Packit 98cdb6
#define BOOL_COLUMN 7
Packit 98cdb6
      column_types[BOOL_COLUMN] = G_TYPE_BOOLEAN;
Packit 98cdb6
      column_types[8] = G_TYPE_INT;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return column_types;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
col_clicked_cb (GtkTreeViewColumn *col, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GtkWindow *win;
Packit 98cdb6
Packit 98cdb6
  win = GTK_WINDOW (create_prop_editor (G_OBJECT (col), GTK_TYPE_TREE_VIEW_COLUMN));
Packit 98cdb6
Packit 98cdb6
  gtk_window_set_title (win, gtk_tree_view_column_get_title (col));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
setup_column (GtkTreeViewColumn *col)
Packit 98cdb6
{
Packit 98cdb6
  gtk_tree_view_column_set_clickable (col, TRUE);
Packit 98cdb6
  g_signal_connect (col,
Packit 98cdb6
		    "clicked",
Packit 98cdb6
		    G_CALLBACK (col_clicked_cb),
Packit 98cdb6
		    NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
toggled_callback (GtkCellRendererToggle *celltoggle,
Packit 98cdb6
                  gchar                 *path_string,
Packit 98cdb6
                  GtkTreeView           *tree_view)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeModel *model = NULL;
Packit 98cdb6
  GtkTreeModelSort *sort_model = NULL;
Packit 98cdb6
  GtkTreePath *path;
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  gboolean active = FALSE;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
Packit 98cdb6
Packit 98cdb6
  model = gtk_tree_view_get_model (tree_view);
Packit 98cdb6
  
Packit 98cdb6
  if (GTK_IS_TREE_MODEL_SORT (model))
Packit 98cdb6
    {
Packit 98cdb6
      sort_model = GTK_TREE_MODEL_SORT (model);
Packit 98cdb6
      model = gtk_tree_model_sort_get_model (sort_model);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (model == NULL)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (sort_model)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("FIXME implement conversion from TreeModelSort iter to child model iter");
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
      
Packit 98cdb6
  path = gtk_tree_path_new_from_string (path_string);
Packit 98cdb6
  if (!gtk_tree_model_get_iter (model,
Packit 98cdb6
                                &iter, path))
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: bad path?", G_STRLOC);
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
  gtk_tree_path_free (path);
Packit 98cdb6
  
Packit 98cdb6
  if (GTK_IS_LIST_STORE (model))
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_model_get (GTK_TREE_MODEL (model),
Packit 98cdb6
                          &iter,
Packit 98cdb6
                          BOOL_COLUMN,
Packit 98cdb6
                          &active,
Packit 98cdb6
                          -1);
Packit 98cdb6
      
Packit 98cdb6
      gtk_list_store_set (GTK_LIST_STORE (model),
Packit 98cdb6
                          &iter,
Packit 98cdb6
                          BOOL_COLUMN,
Packit 98cdb6
                          !active,
Packit 98cdb6
                          -1);
Packit 98cdb6
    }
Packit 98cdb6
  else if (GTK_IS_TREE_STORE (model))
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_model_get (GTK_TREE_MODEL (model),
Packit 98cdb6
                          &iter,
Packit 98cdb6
                          BOOL_COLUMN,
Packit 98cdb6
                          &active,
Packit 98cdb6
                          -1);
Packit 98cdb6
            
Packit 98cdb6
      gtk_tree_store_set (GTK_TREE_STORE (model),
Packit 98cdb6
                          &iter,
Packit 98cdb6
                          BOOL_COLUMN,
Packit 98cdb6
                          !active,
Packit 98cdb6
                          -1);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    g_warning ("don't know how to actually toggle value for model type %s",
Packit 98cdb6
               g_type_name (G_TYPE_FROM_INSTANCE (model)));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
edited_callback (GtkCellRendererText *renderer,
Packit 98cdb6
		 const gchar   *path_string,
Packit 98cdb6
		 const gchar   *new_text,
Packit 98cdb6
		 GtkTreeView  *tree_view)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeModel *model = NULL;
Packit 98cdb6
  GtkTreeModelSort *sort_model = NULL;
Packit 98cdb6
  GtkTreePath *path;
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  guint value = atoi (new_text);
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
Packit 98cdb6
Packit 98cdb6
  model = gtk_tree_view_get_model (tree_view);
Packit 98cdb6
  
Packit 98cdb6
  if (GTK_IS_TREE_MODEL_SORT (model))
Packit 98cdb6
    {
Packit 98cdb6
      sort_model = GTK_TREE_MODEL_SORT (model);
Packit 98cdb6
      model = gtk_tree_model_sort_get_model (sort_model);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (model == NULL)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (sort_model)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("FIXME implement conversion from TreeModelSort iter to child model iter");
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
      
Packit 98cdb6
  path = gtk_tree_path_new_from_string (path_string);
Packit 98cdb6
  if (!gtk_tree_model_get_iter (model,
Packit 98cdb6
                                &iter, path))
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("%s: bad path?", G_STRLOC);
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
  gtk_tree_path_free (path);
Packit 98cdb6
Packit 98cdb6
  if (GTK_IS_LIST_STORE (model))
Packit 98cdb6
    {
Packit 98cdb6
      gtk_list_store_set (GTK_LIST_STORE (model),
Packit 98cdb6
                          &iter,
Packit 98cdb6
                          4,
Packit 98cdb6
                          value,
Packit 98cdb6
                          -1);
Packit 98cdb6
    }
Packit 98cdb6
  else if (GTK_IS_TREE_STORE (model))
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_store_set (GTK_TREE_STORE (model),
Packit 98cdb6
                          &iter,
Packit 98cdb6
                          4,
Packit 98cdb6
                          value,
Packit 98cdb6
                          -1);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    g_warning ("don't know how to actually toggle value for model type %s",
Packit 98cdb6
               g_type_name (G_TYPE_FROM_INSTANCE (model)));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static ColumnsType current_column_type = COLUMNS_LOTS;
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
set_columns_type (GtkTreeView *tree_view, ColumnsType type)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeViewColumn *col;
Packit 98cdb6
  GtkCellRenderer *rend;
Packit 98cdb6
  GdkPixbuf *pixbuf;
Packit 98cdb6
  GtkWidget *image;
Packit 98cdb6
  GtkObject *adjustment;
Packit 98cdb6
    
Packit 98cdb6
  current_column_type = type;
Packit 98cdb6
  
Packit 98cdb6
  col = gtk_tree_view_get_column (tree_view, 0);
Packit 98cdb6
  while (col)
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_view_remove_column (tree_view, col);
Packit 98cdb6
Packit 98cdb6
      col = gtk_tree_view_get_column (tree_view, 0);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  gtk_tree_view_set_rules_hint (tree_view, FALSE);
Packit 98cdb6
  
Packit 98cdb6
  switch (type)
Packit 98cdb6
    {
Packit 98cdb6
    case COLUMNS_NONE:
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    case COLUMNS_LOTS:
Packit 98cdb6
      /* with lots of columns we need to turn on rules */
Packit 98cdb6
      gtk_tree_view_set_rules_hint (tree_view, TRUE);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 1",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 1,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new();
Packit 98cdb6
      gtk_tree_view_column_set_title (col, "Column 2");
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_pixbuf_new ();
Packit 98cdb6
      gtk_tree_view_column_pack_start (col, rend, FALSE);
Packit 98cdb6
      gtk_tree_view_column_add_attribute (col, rend, "pixbuf", 2);
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      gtk_tree_view_column_pack_start (col, rend, TRUE);
Packit 98cdb6
      gtk_tree_view_column_add_attribute (col, rend, "text", 0);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      gtk_tree_view_set_expander_column (tree_view, col);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_toggle_new ();
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (rend, "toggled",
Packit 98cdb6
			G_CALLBACK (toggled_callback), tree_view);
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 3",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "active", BOOL_COLUMN,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
Packit 98cdb6
      pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
Packit 98cdb6
Packit 98cdb6
      image = gtk_image_new_from_pixbuf (pixbuf);
Packit 98cdb6
Packit 98cdb6
      g_object_unref (pixbuf);
Packit 98cdb6
      
Packit 98cdb6
      gtk_widget_show (image);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_column_set_widget (col, image);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_toggle_new ();
Packit 98cdb6
Packit 98cdb6
      /* you could also set this per-row by tying it to a column
Packit 98cdb6
       * in the model of course.
Packit 98cdb6
       */
Packit 98cdb6
      g_object_set (rend, "radio", TRUE, NULL);
Packit 98cdb6
      
Packit 98cdb6
      g_signal_connect (rend, "toggled",
Packit 98cdb6
			G_CALLBACK (toggled_callback), tree_view);
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 4",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "active", BOOL_COLUMN,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
Packit 98cdb6
      rend = gtk_cell_renderer_spin_new ();
Packit 98cdb6
Packit 98cdb6
      adjustment = gtk_adjustment_new (0, 0, 10000, 100, 100, 100);
Packit 98cdb6
      g_object_set (rend, "editable", TRUE, NULL);
Packit 98cdb6
      g_object_set (rend, "adjustment", adjustment, NULL);
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (rend, "edited",
Packit 98cdb6
			G_CALLBACK (edited_callback), tree_view);
Packit 98cdb6
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 5",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 4,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
#if 0
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 6",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 4,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 7",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 5,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 8",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 6,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 9",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 7,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 10",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 8,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
Packit 98cdb6
      
Packit 98cdb6
#endif
Packit 98cdb6
      
Packit 98cdb6
      /* FALL THRU */
Packit 98cdb6
      
Packit 98cdb6
    case COLUMNS_ONE:
Packit 98cdb6
      rend = gtk_cell_renderer_text_new ();
Packit 98cdb6
      
Packit 98cdb6
      col = gtk_tree_view_column_new_with_attributes ("Column 0",
Packit 98cdb6
                                                      rend,
Packit 98cdb6
                                                      "text", 0,
Packit 98cdb6
                                                      NULL);
Packit 98cdb6
Packit 98cdb6
      setup_column (col);
Packit 98cdb6
      
Packit 98cdb6
      gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), col, 0);
Packit 98cdb6
    default:
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static ColumnsType
Packit 98cdb6
get_columns_type (void)
Packit 98cdb6
{
Packit 98cdb6
  return current_column_type;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GdkPixbuf *our_pixbuf;
Packit 98cdb6
  
Packit 98cdb6
typedef enum
Packit 98cdb6
{
Packit 98cdb6
  /*   MODEL_TYPES, */
Packit 98cdb6
  MODEL_TREE,
Packit 98cdb6
  MODEL_LIST,
Packit 98cdb6
  MODEL_SORTED_TREE,
Packit 98cdb6
  MODEL_SORTED_LIST,
Packit 98cdb6
  MODEL_EMPTY_LIST,
Packit 98cdb6
  MODEL_EMPTY_TREE,
Packit 98cdb6
  MODEL_NULL,
Packit 98cdb6
  MODEL_LAST
Packit 98cdb6
} ModelType;
Packit 98cdb6
Packit 98cdb6
/* FIXME add a custom model to test */
Packit 98cdb6
static GtkTreeModel *models[MODEL_LAST];
Packit 98cdb6
static const char *model_names[MODEL_LAST] = {
Packit 98cdb6
  "GtkTreeStore",
Packit 98cdb6
  "GtkListStore",
Packit 98cdb6
  "GtkTreeModelSort wrapping GtkTreeStore",
Packit 98cdb6
  "GtkTreeModelSort wrapping GtkListStore",
Packit 98cdb6
  "Empty GtkListStore",
Packit 98cdb6
  "Empty GtkTreeStore",
Packit 98cdb6
  "NULL (no model)"
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static GtkTreeModel*
Packit 98cdb6
create_list_model (void)
Packit 98cdb6
{
Packit 98cdb6
  GtkListStore *store;
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  gint i;
Packit 98cdb6
  GType *t;
Packit 98cdb6
Packit 98cdb6
  t = get_model_types ();
Packit 98cdb6
  
Packit 98cdb6
  store = gtk_list_store_new (N_COLUMNS,
Packit 98cdb6
			      t[0], t[1], t[2],
Packit 98cdb6
			      t[3], t[4], t[5],
Packit 98cdb6
			      t[6], t[7], t[8]);
Packit 98cdb6
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < 200)
Packit 98cdb6
    {
Packit 98cdb6
      char *msg;
Packit 98cdb6
      
Packit 98cdb6
      gtk_list_store_append (store, &iter);
Packit 98cdb6
Packit 98cdb6
      msg = g_strdup_printf ("%d", i);
Packit 98cdb6
      
Packit 98cdb6
      gtk_list_store_set (store, &iter, 0, msg, 1, "Foo! Foo! Foo!",
Packit 98cdb6
                          2, our_pixbuf,
Packit 98cdb6
                          3, 7.0, 4, (guint) 9000,
Packit 98cdb6
                          5, 'f', 6, 'g',
Packit 98cdb6
                          7, TRUE, 8, 23245454,
Packit 98cdb6
                          -1);
Packit 98cdb6
Packit 98cdb6
      g_free (msg);
Packit 98cdb6
      
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return GTK_TREE_MODEL (store);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
typesystem_recurse (GType        type,
Packit 98cdb6
                    GtkTreeIter *parent_iter,
Packit 98cdb6
                    GtkTreeStore *store)
Packit 98cdb6
{
Packit 98cdb6
  GType* children;
Packit 98cdb6
  guint n_children = 0;
Packit 98cdb6
  gint i;
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  gchar *str;
Packit 98cdb6
  
Packit 98cdb6
  gtk_tree_store_append (store, &iter, parent_iter);
Packit 98cdb6
Packit 98cdb6
  str = g_strdup_printf ("%ld", (glong)type);
Packit 98cdb6
  gtk_tree_store_set (store, &iter, 0, str, 1, g_type_name (type),
Packit 98cdb6
                      2, our_pixbuf,
Packit 98cdb6
                      3, 7.0, 4, (guint) 9000,
Packit 98cdb6
                      5, 'f', 6, 'g',
Packit 98cdb6
                      7, TRUE, 8, 23245454,
Packit 98cdb6
                      -1);
Packit 98cdb6
  g_free (str);
Packit 98cdb6
  
Packit 98cdb6
  children = g_type_children (type, &n_children);
Packit 98cdb6
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < n_children)
Packit 98cdb6
    {
Packit 98cdb6
      typesystem_recurse (children[i], &iter, store);
Packit 98cdb6
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  g_free (children);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GtkTreeModel*
Packit 98cdb6
create_tree_model (void)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeStore *store;
Packit 98cdb6
  gint i;
Packit 98cdb6
  GType *t;
Packit 98cdb6
  volatile GType dummy; /* G_GNUC_CONST makes the optimizer remove
Packit 98cdb6
                         * get_type calls if you don't do something
Packit 98cdb6
                         * like this
Packit 98cdb6
                         */
Packit 98cdb6
  
Packit 98cdb6
  /* Make the tree more interesting */
Packit 98cdb6
  dummy = gtk_scrolled_window_get_type ();
Packit 98cdb6
  dummy = gtk_label_get_type ();
Packit 98cdb6
  dummy = gtk_hscrollbar_get_type ();
Packit 98cdb6
  dummy = gtk_vscrollbar_get_type ();
Packit 98cdb6
  dummy = pango_layout_get_type ();
Packit 98cdb6
Packit 98cdb6
  t = get_model_types ();
Packit 98cdb6
  
Packit 98cdb6
  store = gtk_tree_store_new (N_COLUMNS,
Packit 98cdb6
			      t[0], t[1], t[2],
Packit 98cdb6
			      t[3], t[4], t[5],
Packit 98cdb6
			      t[6], t[7], t[8]);
Packit 98cdb6
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < G_TYPE_FUNDAMENTAL_MAX)
Packit 98cdb6
    {
Packit 98cdb6
      typesystem_recurse (i, NULL, store);
Packit 98cdb6
      
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return GTK_TREE_MODEL (store);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
model_selected (GtkComboBox *combo_box, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
Packit 98cdb6
  gint hist;
Packit 98cdb6
Packit 98cdb6
  hist = gtk_combo_box_get_active (combo_box);
Packit 98cdb6
Packit 98cdb6
  if (models[hist] != gtk_tree_view_get_model (tree_view))
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_view_set_model (tree_view, models[hist]);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
columns_selected (GtkComboBox *combo_box, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
Packit 98cdb6
  gint hist;
Packit 98cdb6
Packit 98cdb6
  hist = gtk_combo_box_get_active (combo_box);
Packit 98cdb6
Packit 98cdb6
  if (hist != get_columns_type ())
Packit 98cdb6
    {
Packit 98cdb6
      set_columns_type (tree_view, hist);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
enum
Packit 98cdb6
{
Packit 98cdb6
  TARGET_GTK_TREE_MODEL_ROW
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static GtkTargetEntry row_targets[] = {
Packit 98cdb6
  { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP,
Packit 98cdb6
    TARGET_GTK_TREE_MODEL_ROW }
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
int
Packit 98cdb6
main (int    argc,
Packit 98cdb6
      char **argv)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *window;
Packit 98cdb6
  GtkWidget *sw;
Packit 98cdb6
  GtkWidget *tv;
Packit 98cdb6
  GtkWidget *table;
Packit 98cdb6
  GtkWidget *combo_box;
Packit 98cdb6
  GtkTreeModel *model;
Packit 98cdb6
  gint i;
Packit 98cdb6
  
Packit 98cdb6
  gtk_init (&argc, &argv);
Packit 98cdb6
Packit 98cdb6
  our_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) book_closed_xpm);  
Packit 98cdb6
  
Packit 98cdb6
#if 0
Packit 98cdb6
  models[MODEL_TYPES] = GTK_TREE_MODEL (gtk_tree_model_types_new ());
Packit 98cdb6
#endif
Packit 98cdb6
  models[MODEL_LIST] = create_list_model ();
Packit 98cdb6
  models[MODEL_TREE] = create_tree_model ();
Packit 98cdb6
Packit 98cdb6
  model = create_list_model ();
Packit 98cdb6
  models[MODEL_SORTED_LIST] = gtk_tree_model_sort_new_with_model (model);
Packit 98cdb6
  g_object_unref (model);
Packit 98cdb6
Packit 98cdb6
  model = create_tree_model ();
Packit 98cdb6
  models[MODEL_SORTED_TREE] = gtk_tree_model_sort_new_with_model (model);
Packit 98cdb6
  g_object_unref (model);
Packit 98cdb6
Packit 98cdb6
  models[MODEL_EMPTY_LIST] = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_INT));
Packit 98cdb6
  models[MODEL_EMPTY_TREE] = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
Packit 98cdb6
  
Packit 98cdb6
  models[MODEL_NULL] = NULL;
Packit 98cdb6
Packit 98cdb6
  run_automated_tests ();
Packit 98cdb6
  
Packit 98cdb6
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Packit 98cdb6
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
Packit 98cdb6
  gtk_window_set_default_size (GTK_WINDOW (window), 430, 400);
Packit 98cdb6
Packit 98cdb6
  table = gtk_table_new (3, 1, FALSE);
Packit 98cdb6
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (window), table);
Packit 98cdb6
Packit 98cdb6
  tv = gtk_tree_view_new_with_model (models[0]);
Packit 98cdb6
  
Packit 98cdb6
  gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tv),
Packit 98cdb6
					  GDK_BUTTON1_MASK,
Packit 98cdb6
					  row_targets,
Packit 98cdb6
					  G_N_ELEMENTS (row_targets),
Packit 98cdb6
					  GDK_ACTION_MOVE | GDK_ACTION_COPY);
Packit 98cdb6
Packit 98cdb6
  gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (tv),
Packit 98cdb6
					row_targets,
Packit 98cdb6
					G_N_ELEMENTS (row_targets),
Packit 98cdb6
					GDK_ACTION_MOVE | GDK_ACTION_COPY);
Packit 98cdb6
  
Packit 98cdb6
  /* Model menu */
Packit 98cdb6
  combo_box = gtk_combo_box_text_new ();
Packit 98cdb6
  for (i = 0; i < MODEL_LAST; i++)
Packit 98cdb6
      gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), model_names[i]);
Packit 98cdb6
Packit 98cdb6
  gtk_table_attach (GTK_TABLE (table), combo_box,
Packit 98cdb6
                    0, 1, 0, 1,
Packit 98cdb6
                    0, 0, 
Packit 98cdb6
                    0, 0);
Packit 98cdb6
Packit 98cdb6
  g_signal_connect (combo_box,
Packit 98cdb6
                    "changed",
Packit 98cdb6
                    G_CALLBACK (model_selected),
Packit 98cdb6
		    tv);
Packit 98cdb6
  
Packit 98cdb6
  /* Columns menu */
Packit 98cdb6
  combo_box = gtk_combo_box_text_new ();
Packit 98cdb6
  for (i = 0; i < COLUMNS_LAST; i++)
Packit 98cdb6
      gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), column_type_names[i]);
Packit 98cdb6
Packit 98cdb6
  gtk_table_attach (GTK_TABLE (table), combo_box,
Packit 98cdb6
                    0, 1, 1, 2,
Packit 98cdb6
                    0, 0, 
Packit 98cdb6
                    0, 0);
Packit 98cdb6
Packit 98cdb6
  set_columns_type (GTK_TREE_VIEW (tv), COLUMNS_LOTS);
Packit 98cdb6
  gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), COLUMNS_LOTS);
Packit 98cdb6
  
Packit 98cdb6
  g_signal_connect (combo_box,
Packit 98cdb6
                    "changed",
Packit 98cdb6
                    G_CALLBACK (columns_selected),
Packit 98cdb6
                    tv);
Packit 98cdb6
  
Packit 98cdb6
  sw = gtk_scrolled_window_new (NULL, NULL);
Packit 98cdb6
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
Packit 98cdb6
                                  GTK_POLICY_AUTOMATIC,
Packit 98cdb6
                                  GTK_POLICY_AUTOMATIC);
Packit 98cdb6
  
Packit 98cdb6
  gtk_table_attach (GTK_TABLE (table), sw,
Packit 98cdb6
                    0, 1, 2, 3,
Packit 98cdb6
                    GTK_EXPAND | GTK_FILL,
Packit 98cdb6
                    GTK_EXPAND | GTK_FILL,
Packit 98cdb6
                    0, 0);
Packit 98cdb6
  
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (sw), tv);
Packit 98cdb6
  
Packit 98cdb6
  gtk_widget_show_all (window);
Packit 98cdb6
  
Packit 98cdb6
  gtk_main ();
Packit 98cdb6
Packit 98cdb6
  return 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * GtkTreeModelTypes
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
static void         gtk_tree_model_types_init                 (GtkTreeModelTypes      *model_types);
Packit 98cdb6
static void         gtk_tree_model_types_tree_model_init      (GtkTreeModelIface   *iface);
Packit 98cdb6
static gint         gtk_real_model_types_get_n_columns   (GtkTreeModel        *tree_model);
Packit 98cdb6
static GType        gtk_real_model_types_get_column_type (GtkTreeModel        *tree_model,
Packit 98cdb6
							   gint                 index);
Packit 98cdb6
static GtkTreePath *gtk_real_model_types_get_path        (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter);
Packit 98cdb6
static void         gtk_real_model_types_get_value       (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter,
Packit 98cdb6
							   gint                 column,
Packit 98cdb6
							   GValue              *value);
Packit 98cdb6
static gboolean     gtk_real_model_types_iter_next       (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter);
Packit 98cdb6
static gboolean     gtk_real_model_types_iter_children   (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter,
Packit 98cdb6
							   GtkTreeIter         *parent);
Packit 98cdb6
static gboolean     gtk_real_model_types_iter_has_child  (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter);
Packit 98cdb6
static gint         gtk_real_model_types_iter_n_children (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter);
Packit 98cdb6
static gboolean     gtk_real_model_types_iter_nth_child  (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter,
Packit 98cdb6
							   GtkTreeIter         *parent,
Packit 98cdb6
							   gint                 n);
Packit 98cdb6
static gboolean     gtk_real_model_types_iter_parent     (GtkTreeModel        *tree_model,
Packit 98cdb6
							   GtkTreeIter         *iter,
Packit 98cdb6
							   GtkTreeIter         *child);
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
GType
Packit 98cdb6
gtk_tree_model_types_get_type (void)
Packit 98cdb6
{
Packit 98cdb6
  static GType model_types_type = 0;
Packit 98cdb6
Packit 98cdb6
  if (!model_types_type)
Packit 98cdb6
    {
Packit 98cdb6
      const GTypeInfo model_types_info =
Packit 98cdb6
      {
Packit 98cdb6
        sizeof (GtkTreeModelTypesClass),
Packit 98cdb6
	NULL,		/* base_init */
Packit 98cdb6
	NULL,		/* base_finalize */
Packit 98cdb6
        NULL,           /* class_init */
Packit 98cdb6
	NULL,		/* class_finalize */
Packit 98cdb6
	NULL,		/* class_data */
Packit 98cdb6
        sizeof (GtkTreeModelTypes),
Packit 98cdb6
	0,
Packit 98cdb6
        (GInstanceInitFunc) gtk_tree_model_types_init
Packit 98cdb6
      };
Packit 98cdb6
Packit 98cdb6
      const GInterfaceInfo tree_model_info =
Packit 98cdb6
      {
Packit 98cdb6
	(GInterfaceInitFunc) gtk_tree_model_types_tree_model_init,
Packit 98cdb6
	NULL,
Packit 98cdb6
	NULL
Packit 98cdb6
      };
Packit 98cdb6
Packit 98cdb6
      model_types_type = g_type_register_static (G_TYPE_OBJECT,
Packit 98cdb6
						 "GtkTreeModelTypes",
Packit 98cdb6
						 &model_types_info, 0);
Packit 98cdb6
      g_type_add_interface_static (model_types_type,
Packit 98cdb6
				   GTK_TYPE_TREE_MODEL,
Packit 98cdb6
				   &tree_model_info);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return model_types_type;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GtkTreeModelTypes *
Packit 98cdb6
gtk_tree_model_types_new (void)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeModelTypes *retval;
Packit 98cdb6
Packit 98cdb6
  retval = g_object_new (GTK_TYPE_MODEL_TYPES, NULL);
Packit 98cdb6
Packit 98cdb6
  return retval;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_tree_model_types_tree_model_init (GtkTreeModelIface *iface)
Packit 98cdb6
{
Packit 98cdb6
  iface->get_n_columns = gtk_real_model_types_get_n_columns;
Packit 98cdb6
  iface->get_column_type = gtk_real_model_types_get_column_type;
Packit 98cdb6
  iface->get_path = gtk_real_model_types_get_path;
Packit 98cdb6
  iface->get_value = gtk_real_model_types_get_value;
Packit 98cdb6
  iface->iter_next = gtk_real_model_types_iter_next;
Packit 98cdb6
  iface->iter_children = gtk_real_model_types_iter_children;
Packit 98cdb6
  iface->iter_has_child = gtk_real_model_types_iter_has_child;
Packit 98cdb6
  iface->iter_n_children = gtk_real_model_types_iter_n_children;
Packit 98cdb6
  iface->iter_nth_child = gtk_real_model_types_iter_nth_child;
Packit 98cdb6
  iface->iter_parent = gtk_real_model_types_iter_parent;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_tree_model_types_init (GtkTreeModelTypes *model_types)
Packit 98cdb6
{
Packit 98cdb6
  model_types->stamp = g_random_int ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GType column_types[] = {
Packit 98cdb6
  G_TYPE_STRING, /* GType */
Packit 98cdb6
  G_TYPE_STRING  /* type name */
Packit 98cdb6
};
Packit 98cdb6
  
Packit 98cdb6
static gint
Packit 98cdb6
gtk_real_model_types_get_n_columns (GtkTreeModel *tree_model)
Packit 98cdb6
{
Packit 98cdb6
  return G_N_ELEMENTS (column_types);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GType
Packit 98cdb6
gtk_real_model_types_get_column_type (GtkTreeModel *tree_model,
Packit 98cdb6
                                      gint          index)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (index < G_N_ELEMENTS (column_types), G_TYPE_INVALID);
Packit 98cdb6
  
Packit 98cdb6
  return column_types[index];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#if 0
Packit 98cdb6
/* Use default implementation of this */
Packit 98cdb6
static gboolean
Packit 98cdb6
gtk_real_model_types_get_iter (GtkTreeModel *tree_model,
Packit 98cdb6
                               GtkTreeIter  *iter,
Packit 98cdb6
                               GtkTreePath  *path)
Packit 98cdb6
{
Packit 98cdb6
  
Packit 98cdb6
}
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
/* The toplevel nodes of the tree are the reserved types, G_TYPE_NONE through
Packit 98cdb6
 * G_TYPE_RESERVED_FUNDAMENTAL.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
static GtkTreePath *
Packit 98cdb6
gtk_real_model_types_get_path (GtkTreeModel *tree_model,
Packit 98cdb6
                               GtkTreeIter  *iter)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreePath *retval;
Packit 98cdb6
  GType type;
Packit 98cdb6
  GType parent;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (GTK_IS_TREE_MODEL_TYPES (tree_model), NULL);
Packit 98cdb6
  g_return_val_if_fail (iter != NULL, NULL);
Packit 98cdb6
Packit 98cdb6
  type = GPOINTER_TO_INT (iter->user_data);
Packit 98cdb6
  
Packit 98cdb6
  retval = gtk_tree_path_new ();
Packit 98cdb6
  
Packit 98cdb6
  parent = g_type_parent (type);
Packit 98cdb6
  while (parent != G_TYPE_INVALID)
Packit 98cdb6
    {
Packit 98cdb6
      GType* children = g_type_children (parent, NULL);
Packit 98cdb6
      gint i = 0;
Packit 98cdb6
Packit 98cdb6
      if (!children || children[0] == G_TYPE_INVALID)
Packit 98cdb6
        {
Packit 98cdb6
          g_warning ("bad iterator?");
Packit 98cdb6
          return NULL;
Packit 98cdb6
        }
Packit 98cdb6
      
Packit 98cdb6
      while (children[i] != type)
Packit 98cdb6
        ++i;
Packit 98cdb6
Packit 98cdb6
      gtk_tree_path_prepend_index (retval, i);
Packit 98cdb6
Packit 98cdb6
      g_free (children);
Packit 98cdb6
      
Packit 98cdb6
      type = parent;
Packit 98cdb6
      parent = g_type_parent (parent);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* The fundamental type itself is the index on the toplevel */
Packit 98cdb6
  gtk_tree_path_prepend_index (retval, type);
Packit 98cdb6
Packit 98cdb6
  return retval;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_real_model_types_get_value (GtkTreeModel *tree_model,
Packit 98cdb6
                                GtkTreeIter  *iter,
Packit 98cdb6
                                gint          column,
Packit 98cdb6
                                GValue       *value)
Packit 98cdb6
{
Packit 98cdb6
  GType type;
Packit 98cdb6
Packit 98cdb6
  type = GPOINTER_TO_INT (iter->user_data);
Packit 98cdb6
Packit 98cdb6
  switch (column)
Packit 98cdb6
    {
Packit 98cdb6
    case 0:
Packit 98cdb6
      {
Packit 98cdb6
        gchar *str;
Packit 98cdb6
        
Packit 98cdb6
        g_value_init (value, G_TYPE_STRING);
Packit 98cdb6
Packit 98cdb6
        str = g_strdup_printf ("%ld", (long int) type);
Packit 98cdb6
        g_value_set_string (value, str);
Packit 98cdb6
        g_free (str);
Packit 98cdb6
      }
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    case 1:
Packit 98cdb6
      g_value_init (value, G_TYPE_STRING);
Packit 98cdb6
      g_value_set_string (value, g_type_name (type));
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    default:
Packit 98cdb6
      g_warning ("Bad column %d requested", column);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gtk_real_model_types_iter_next (GtkTreeModel  *tree_model,
Packit 98cdb6
                                GtkTreeIter   *iter)
Packit 98cdb6
{
Packit 98cdb6
  
Packit 98cdb6
  GType parent;
Packit 98cdb6
  GType type;
Packit 98cdb6
Packit 98cdb6
  type = GPOINTER_TO_INT (iter->user_data);
Packit 98cdb6
Packit 98cdb6
  parent = g_type_parent (type);
Packit 98cdb6
  
Packit 98cdb6
  if (parent == G_TYPE_INVALID)
Packit 98cdb6
    {
Packit 98cdb6
      /* find next _valid_ fundamental type */
Packit 98cdb6
      do
Packit 98cdb6
	type++;
Packit 98cdb6
      while (!g_type_name (type) && type <= G_TYPE_FUNDAMENTAL_MAX);
Packit 98cdb6
      if (type <= G_TYPE_FUNDAMENTAL_MAX)
Packit 98cdb6
	{
Packit 98cdb6
	  /* found one */
Packit 98cdb6
          iter->user_data = GINT_TO_POINTER (type);
Packit 98cdb6
          return TRUE;
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      GType* children = g_type_children (parent, NULL);
Packit 98cdb6
      gint i = 0;
Packit 98cdb6
Packit 98cdb6
      g_assert (children != NULL);
Packit 98cdb6
      
Packit 98cdb6
      while (children[i] != type)
Packit 98cdb6
        ++i;
Packit 98cdb6
  
Packit 98cdb6
      ++i;
Packit 98cdb6
Packit 98cdb6
      if (children[i] != G_TYPE_INVALID)
Packit 98cdb6
        {
Packit 98cdb6
          g_free (children);
Packit 98cdb6
          iter->user_data = GINT_TO_POINTER (children[i]);
Packit 98cdb6
          return TRUE;
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        {
Packit 98cdb6
          g_free (children);
Packit 98cdb6
          return FALSE;
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gtk_real_model_types_iter_children (GtkTreeModel *tree_model,
Packit 98cdb6
                                    GtkTreeIter  *iter,
Packit 98cdb6
                                    GtkTreeIter  *parent)
Packit 98cdb6
{
Packit 98cdb6
  GType type;
Packit 98cdb6
  GType* children;
Packit 98cdb6
  
Packit 98cdb6
  type = GPOINTER_TO_INT (parent->user_data);
Packit 98cdb6
Packit 98cdb6
  children = g_type_children (type, NULL);
Packit 98cdb6
Packit 98cdb6
  if (!children || children[0] == G_TYPE_INVALID)
Packit 98cdb6
    {
Packit 98cdb6
      g_free (children);
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      iter->user_data = GINT_TO_POINTER (children[0]);
Packit 98cdb6
      g_free (children);
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gtk_real_model_types_iter_has_child (GtkTreeModel *tree_model,
Packit 98cdb6
                                     GtkTreeIter  *iter)
Packit 98cdb6
{
Packit 98cdb6
  GType type;
Packit 98cdb6
  GType* children;
Packit 98cdb6
  
Packit 98cdb6
  type = GPOINTER_TO_INT (iter->user_data);
Packit 98cdb6
  
Packit 98cdb6
  children = g_type_children (type, NULL);
Packit 98cdb6
Packit 98cdb6
  if (!children || children[0] == G_TYPE_INVALID)
Packit 98cdb6
    {
Packit 98cdb6
      g_free (children);
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      g_free (children);
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gint
Packit 98cdb6
gtk_real_model_types_iter_n_children (GtkTreeModel *tree_model,
Packit 98cdb6
                                      GtkTreeIter  *iter)
Packit 98cdb6
{
Packit 98cdb6
  if (iter == NULL)
Packit 98cdb6
    {
Packit 98cdb6
      return G_TYPE_FUNDAMENTAL_MAX;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      GType type;
Packit 98cdb6
      GType* children;
Packit 98cdb6
      guint n_children = 0;
Packit 98cdb6
Packit 98cdb6
      type = GPOINTER_TO_INT (iter->user_data);
Packit 98cdb6
      
Packit 98cdb6
      children = g_type_children (type, &n_children);
Packit 98cdb6
      
Packit 98cdb6
      g_free (children);
Packit 98cdb6
      
Packit 98cdb6
      return n_children;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gtk_real_model_types_iter_nth_child (GtkTreeModel *tree_model,
Packit 98cdb6
                                     GtkTreeIter  *iter,
Packit 98cdb6
                                     GtkTreeIter  *parent,
Packit 98cdb6
                                     gint          n)
Packit 98cdb6
{  
Packit 98cdb6
  if (parent == NULL)
Packit 98cdb6
    {
Packit 98cdb6
      /* fundamental type */
Packit 98cdb6
      if (n < G_TYPE_FUNDAMENTAL_MAX)
Packit 98cdb6
        {
Packit 98cdb6
          iter->user_data = GINT_TO_POINTER (n);
Packit 98cdb6
          return TRUE;
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      GType type = GPOINTER_TO_INT (parent->user_data);      
Packit 98cdb6
      guint n_children = 0;
Packit 98cdb6
      GType* children = g_type_children (type, &n_children);
Packit 98cdb6
Packit 98cdb6
      if (n_children == 0)
Packit 98cdb6
        {
Packit 98cdb6
          g_free (children);
Packit 98cdb6
          return FALSE;
Packit 98cdb6
        }
Packit 98cdb6
      else if (n >= n_children)
Packit 98cdb6
        {
Packit 98cdb6
          g_free (children);
Packit 98cdb6
          return FALSE;
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        {
Packit 98cdb6
          iter->user_data = GINT_TO_POINTER (children[n]);
Packit 98cdb6
          g_free (children);
Packit 98cdb6
Packit 98cdb6
          return TRUE;
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gtk_real_model_types_iter_parent (GtkTreeModel *tree_model,
Packit 98cdb6
                                  GtkTreeIter  *iter,
Packit 98cdb6
                                  GtkTreeIter  *child)
Packit 98cdb6
{
Packit 98cdb6
  GType type;
Packit 98cdb6
  GType parent;
Packit 98cdb6
  
Packit 98cdb6
  type = GPOINTER_TO_INT (child->user_data);
Packit 98cdb6
  
Packit 98cdb6
  parent = g_type_parent (type);
Packit 98cdb6
  
Packit 98cdb6
  if (parent == G_TYPE_INVALID)
Packit 98cdb6
    {
Packit 98cdb6
      if (type > G_TYPE_FUNDAMENTAL_MAX)
Packit 98cdb6
        g_warning ("no parent for %ld %s\n",
Packit 98cdb6
                   (long int) type,
Packit 98cdb6
                   g_type_name (type));
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      iter->user_data = GINT_TO_POINTER (parent);
Packit 98cdb6
      
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Automated testing
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#if 0
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
treestore_torture_recurse (GtkTreeStore *store,
Packit 98cdb6
                           GtkTreeIter  *root,
Packit 98cdb6
                           gint          depth)
Packit 98cdb6
{
Packit 98cdb6
  GtkTreeModel *model;
Packit 98cdb6
  gint i;
Packit 98cdb6
  GtkTreeIter iter;  
Packit 98cdb6
  
Packit 98cdb6
  model = GTK_TREE_MODEL (store);    
Packit 98cdb6
Packit 98cdb6
  if (depth > 2)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  ++depth;
Packit 98cdb6
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
  
Packit 98cdb6
  gtk_tree_model_iter_children (model, &iter, root);
Packit 98cdb6
  
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < 100)
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  while (gtk_tree_model_iter_children (model, &iter, root))
Packit 98cdb6
    gtk_tree_store_remove (store, &iter);
Packit 98cdb6
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
Packit 98cdb6
  /* inserts before last node in tree */
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < 100)
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_store_insert_before (store, &iter, root, &iter);
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* inserts after the node before the last node */
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < 100)
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_store_insert_after (store, &iter, root, &iter);
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* inserts after the last node */
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
    
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < 100)
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_store_insert_after (store, &iter, root, &iter);
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* remove everything again */
Packit 98cdb6
  while (gtk_tree_model_iter_children (model, &iter, root))
Packit 98cdb6
    gtk_tree_store_remove (store, &iter);
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
    /* Prepends */
Packit 98cdb6
  gtk_tree_store_prepend (store, &iter, root);
Packit 98cdb6
    
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < 100)
Packit 98cdb6
    {
Packit 98cdb6
      gtk_tree_store_prepend (store, &iter, root);
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* remove everything again */
Packit 98cdb6
  while (gtk_tree_model_iter_children (model, &iter, root))
Packit 98cdb6
    gtk_tree_store_remove (store, &iter);
Packit 98cdb6
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
  gtk_tree_store_append (store, &iter, root);
Packit 98cdb6
Packit 98cdb6
  while (gtk_tree_model_iter_children (model, &iter, root))
Packit 98cdb6
    {
Packit 98cdb6
      treestore_torture_recurse (store, &iter, depth);
Packit 98cdb6
      gtk_tree_store_remove (store, &iter);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
run_automated_tests (void)
Packit 98cdb6
{
Packit 98cdb6
  g_print ("Running automated tests...\n");
Packit 98cdb6
  
Packit 98cdb6
  /* FIXME TreePath basic verification */
Packit 98cdb6
Packit 98cdb6
  /* FIXME generic consistency checks on the models */
Packit 98cdb6
Packit 98cdb6
  {
Packit 98cdb6
    /* Make sure list store mutations don't crash anything */
Packit 98cdb6
    GtkListStore *store;
Packit 98cdb6
    GtkTreeModel *model;
Packit 98cdb6
    gint i;
Packit 98cdb6
    GtkTreeIter iter;
Packit 98cdb6
    
Packit 98cdb6
    store = gtk_list_store_new (1, G_TYPE_INT);
Packit 98cdb6
Packit 98cdb6
    model = GTK_TREE_MODEL (store);
Packit 98cdb6
    
Packit 98cdb6
    i = 0;
Packit 98cdb6
    while (i < 100)
Packit 98cdb6
      {
Packit 98cdb6
        gtk_list_store_append (store, &iter);
Packit 98cdb6
        ++i;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
    while (gtk_tree_model_get_iter_first (model, &iter))
Packit 98cdb6
      gtk_list_store_remove (store, &iter);
Packit 98cdb6
Packit 98cdb6
    gtk_list_store_append (store, &iter);
Packit 98cdb6
Packit 98cdb6
    /* inserts before last node in list */
Packit 98cdb6
    i = 0;
Packit 98cdb6
    while (i < 100)
Packit 98cdb6
      {
Packit 98cdb6
        gtk_list_store_insert_before (store, &iter, &iter);
Packit 98cdb6
        ++i;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
    /* inserts after the node before the last node */
Packit 98cdb6
    i = 0;
Packit 98cdb6
    while (i < 100)
Packit 98cdb6
      {
Packit 98cdb6
        gtk_list_store_insert_after (store, &iter, &iter);
Packit 98cdb6
        ++i;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
    /* inserts after the last node */
Packit 98cdb6
    gtk_list_store_append (store, &iter);
Packit 98cdb6
    
Packit 98cdb6
    i = 0;
Packit 98cdb6
    while (i < 100)
Packit 98cdb6
      {
Packit 98cdb6
        gtk_list_store_insert_after (store, &iter, &iter);
Packit 98cdb6
        ++i;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
    /* remove everything again */
Packit 98cdb6
    while (gtk_tree_model_get_iter_first (model, &iter))
Packit 98cdb6
      gtk_list_store_remove (store, &iter);
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
    /* Prepends */
Packit 98cdb6
    gtk_list_store_prepend (store, &iter);
Packit 98cdb6
    
Packit 98cdb6
    i = 0;
Packit 98cdb6
    while (i < 100)
Packit 98cdb6
      {
Packit 98cdb6
        gtk_list_store_prepend (store, &iter);
Packit 98cdb6
        ++i;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
    /* remove everything again */
Packit 98cdb6
    while (gtk_tree_model_get_iter_first (model, &iter))
Packit 98cdb6
      gtk_list_store_remove (store, &iter);
Packit 98cdb6
    
Packit 98cdb6
    g_object_unref (store);
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  {
Packit 98cdb6
    /* Make sure tree store mutations don't crash anything */
Packit 98cdb6
    GtkTreeStore *store;
Packit 98cdb6
    GtkTreeIter root;
Packit 98cdb6
Packit 98cdb6
    store = gtk_tree_store_new (1, G_TYPE_INT);
Packit 98cdb6
    gtk_tree_store_append (GTK_TREE_STORE (store), &root, NULL);
Packit 98cdb6
    /* Remove test until it is rewritten to work */
Packit 98cdb6
    /*    treestore_torture_recurse (store, &root, 0);*/
Packit 98cdb6
    
Packit 98cdb6
    g_object_unref (store);
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  g_print ("Passed.\n");
Packit 98cdb6
}