Here is my problem.
I have TreeStore with data, that looks like this:
"item 0 - level 0"
"item 0:0 - level 1"
"item 0:0:0 - level 2"
"item 0:0:1 - level2"
"item 1 - level 0"
"item 1:0 - level 1"
"item 1:0:0 - level 2"...and so on. Depth of this tree is exactly 3. Now I want to filter the lowest level items. Only 2nd level items, which names contain some substring will be visible. 0th and 1st level items will be visible only, when they contain some visible 2nd level items. That means: if "item 0:0:0" and "item 0:0:1" will be filtered out, "item 0" and "item 0:0" should disappear as well. The process of filtering has been solved and is not a problem here. There are two implementations (attached to this post): one in C, the other one in Python. In fact they both are supposed to work in identical way. One was derived from another by simply translating statements. The problem is that while C version works as expected (hides level 0 and 1 rows when necessary while showing level 2 rows), the Python version gives unpredictable results. It looks like it filters rows properly (level 0 items disappear when they should), but never shows level 1 and 2 items! From these two examples it looks to me like there is some problem on Python-C boundary. I'm not familiar with that kind of debugging, so I ask you for help. Does anybody know what's the source of the problem can be? Can anybody either give me hints on ways of debugging such problems or take a look and provide exact solution? Thank you in advance, p_michalczyk
#include <gtk/gtk.h>
#include <iostream>
#include <set>
#include <string>
#include <assert.h>
using namespace std;
enum
{
COL_NAME = 0,
COL_LEVEL = 1,
COL_ID = 2,
NUM_COLS
};
typedef struct {
char name[50];
uint level;
uint id;
} row;
row rows[] = {{"albums", 0, 501}, {"richard_galliano", 1, 502}, {"richard_galliano_luz_negra", 2, 503},
{"classical", 0, 504}, {"collections", 1, 505}, {"magic_of_waltz_cd1", 2, 506},
{"magic_of_waltz_cd2", 2, 507}};
GtkTreeModelFilter *modelFilter;
set<int> visibleItems;
string filterText;
GtkWidget *view;
void
onEntryChanged(GtkWidget *entry, void *data) {
cout << gtk_entry_get_text(GTK_ENTRY(entry)) << endl;
filterText = gtk_entry_get_text(GTK_ENTRY(entry));
visibleItems.clear();
gtk_tree_model_filter_refilter(modelFilter);
gtk_tree_view_expand_all(GTK_TREE_VIEW (view));
//cout.flush();
}
gboolean visibleFunc(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
gint level, id;
gtk_tree_model_get(model, iter, 1, &level, 2, &id, -1);
if( level == 0) {
return visibleItems.find(id) != visibleItems.end();
}
else if( level == 1) {
return visibleItems.find(id) != visibleItems.end();
}
else if( level == 2) {
gchar* text;
gtk_tree_model_get(model, iter, 0, &text, -1);
string albumName = text;
if( !filterText.empty() && (albumName.find(filterText) == -1)) {
return 0;
}
else {
gboolean ret;
GtkTreeIter artistIter, reposIter;
ret = gtk_tree_model_iter_parent(model, &artistIter, iter);
assert(ret);
ret = gtk_tree_model_iter_parent(model, &reposIter, &artistIter);
assert(ret);
gint reposId;
gtk_tree_model_get(model, &reposIter, 2, &reposId, -1);
if( visibleItems.find(reposId) == visibleItems.end()) {
visibleItems.insert(reposId);
GtkTreePath* path;
path = gtk_tree_model_get_path(model, &reposIter);
gtk_tree_model_row_changed(model, path, &reposIter);
gtk_tree_path_free(path);
}
gint artistId;
gtk_tree_model_get(model, &artistIter, 2, &artistId, -1);
if( visibleItems.find(artistId) == visibleItems.end()) {
visibleItems.insert(artistId);
GtkTreePath* path;
path = gtk_tree_model_get_path(model, &artistIter);
gtk_tree_model_row_changed(model, path, &artistIter);
gtk_tree_path_free(path);
}
return 1;
}
}
return 0;
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkCellRenderer *renderer;
GtkTreeModel *model;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_resize(GTK_WINDOW(window), 300, 250);
g_signal_connect (window, "delete_event", gtk_main_quit, NULL);
view = gtk_tree_view_new ();
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"Name",
renderer,
"text", COL_NAME,
NULL);
GtkTreeStore *store;
GtkTreeIter iter[5];
store = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT);
uint i;
for(i = 0; i < sizeof(rows)/sizeof(rows[0]); i++) {
if(rows[i].level == 0)
gtk_tree_store_append (store, &iter[rows[i].level], NULL);
else
gtk_tree_store_append (store, &iter[rows[i].level], &iter[rows[i].level-1]);
gtk_tree_store_set (store, &iter[rows[i].level],
COL_NAME, rows[i].name,
COL_LEVEL, rows[i].level,
COL_ID, rows[i].id,
-1);
}
model = GTK_TREE_MODEL (store);
modelFilter = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(model, NULL));
gtk_tree_model_filter_set_visible_func(modelFilter, visibleFunc, NULL, NULL);
gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL(modelFilter));
GtkWidget *box = gtk_vbox_new(FALSE, 5);
GtkWidget *entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(box), entry, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), view, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (window), box);
g_signal_connect(entry, "changed", (GCallback)onEntryChanged, NULL);
gtk_tree_model_filter_refilter(modelFilter);
gtk_tree_view_expand_all(GTK_TREE_VIEW (view));
gtk_widget_show_all (window);
gtk_main ();
g_object_unref (modelFilter);
return 0;
}
tmf.py
Description: application/python
_______________________________________________ pygtk mailing list [email protected] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
