On Fri, 2008-12-19 at 16:10 +0000, John M Collins wrote: > Sorry to trouble you again but I assume that in this function (and > others) I need a "g_free(old_text)" prior to both returns?
Yes. > (From the documentation of gtk_tree_model_get). > > Thanks > > > 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 ); > } > > > 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 > > _______________________________________________ > gtk-app-devel-list mailing list > gtk-app-devel-list@gnome.org > http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list -- Murray Cumming murr...@murrayc.com www.murrayc.com www.openismus.com _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list