Sign up

How to filter TreeView according to user input

I'd like to filter Treeview data according to user input. But when I execute this program it gives this error:

Gtk-CRITICAL **: gtktreemodelfiltergetvalue: assertion `GTKTREEMODELFILTER (model)->priv->stamp == iter->stamp' failed
(Segmentation fault)

What should I pass exactly to setVisibleFunc? I was expecting to pass filtered data and an iterator.

Also is cast(GtkTreeModelFilterVisibleFunc) part really needed?

Here is the complete example program.

import gtk.Main;
import gtk.MainWindow;
import gtk.Box;
import gtk.Entry;
import gtk.EditableIF;
import gtk.TreeModelFilter;
import gtk.TreeView;
import gtk.HBox;
import gtk.VBox;
import gtk.Label;
import gtk.ListStore;
import gtk.TreeViewColumn;
import gtk.CellRendererText;
import gtk.TreeModel;
import gtk.TreeIter;

import std.conv;
import std.stdio;

class MyWindow: MainWindow
{
    Box mainBox;
    Entry filterEntry;
    TreeModelFilter filter;
    TreeIter iter;

    this()
    {
        super("TreeView Example");
        setSizeRequest(500, 200);
        filterEntry = new Entry();
        auto filterLabel= new Label("Artist search");
        auto tree = new TreeView();
        auto box = new VBox(false, 0);

        auto dataModel = new ListStore([GType.STRING, GType.STRING]);
                
        auto artistColumn = new TreeViewColumn("Artist", new CellRendererText(), "text", 0);
        tree.appendColumn(artistColumn);
        auto songColumn = new TreeViewColumn("Song title", new CellRendererText(), "text", 1);
        tree.appendColumn(songColumn);

        iter = dataModel.createIter();
        dataModel.setValue(iter, 0, "This is a test");
        dataModel.setValue(iter, 1, "Sample song");

        iter = dataModel.createIter();
        dataModel.setValue(iter, 0, "This is a test");
        dataModel.setValue(iter, 1, "Another song");

        iter = dataModel.createIter();
        dataModel.setValue(iter, 0, "Another artist");
        dataModel.setValue(iter, 1, "Test song");

        filter = new TreeModelFilter(dataModel, null);
        filter.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc) filterTree(filter, iter), null, null);

        tree.setModel(filter);

        auto mainBox = new HBox(false, 0);
        mainBox.packStart(filterLabel, false, false, 5);
        mainBox.packStart(filterEntry, true, true, 5);
        box.packStart(mainBox, false, false, 5);
        box.packStart(tree, true, true, 5);

        add(box);

        showAll();
    }

    bool filterTree(TreeModelFilter model1, TreeIter it1)
    {
        string artistName = to!string(model1.getValue(it1, 0));
        return true;
    }
    void onFilterEntryTextChanged(EditableIF filterEntry)
    {
        filter.refilter();
    }

    // void onFilterEntryTextChanged(ParamSpec param, ObjectG object)
    // {
    //     filter.refilter();
    // }
}

void main(string[] args)
{
    Main.init(args);
    new MyWindow();
    Main.run();
}

Re: How to filter TreeView according to user input

On 01/16/2017 08:48 PM, Erdem wrote:

I'd like to filter Treeview data according to user input. But when I execute this program it gives this error:

Gtk-CRITICAL **: gtktreemodelfiltergetvalue: assertion `GTKTREEMODELFILTER (model)->priv->stamp == iter->stamp' failed
(Segmentation fault)

What should I pass exactly to setVisibleFunc? I was expecting to pass filtered data and an iterator.

Also is cast(GtkTreeModelFilterVisibleFunc) part really needed?

Here is the complete example program.

Yes, the cast is necessary and unfortunately the callback receives the C
arguments, this is probably what is causing the problems.

filter.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc) &filterTree, 
null, null);

bool filterTree(GtkTreeModelFilter gtk_model, GtkTreeIter gtk_iter)
{
     model1 = new TreeModel(gtk_model);
     it1 = new TreeIter(gtk_iter);

     string artistName = to!string(model1.getValue(it1, 0));
     return true;
}

