// Bug #582981 - an editable TreeViewColumn when a TreeModelFilter is used as
//               TreeModel doesn't work properly
// Modification of test case in comment 1, including a suggested solution

// Contents:
// 1. Copy of treemodel.h, where two lines have been added in order to make
//    TreeModelFilter2 a friend of TreeModel.
//
// 2. Version of TreeView::_get_base_model() which unconditionally
//    returns get_model().
//
// 3. class TreeModelFilter2 : public TreeModelFilter
//    which overrides TreeModelFilter::create and set_value_impl.
//    TreeModelFilter2::set_value_impl acts as TreeModelSort::set_value_impl,
//    i.e. it forwards the request to its child model.
//
// 4. The main program from comment 1, extended with more tree models and
//    tree views. There are now 5 tree models:
//    liststore, filtered_liststore, sorted_liststore,
//    filtered_sorted_liststore, sorted_filtered_liststore,
//    and corresponding tree views.
//
// Parts 1, 2, and 3 are compiled only if MODIFY_TREE_MODEL_FILTER is defined.
//
// Has been tested on Ubuntu 10.10 with gcc 4.4.5, gtkmm 2.20.3, gtk+ 2.22.0.
//
// I first tried to add my own version of TreeModelFilter::set_value_impl
// as part 3 of this file, but then the linker chose the version in
// libgtkmm-2.4.so. (But it chooses my version of TreeView::_get_base_model.)

#define MODIFY_TREE_MODEL_FILTER

#ifdef MODIFY_TREE_MODEL_FILTER
// A copy of treemodel.h, where TreeModelFilter2 is a friend of TreeModel.
// If it's not a friend, TreeModelFilter2::set_value_impl can't call the
// protected virtual function TreeModel::set_value_impl.

// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GTKMM_TREEMODEL_H
#define _GTKMM_TREEMODEL_H


#include <glibmm.h>

/* $Id: treemodel.hg,v 1.25 2006/05/10 20:59:28 murrayc Exp $ */

/* Copyright (C) 1998-2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gtk/gtk.h>
#include <glibmm/interface.h>
#include <gtkmm/treeiter.h>
#include <gtkmm/treemodelcolumn.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GtkTreeModel GtkTreeModel;
typedef struct _GtkTreeModelClass GtkTreeModelClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{ class TreeModel_Class; } // namespace Gtk
namespace Gtk
{

class TreeModelFilter2;
class TreeModelSort;
class TreePath;
class TreeRowReference;


/** @addtogroup gtkmmEnums Enums and Flags */

/**
 * @ingroup gtkmmEnums
 * @par Bitwise operators:
 * <tt>%TreeModelFlags operator|(TreeModelFlags, TreeModelFlags)</tt><br>
 * <tt>%TreeModelFlags operator&(TreeModelFlags, TreeModelFlags)</tt><br>
 * <tt>%TreeModelFlags operator^(TreeModelFlags, TreeModelFlags)</tt><br>
 * <tt>%TreeModelFlags operator~(TreeModelFlags)</tt><br>
 * <tt>%TreeModelFlags& operator|=(TreeModelFlags&, TreeModelFlags)</tt><br>
 * <tt>%TreeModelFlags& operator&=(TreeModelFlags&, TreeModelFlags)</tt><br>
 * <tt>%TreeModelFlags& operator^=(TreeModelFlags&, TreeModelFlags)</tt><br>
 */
enum TreeModelFlags
{
  TREE_MODEL_ITERS_PERSIST = 1 << 0,
  TREE_MODEL_LIST_ONLY = 1 << 1
};

/** @ingroup gtkmmEnums */
inline TreeModelFlags operator|(TreeModelFlags lhs, TreeModelFlags rhs)
  { return static_cast<TreeModelFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }

/** @ingroup gtkmmEnums */
inline TreeModelFlags operator&(TreeModelFlags lhs, TreeModelFlags rhs)
  { return static_cast<TreeModelFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }

/** @ingroup gtkmmEnums */
inline TreeModelFlags operator^(TreeModelFlags lhs, TreeModelFlags rhs)
  { return static_cast<TreeModelFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }

/** @ingroup gtkmmEnums */
inline TreeModelFlags operator~(TreeModelFlags flags)
  { return static_cast<TreeModelFlags>(~static_cast<unsigned>(flags)); }

