]> Pileus Git - ~andy/gtk/blobdiff - tests/testtreeview.c
handle case where there are no rows in the model
[~andy/gtk] / tests / testtreeview.c
index 0b38023ce662289758d7225ce4361e356aa4a1f6..e224c3724cb5425c93b0da874d4c3ee3df317237 100644 (file)
@@ -2,13 +2,44 @@
 #include <gtk/gtk.h>
 #include <string.h>
 
+
+/* Don't copy this bad example; inline RGB data is always a better
+ * idea than inline XPMs.
+ */
+static char  *book_closed_xpm[] = {
+"16 16 6 1",
+"       c None s None",
+".      c black",
+"X      c red",
+"o      c yellow",
+"O      c #808080",
+"#      c white",
+"                ",
+"       ..       ",
+"     ..XX.      ",
+"   ..XXXXX.     ",
+" ..XXXXXXXX.    ",
+".ooXXXXXXXXX.   ",
+"..ooXXXXXXXXX.  ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX..  ",
+" .XX.ooXXX..#O  ",
+"  .XX.oo..##OO. ",
+"   .XX..##OO..  ",
+"    .X.#OO..    ",
+"     ..O..      ",
+"      ..        ",
+"                "
+};
+
 static GtkWidget* create_prop_editor (GObject *object);
+static void run_automated_tests (void);
 
 /* This custom model is to test custom model use. */
 
 #define GTK_TYPE_MODEL_TYPES                   (gtk_tree_model_types_get_type ())
-#define GTK_TREE_MODEL_TYPES(obj)                      (GTK_CHECK_CAST ((obj), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypes))
-#define GTK_TREE_MODEL_TYPES_CLASS(klass)              (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypesClass))
+#define GTK_TREE_MODEL_TYPES(obj)              (GTK_CHECK_CAST ((obj), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypes))
+#define GTK_TREE_MODEL_TYPES_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_MODEL_TYPES, GtkTreeModelTypesClass))
 #define GTK_IS_TREE_MODEL_TYPES(obj)           (GTK_CHECK_TYPE ((obj), GTK_TYPE_MODEL_TYPES))
 #define GTK_IS_TREE_MODEL_TYPES_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_MODEL_TYPES))
 
@@ -79,11 +110,250 @@ GtkTreeModelTypes *gtk_tree_model_types_new           (void);
 
 typedef enum
 {
-  MODEL_TYPES,
-  MODEL_LAST  
+  COLUMNS_NONE,
+  COLUMNS_ONE,
+  COLUMNS_LOTS,
+  COLUMNS_LAST
+} ColumnsType;
+
+#define N_COLUMNS 9
+
+static GType*
+get_model_types (void)
+{
+  static GType column_types[N_COLUMNS] = { 0 };
+  
+  if (column_types[0] == 0)
+    {
+      column_types[0] = G_TYPE_STRING;
+      column_types[1] = G_TYPE_STRING;
+      column_types[2] = GDK_TYPE_PIXBUF;
+      column_types[3] = G_TYPE_FLOAT;
+      column_types[4] = G_TYPE_UINT;
+      column_types[5] = G_TYPE_UCHAR;
+      column_types[6] = G_TYPE_CHAR;
+      column_types[7] = G_TYPE_BOOLEAN;
+      column_types[8] = G_TYPE_INT;
+    }
+
+  return column_types;
+}
+
+static void
+set_columns_type (GtkTreeView *tree_view, ColumnsType type)
+{
+  GtkTreeViewColumn *col;
+  GtkCellRenderer *rend;
+
+  col = gtk_tree_view_get_column (tree_view, 0);
+  while (col)
+    {
+      gtk_tree_view_remove_column (tree_view, col);
+
+      col = gtk_tree_view_get_column (tree_view, 0);
+    }
+
+  switch (type)
+    {
+    case COLUMNS_NONE:
+      break;
+
+    case COLUMNS_LOTS:      
+      rend = gtk_cell_renderer_text_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 1",
+                                                      rend,
+                                                      "text", 1,
+                                                      NULL);
+      
+      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+
+      rend = gtk_cell_renderer_text_pixbuf_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 2",
+                                                      rend,
+                                                      "text", 0,
+                                                      "pixbuf", 2,
+                                                      NULL);
+      
+      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+      
+      /* FALL THRU */
+      
+    case COLUMNS_ONE:
+      rend = gtk_cell_renderer_text_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 0",
+                                                      rend,
+                                                      "text", 0,
+                                                      NULL);
+      
+      gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), col, 0);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+      
+    default:
+      break;
+    }
+}
+
+static GdkPixbuf *our_pixbuf;
+  
+typedef enum
+{
+  /*   MODEL_TYPES, */
+  MODEL_TREE,
+  MODEL_LIST,
+  MODEL_SORTED_TREE,
+  MODEL_SORTED_LIST,
+  MODEL_EMPTY_LIST,
+  MODEL_EMPTY_TREE,
+  MODEL_NULL,
+  MODEL_LAST
 } ModelType;
 
