I think that this cannot be achieved, main reason being that combo cell renderer is actually drawing it's content with 2 different renderers. First renderer is drawing text in non-editing state and gets it's data from treeview's model. The second renders the whole popup list in editing state and it's data comes from internal model.
This is why you need to copy the new string to the master model in the "edited" signal handler - you cannot use data in combo renderer's internal model in non-editing state. 2008/12/16 John M Collins <j...@xisl.com>: > Thanks again for your help: > > I do actually need to create and delete this dialog as needed, indeed in > principle I could have several of them active at the same time (they are > sub-structures hanging off a list of "master" structures) so I do need to be > careful that everything is destroyed. > > The question you didn't quite understand was: > > In your example code you specified the relevant column of the "master" list > store as a string, so when the rows were initialised you set a string value > "None", "String" "Integer" in the code below: > > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, "None", > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 0, > INT_SENS_COL, FALSE, > -1 ); > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, "Integer", > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 5, > INT_SENS_COL, TRUE, > -1 ); > > The type field in the structure which is being represented here by the combo > box renderer is an int so with the column given as a string the int has to > be translated to the appropriate string in the combo box list when it is > initialised and when the dialog finishes (or when the selection changes and > the relevant columns made sensitive or not sensitive) the string being > displayed has to be translated back to the appropriate int value. > > I just wondered if it was possible to make the TYPE_COL column in the > "master" list store a G_TYPE_INT and have it select the relevant row in the > "model" combo box list store row and display the string for that so the code > could be: > > > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, MY_STRUCT_TYPE_NONE, > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 0, > INT_SENS_COL, FALSE, > -1 ); > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, MY_STRUCT_TYPE_INT, > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 5, > INT_SENS_COL, TRUE, > -1 ); > > My conclusion was that as the GtkCellRendererCombo was a derivative of the > GtkCellRendererText, (and with "has-entry" TRUE the string in there can be > different from any in the combo box list), this is not possible but I just > wanted to confirm it. > > > On Tue, 2008-12-16 at 12:25 +0100, Tadej Borovšak wrote: > >> 1. Given that this is a dialog which may be popped up and dismissed >> several >> times whilst the application runs, do I need to do any g_object_unrefs on >> any of the list stores or other parts to avoid memory leaks? > > If you'll be only hiding your popup window and reuse it several times, > you don't need to do anything, since the data structures will be > needed throughout the whole application life cycle. > > On the other hand, if you intend to replace models or if you'll be > destroying your popup after every usage and re-create it on demand, > you need to unref models after they have been added to their place. > This way, the container will hold the last reference to that model and > when the models will be destroyed together with the parent. > > Note that you don't need to unref GtkAdjustment, since it's created > with only floating reference which is sunken when adjustment gets > added in cell renderer. > > (TIP: How to determine refcount of the created object? > If one of the object's ancestors is GInitiallyUnowned, the object has > only floating reference when created, otherwise it has refcount of 1.) > > The required code modifications are marked inside my code snippet below. > >> 2. Given that the type field in my structure is an integer, do I take it >> that the appropriate starting type cannot be selected nor the final value >> extracted when the dialog completes out of the combo as an integer, I have >> to make the list column a string and insert the appropriate string and >> decipher the appropriate string at the end as the Combo renderer is based >> on >> a text entry so there is no equivalent of xxxx_get_active() like I have >> with >> a "standalone" combo box? > > I don't quite understand what are you trying to say here. But in > general, "look-a-like" treeview widgets (like GtkCellRendererCombo) > are whole different beasts than their "standalone" counterparts. > > Their main task is to display things that they are ordered to. Orders > can come directly from their properties (these kind of orders are > created with g_object_set function call) or from underlying treeview's > model (put in place with gtk_tree_view_column_set_attributes function > call). > > The "bonus" functionality is limited to the time when the cell > renderer is in "editing mode" (this is why you need to set their > "editable" property to TRUE - if you don't, combo and spin cell > renderers offer the same functionality as the non-editable text cell > renderer). Plus their bonus is strictly superficial - the underlying > model is NOT modified at all. It's programmer's responsibility to get > the selected value at the end of the editing and update the model. > > I'm not sure if I answered your question, so feel free to send another mail. > >> 3. Is there a sensible way without speaking pixels that I can say "allow >> for >> at least n rows initially" as if my initial list is empty or has only one >> row the thing is stupidly small (I am using a scroll on the treeview as it >> could get arbitrarily large). > > I only know gtk_widget_set_size_request function (and trying to avoid > it since it usually brings more problems than it solves). My usual > approach is to pack GtkScrolledWindow in such a way that it gets > resided whenever the main window is resized and the set the default > window size. It's not the perfect solution, but most of the time works > OK. > > > -------------- > #include <gtk/gtk.h> > > enum > { > TYPE_COL, > TEXT_COL, > TEXT_SENS_COL, > INT_COL, > INT_SENS_COL, > NO_COLS > }; > > > static void > cb_type_changed( GtkCellRendererText *renderer, > gchar *path, > gchar *new_text, > GtkListStore *master ) > { > GtkTreeIter iter; > gchar *old_text; > gboolean text_sens = FALSE; > gboolean int_sens = FALSE; > > /* Get previous value from master model */ > gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( master ), > &iter, path ); > gtk_tree_model_get( GTK_TREE_MODEL( master ), &iter, > TYPE_COL, &old_text, -1 ); > > /* Do we need to change anything? */ > if( ! g_strcmp0( old_text, new_text ) ) > return; > > /* What changes are needed? */ > if( ! g_strcmp0( new_text, "String" ) ) > text_sens = TRUE; > else if( ! g_strcmp0( new_text, "Integer" ) ) > int_sens = TRUE; > > /* Update master model */ > gtk_list_store_set( master, &iter, TYPE_COL, new_text, > TEXT_SENS_COL, text_sens, > INT_SENS_COL, int_sens, > -1 ); > } > > > static void > cb_string_param_changed( GtkCellRendererText *renderer, > gchar *path, > gchar *new_text, > GtkListStore *master ) > { > GtkTreeIter iter; > > /* Update master model */ > gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( master ), > &iter, path ); > gtk_list_store_set( master, &iter, TEXT_COL, new_text, -1 ); > } > > static void > cb_integer_param_changed( GtkCellRendererText *renderer, > gchar *path, > gchar *new_text, > GtkListStore *master ) > { > GtkTreeIter iter; > gint value; > > /* Update master model */ > gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( master ), > &iter, path ); > value = (gint)strtol( new_text, NULL, 10 ); > gtk_list_store_set( master, &iter, INT_COL, value, -1 ); > } > > int > main( int argc, > char **argv ) > { > GtkWidget *window; > GtkWidget *treeview; > GtkListStore *model; > GtkListStore *master; > GtkTreeIter iter; > GtkCellRenderer *renderer; > GtkAdjustment *adj; > GtkTreeViewColumn *col; > > gtk_init( &argc, &argv ); > > window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); > g_signal_connect( G_OBJECT( window ), "destroy", > G_CALLBACK( gtk_main_quit ), NULL ); > > > /* create treeview */ > treeview = gtk_tree_view_new(); > gtk_tree_view_set_reorderable( GTK_TREE_VIEW( treeview ), TRUE ); > gtk_container_add( GTK_CONTAINER( window ), treeview ); > > /* Create "master" model for treeview and add 2 entries */ > master = gtk_list_store_new( NO_COLS, G_TYPE_STRING, > G_TYPE_STRING, > G_TYPE_BOOLEAN, > G_TYPE_INT, > G_TYPE_BOOLEAN ); > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, "None", > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 0, > INT_SENS_COL, FALSE, > -1 ); > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, "Integer", > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 5, > INT_SENS_COL, TRUE, > -1 ); > gtk_tree_view_set_model( GTK_TREE_VIEW( treeview ), > GTK_TREE_MODEL( master ) ); > /* master has now refcount of 2 (1 from our initial creation + > * 1 from addition to treeview). We'll remove our reference so > * the model will be destroyed if: > * - it's removed from treeview > * - treeview gets destroyed > */ > g_object_unref( G_OBJECT( master ) ); > > /* column 1 */ > /* Create model for combo renderer and populate it */ > model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "None", 1, 0, -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "String", 1, 1, -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Integer", 1, 2, -1 ); > > /* Create column and add renderer to it */ > col = gtk_tree_view_column_new(); > gtk_tree_view_column_set_resizable( col, TRUE ); > > renderer = gtk_cell_renderer_combo_new(); > g_signal_connect( G_OBJECT( renderer ), "edited", > G_CALLBACK( cb_type_changed ), master ); > g_object_set( G_OBJECT( renderer ), "model", GTK_TREE_MODEL( model ), > "text-column", 0, > "editable", TRUE, > "has_entry", FALSE, > NULL ); > /* Unref model (the same logic applies here as with the first unref) */ > g_object_unref( G_OBJECT( model ) ); > > gtk_tree_view_column_pack_start( col, renderer, TRUE ); > gtk_tree_view_column_set_attributes( col, renderer, "text", TYPE_COL, > NULL ); > gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), col ); > > /* column 2 */ > /* Again create model for combo renderer and populate it */ > model = gtk_list_store_new( 1, G_TYPE_STRING ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Parameter 1", -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Parameter 2", -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Parameter 3", -1 ); > > /* Create column and add renderer to it */ > col = gtk_tree_view_column_new(); > gtk_tree_view_column_set_resizable( col, TRUE ); > > renderer = gtk_cell_renderer_combo_new(); > g_signal_connect( G_OBJECT( renderer ), "edited", > G_CALLBACK( cb_string_param_changed ), master ); > g_object_set( G_OBJECT( renderer ), "model", GTK_TREE_MODEL( model ), > "text-column", 0, > "has_entry", FALSE, > NULL ); > /* Unref model (the same logic applies here as with the first unref) */ > g_object_unref( G_OBJECT( model ) ); > > gtk_tree_view_column_pack_start( col, renderer, TRUE ); > gtk_tree_view_column_set_attributes( col, renderer, > "text", TEXT_COL, > "sensitive", TEXT_SENS_COL, > "editable", TEXT_SENS_COL, > NULL ); > gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), col ); > > /* column 3 */ > /* Create adjustment for spin renderer */ > adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 100, 1, 10, 0 ) ); > > /* Create column and add renderer to it */ > col = gtk_tree_view_column_new(); > gtk_tree_view_column_set_resizable( col, TRUE ); > > renderer = gtk_cell_renderer_spin_new(); > g_signal_connect( G_OBJECT( renderer ), "edited", > G_CALLBACK( cb_integer_param_changed ), master ); > g_object_set( G_OBJECT( renderer ), "adjustment", adj, > "editable", TRUE, > NULL ); > gtk_tree_view_column_pack_start( col, renderer, TRUE ); > gtk_tree_view_column_set_attributes( col, renderer, > "text", INT_COL, > "sensitive", INT_SENS_COL, > "editable", INT_SENS_COL, > NULL ); > gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), col ); > > > gtk_widget_show_all( window ); > > gtk_main(); > > return( 0); > } > -------------- > > John Collins Xi Software Ltd www.xisl.com > > > -- Tadej Borovšak 00386 (0)40 613 131 tadeb...@gmail.com tadej.borov...@gmail.com _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list