ModelFilter trouble
- From: Jason Edgecombe <jason rampaginggeek com>
- To: gtk-app-devel-list gnome org
- Subject: ModelFilter trouble
- Date: Mon, 21 Jan 2008 19:07:23 -0500
Hi,
I'm having trouble with GtkModelFilter. I'm trying to make a shopping
list using hildon and a gtknotebook with three tabs, all, have & need.
All is the unfiltered model which has a boolean and a label.The need tab
shows only items where the boolean is true and the have tabe shows an
item only when the boolean is false.
The need tab appears correct when first displayed, but when I click a
checkbox, it shows what the have tab shows.
My code is attached.right now, I'm working on the gui, which will
eventually be connected to an sqlite backend. My target is maemo on the
Nokia N800.
Any help is appreciated.
Thanks,
Jason
#include <hildon/hildon-program.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkbutton.h>
#include <stdio.h>
#include <stdlib.h>
GtkTreeModel *create_and_fill_model (void);
GtkWidget *create_view_and_model (void);
void cell_toggled_callback (GtkCellRendererToggle *cell,
gchar *path_string,
GtkTreeView *tree_view);
GtkTreeView *create_view_from_model( GtkTreeModel *model );
GtkTreeModel *create_model_filter( GtkTreeModel* model,
int condition );
gboolean tab_focus_callback( GtkNotebook *notebook,
gint *arg1,
gpointer model );
const true = 1;
const false = 0;
enum {
COL_NAME = 0,
COL_NEED,
NUM_COLS
};
const FILTER_HAVE = 0;
const FILTER_NEED = 1;
gboolean filter_visible( GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data );
int main(int argc, char *argv[])
{
/* Create needed variables */
HildonProgram *program;
HildonWindow *window;
GtkWidget *view;
GtkTreeView *have_view;
GtkTreeView *need_view;
GtkTreeModel *model;
GtkTreeModel *have_model;
GtkTreeModel *need_model;
GtkWidget *all_label, *need_label, *have_label;
GtkWidget *scrolled_window, *have_scrolled_window,
*need_scrolled_window;
GtkWidget *notebook;
/* Initialize the GTK. */
gtk_init(&argc, &argv);
/* Create the hildon program and setup the title */
program = HILDON_PROGRAM(hildon_program_get_instance());
g_set_application_name("ShoppingList");
/* Create HildonWindow and set it to HildonProgram */
window = HILDON_WINDOW(hildon_window_new());
hildon_program_add_window(program, window);
scrolled_window = gtk_scrolled_window_new( GTK_ADJUSTMENT( NULL ),
GTK_ADJUSTMENT( NULL ) );
// setup the notebook
notebook = gtk_notebook_new();
gtk_notebook_set_tab_pos( GTK_NOTEBOOK( notebook ),
GTK_POS_BOTTOM );
gtk_container_add (GTK_CONTAINER (window), notebook);
view = create_view_and_model();
model = gtk_tree_view_get_model( GTK_TREE_VIEW( view ) );
gtk_container_add (GTK_CONTAINER (scrolled_window), view);
// add the all tab
all_label = gtk_label_new( "All" );
gtk_notebook_append_page( GTK_NOTEBOOK( notebook ),
scrolled_window,
all_label );
/*
// create the "have" filtered model
have_scrolled_window = gtk_scrolled_window_new( NULL, NULL );
have_model = create_model_filter( model, FILTER_HAVE );
have_view = create_view_from_model( GTK_TREE_MODEL( have_model ) );
gtk_container_add (GTK_CONTAINER( have_scrolled_window ),
GTK_WIDGET( have_view ) );
// add the Have tab
have_label = gtk_label_new( "Have" );
gtk_notebook_append_page( GTK_NOTEBOOK( notebook ),
have_scrolled_window,
have_label );
// refilter HAVE tab on focus
g_signal_connect( GTK_NOTEBOOK( notebook ), "switch-page",
(GCallback) tab_focus_callback, have_model);
*/
// create the "need" filtered model
need_scrolled_window = gtk_scrolled_window_new( NULL, NULL );
need_model = create_model_filter( model, FILTER_NEED );
gtk_tree_model_filter_refilter( need_model );
need_view = create_view_from_model( GTK_TREE_MODEL( need_model ) );
gtk_container_add (GTK_CONTAINER( need_scrolled_window ),
GTK_WIDGET( need_view ) );
// add the Need tab
need_label = gtk_label_new( "Need" );
gtk_notebook_append_page( GTK_NOTEBOOK( notebook ),
need_scrolled_window,
need_label );
// refilter NEED tab on focus
//g_signal_connect( GTK_NOTEBOOK( notebook ), "switch-page",
// (GCallback) tab_focus_callback, need_view);
/* Connect signal to X in the upper corner */
g_signal_connect( G_OBJECT( window ), "delete_event",
G_CALLBACK( gtk_main_quit ), NULL );
/* Begin the main application */
gtk_widget_show_all( GTK_WIDGET( window ) );
gtk_main();
/* Exit */
return EXIT_SUCCESS;
}
gboolean filter_visible( GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data ) {
gint *filter = (gint *) data;
gboolean column_value;
gboolean result = FALSE;
gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
COL_NEED, &column_value, -1);
// if "need" view
if ( *filter == FILTER_NEED ) {
// "need" view, show rows where need_column is true
result = column_value;
} else {
// "have" view, show rows where need_column is false
result = column_value==TRUE ? FALSE : TRUE;
}
return result;
}
GtkTreeModel *create_model_filter( GtkTreeModel* model,
int condition ) {
GtkTreeModel *model_filter =
gtk_tree_model_filter_new( model, NULL );
gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER( model_filter ),
filter_visible,
( gpointer ) &condition, NULL );
GtkWidget *view = gtk_tree_view_new();
gtk_tree_view_set_model( GTK_TREE_VIEW( view ),
GTK_TREE_MODEL( model_filter ) );
return GTK_TREE_MODEL( model_filter );
}
GtkTreeModel *create_and_fill_model (void) {
GtkListStore *store;
GtkTreeIter iter;
int i = 0;
store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_BOOLEAN);
for( i=0; i < 25; i++ ) {
/* Append a row and fill in some data */
char number_string[30];
char item_string[50] = "item";
int checked = i % 2;
snprintf( number_string, 30, "%i", i );
strncat(item_string, number_string, 50);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COL_NAME, item_string,
COL_NEED, checked,
-1);
}
return GTK_TREE_MODEL (store);
}
GtkTreeView *create_view_from_model( GtkTreeModel *model ) {
GtkCellRenderer *name_renderer, *need_renderer;
GtkWidget *view;
view = gtk_tree_view_new ();
gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), true );
/* --- Column #1 --- */
need_renderer = gtk_cell_renderer_toggle_new ();
g_object_set( need_renderer, "activatable", TRUE, NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"Need",
need_renderer,
"active", COL_NEED,
NULL);
/* --- Column #2 --- */
name_renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"Name",
name_renderer,
"text", COL_NAME,
NULL);
g_signal_connect(need_renderer, "toggled",
(GCallback) cell_toggled_callback, view);
/* The tree view has acquired its own reference to the
* model, so we can drop ours. That way the model will
* be freed automatically when the tree view is destroyed */
//g_object_unref (model);
return GTK_TREE_VIEW( view );
}
GtkWidget *create_view_and_model (void) {
GtkCellRenderer *name_renderer, *need_renderer;
GtkListStore *model;
GtkWidget *view;
view = gtk_tree_view_new ();
gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), true );
/* --- Column #1 --- */
need_renderer = gtk_cell_renderer_toggle_new ();
g_object_set( need_renderer, "activatable", TRUE, NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"Need",
need_renderer,
"active", COL_NEED,
NULL);
/* --- Column #2 --- */
name_renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"Name",
name_renderer,
"text", COL_NAME,
NULL);
model = create_and_fill_model ();
g_signal_connect(need_renderer, "toggled",
(GCallback) cell_toggled_callback, view);
gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
/* The tree view has acquired its own reference to the
* model, so we can drop ours. That way the model will
* be freed automatically when the tree view is destroyed */
g_object_unref (model);
return view;
}
void cell_toggled_callback (GtkCellRendererToggle *cell,
gchar *path_string,
GtkTreeView *tree_view) {
GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
GtkTreeModelFilter *filter_model;
//g_print("CB(cell_toggled:tree_view %s\n",G_OBJECT_TYPE_NAME( model ) );
char *model_class = G_OBJECT_TYPE_NAME( model );
GtkTreeIter iter;
GtkTreePath *path, *filter_path;
gboolean column_value, new_column_value;
path = gtk_tree_path_new_from_string( path_string );
// get the real model, & path if model is a GtkTreeModelFilter
if ( !strcmp( "GtkTreeModelFilter", model_class ) ) {
filter_model = model;
model = gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model ) );
filter_path = path;
path = gtk_tree_model_filter_convert_path_to_child_path( filter_model,
filter_path);
}
if ( !gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path ) ) {
g_warning ("%s: could not find path", G_STRLOC);
return;
}
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
COL_NEED, &column_value, -1);
// toggle the column_value 0=>1; 1=>0;
new_column_value = column_value ? 0 : 1;
gtk_list_store_set( GTK_LIST_STORE( model ), &iter,
COL_NEED, new_column_value, -1);
//gtk_list_store_set_value( GTK_LIST_STORE( model ), &iter,
// COL_NEED, new_column_value );
//gtk_tree_model_row_changed( model, path, &iter );
gtk_tree_path_free (path);
// get the real model, & path if model is a GtkTreeModelFilter
if ( !strcmp( "GtkTreeModelFilter", model_class ) ) {
gtk_tree_model_filter_refilter( filter_model );
gtk_tree_path_free (filter_path);
}
return;
}
gboolean tab_focus_callback( GtkNotebook *notebook,
gint *arg1,
gpointer data ) {
// GtkTreeView* view = (GtkTreeView *)data;
//g_print( "CB: tab_focus_callback:mode %s\n",G_OBJECT_TYPE_NAME( view ) );
g_print( "CB: tab_focus_callback:begin\n" );
//gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ) );
g_print( "CB: tab_focus_callback:end\n" );
// g_print( "CB: tab_focus_callback %i\n", *arg1 );
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]