/** @ingroup gtkmmEnums */
inline TreeModelFlags& operator|=(TreeModelFlags& lhs, TreeModelFlags rhs)
  { return (lhs = static_cast<TreeModelFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }

/** @ingroup gtkmmEnums */
inline TreeModelFlags& operator&=(TreeModelFlags& lhs, TreeModelFlags rhs)
  { return (lhs = static_cast<TreeModelFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }

/** @ingroup gtkmmEnums */
inline TreeModelFlags& operator^=(TreeModelFlags& lhs, TreeModelFlags rhs)
  { return (lhs = static_cast<TreeModelFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }

} // namespace Gtk


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gtk::TreeModelFlags> : public Glib::Value_Flags<Gtk::TreeModelFlags>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{


//TODO: Remove any mention of null arguments from the method documentation, by adding overrides in gtk_docs_override.xml.
/** This class defines a generic tree interface for use by the Gtk::TreeView widget.
 * @ingroup TreeView
 *
 * It is is designed to be usable with any appropriate data structure. The
 * programmer just has to implement this interface on their own data type for
 * it to be viewable by a Gtk::TreeView widget.
 *
 * The model is represented as a hierarchical tree of strongly-typed, columned
 * data. In other words, the model can be seen as a tree where every node has
 * different values depending on which column is being queried.  The type of
 * data found in a column is determined by TreeModel::Column<> templates.
 * The types are homogeneous per column across all nodes. It is important to note that this
 * interface only provides a way of examining a model and observing changes.
 * The implementation of each individual model decides how and if changes are
 * made.
 *
 * In order to make life simpler for programmers who do not need to write their
 * own specialized model, two generic models are provided - the Gtk::TreeStore
 * and the Gtk::ListStore. To use these, the developer simply pushes data into
 * these models as necessary. These models provide the data structure as well
 * as all appropriate tree interfaces. As a result, implementing drag and drop,
 * sorting, and storing data is trivial. For the vast majority of trees and
 * lists, these two models are sufficient.
 *
 * Models are accessed on a node/column level of granularity. One can query for
 * the value of a model at a certain node and a certain column on that node.
 * There are two structures used to reference a particular node in a model.
 * They are the @link Gtk::TreePath Path@endlink and the iterator. Most of the interface consists of
 * operations on an @link Gtk::TreeIter iterator@endlink.
 *
 * A @link Gtk::TreePath Gtk::TreeModel::Path@endlink is essentially a potential node. It is a location on a model that may
 * or may not actually correspond to a node on a specific model.
 *
 * By contrast, an @link Gtk::TreeIter Gtk::TreeModel::iterator@endlink  is a reference to a specific node on a specific
 * model. One can convert a path to an @link Gtk::TreeIter iterator@endlink by calling Gtk::TreeModel::get_iter().
 * These iterators are the primary way of accessing a model and are similar to the iterators
 * used by Gtk::TextBuffer. The model interface defines a set of operations
 * using them for navigating the model.
 *
 * The @link Gtk::TreeRowReference RowReference@endlink is also useful, because it remains
 * valid as long as there is an existing row pointed to by it's path. You can convert between RowReferences and iterators and @link Gtk::TreePath Path@endlink s.
 */

class TreeModel : public Glib::Interface
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef TreeModel CppObjectType;
  typedef TreeModel_Class CppClassType;
  typedef GtkTreeModel BaseObjectType;
  typedef GtkTreeModelIface BaseClassType;

private:
  friend class TreeModel_Class;
  static CppClassType treemodel_class_;

  // noncopyable
  TreeModel(const TreeModel&);
  TreeModel& operator=(const TreeModel&);

protected:
  TreeModel(); // you must derive from this class

  /** Called by constructors of derived classes. Provide the result of 
   * the Class init() function to ensure that it is properly 
   * initialized.
   * 
   * @param interface_class The Class object for the derived type.
   */
  explicit TreeModel(const Glib::Interface_Class& interface_class);

public:
  // This is public so that C++ wrapper instances can be
  // created for C instances of unwrapped types.
  // For instance, if an unexpected C type implements the C interface. 
  explicit TreeModel(GtkTreeModel* castitem);

protected:
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~TreeModel();

  static void add_interface(GType gtype_implementer);

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;
  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  GtkTreeModel*       gobj()       { return reinterpret_cast<GtkTreeModel*>(gobject_); }

  ///Provides access to the underlying C GObject.  
  const GtkTreeModel* gobj() const { return reinterpret_cast<GtkTreeModel*>(gobject_); }

private:

  
public:
  typedef TreeModelColumnRecord ColumnRecord;

  typedef TreeNodeChildren Children;
  typedef Children::iterator iterator;
  typedef Children::reverse_iterator reverse_iterator;
  typedef Children::const_iterator const_iterator;
  typedef Children::const_reverse_iterator const_reverse_iterator;
  
  typedef TreeRow Row;
  typedef TreePath Path;
  typedef TreeRowReference RowReference;
  

  //These are part of GtkTreeModelFilter or GtkTreeModelSort, not GtkTreeModel:
  

  /** Returns a valid iterator pointing to @a path.
   *
   * @param path The @link Gtk::TreePath Gtk::TreeModel::Path@endlink.
   * @result A valid iterator pointing to the path, or an invalid iterator if that is not possible.
   */
  iterator get_iter(const Path& path);
  //TODO: Add const_iterator get_iter(const Path& path) const;
  //Implement a const_iterator?

  /** Returns a valid iterator pointing to @a path_string.
   *
   * @param path_string The path, as a string representation.
   * @result A valid iterator pointing to the path, or an invalid iterator if that is not possible.
   */
  iterator get_iter(const Glib::ustring& path_string);
  //TODO: Implement a const_iterator? const_iterator get_iter(const Glib::ustring& path_string) const;

  ///This returns an STL-like container API, for iterating over the rows.
  Children children();

  //TODO: Return a real TreeNodeChildren (a container of const_iterators), when we have a real const_iterator.
  ///This returns an STL-like container API, for iterating over the rows.
  Children children() const;

  
  /** For example,
   * void on_foreach(const Gtk::TreeModel::iterator& iter);
   *
   * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
   */
  typedef sigc::slot<bool, const TreeModel::iterator&> SlotForeachIter;

  /** Calls a callback slot on each node in the model in a depth-first fashion.
   * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
   *
   * @param slot The function to call for each selected node.
   */
  void foreach_iter(const SlotForeachIter& slot);

  /** For example,
   * void on_foreach(const Gtk::TreeModel::Path& path);
   *
   * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
   */
  typedef sigc::slot<bool, const TreeModel::Path&> SlotForeachPath;

  /** Calls a callback slot on each node in the model in a depth-first fashion.
   * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
   *
   * @param slot The function to call for each selected node.
   */
  void foreach_path(const SlotForeachPath& slot);

  /** For example,
   * void on_foreach(const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter);
   *
   * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
   */
  typedef sigc::slot<bool, const TreeModel::Path&, const TreeModel::iterator&> SlotForeachPathAndIter;

  /** Calls a callback slot on each node in the model in a depth-first fashion.
   * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
   *
   * @param slot The function to call for each selected node.
   */
  void foreach(const SlotForeachPathAndIter& slot);

  
  /** Returns a set of flags supported by this interface.  The flags are a bitwise
   * combination of Gtk::TreeModelFlags.  The flags supported should not change
   * during the lifecycle of the @a tree_model.
   * @return The flags supported by this interface.
   */
  TreeModelFlags get_flags() const;
  
  /** Returns the number of columns supported by @a tree_model.
   * @return The number of columns.
   */
  int get_n_columns() const;
  
  /** Returns the type of the column.
   * @param index The column index.
   * @return The type of the column.
   */
  GType get_column_type(int index) const;
  //TODO: A C++-type version of get_column_type()?
  
  
  /** Returns a Gtk::TreePath referenced by @a iter.
   * @param iter The Gtk::TreeIter.
   * @return A Gtk::TreePath.
   */
  TreeModel::Path get_path(const iterator& iter) const;

  
  /** Emits the "row-changed" signal on @a tree_model.
   * @param path A Gtk::TreePath pointing to the changed row.
   * @param iter A valid Gtk::TreeIter pointing to the changed row.
   */
  void row_changed(const Path& path, const iterator& iter);
  
  /** Emits the "row-inserted" signal on @a tree_model
   * @param path A Gtk::TreePath pointing to the inserted row.
   * @param iter A valid Gtk::TreeIter pointing to the inserted row.
   */
  void row_inserted(const Path& path, const iterator& iter);
  
  /** Emits the "row-has-child-toggled" signal on @a tree_model.  This should be
   * called by models after the child state of a node changes.
   * @param path A Gtk::TreePath pointing to the changed row.
   * @param iter A valid Gtk::TreeIter pointing to the changed row.
   */
  void row_has_child_toggled(const Path& path, const iterator& iter);
  
  /** Emits the "row-deleted" signal on @a tree_model.  This should be called by
   * models after a row has been removed.  The location pointed to by @a path 
   * should be the location that the row previously was at.  It may not be a 
   * valid location anymore.
   * @param path A Gtk::TreePath pointing to the previous location of the deleted row.
   */
  void row_deleted(const Path& path);

 /** Emits the "rows_reordered" signal on the tree model.  This should be called by
  * custom models when their rows have been reordered. 
  *
  * @param path A tree path pointing to the tree node whose children have been reordered.
  * @param iter A valid iterator pointing to the node whose children have been reordered. See also, rows_reordered(const Path& path, const Glib::ArrayHandle<int>& new_order), if the path has a depth of 0.
  * @param new_order An array of integers mapping the current position of each child
  * to its old position before the re-ordering, i.e. @a new_order<literal>[newpos] = oldpos.
  */
  void rows_reordered(const Path& path, const iterator& iter, const Glib::ArrayHandle<int>& new_order);

 /** Emits the "rows_reordered" signal on the tree model.  This should be called by
  * custom models when their rows have been reordered. This method overload is for nodes whose 
  * path has a depth of 0.
  * @newin{2,10}
  *
  * @param path A tree path pointing to the tree node whose children have been reordered.
  * @param new_order An array of integers mapping the current position of each child
  * to its old position before the re-ordering, i.e. @a new_order<literal>[newpos] = oldpos.
  */
  void rows_reordered(const Path& path, const Glib::ArrayHandle<int>& new_order);
  
  
  /** Emits the "rows-reordered" signal on @a tree_model.  This should be called by
   * models when their rows have been reordered.
   * @param path A Gtk::TreePath pointing to the tree node whose children have been 
   * reordered.
   * @param iter A valid Gtk::TreeIter pointing to the node whose children have been 
   * reordered, or <tt>0</tt> if the depth of @a path is 0.
   * @param new_order An array of integers mapping the current position of each child
   * to its old position before the re-ordering,
   * i.e. @a new_order<literal>[newpos] = oldpos</literal>.
   */
  void rows_reordered(const Path& path, const iterator& iter, int* new_order);

  
  /** Generates a string representation of the iter. This string is a ':'
   * separated list of numbers. For example, "4:10:0:3" would be an
   * acceptable return value for this string.
   * 
   * @newin{2,2}
   * @param iter An Gtk::TreeIter.
   * @return The string.
   */
  Glib::ustring get_string(const iterator& iter) const;

 
  /**
   * @par Prototype:
   * <tt>void on_my_%row_changed(const TreeModel::Path& path, const TreeModel::iterator& iter)</tt>
   */

  Glib::SignalProxy2< void,const TreeModel::Path&,const TreeModel::iterator& > signal_row_changed();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%row_inserted(const TreeModel::Path& path, const TreeModel::iterator& iter)</tt>
   */

  Glib::SignalProxy2< void,const TreeModel::Path&,const TreeModel::iterator& > signal_row_inserted();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%row_has_child_toggled(const TreeModel::Path& path, const TreeModel::iterator& iter)</tt>
   */

  Glib::SignalProxy2< void,const TreeModel::Path&,const TreeModel::iterator& > signal_row_has_child_toggled();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%row_deleted(const TreeModel::Path& path)</tt>
   */

  Glib::SignalProxy1< void,const TreeModel::Path& > signal_row_deleted();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%rows_reordered(const TreeModel::Path& path, const TreeModel::iterator& iter, int* new_order)</tt>
   */

  Glib::SignalProxy3< void,const TreeModel::Path&,const TreeModel::iterator&,int* > signal_rows_reordered();


protected:
  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual TreeModelFlags get_flags_vfunc() const;
#endif //GLIBMM_VFUNCS_ENABLED

  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual int get_n_columns_vfunc() const;
#endif //GLIBMM_VFUNCS_ENABLED

  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual GType get_column_type_vfunc(int index) const;
#endif //GLIBMM_VFUNCS_ENABLED


  //These are only for deriving new TreeModels, which isn't very common or easy:

#ifdef GLIBMM_VFUNCS_ENABLED
  /** Override and implement this in a derived TreeModel class.
   * Sets @a iter_next to refer to the node following @a iter it at the current level.
   * If there is no next iter, false is returned and iter_next is set to be invalid.
   *
   * @param iter An iterator.
   * @param iter_next An iterator that will be set to refer to the next node, or will be set as invalid.
   * @result true if the operation was possible.
   */
  virtual bool iter_next_vfunc(const iterator& iter, iterator& iter_next) const;

  /** Override and implement this in a derived TreeModel class.
   * Sets @a iter to a valid iterator pointing to @a path
   *
   * @param path An path to a node.
   * @param iter An iterator that will be set to refer to a node to the path, or will be set as invalid.
   * @result true if the operation was possible.
   */
  virtual bool get_iter_vfunc(const Path& path, iterator& iter) const;

  /** Override and implement this in a derived TreeModel class.
   * Sets @a iter to refer to the first child of @a parent. If @a parent has no children,
   * false is returned and @a iter is set to be invalid.
   *
   * @param parent An iterator.
   * @param iter An iterator that will be set to refer to the firt child node, or will be set as invalid.
   * @result true if the operation was possible.
   */
  virtual bool iter_children_vfunc(const iterator& parent, iterator& iter) const;
  
  /** Override and implement this in a derived TreeModel class.
   * Sets @a iter to be the parent of @a child. If @a child is at the toplevel, and
   * doesn't have a parent, then @a iter is set to an invalid iterator and false
   * is returned.
   *
   * @param child An iterator.
   * @param iter An iterator that will be set to refer to the parent node, or will be set as invalid.
   * @result true if the operation was possible.
   */
  virtual bool iter_parent_vfunc(const iterator& child, iterator& iter) const;

  /** Override and implement this in a derived TreeModel class.
   * Sets @a iter to be the child of @a parent using the given index.  The first
   * index is 0.  If @a n is too big, or @a parent has no children, @a iter is set
   * to an invalid iterator and false is returned.
   * See also iter_nth_root_child_vfunc()
   *
   * @param parent An iterator.
   * @param n The index of the child node to which @a iter should be set.
   * @param iter An iterator that will be set to refer to the nth node, or will be set as invalid.
   * @result true if the operation was possible.
   */
  virtual bool iter_nth_child_vfunc(const iterator& parent, int n, iterator& iter) const;

   /** Override and implement this in a derived TreeModel class.
   * Sets @a iter to be the child of at the root level using the given index.  The first
   * index is 0.  If @a n is too big, or if there are no children, @a iter is set
   * to an invalid iterator and false is returned.
   * See also iter_nth_child_vfunc().
   *
   * @param n The index of the child node to which @a iter should be set.
   * @param iter An iterator that will be set to refer to the nth node, or will be set as invalid.
   * @result true if the operation was possible.
   */
  virtual bool iter_nth_root_child_vfunc(int n, iterator& iter) const;
#endif //GLIBMM_VFUNCS_ENABLED

  
  /** Override and implement this in a derived TreeModel class.
   * Returns true if @a iter has children, false otherwise.
   *
   * @param iter The iterator to test for children.
   * @result true if @a iter has children.
   */
  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual bool iter_has_child_vfunc(const iterator& iter) const;
#endif //GLIBMM_VFUNCS_ENABLED


#ifdef GLIBMM_VFUNCS_ENABLED
  /** Override and implement this in a derived TreeModel class.
   * Returns the number of children that @a iter has.
   * See also iter_n_root_children_vfunc().  
   *
   * @param iter The iterator to test for children.
   * @result The number of children of @a iter.
   */
  virtual int iter_n_children_vfunc(const iterator& iter) const;

  /** Override and implement this in a derived TreeModel class.
   * Returns the number of toplevel nodes.
   * See also iter_n_children().
   *
   * @result The number of children at the root level.
   */
  virtual int iter_n_root_children_vfunc() const;
#endif //GLIBMM_VFUNCS_ENABLED

  /** Override and implement this in a derived TreeModel class.
   * Lets the tree ref the node.  This is an optional method for models to
   * implement.  To be more specific, models may ignore this call as it exists
   * primarily for performance reasons.
   *
   * This function is primarily meant as a way for views to let caching model know
   * when nodes are being displayed (and hence, whether or not to cache that
   * node.)  For example, a file-system based model would not want to keep the
   * entire file-hierarchy in memory, just the sections that are currently being
   * displayed by every current view.
   *
   * A model should be expected to be able to get an iter independent of its
   * reffed state.
   *
   * @param iter the iterator.
   */
  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual void ref_node_vfunc(const iterator& iter) const;
#endif //GLIBMM_VFUNCS_ENABLED


  /** Override and implement this in a derived TreeModel class.
   * Lets the tree unref the node.  This is an optional method for models to
   * implement.  To be more specific, models may ignore this call as it exists
   * primarily for performance reasons.
   *
   * For more information on what this means, see unref_node_vfunc().
   * Please note that nodes that are deleted are not unreffed.
   *
   * @param iter the iterator.
   */
  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual void unref_node_vfunc(const iterator& iter) const;
#endif //GLIBMM_VFUNCS_ENABLED


  /** Override and implement this in a derived TreeModel class.
   * Returns a Path referenced by @a iter.
   *
   * @param iter The iterator.
   * @result The path.
   */
 

  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual TreeModel::Path get_path_vfunc(const iterator& iter) const;
#endif //GLIBMM_VFUNCS_ENABLED


  /** Override and implement this in a derived TreeModel class.
   * Initializes and sets @a value to that at @a column.
   *
   * @param iter The iterator.
   * @param column The column to lookup the value at.
   * @param value An empty Glib:Value to set.
   */
  #ifdef GLIBMM_VFUNCS_ENABLED
  virtual void get_value_vfunc(const iterator& iter, int column, Glib::ValueBase& value) const;
#endif //GLIBMM_VFUNCS_ENABLED


  /** Override and implement this in a derived TreeModel class.
   * @note This virtual method is not recommended.  To check
   * whether an iterator is valid, call TreeStore::iter_is_valid(),
   * ListStore::iter_is_valid() or TreeModelSort::iter_is_valid() directly
   * instead.  Because these methods are intended to be used only for debugging
   * and/or testing purposes, it doesn't make sense to provide an abstract
   * interface to them.
   *
   * @result true if the iterator is valid.
   *
   * @deprecated Use iter_is_valid() in the derived class.
   */
  virtual bool iter_is_valid(const iterator& iter) const;

  //Called by TreeRow, which is a friend class:
  //The comment about set_row_changed() in the documentation is based on my reading of the source of
  //gtk_list_store_set_value() and gtk_tree_store_set_value().  
  /** Override and implement this in a derived TreeModel class, so that Row::operator() and
   * Row::set_value() work.
   * You can probably just implement this by calling set_value_vfunc().
   * Your implementation of set_value_impl() should also call row_changed() after changing the value.
   */
  virtual void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value);

  //This might not need to be virtual, but it's not a big deal. murrayc.
  virtual void get_value_impl(const iterator& row, int column, Glib::ValueBase& value) const;

  friend class Gtk::TreeModelFilter2;
  friend class Gtk::TreeModelSort;
  friend class Gtk::TreeRow;
  friend class Gtk::TreeIter;


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:
#ifdef GLIBMM_VFUNCS_ENABLED
#endif //GLIBMM_VFUNCS_ENABLED

protected:
  //GTK+ Virtual Functions (override these to change behaviour):
#ifdef GLIBMM_VFUNCS_ENABLED
#endif //GLIBMM_VFUNCS_ENABLED

  //Default Signal Handlers::
#ifdef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
  virtual void on_row_changed(const TreeModel::Path& path, const TreeModel::iterator& iter);
  virtual void on_row_inserted(const TreeModel::Path& path, const TreeModel::iterator& iter);
  virtual void on_row_has_child_toggled(const TreeModel::Path& path, const TreeModel::iterator& iter);
  virtual void on_row_deleted(const TreeModel::Path& path);
  virtual void on_rows_reordered(const TreeModel::Path& path, const TreeModel::iterator& iter, int* new_order);
#endif //GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED


};

} // namespace Gtk


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gtk::TreeModel
   */
  Glib::RefPtr<Gtk::TreeModel> wrap(GtkTreeModel* object, bool take_copy = false);

} // namespace Glib


