home *** CD-ROM | disk | FTP | other *** search
/ Freelog 65 / Freelog065.iso / BAS / Bureautique / Gnumeric / gnumeric-1.3.92-rc1.exe / editable_cells.c < prev    next >
C/C++ Source or Header  |  2004-10-15  |  8KB  |  303 lines

  1. /* Tree View/Editable Cells
  2.  *
  3.  * This demo demonstrates the use of editable cells in a GtkTreeView. If
  4.  * you're new to the GtkTreeView widgets and associates, look into
  5.  * the GtkListStore example first.
  6.  *
  7.  */
  8.  
  9. #include <config.h>
  10. #include <gtk/gtk.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13.  
  14. static GtkWidget *window = NULL;
  15.  
  16. typedef struct
  17. {
  18.   gint     number;
  19.   gchar   *product;
  20.   gboolean editable;
  21. }
  22. Item;
  23.  
  24. enum
  25. {
  26.   COLUMN_NUMBER,
  27.   COLUMN_PRODUCT,
  28.   COLUMN_EDITABLE,
  29.   NUM_COLUMNS
  30. };
  31.  
  32. static GArray *articles = NULL;
  33.  
  34. static void
  35. add_items (void)
  36. {
  37.   Item foo;
  38.  
  39.   g_return_if_fail (articles != NULL);
  40.  
  41.   foo.number = 3;
  42.   foo.product = g_strdup ("bottles of coke");
  43.   foo.editable = TRUE;
  44.   g_array_append_vals (articles, &foo, 1);
  45.  
  46.   foo.number = 5;
  47.   foo.product = g_strdup ("packages of noodles");
  48.   foo.editable = TRUE;
  49.   g_array_append_vals (articles, &foo, 1);
  50.  
  51.   foo.number = 2;
  52.   foo.product = g_strdup ("packages of chocolate chip cookies");
  53.   foo.editable = TRUE;
  54.   g_array_append_vals (articles, &foo, 1);
  55.  
  56.   foo.number = 1;
  57.   foo.product = g_strdup ("can vanilla ice cream");
  58.   foo.editable = TRUE;
  59.   g_array_append_vals (articles, &foo, 1);
  60.  
  61.   foo.number = 6;
  62.   foo.product = g_strdup ("eggs");
  63.   foo.editable = TRUE;
  64.   g_array_append_vals (articles, &foo, 1);
  65. }
  66.  
  67. static GtkTreeModel *
  68. create_model (void)
  69. {
  70.   gint i = 0;
  71.   GtkListStore *model;
  72.   GtkTreeIter iter;
  73.  
  74.   /* create array */
  75.   articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 1);
  76.  
  77.   add_items ();
  78.  
  79.   /* create list store */
  80.   model = gtk_list_store_new (NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
  81.                   G_TYPE_BOOLEAN);
  82.  
  83.   /* add items */
  84.   for (i = 0; i < articles->len; i++)
  85.     {
  86.       gtk_list_store_append (model, &iter);
  87.  
  88.       gtk_list_store_set (model, &iter,
  89.               COLUMN_NUMBER,
  90.               g_array_index (articles, Item, i).number,
  91.               COLUMN_PRODUCT,
  92.               g_array_index (articles, Item, i).product,
  93.               COLUMN_EDITABLE,
  94.               g_array_index (articles, Item, i).editable,
  95.               -1);
  96.     }
  97.  
  98.   return GTK_TREE_MODEL (model);
  99. }
  100.  
  101. static void
  102. add_item (GtkWidget *button, gpointer data)
  103. {
  104.   Item foo;
  105.   GtkTreeIter iter;
  106.   GtkTreeModel *model = (GtkTreeModel *)data;
  107.  
  108.   g_return_if_fail (articles != NULL);
  109.  
  110.   foo.number = 0;
  111.   foo.product = g_strdup ("Description here");
  112.   foo.editable = TRUE;
  113.   g_array_append_vals (articles, &foo, 1);
  114.  
  115.   gtk_list_store_append (GTK_LIST_STORE (model), &iter);
  116.   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
  117.               COLUMN_NUMBER, foo.number,
  118.               COLUMN_PRODUCT, foo.product,
  119.               COLUMN_EDITABLE, foo.editable,
  120.               -1);
  121. }
  122.  
  123. static void
  124. remove_item (GtkWidget *widget, gpointer data)
  125. {
  126.   GtkTreeIter iter;
  127.   GtkTreeView *treeview = (GtkTreeView *)data;
  128.   GtkTreeModel *model = gtk_tree_view_get_model (treeview);
  129.   GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
  130.  
  131.   if (gtk_tree_selection_get_selected (selection, NULL, &iter))
  132.     {
  133.       gint i;
  134.       GtkTreePath *path;
  135.  
  136.       path = gtk_tree_model_get_path (model, &iter);
  137.       i = gtk_tree_path_get_indices (path)[0];
  138.       gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
  139.  
  140.       g_array_remove_index (articles, i);
  141.  
  142.       gtk_tree_path_free (path);
  143.     }
  144. }
  145.  
  146. static void
  147. cell_edited (GtkCellRendererText *cell,
  148.          const gchar         *path_string,
  149.          const gchar         *new_text,
  150.          gpointer             data)
  151. {
  152.   GtkTreeModel *model = (GtkTreeModel *)data;
  153.   GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
  154.   GtkTreeIter iter;
  155.  
  156.   gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
  157.  
  158.   gtk_tree_model_get_iter (model, &iter, path);
  159.  
  160.   switch (column)
  161.     {
  162.     case COLUMN_NUMBER:
  163.       {
  164.     gint i;
  165.  
  166.     i = gtk_tree_path_get_indices (path)[0];
  167.     g_array_index (articles, Item, i).number = atoi (new_text);
  168.  
  169.     gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
  170.                 g_array_index (articles, Item, i).number, -1);
  171.       }
  172.       break;
  173.  
  174.     case COLUMN_PRODUCT:
  175.       {
  176.     gint i;
  177.     gchar *old_text;
  178.  
  179.         gtk_tree_model_get (model, &iter, column, &old_text, -1);
  180.     g_free (old_text);
  181.  
  182.     i = gtk_tree_path_get_indices (path)[0];
  183.     g_free (g_array_index (articles, Item, i).product);
  184.     g_array_index (articles, Item, i).product = g_strdup (new_text);
  185.  
  186.     gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
  187.                             g_array_index (articles, Item, i).product, -1);
  188.       }
  189.       break;
  190.     }
  191.  
  192.   gtk_tree_path_free (path);
  193. }
  194.  
  195. static void
  196. add_columns (GtkTreeView *treeview)
  197. {
  198.   GtkCellRenderer *renderer;
  199.   GtkTreeModel *model = gtk_tree_view_get_model (treeview);
  200.  
  201.   /* number column */
  202.   renderer = gtk_cell_renderer_text_new ();
  203.   g_signal_connect (renderer, "edited",
  204.             G_CALLBACK (cell_edited), model);
  205.   g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_NUMBER);
  206.  
  207.   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
  208.                            -1, "Number", renderer,
  209.                            "text", COLUMN_NUMBER,
  210.                            "editable", COLUMN_EDITABLE,
  211.                            NULL);
  212.  
  213.   /* product column */
  214.   renderer = gtk_cell_renderer_text_new ();
  215.   g_signal_connect (renderer, "edited",
  216.             G_CALLBACK (cell_edited), model);
  217.   g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_PRODUCT);
  218.  
  219.   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
  220.                            -1, "Product", renderer,
  221.                            "text", COLUMN_PRODUCT,
  222.                            "editable", COLUMN_EDITABLE,
  223.                            NULL);
  224. }
  225.  
  226. GtkWidget *
  227. do_editable_cells (GtkWidget *do_widget)
  228. {
  229.   if (!window)
  230.     {
  231.       GtkWidget *vbox;
  232.       GtkWidget *hbox;
  233.       GtkWidget *sw;
  234.       GtkWidget *treeview;
  235.       GtkWidget *button;
  236.       GtkTreeModel *model;
  237.  
  238.       /* create window, etc */
  239.       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  240.       gtk_window_set_screen (GTK_WINDOW (window),
  241.                  gtk_widget_get_screen (do_widget));
  242.       gtk_window_set_title (GTK_WINDOW (window), "Shopping list");
  243.       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
  244.       g_signal_connect (window, "destroy",
  245.             G_CALLBACK (gtk_widget_destroyed), &window);
  246.  
  247.       vbox = gtk_vbox_new (FALSE, 5);
  248.       gtk_container_add (GTK_CONTAINER (window), vbox);
  249.  
  250.       gtk_box_pack_start (GTK_BOX (vbox),
  251.               gtk_label_new ("Shopping list (you can edit the cells!)"),
  252.               FALSE, FALSE, 0);
  253.  
  254.       sw = gtk_scrolled_window_new (NULL, NULL);
  255.       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
  256.                        GTK_SHADOW_ETCHED_IN);
  257.       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  258.                       GTK_POLICY_AUTOMATIC,
  259.                       GTK_POLICY_AUTOMATIC);
  260.       gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
  261.  
  262.       /* create model */
  263.       model = create_model ();
  264.  
  265.       /* create tree view */
  266.       treeview = gtk_tree_view_new_with_model (model);
  267.       g_object_unref (model);
  268.       gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
  269.       gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
  270.                    GTK_SELECTION_SINGLE);
  271.  
  272.       add_columns (GTK_TREE_VIEW (treeview));
  273.  
  274.       gtk_container_add (GTK_CONTAINER (sw), treeview);
  275.  
  276.       /* some buttons */
  277.       hbox = gtk_hbox_new (TRUE, 4);
  278.       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  279.  
  280.       button = gtk_button_new_with_label ("Add item");
  281.       g_signal_connect (button, "clicked",
  282.             G_CALLBACK (add_item), model);
  283.       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  284.  
  285.       button = gtk_button_new_with_label ("Remove item");
  286.       g_signal_connect (button, "clicked",
  287.             G_CALLBACK (remove_item), treeview);
  288.       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  289.  
  290.       gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
  291.     }
  292.  
  293.   if (!GTK_WIDGET_VISIBLE (window))
  294.     gtk_widget_show_all (window);
  295.   else
  296.     {
  297.       gtk_widget_destroy (window);
  298.       window = NULL;
  299.     }
  300.  
  301.   return window;
  302. }
  303.