+/* FIXME add a custom model to test */
 static GtkTreeModel *models[MODEL_LAST];
+static const char *model_names[MODEL_LAST] = {
+  "GtkTreeStore",
+  "GtkListStore",
+  "GtkTreeModelSort wrapping GtkTreeStore",
+  "GtkTreeModelSort wrapping GtkListStore",
+  "Empty GtkListStore",
+  "Empty GtkTreeStore",
+  "NULL (no model)"
+};
+
+static GtkTreeModel*
+create_list_model (void)
+{
+  GtkListStore *store;
+  GtkTreeIter iter;
+  gint i;
+  GType *t;
+
+  t = get_model_types ();
+  
+  store = gtk_list_store_new_with_types (N_COLUMNS,
+                                         t[0], t[1], t[2],
+                                         t[3], t[4], t[5],
+                                         t[6], t[7], t[8]);
+
+  i = 0;
+  while (i < 200)
+    {
+      char *msg;
+      
+      gtk_list_store_append (store, &iter);
+
+      msg = g_strdup_printf ("%d", i);
+      
+      gtk_list_store_set (store, &iter, 0, msg, 1, "Foo! Foo! Foo!",
+                          2, our_pixbuf,
+                          3, 7.0, 4, (guint) 9000,
+                          5, 'f', 6, 'g',
+                          7, TRUE, 8, 23245454,
+                          -1);
+
+      g_free (msg);
+      
+      ++i;
+    }
+
+  return GTK_TREE_MODEL (store);
+}
+
+static void
+typesystem_recurse (GType        type,
+                    GtkTreeIter *parent_iter,
+                    GtkTreeStore *store)
+{
+  GType* children;
+  guint n_children = 0;
+  gint i;
+  GtkTreeIter iter;
+  gchar *str;
+  
+  gtk_tree_store_append (store, &iter, parent_iter);
+
+  str = g_strdup_printf ("%d", type);
+  gtk_tree_store_set (store, &iter, 0, str, 1, g_type_name (type),
+                      2, our_pixbuf,
+                      3, 7.0, 4, (guint) 9000,
+                      5, 'f', 6, 'g',
+                      7, TRUE, 8, 23245454,
+                      -1);
+  g_free (str);
+  
+  children = g_type_children (type, &n_children);
+
+  i = 0;
+  while (i < n_children)
+    {
+      typesystem_recurse (children[i], &iter, store);
+
+      ++i;
+    }
+  
+  g_free (children);
+}
+
+static GtkTreeModel*
+create_tree_model (void)
+{
+  GtkTreeStore *store;
+  gint i;
+  GType *t;
+  volatile GType dummy; /* G_GNUC_CONST makes the optimizer remove
+                         * get_type calls if you don't do something
+                         * like this
+                         */
+  
+  /* Make the tree more interesting */
+  dummy = gtk_scrolled_window_get_type ();
+  dummy = gtk_label_get_type ();
+  dummy = gtk_hscrollbar_get_type ();
+  dummy = gtk_vscrollbar_get_type ();
+  dummy = pango_layout_get_type ();
+
+  t = get_model_types ();
+  
+  store = gtk_tree_store_new_with_types (N_COLUMNS,
+                                         t[0], t[1], t[2],
+                                         t[3], t[4], t[5],
+                                         t[6], t[7], t[8]);
+
+  i = 0;
+  while (i < G_TYPE_LAST_RESERVED_FUNDAMENTAL)
+    {
+      typesystem_recurse (i, NULL, store);
+      
+      ++i;
+    }
+
+  return GTK_TREE_MODEL (store);
+}
+
+static void
+model_selected (GtkOptionMenu *om, gpointer data)
+{
+  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
+  gint hist;
+
+  hist = gtk_option_menu_get_history (om);
+
+  if (models[hist] != gtk_tree_view_get_model (tree_view))
+    {
+      gtk_tree_view_set_model (tree_view, models[hist]);
+    }
+}
 
 int
 main (int    argc,
@@ -92,63 +362,100 @@ main (int    argc,
   GtkWidget *window;
   GtkWidget *sw;
   GtkWidget *tv;
-  GtkTreeViewColumn *col;
-  GtkCellRenderer *rend;
+  GtkWidget *table;
+  GtkWidget *om;
+  GtkWidget *menu;
+  GtkTreeModel *model;
   gint i;
   
   gtk_init (&argc, &argv);
 
+  our_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) book_closed_xpm);  
+  
+#if 0
   models[MODEL_TYPES] = GTK_TREE_MODEL (gtk_tree_model_types_new ());