#endif /* _GTKMM_TREEMODEL_H */
#endif // MODIFY_TREE_MODEL_FILTER

#include<iostream>
#include<gtkmm.h>

#ifdef MODIFY_TREE_MODEL_FILTER
namespace Gtk
{
// All calls to TreeView::_get_base_model() shall be replaced by
// calls to TreeView::get_model().
Glib::RefPtr<Gtk::TreeModel> TreeView::_get_base_model()
{
  return get_model();
}

class TreeModelFilter2 : public TreeModelFilter
{
public:
   static Glib::RefPtr<TreeModelFilter2> create (const Glib::RefPtr< TreeModel >& child_model)
   {
      return Glib::RefPtr<TreeModelFilter2>(new TreeModelFilter2(child_model));
   }

protected:
   TreeModelFilter2(const Glib::RefPtr< TreeModel >& child_model)
   : TreeModelFilter(child_model)
   {
   }

   virtual void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value);
};

// TreeModelFilter2::set_value_impl forwards the request to its child model,
// just as TreeModelSort::set_value_impl.
void TreeModelFilter2::set_value_impl(const iterator& row, int column, const Glib::ValueBase& value)
{
  // Avoid two extra ref/unref cycles -- we don't store the child
  // model pointer anywhere, so it's OK to do this _internally_.

  TreeModel *const child_model = dynamic_cast<TreeModel*>(
      Glib::wrap_auto((GObject*) gtk_tree_model_filter_get_model(gobj()), false));

  TreeIter child_iter (child_model);

  gtk_tree_model_filter_convert_iter_to_child_iter(
      gobj(), child_iter.gobj(), const_cast<GtkTreeIter*>(row.gobj()));

  child_model->set_value_impl(child_iter, column, value);
}

} // namespace Gtk

