Problem with TreeModelFilter and editable columns



I ran into a strange problem with when I use a filtered tree model and
editable columns: when I edit the data in row X of the filtered data
set, the data in row X of the /unfiltered/ data set is updated (which is
usually not the same row :-().

I have reduced the code to a minimum and attached this below. Does
anyone have any ideas on what is going wrong?

Thanks,
Dingeman
// ===================================== MainWindow.h ==============================
#ifndef MainWindow_h
#define MainWindow_h

#include <gtkmm/window.h>
#include <gtkmm/treeview.h>
#include <gtkmm/treemodelfilter.h>
#include <gtkmm/liststore.h>

class MainWindow : public Gtk::Window
{
  public:
    MainWindow();
    virtual ~MainWindow();

  protected:
    virtual bool on_filter_row_visible(const Gtk::TreeModel::const_iterator& iter);
    virtual void on_filter();

  private:
    class ModelColumns : public Gtk::TreeModel::ColumnRecord
    {
      public:
	ModelColumns()
	{ 
	  add(m_field1); 
	  add(m_field2); 
	};
	Gtk::TreeModelColumn<bool> m_field1;
	Gtk::TreeModelColumn<int>  m_field2;
    };

    Gtk::TreeView m_treeview;
    ModelColumns m_columns;
    Glib::RefPtr<Gtk::ListStore> m_reftreemodel;
    Glib::RefPtr<Gtk::TreeModelFilter> m_reftreemodelfilter;
    bool m_filtered;
};

#endif

// ===================================== MainWindow.cpp ==============================
#include "MainWindow.h"
#include <gtkmm/box.h>
#include <gtkmm/togglebutton.h>

MainWindow::MainWindow() : m_filtered(false)
{
  set_title("Test");
  // add vbox
  Gtk::VBox* box = Gtk::manage(new Gtk::VBox);
  add(*box);
  // add button
  Gtk::ToggleButton* button = Gtk::manage(new Gtk::ToggleButton("show only rows > 5"));
  button->signal_toggled().connect(sigc::mem_fun(*this, &MainWindow::on_filter));
  box->pack_start(*button, Gtk::PACK_SHRINK);
  // create treeview
  m_reftreemodel = Gtk::ListStore::create(m_columns);
  m_reftreemodelfilter = Gtk::TreeModelFilter::create(m_reftreemodel);
  m_reftreemodelfilter->set_visible_func( sigc::mem_fun(*this, &MainWindow::on_filter_row_visible) );
  m_treeview.set_model(m_reftreemodelfilter);
  m_treeview.append_column_editable("Field1", m_columns.m_field1);
  m_treeview.append_column("Field2", m_columns.m_field2);
  // add treeview
  box->pack_start(m_treeview);
  // finished
  show_all_children();
  // generate example data
  for (int i = 0; i <10; i++)
  {
    Gtk::TreeModel::iterator iter = m_reftreemodel->append();
    Gtk::TreeModel::Row row = *iter;
    row[m_columns.m_field1] = true;
    row[m_columns.m_field2] = i;
  }
}

MainWindow::~MainWindow()
{}

bool MainWindow::on_filter_row_visible(const Gtk::TreeModel::const_iterator& iter)
{
  if (m_filtered && iter)
    return (iter->get_value(m_columns.m_field2) > 5);
  return true;
}

void MainWindow::on_filter()
{ 
  m_filtered = !m_filtered;
  m_reftreemodelfilter->refilter();
}

// ===================================== example.cpp ==============================
#include "MainWindow.h"
#include <gtkmm/main.h>

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MainWindow window;
  Gtk::Main::run(window);
  return 0;
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]