+#endif
+  models[MODEL_LIST] = create_list_model ();
+  models[MODEL_TREE] = create_tree_model ();
+
+  model = create_list_model ();
+  models[MODEL_SORTED_LIST] = gtk_tree_model_sort_new_with_model (model, NULL, 0);
+  g_object_unref (G_OBJECT (model));
+
+  model = create_tree_model ();
+  models[MODEL_SORTED_TREE] = gtk_tree_model_sort_new_with_model (model, NULL, 0);
+  g_object_unref (G_OBJECT (model));
+
+  models[MODEL_EMPTY_LIST] = GTK_TREE_MODEL (gtk_list_store_new ());
+  models[MODEL_EMPTY_TREE] = GTK_TREE_MODEL (gtk_tree_store_new ());
+  
+  models[MODEL_NULL] = NULL;
+
+  run_automated_tests ();
+  
+  menu = gtk_menu_new ();
   
   i = 0;
   while (i < MODEL_LAST)
     {
+      GtkWidget *mi;
+      const char *name;
+
+      name = model_names[i];
+      
+      mi = gtk_menu_item_new_with_label (name);
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+#if 0
       window = create_prop_editor (G_OBJECT (models[i]));
 
-      gtk_window_set_title (GTK_WINDOW (window), g_type_name (G_TYPE_FROM_INSTANCE (models[i])));
+      gtk_window_set_title (GTK_WINDOW (window),                            
+                            name);
+#endif
 
       ++i;
     }
-
+  gtk_widget_show_all (menu);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
   gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
+
+  table = gtk_table_new (2, 1, FALSE);
+
+  gtk_container_add (GTK_CONTAINER (window), table);
+
+  om = gtk_option_menu_new ();
+  gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+  
+  gtk_table_attach (GTK_TABLE (table), om,
+                    0, 1, 0, 1,
+                    0, 0, 
+                    0, 0);
   
   sw = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                   GTK_POLICY_AUTOMATIC,
                                   GTK_POLICY_AUTOMATIC);
 
-  gtk_container_add (GTK_CONTAINER (window), sw);
+  
+  gtk_table_attach (GTK_TABLE (table), sw,
+                    0, 1, 1, 2,
+                    GTK_EXPAND | GTK_FILL,
+                    GTK_EXPAND | GTK_FILL,
+                    0, 0);
   
   tv = gtk_tree_view_new_with_model (models[0]);
 
-  gtk_container_add (GTK_CONTAINER (sw), tv);
-
-  rend = gtk_cell_renderer_text_new ();
+  gtk_signal_connect (GTK_OBJECT (om),
+                      "changed",
+                      GTK_SIGNAL_FUNC (model_selected),
+                      tv);
   
-  col = gtk_tree_view_column_new_with_attributes ("Type ID",
-                                                  rend,
-                                                  "text", 0,
-                                                  NULL);
-
-  gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
+  gtk_container_add (GTK_CONTAINER (sw), tv);
 
-  g_object_unref (G_OBJECT (rend));
-  g_object_unref (G_OBJECT (col));
+  set_columns_type (GTK_TREE_VIEW (tv), COLUMNS_LOTS);
   
-  rend = gtk_cell_renderer_text_new ();
-  
-  col = gtk_tree_view_column_new_with_attributes ("Name",
-                                                  rend,
-                                                  "text", 1,
-                                                  NULL);
-
-  gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
-
-  g_object_unref (G_OBJECT (rend));
-  g_object_unref (G_OBJECT (col));
-
   gtk_widget_show_all (window);
   
   gtk_main ();
@@ -1007,3 +1314,15 @@ create_prop_editor (GObject *object)
   return win;
 }
 
+/*
+ * Automated testing
+ */
+
+static void
+run_automated_tests (void)
+{
+  /* FIXME TreePath basic verification */
+
+  /* FIXME consistency checks on the models */
+  
+}