Hi,
It has taken a far bit of time for many different reasons, but here goes.
There is no need to file a bug report, as all is actually OK, but not what you may expect should happen. I have done a fair bit of rewriting of your code.
Code:
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
static GtkWidget *window = NULL;
typedef struct
{
gchar *product;
gfloat yummy;
}
Item;
enum
{
COLUMN_ITEM_PRODUCT,
COLUMN_ITEM_YUMMY,
NUM_ITEM_COLUMNS
};
static GtkWidget *treeview;
static GtkListStore *model;
static GArray *
add_items (void)
{
Item foo;
GArray *articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 2);
if (!articles) return NULL;
foo.product = "bottles of coke";
foo.yummy = 20.0;
g_array_append_vals (articles, &foo, 1);
foo.product = "packages of noodles";
foo.yummy = 50.0;
g_array_append_vals (articles, &foo, 1);
return articles;
}
static void
create_items_model (void)
{
gint i = 0;
GtkTreeIter iter;
GArray *articles = add_items();
/* create list store */
model = gtk_list_store_new (NUM_ITEM_COLUMNS, G_TYPE_STRING,
G_TYPE_FLOAT, G_TYPE_BOOLEAN);
/* add items */
for (i = 0; i < articles->len; i++)
{
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter,
COLUMN_ITEM_PRODUCT,
g_array_index (articles, Item, i).product,
COLUMN_ITEM_YUMMY,
g_array_index (articles, Item, i).yummy,
-1);
}
g_array_free (articles, TRUE);
}
static void
edited_done (GtkCellRendererText *renderer,
gchar *path,
gchar *new_text,
gpointer user_data)
{
GtkTreeIter iter;
gfloat value = g_strtod(new_text, NULL);
if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path)) {
gtk_list_store_set (model, &iter,
COLUMN_ITEM_YUMMY, value, -1);
}
}
static void
edit_started_spin_cb (GtkCellRenderer *renderer,
GtkCellEditable *editable,
gchar *path,
gpointer user_data)
{
GtkAdjustment *adj;
g_object_get (renderer, "adjustment", &adj, NULL);
if (adj)
g_object_unref (adj);
adj = gtk_adjustment_new (0.0, 0.0, 1000.0, 0.1, 1.0, 1.0);
g_object_set (renderer, "adjustment", adj, NULL);
}
static void
add_columns ()
{
GtkCellRenderer *renderer;
GtkAdjustment *adjust;
/* product column */
renderer = gtk_cell_renderer_text_new ();
g_object_set_data (G_OBJECT (renderer),
"column", GINT_TO_POINTER (COLUMN_ITEM_PRODUCT));
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-1, "Product", renderer,
"text", COLUMN_ITEM_PRODUCT,
NULL);
/* yummy column */
adjust = gtk_adjustment_new (0.0, 0.0, 1000.0, 0.1, 1.0, 1.0);
renderer = gtk_cell_renderer_spin_new ();
g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_YUMMY));
g_object_set (renderer,
"editable", TRUE,
"adjustment", adjust,
"digits", 3,
// "climb-rate", 0.5
NULL);
g_signal_connect (renderer, "edited", G_CALLBACK (edited_done), NULL);
g_signal_connect (renderer, "editing-started", G_CALLBACK (edit_started_spin_cb), NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-1, "Yummy", renderer,
"text", COLUMN_ITEM_YUMMY,
NULL);
}
int main (int argc, char *argv[])
{
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *sw;
GtkWidget *button;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // GTK_WINDOW_TOPLEVEL
gtk_widget_set_size_request(window, 800, 600);
gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_title (GTK_WINDOW (window), "Shopping list");
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), &window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_box_pack_start (GTK_BOX (vbox),
gtk_label_new ("Shopping list (you can edit only SPIN-BUTTON cell !)"),
FALSE, FALSE, 0);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
/* create models */
create_items_model ();
/* create tree view */
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
GTK_SELECTION_SINGLE);
add_columns ();
gtk_container_add (GTK_CONTAINER (sw), treeview);
/* some buttons */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("EXIT");
g_signal_connect (button, "clicked", G_CALLBACK(gtk_main_quit), NULL);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
First I removed the deprecated use of code. These were gtk_hbox_new() and gtk_vbox_new() and replced them with gtk_box_new().
You were using the wrong signals for your original code. The signals that you should have used are "edited" and "editing-started".
The call back function for the signal "editing-started" is call before the editing is started and the GtkSpinButton is displayed. This function removes the old GtkAdjustment from the cell renderer and replaces it with a new one. Without doing this every time the user edits a GtkCellRendererSpin field more signals are added to the GtkAdjustment, and when the value changes all the signals are called including the old ones with invalid data.
The call back function for the signal "edited" is call once all editing has completed. All this function has to do is get the new data and insert it into the correct place in the tree view model.
I have also tided up the code is various places.
Hopefully the code is easier to read although still not perfect. There is still rounding errors, this is partly due to the different precision that is used for displaying the values and for working with the values in the GtkSpinButton.
I shall leave this as an exercise to improve the displaying of the values in the tree view. As a hint the function that you need is gtk_tree_view_column_set_cell_data_func () and the property to set is "text".
Hope this is of help.