Re: How to filter TreeView according to user input

On Mon, 16 Jan 2017 22:31:34 +0100, Mike Wey wrote:

Yes, the cast is necessary and unfortunately the callback receives the C
arguments, this is probably what is causing the problems.

filter.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc) &filterTree, 
null, null);

bool filterTree(GtkTreeModelFilter gtk_model, GtkTreeIter gtk_iter)
{
     model1 = new TreeModel(gtk_model);
     it1 = new TreeIter(gtk_iter);

     string artistName = to!string(model1.getValue(it1, 0));
     return true;
}

I tried this approach but TreeModel class's doesn't take a GtkTreeModelFilter * . So I decided to make an instance of TreeModelFilter class but still segfaults.

filter.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc) & filterTree, null, null);
    bool filterTree(GtkTreeModelFilter gtkModel, GtkTreeIter gtkIter)
    {
        auto model1 = new TreeModelFilter(&gtkModel, false);
        auto it1 = new TreeIter(&gtkIterator, false);
        
        string artistName = to!string(model1.getValue(it1, 0));
        
        return true;
    }

Re: How to filter TreeView according to user input

This one should work:

import gtk.Main;
import gtk.MainWindow;
import gtk.Box;
import gtk.Entry;
import gtk.EditableIF;
import gtk.TreeModelFilter;
import gtk.TreeView;
import gtk.HBox;
import gtk.VBox;
import gtk.Label;
import gtk.ListStore;
import gtk.TreeViewColumn;
import gtk.CellRendererText;
import gtk.TreeModel;
import gtk.TreeIter;

import std.conv;
import std.stdio;

class MyWindow: MainWindow
{
     Box mainBox;
     Entry filterEntry;
     TreeModelFilter filter;
     TreeIter iter;

     this()
     {
         super("TreeView Example");
         setSizeRequest(500, 200);
         filterEntry = new Entry();
         auto filterLabel= new Label("Artist search");
         auto tree = new TreeView();
         auto box = new VBox(false, 0);

         auto dataModel = new ListStore([GType.STRING, GType.STRING]);

         auto artistColumn = new TreeViewColumn("Artist", new 
CellRendererText(), "text", 0);
         tree.appendColumn(artistColumn);
         auto songColumn = new TreeViewColumn("Song title", new 
CellRendererText(), "text", 1);
         tree.appendColumn(songColumn);

         iter = dataModel.createIter();
         dataModel.setValue(iter, 0, "This is a test");
         dataModel.setValue(iter, 1, "Sample song");

         iter = dataModel.createIter();
         dataModel.setValue(iter, 0, "This is a test");
         dataModel.setValue(iter, 1, "Another song");

         iter = dataModel.createIter();
         dataModel.setValue(iter, 0, "Another artist");
         dataModel.setValue(iter, 1, "Test song");

         filter = new TreeModelFilter(dataModel, null);
         filter.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc) 
&filterTree, null, null);

         tree.setModel(filter);

         auto mainBox = new HBox(false, 0);
         mainBox.packStart(filterLabel, false, false, 5);
         mainBox.packStart(filterEntry, true, true, 5);
         box.packStart(mainBox, false, false, 5);
         box.packStart(tree, true, true, 5);

         add(box);

         showAll();
     }

     static extern(C) int filterTree(GtkTreeModel* gtkModel, 
GtkTreeIter* gtkIter, void* data)
     {
         auto model1 = new TreeModel(gtkModel, false);
         auto it1 = new TreeIter(gtkIter, false);

         string artistName = to!string(model1.getValue(it1, 0));

         return true;
     }

     void onFilterEntryTextChanged(EditableIF filterEntry)
     {
         filter.refilter();
     }

     // void onFilterEntryTextChanged(ParamSpec param, ObjectG object)
     // {
     //     filter.refilter();
     // }
}

void main(string[] args)
{
     Main.init(args);
     new MyWindow();
     Main.run();
}

Re: How to filter TreeView according to user input

On Tue, 17 Jan 2017 15:43:28 +0100, Mike Wey wrote:

This one should work:

Thanks.