#else
#define TreeModelFilter2 TreeModelFilter
#endif // MODIFY_TREE_MODEL_FILTER

int main (int argc, char** argv)
{
	Gtk::Main kit(argc, argv);
	
	Gtk::TreeModelColumn<bool> visible;
	Gtk::TreeModelColumn<bool> active;
	Gtk::TreeModelColumn<Glib::ustring> description;	
	Gtk::TreeModel::ColumnRecord columns;
	columns.add(visible);
	columns.add(active);
	columns.add(description);
	
	Glib::RefPtr<Gtk::ListStore> liststore = Gtk::ListStore::create (columns);
	Glib::RefPtr<Gtk::TreeModelFilter2> filtered_liststore =
      Gtk::TreeModelFilter2::create (liststore);
	filtered_liststore->set_visible_column (0);
	Glib::RefPtr<Gtk::TreeModelSort> sorted_liststore =
	   Gtk::TreeModelSort::create (liststore);
	sorted_liststore->set_sort_column (2, Gtk::SORT_ASCENDING);
	Glib::RefPtr<Gtk::TreeModelFilter2> filtered_sorted_liststore =
      Gtk::TreeModelFilter2::create (sorted_liststore);
	filtered_sorted_liststore->set_visible_column (0);
	Glib::RefPtr<Gtk::TreeModelSort> sorted_filtered_liststore =
	   Gtk::TreeModelSort::create (filtered_liststore);
	sorted_filtered_liststore->set_sort_column (2, Gtk::SORT_ASCENDING);
	
	Gtk::TreeModel::Row row = *(liststore->append());
	row[visible] = false;
	row[active] = true;
	row[description] = "First";
	
	row = *(liststore->append());
	row[visible] = false;
	row[active] = true;
	row[description] = "Second";
	
	row = *(liststore->append());
	row[visible] = true;
	row[active] = true;
	row[description] = "Third";
	
	row = *(liststore->append());
	row[visible] = true;
	row[active] = true;
	row[description] = "Fourth";

	Gtk::TreeView full_view(liststore);
	Gtk::TreeView filtered_view(filtered_liststore);
	Gtk::TreeView sorted_view(sorted_liststore);
	Gtk::TreeView filtered_sorted_view(filtered_sorted_liststore);
	Gtk::TreeView sorted_filtered_view(sorted_filtered_liststore);
	full_view.append_column_editable ("Active", active);
	full_view.append_column ("Description", description);
	filtered_view.append_column_editable ("F Active", active);
	filtered_view.append_column ("F Description", description);
	sorted_view.append_column_editable ("S Active", active);
	sorted_view.append_column ("S Description", description);
	filtered_sorted_view.append_column_editable ("FS Active", active);
	filtered_sorted_view.append_column ("FS Description", description);
	sorted_filtered_view.append_column_editable ("SF Active", active);
	sorted_filtered_view.append_column ("SF Description", description);
	
	Gtk::HBox box;
	box.pack_start (full_view);
	box.pack_start (filtered_view);
	box.pack_start (sorted_view);
	box.pack_start (filtered_sorted_view);
	box.pack_start (sorted_filtered_view);
	
	Gtk::Window window;
	window.add (box);
	window.show_all();
	
	Gtk::Main::run(window);
}

