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

#include <cstdlib>
#include <glibmm.h>

/* $Id: treeview.hg,v 1.71 2004/06/03 09:38:35 murrayc Exp $ */

/* Copyright(C) 2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm/listhandle.h>
#include <gtkmm/container.h>
#include <gtkmm/adjustment.h>
#include <gdkmm/pixmap.h>
#include <gtkmm/treeviewcolumn.h>
#include <gtkmm/treeselection.h>
#include <gtkmm/treemodelcolumn.h>
#include <gtkmm/cellrenderer.h>
#include <gtkmm/targetentry.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GtkTreeView GtkTreeView;
typedef struct _GtkTreeViewClass GtkTreeViewClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{ class TreeView_Class; } // namespace Gtk
namespace Gtk
{


/** @addtogroup gtkmmEnums Enums and Flags */

/**
 * @ingroup gtkmmEnums
 */
enum TreeViewDropPosition
{
  TREE_VIEW_DROP_BEFORE,
  TREE_VIEW_DROP_AFTER,
  TREE_VIEW_DROP_INTO_OR_BEFORE,
  TREE_VIEW_DROP_INTO_OR_AFTER
};

} // namespace Gtk


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gtk
{


#ifndef DOXYGEN_SHOULD_SKIP_THIS

class TreeView;

namespace TreeView_Private
{
/* This helper function is not a member of TreeView just for the reason that
 * there are compilers that have problems compiling it otherwise. E.g. in gcc
 * 2.95.3 a compiler bug prevents member functions from refering to specialized
 * member function templates and that's what we do here: In function
 * _connect_auto_store_editable_signal_handler we build a slot from
 * TreeView::_auto_store_on_cellrenderer_*_edited. (The latter must be member
 * functions of TreeView since we connect them to signals and we want the
 * connections to vanish when the TreeView dies, of course.)
 */
  template <class ColumnType> inline
  void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer, const Gtk::TreeModelColumn<ColumnType>& model_column);

#ifdef GTKMM_MSC_NET
/* VisualStudio .NET 2003 workaround
 * The compiler fails to find the the right template specialization
 * of the _auto_store_on_cellrenderer_text_edited_*<> template member method
 * of the Gtk::TreeView. I think this is related to the missing feature
 * of supporting partial template specialization of template member methods
 * in classes (look in the VisualStudio .NET documentation for C++ conformance
 * failures and misbehaviour).
 * 
 * The exact compiler error: 
 * 
 * ..\..\..\gtk\gtkmm\treeview.h(1046) : error C2784: 'SigC::Slot6<R,P1,P2,P3,P4,P5
 * ,P6> SigC::slot(O1 &,R (__thiscall O2::* )(P1,P2,P3,P4,P5,P6) const)' : could not
 * deduce template argument for 'T8 &' from 'Gtk::TreeView'
 * 
 * and lot more for all SigC::slot cases.
 *
 * My solution: Just move the _auto_store_on_cellrenderer_text_edited_*
 * to the TreeView_Private namespace as template function. This work very well.
 * I can't aggree to the above statement that TreeView::_auto_store_on_cellrenderer_text_edited_*
 * *must* be member methods of the Gtk::TreeView. The connection is already vanished
 * as it's instaciated from the append_column_editable template method. This method
 * create the right cellrenderer and connect the signals. So the cellrenderer is a child of the
 * TreeView and destructed if the TreeView is destructed. It doesn't matter if the
 * _auto_store_on_cellrenderer_text_edited_* is a method of TreeView or not.
 * So far, the gtk-demo compiled fine and work absolutly ok.
 *
 * Frank Nauman.
 * 
 * TODO: I suggest to make this change generally in 2.4
 */
  template<class ColumnType> inline
  void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, Gtk::TreeView*);

  template <class ColumnType> inline
  void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, Gtk::TreeView*);
#endif
}

#endif //DOXYGEN_SHOULD_SKIP_THIS


//class TreeViewColumn;
class TreeModel;

/** @defgroup TreeView TreeView Classes
 * These classes are used with the Gtk::TreeView widget.
 */

/**
 * @ingroup Widgets
 * @ingroup Containers
 * @ingroup TreeView
 */

class TreeView : public Container
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef TreeView CppObjectType;
  typedef TreeView_Class CppClassType;
  typedef GtkTreeView BaseObjectType;
  typedef GtkTreeViewClass BaseClassType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  virtual ~TreeView();

#ifndef DOXYGEN_SHOULD_SKIP_THIS

private:
  friend class TreeView_Class;
  static CppClassType treeview_class_;

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

protected:
  explicit TreeView(const Glib::ConstructParams& construct_params);
  explicit TreeView(GtkTreeView* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
#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 GtkObject.
  GtkTreeView*       gobj()       { return reinterpret_cast<GtkTreeView*>(gobject_); }

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


public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::
  virtual void on_set_scroll_adjustments(Adjustment* hadjustment, Adjustment* vadjustment);
  virtual void on_row_activated(const TreeModel::Path& path, TreeViewColumn* column);
  virtual bool on_test_expand_row(const TreeModel::iterator& iter, const TreeModel::Path& path);
  virtual bool on_test_collapse_row(const TreeModel::iterator& iter, const TreeModel::Path& path);
  virtual void on_row_expanded(const TreeModel::iterator& iter, const TreeModel::Path& path);
  virtual void on_row_collapsed(const TreeModel::iterator& iter, const TreeModel::Path& path);
  virtual void on_cursor_changed();
  virtual void on_columns_changed();
  virtual bool on_move_cursor(MovementStep step, int count);
  virtual bool on_select_all();
  virtual bool on_unselect_all();
  virtual bool on_select_cursor_row(bool start_editing);
  virtual bool on_toggle_cursor_row();
  virtual bool on_expand_collapse_cursor_row(bool logical, bool expand, bool open_all);
  virtual bool on_select_cursor_parent();
  virtual bool on_start_interactive_search();


private:

  
public:
  typedef TreeViewColumn Column;
  typedef TreeSelection Selection;

  TreeView();
  explicit TreeView(const Glib::RefPtr<TreeModel>& model);

  
  /** Returns the model the the Gtk::TreeView is based on.  Returns <tt>0</tt> if the
   * model is unset.
   * @return A Gtk::TreeModel, or <tt>0</tt> if none is currently being used.
   */
  Glib::RefPtr<TreeModel> get_model();
  
  /** Returns the model the the Gtk::TreeView is based on.  Returns <tt>0</tt> if the
   * model is unset.
   * @return A Gtk::TreeModel, or <tt>0</tt> if none is currently being used.
   */
  Glib::RefPtr<const TreeModel> get_model() const;
  
  /** Sets the model for a Gtk::TreeView.  If the @a tree_view  already has a model
   * set, it will remove it before setting the new model.  If @a model  is <tt>0</tt>, then
   * it will unset the old model.
   * @param model The model.
   */
  void set_model(const Glib::RefPtr<TreeModel>& model);
  
  /** Gets the Gtk::TreeSelection associated with @a tree_view .
   * @return A Gtk::TreeSelection object.
   */
  Glib::RefPtr<TreeSelection> get_selection();
  
  /** Gets the Gtk::TreeSelection associated with @a tree_view .
   * @return A Gtk::TreeSelection object.
   */
  Glib::RefPtr<const TreeSelection> get_selection() const;
  
  /** Gets the Gtk::Adjustment currently being used for the horizontal aspect.
   * @return A Gtk::Adjustment object, or <tt>0</tt> if none is currently being
   * used.
   */
  Adjustment* get_hadjustment();
  
  /** Gets the Gtk::Adjustment currently being used for the horizontal aspect.
   * @return A Gtk::Adjustment object, or <tt>0</tt> if none is currently being
   * used.
   */
  const Adjustment* get_hadjustment() const;
  
  /** Sets the Gtk::Adjustment for the current horizontal aspect.
   * @param adjustment The Gtk::Adjustment to set, or <tt>0</tt>.
   */
  void set_hadjustment(Adjustment& adjustment);
  void unset_hadjustment();
  
  /** Gets the Gtk::Adjustment currently being used for the vertical aspect.
   * @return A Gtk::Adjustment object, or <tt>0</tt> if none is currently being
   * used.
   */
  Adjustment* get_vadjustment();
  
  /** Gets the Gtk::Adjustment currently being used for the vertical aspect.
   * @return A Gtk::Adjustment object, or <tt>0</tt> if none is currently being
   * used.
   */
  const Adjustment* get_vadjustment() const;
  
  /** Sets the Gtk::Adjustment for the current vertical aspect.
   * @param adjustment The Gtk::Adjustment to set, or <tt>0</tt>.
   */
  void set_vadjustment(Adjustment& adjustment);
  void unset_vadjustment();
  
  /** Returns <tt>true</tt> if the headers on the @a tree_view  are visible.
   * @return Whether the headers are visible or not.
   */
  bool get_headers_visible() const;
  
  /** Sets the the visibility state of the headers.
   * @param headers_visible <tt>true</tt> if the headers are visible.
   */
  void set_headers_visible(bool headers_visible);
  
  /** Resizes all columns to their optimal width. Only works after the
   * treeview has been realized.
   */
  void columns_autosize();
  
  /** Allow the column title buttons to be clicked.
   * @param setting <tt>true</tt> if the columns are clickable.
   */
  void set_headers_clickable(bool setting = true);
  
  /** This function tells GTK+ that the user interface for your
   * application requires users to read across tree rows and associate
   * cells with one another. By default, GTK+ will then render the tree
   * with alternating row colors. Do <em>not</em> use it
   * just because you prefer the appearance of the ruled tree; that's a
   * question for the theme. Some themes will draw tree rows in
   * alternating colors even when rules are turned off, and users who
   * prefer that appearance all the time can choose those themes. You
   * should call this function only as a <em>semantic</em>
   * hint to the theme engine that your tree makes alternating colors
   * useful from a functional standpoint (since it has lots of columns,
   * generally).
   * @param setting <tt>true</tt> if the tree requires reading across rows.
   */
  void set_rules_hint(bool setting = true);
  
  /** Gets the setting set by set_rules_hint().
   * @return <tt>true</tt> if rules are useful for the user of this tree.
   */
  bool get_rules_hint() const;

  
  /** Appends @a column  to the list of columns.
   * @param column The Gtk::TreeViewColumn to add.
   * @return The number of columns in @a tree_view  after appending.
   */
  int append_column(TreeViewColumn& column);

  /** Appends a View column with the appropriate CellRenderer for the Model column.
   * The CellRenderer can only be created automatically for some basic
   * column types, such as Glib::ustring, int, bool, Gdk::Pixbuf. Also,
   * the default CellRenderer might not be setup exactly as needed.
   * You might prefer to create the TreeViewColumn and or CellRenderer
   * manually. You might provide a callback that converts the type into a
   * string representation with TreeViewColumn::set_cell_data_func().
   * Otherwise, if the type is not supported, at run-time no text will
   * appear in the column while the following warning will be generated repeatedly:
   * GLib-GObject-WARNING **: unable to set property `text' of type
   * `gchararray' from value of type `glibmm__CustomBoxed_t'
   * TODO: Give a more specific warning and/or do more compile-time checks.
   */
  template <class ColumnType> inline
  int append_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column);

  //TODO: danielk suggested use of Glib::Value to simplify/improve this.
  /** Appends a View column with the appropriate CellRenderer for the Model
   * column.  The compiler will attempt to instantiate appropriate template
   * code to automatically store user changes in the model.  To intercept the
   * user's change and implement non-default logic, or if the compiler can't
   * instantiate appropriate code for your model type, you should use
   * append_column() and connect a signal handler to the CellRenderer.
   */
  template <class ColumnType> inline
  int append_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column);


  /// Creates a View column containing the CellRenderer, and appends it.
  int append_column(const Glib::ustring& title, CellRenderer& cell);

  
  /** Removes @a column  from @a tree_view .
   * @param column The Gtk::TreeViewColumn to remove.
   * @return The number of columns in @a tree_view  after removing.
   */
  int remove_column(TreeViewColumn& column);

  /// Removes all View columns.
  void remove_all_columns();

  
  /** This inserts the @a column  into the @a tree_view  at @a position .  If @a position  is
   * -1, then the column is inserted at the end.
   * @param column The Gtk::TreeViewColumn to be inserted.
   * @param position The position to insert @a column  in.
   * @return The number of columns in @a tree_view  after insertion.
   */
  int insert_column(TreeViewColumn& column, int position);

  /// Creates a View column containing the CellRenderer, and inserts it.
  int insert_column(const Glib::ustring& title, CellRenderer& cell, int position);

  
  /// Inserts a View column with the appropriate CellRenderer for the Model column.
  template <class ColumnType> inline
  int insert_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position);

  /** Inserts a View column with the appropriate CellRenderer for the Model
   * column.  The compiler will attempt to instantiate appropriate template
   * code to automatically store user changes in the model.  To intercept the
   * user's change and implement non-default logic, or if the compiler can't
   * instantiate appropriate code for your model type, you should use
   * append_column() and connect a signal handler to the CellRenderer.
   */
  template <class ColumnType> inline
  int insert_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position);

  typedef TreeViewColumn::SlotCellData SlotCellData;
  int insert_column_with_data_func(int position, const Glib::ustring& title, CellRenderer& cell, const SlotCellData& slot);

  
  /** Gets the Gtk::TreeViewColumn at the given position in the #tree_view.
   * @param n The position of the column, counting from 0.
   * @return The Gtk::TreeViewColumn, or <tt>0</tt> if the position is outside the
   * range of columns.
   */
  TreeViewColumn* get_column(int n);
  
  /** Gets the Gtk::TreeViewColumn at the given position in the #tree_view.
   * @param n The position of the column, counting from 0.
   * @return The Gtk::TreeViewColumn, or <tt>0</tt> if the position is outside the
   * range of columns.
   */
  const TreeViewColumn* get_column(int n) const;

  //TODO: Add TreeViewColumn* get_column(TreeViewColumn& base_column); and a const one.

  /** Gets the CellRenderer for that column.
    * You should dynamic_cast<> to the expected derived CellRenderer type.
    * This assumes that the TreeViewColumn contains only one CellRenderer.
    */
  CellRenderer* get_column_cell_renderer(int n);

 //TODO: Add TreeViewColumn* get_column_cell_renderer(TreeViewColumn& base_column); and a const one.


  /** Gets the CellRenderer for that column.
    * You should dynamic_cast<> to the expected derived CellRenderer type.
    * This assumes that the TreeViewColumn contains only one CellRenderer.
    */
  const CellRenderer* get_column_cell_renderer(int n) const;

  
  /** Returns a list of all the Gtk::TreeViewColumn s currently in @a tree_view .
   * @return A list of Gtk::TreeViewColumn s.
   */
  Glib::ListHandle<TreeViewColumn*> get_columns();
  
  /** Returns a list of all the Gtk::TreeViewColumn s currently in @a tree_view .
   * @return A list of Gtk::TreeViewColumn s.
   */
  Glib::ListHandle<const TreeViewColumn*> get_columns() const;
  
  /** Moves @a column  to be after to @a base_column .  If @a base_column  is <tt>0</tt>, then
   *  @a column  is placed in the first position.
   * @param column The Gtk::TreeViewColumn to be moved.
   * @param base_column The Gtk::TreeViewColumn to be moved relative to, or <tt>0</tt>.
   */
  void move_column_after(TreeViewColumn& column, TreeViewColumn& base_column);
  
  /** Sets the column to draw the expander arrow at. It must be in @a tree_view .  If
   *  @a column  is <tt>0</tt>, then the expander arrow is always at the first visible
   * column.
   * @param column <tt>0</tt>, or the column to draw the expander arrow at.
   */
  void set_expander_column(TreeViewColumn& column);
  void unset_expander_column();
  
  /** Returns the column that is the current expander column.  This
   * column has the expander arrow drawn next to it.
   * @return The expander column.
   */
  TreeViewColumn* get_expander_column();
  
  /** Returns the column that is the current expander column.  This
   * column has the expander arrow drawn next to it.
   * @return The expander column.
   */
  const TreeViewColumn* get_expander_column() const;

  //bool on_column_drop(TreeView*, tree_view, TreeViewColumn* column, TreeViewColumn* prev_column,TreeViewColumn* next_column)
  typedef SigC::Slot4<bool, TreeView*, TreeViewColumn*,  TreeViewColumn*, TreeViewColumn*> SlotColumnDrop;
  void set_column_drag_function(const SlotColumnDrop& slot);
  

  /** Scrolls the tree view such that the top-left corner of the visible
   * area is @a tree_x , @a tree_y , where @a tree_x  and @a tree_y  are specified
   * in tree window coordinates.  The @a tree_view  must be realized before
   * this function is called.  If it isn't, you probably want to be
   * using scroll_to_cell().
   * 
   * If either @a tree_x  or @a tree_y  are -1, then that direction isn't scrolled.
   * @param tree_x X coordinate of new top-left pixel of visible area, or -1.
   * @param tree_y Y coordinate of new top-left pixel of visible area, or -1.
   */
  void scroll_to_point(int tree_x, int tree_y);

  /** Moves the alignments of tree view to the position specified by @a column and @a path.
   * @a row_align determines where the row is placed, and @a col_align determines where
   * column is placed. Both are expected to be between 0.0 and 1.0. 0.0 means left/top
   * alignment, 1.0 means right/bottom alignment, 0.5 means center.
   *
   * This function only works if the model is set, and @a path is a valid row on the model.
   * If the model changes before the tree view is realized, the centered path will be
   * modified to reflect this change.
   *
   * @param path The path of the row to move to.
   * @param column The Gtk::TreeViewColumn to move horizontally to.
   * @param row_align The vertical alignment of the row specified by @a path.
   * @param col_align The horizontal alignment of the column specified by @a column.
   */
  void scroll_to_cell(const TreeModel::Path& path, TreeViewColumn& column, float row_align, float col_align);
  

  /** Moves the alignments of tree view to the position specified by @a column and @a path.
   * The tree does the minimum amount of work to scroll the cell onto the screen. This means
   * that the cell will be scrolled to the edge closest to it's current position. If the cell
   * is currently visible on the screen, nothing is done.
   *
   * This function only works if the model is set, and @a path is a valid row on the model.
   * If the model changes before the tree_view is realized, the centered path will be modified
   * to reflect this change.
   *
   * @param path The path of the row to move to.
   * @param column The Gtk::TreeViewColumn to move horizontally to.
   */
  void scroll_to_cell(const TreeModel::Path& path, TreeViewColumn& column);

  /** Moves the alignments of tree view to the position specified by @a path.
   * @a row_align determines where the row is placed, and is expected to be between 0.0
   * and 1.0.  0.0 means top alignment, 1.0 means bottom alignment, 0.5 means center.
   *
   * This function only works if the model is set, and @a path is a valid row on the model.
   * If the model changes before the tree view is realized, the centered path will be
   * modified to reflect this change.
   *
   * @param path The path of the row to move to.
   * @param row_align The vertical alignment of the row specified by @a path.
   */
  void scroll_to_row(const TreeModel::Path& path, float row_align);

  /** Moves the alignments of tree view to the position specified by @a path.
   * The tree does the minimum amount of work to scroll the row onto the screen. This means
   * that the row will be scrolled to the edge closest to it's current position. If the row
   * is currently visible on the screen, nothing is done.
   *
   * This function only works if the model is set, and @a path is a valid row on the model.
   * If the model changes before the tree view is realized, the centered path will be
   * modified to reflect this change.
   *
   * @param path The path of the row to move to.
   */
  void scroll_to_row(const TreeModel::Path& path);

  /** Moves the alignments of tree view to the position specified by @a column.
   * @a col_align determines where the column is placed, and is expected to be between 0.0
   * and 1.0.  0.0 means left alignment, 1.0 means right alignment, 0.5 means center.
   *
   * This function only works if the model is set.  If the model changes before the tree
   * view is realized, the centered path will be modified to reflect this change.
   *
   * @param column The Gtk::TreeViewColumn to move horizontally to.
   * @param col_align The horizontal alignment of the column specified by @a column.
   */
  void scroll_to_column(TreeViewColumn& column, float col_align);

  /** Moves the alignments of tree view to the position specified by @a column.
   * The tree does the minimum amount of work to scroll the column onto the screen. This means
   * that the column will be scrolled to the edge closest to it's current position. If the column
   * is currently visible on the screen, nothing is done.
   *
   * This function only works if the model is set.  If the model changes before the
   * tree view is realized, the centered path will be modified to reflect this change.
   *
   * @param column The Gtk::TreeViewColumn to move horizontally to.
   */
  void scroll_to_column(TreeViewColumn& column);

  
  /** Activates the cell determined by @a path  and @a column .
   * @param path The Gtk::TreePath to be activated.
   * @param column The Gtk::TreeViewColumn to be activated.
   */
  void row_activated(const TreeModel::Path& path,TreeViewColumn& column);
  
  /** Recursively expands all nodes in the @a tree_view .
   */
  void expand_all();
  
  /** Recursively collapses all visible, expanded nodes in @a tree_view .
   */
  void collapse_all();
  
  /** Expands the row at @a path . This will also expand all parent rows of
   *  @a path  as necessary.
   * 
   * Since: 2.2
   * @param path Path to a row.
   */
  void expand_to_path(const TreeModel::Path& path);
  
  /** Opens the row so its children are visible.
   * @param path Path to a row.
   * @param open_all Whether to recursively expand, or just expand immediate children.
   * @return <tt>true</tt> if the row existed and had children.
   */
  bool expand_row(const TreeModel::Path& path, bool open_all);
  
  /** Collapses a row (hides its child rows, if they exist).
   * @param path Path to a row in the @a tree_view .
   * @return <tt>true</tt> if the row was collapsed.
   */
  bool collapse_row(const TreeModel::Path& path);

  //void on_map_expanded_rows(TreeView* tree_view, const TreeModel::Path& path);
  typedef SigC::Slot2<void, TreeView*, const TreeModel::Path&> SlotMapping;
  void map_expanded_rows(const SlotMapping& slot);
  

  /** Returns <tt>true</tt> if the node pointed to by @a path  is expanded in @a tree_view .
   * @param path A Gtk::TreePath to test expansion state.
   * @return <tt>true</tt> if #path is expanded.
   */
  bool row_expanded(const TreeModel::Path& path);
  
  /** This function is a convenience function to allow you to reorder models that
   * support the Gtk::DragSourceIface and the Gtk::DragDestIface.  Both
   * Gtk::TreeStore and Gtk::ListStore support these.  If @a reorderable  is <tt>true</tt>, then
   * the user can reorder the model by dragging and dropping rows.  The
   * developer can listen to these changes by connecting to the model's
   * signals.
   * 
   * This function does not give you any degree of control over the order -- any
   * reorderering is allowed.  If more control is needed, you should probably
   * handle drag and drop manually.
   * @param reorderable <tt>true</tt>, if the tree can be reordered.
   */
  void set_reorderable(bool reorderable = true);
  
  /** Retrieves whether the user can reorder the tree via drag-and-drop. See
   * set_reorderable().
   * @return <tt>true</tt> if the tree can be reordered.
   */
  bool get_reorderable() const;
  
  /** Sets the current keyboard focus to be at @a path , and selects it.  This is
   * useful when you want to focus the user's attention on a particular row.  If
   *  @a focus_column  is not <tt>0</tt>, then focus is given to the column specified by 
   * it. Additionally, if @a focus_column  is specified, and @a start_editing  is 
   * <tt>true</tt>, then editing should be started in the specified cell.  
   * This function is often followed by @a gtk_widget_grab_focus  ( @a tree_view ) 
   * in order to give keyboard focus to the widget.  Please note that editing 
   * can only happen when the widget is realized.
   * @param path A Gtk::TreePath.
   * @param focus_column A Gtk::TreeViewColumn, or <tt>0</tt>.
   * @param start_editing <tt>true</tt> if the specified cell should start being edited.
   */
  void set_cursor(const TreeModel::Path& path, TreeViewColumn& focus_column, bool start_editing = false);
  
  /** Sets the current keyboard focus to be at @a path , and selects it.  This is
   * useful when you want to focus the user's attention on a particular row.  If
   *  @a focus_column  is not <tt>0</tt>, then focus is given to the column specified by
   * it. If @a focus_column  and @a focus_cell  are not <tt>0</tt>, and @a focus_column 
   * contains 2 or more editable or activatable cells, then focus is given to
   * the cell specified by @a focus_cell . Additionally, if @a focus_column  is
   * specified, and @a start_editing  is <tt>true</tt>, then editing should be started in
   * the specified cell.  This function is often followed by
   *  @a gtk_widget_grab_focus  ( @a tree_view ) in order to give keyboard focus to the
   * widget.  Please note that editing can only happen when the widget is
   * realized.
   * 
   * Since: 2.2
   * @param path A Gtk::TreePath.
   * @param focus_column A Gtk::TreeViewColumn, or <tt>0</tt>.
   * @param focus_cell A Gtk::CellRenderer, or <tt>0</tt>.
   * @param start_editing <tt>true</tt> if the specified cell should start being edited.
   */
  void set_cursor(const TreeModel::Path& path, TreeViewColumn& focus_column, CellRenderer& cell, bool start_editing = false);

  void set_cursor(const TreeModel::Path& path); //TODO: Add bool start_editing = false?, even though a true value doesn't actually start editing?
  void get_cursor(TreeModel::Path& path, TreeViewColumn*& focus_column);

/* Layout information */
  
  /** Returns the window that @a tree_view  renders to.  This is used primarily to
   * compare to <tt>event->window</tt> to confirm that the event on
   *  @a tree_view  is on the right window.
   * @return A Gdk::Window, or <tt>0</tt> when @a tree_view  hasn't been realized yet.
   */
  Glib::RefPtr<Gdk::Window> get_bin_window();
  
  /** Returns the window that @a tree_view  renders to.  This is used primarily to
   * compare to <tt>event->window</tt> to confirm that the event on
   *  @a tree_view  is on the right window.
   * @return A Gdk::Window, or <tt>0</tt> when @a tree_view  hasn't been realized yet.
   */
  Glib::RefPtr<const Gdk::Window> get_bin_window() const;
  bool get_path_at_pos(int x, int y, TreeModel::Path& path, TreeViewColumn*& column, int& cell_x, int& cell_y);
  
  /** Fills the bounding rectangle in tree window coordinates for the cell at the
   * row specified by @a path  and the column specified by @a column .  If @a path  points to a path not currently displayed, the @a y  and @a height  fields
   * of the rectangle will be filled with 0.  The sum of all cell rects does not cover the
   * entire tree; there are extra pixels in between rows, for example. The
   * returned rectangle is equivalent to the @a cell_area  passed to
   * Gtk::CellRenderer::render().  This function is only valid if #tree_view is
   * realized.
   * @param path A Gtk::TreePath for the row.
   * @param column A Gtk::TreeViewColumn for the column.
   * @param rect Rectangle to fill with cell rect.
   */
  void get_cell_area(const TreeModel::Path& path, TreeViewColumn& column, Gdk::Rectangle&  rect);
//We ignore the fact that one of the arguments can be 0 - it does not seem useful.

  
  /** Fills the bounding rectangle in tree window coordinates for the cell at the
   * row specified by @a path  and the column specified by @a column .  The returned rectangle is equivalent to the
   *  @a background_area  passed to Gtk::CellRenderer::render().  These background
   * areas tile to cover the entire tree window (except for the area used for
   * header buttons). Contrast with the @a cell_area , returned by
   * get_cell_area(), which returns only the cell itself, excluding
   * surrounding borders and the tree expander area.
   * @param path A Gtk::TreePath for the row.
   * @param column A Gtk::TreeViewColumn for the column.
   * @param rect Rectangle to fill with cell background rect.
   */
  void get_background_area(const TreeModel::Path& path, TreeViewColumn& column, Gdk::Rectangle& rect);
  //We ignore the fact that one of the arguments can be 0 - it does not seem useful.

  
  /** Fills @a visible_rect  with the currently-visible region of the
   * buffer, in tree coordinates. Convert to widget coordinates with
   * tree_to_widget_coords(). Tree coordinates start at
   * 0,0 for row 0 of the tree, and cover the entire scrollable area of
   * the tree.
   * @param visible_rect Rectangle to fill.
   */
  void get_visible_rect(Gdk::Rectangle&  visible_rect);
  
  /** Converts widget coordinates to coordinates for the
   * tree window (the full scrollable area of the tree).
   * @param wx Widget X coordinate.
   * @param wy Widget Y coordinate.
   * @param tx Return location for tree X coordinate.
   * @param ty Return location for tree Y coordinate.
   */
  void widget_to_tree_coords(int wx, int wy, int& tx, int& ty);
  
  /** Converts tree coordinates (coordinates in full scrollable area of the tree)
   * to widget coordinates.
   * @param tx Tree X coordinate.
   * @param ty Tree Y coordinate.
   * @param wx Return location for widget X coordinate.
   * @param wy Return location for widget Y coordinate.
   */
  void tree_to_widget_coords(int tx, int ty, int& wx, int& wy);

/* Drag-and-Drop support */
  

  //TODO: Remove this override. The other one allows more default args.
  void enable_model_drag_source(Gdk::ModifierType start_button_mask,
                                const ArrayHandle_TargetEntry& targets,
                                Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);

  void enable_model_drag_source(const ArrayHandle_TargetEntry& targets,
                                Gdk::ModifierType start_button_mask = Gdk::MODIFIER_MASK,
                                Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);

  // Uses the default "GTK_TREE_MODEL_ROW" target, which the TreeView can handle automatically.                              
  void enable_model_drag_source(Gdk::ModifierType start_button_mask = Gdk::MODIFIER_MASK,
                                Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);                                                                                              

  
  void enable_model_drag_dest(const ArrayHandle_TargetEntry& targets, Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);

  // Uses the default "GTK_TREE_MODEL_ROW" target, which the TreeView can handle automatically.
  void enable_model_drag_dest(Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);

    
  void unset_rows_drag_source();
  
  void unset_rows_drag_dest();


/* These are useful to implement your own custom stuff. */
  
  void set_drag_dest_row(const TreeModel::Path& path, TreeViewDropPosition pos);
  void get_drag_dest_row(TreeModel::Path& path, TreeViewDropPosition& pos);
  bool get_dest_row_at_pos(int drag_x, int drag_y, TreeModel::Path& path, TreeViewDropPosition& pos);
  
  /** Creates a Gdk::Pixmap representation of the row at @a path .  This image is used
   * for a drag icon.
   * @param path A Gtk::TreePath in @a tree_view .
   * @return A newly-allocated pixmap of the drag icon.
   */
  Glib::RefPtr<Gdk::Pixmap> create_row_drag_icon(const TreeModel::Path& path);

/* Interactive search */
  
  /** If @a enable_search  is set, then the user can type in text to search through
   * the tree interactively.
   * @param enable_search <tt>true</tt>, if the user can search interactively.
   */
  void set_enable_search(bool enable_search = true);
  
  /** Returns whether or not the tree allows interactive searching.
   * @return Whether or not to let the user search interactively.
   */
  bool get_enable_search() const;
  
  /** Gets the column searched on by the interactive search code.
   * @return The column the interactive search code searches in.
   */
  int get_search_column() const;
  
  /** Sets @a column  as the column where the interactive search code should
   * search in.  Additionally, turns on interactive searching. Note that
   *  @a column  refers to a column of the model.
   * @param column The column of the model to search in.
   */
  void set_search_column(const TreeModelColumnBase& column);
  
  /** Sets @a column  as the column where the interactive search code should
   * search in.  Additionally, turns on interactive searching. Note that
   *  @a column  refers to a column of the model.
   * @param column The column of the model to search in.
   */
  void set_search_column(int column);

  ///void on_search_equal(const Glib::RefPtr<TreeModel>& model, int column, const Glib::ustring& key, const TreeModel::iterator& iter)
  typedef SigC::Slot4<bool, const Glib::RefPtr<TreeModel>&, int, const Glib::ustring&, const TreeModel::iterator&> SlotSearchEqual;
  //SlotSearchEqual get_search_equal_func();
  
  void set_search_equal_func(const SlotSearchEqual& slot);
  

  /**
   * @par Prototype:
   * <tt>void %set_scroll_adjustments(Adjustment* hadjustment, Adjustment* vadjustment)</tt>
   */
  Glib::SignalProxy2<void,Adjustment*,Adjustment*> signal_set_scroll_adjustments();

  
  /**
   * @par Prototype:
   * <tt>void %row_activated(const TreeModel::Path& path, TreeViewColumn* column)</tt>
   */
  Glib::SignalProxy2<void,const TreeModel::Path&,TreeViewColumn*> signal_row_activated();

  
  /**
   * @par Prototype:
   * <tt>bool %test_expand_row(const TreeModel::iterator& iter, const TreeModel::Path& path)</tt>
   */
  Glib::SignalProxy2<bool,const TreeModel::iterator&,const TreeModel::Path&> signal_test_expand_row();

  
  /**
   * @par Prototype:
   * <tt>bool %test_collapse_row(const TreeModel::iterator& iter, const TreeModel::Path& path)</tt>
   */
  Glib::SignalProxy2<bool,const TreeModel::iterator&,const TreeModel::Path&> signal_test_collapse_row();

  
  /**
   * @par Prototype:
   * <tt>void %row_expanded(const TreeModel::iterator& iter, const TreeModel::Path& path)</tt>
   */
  Glib::SignalProxy2<void,const TreeModel::iterator&,const TreeModel::Path&> signal_row_expanded();

  
  /**
   * @par Prototype:
   * <tt>void %row_collapsed(const TreeModel::iterator& iter, const TreeModel::Path& path)</tt>
   */
  Glib::SignalProxy2<void,const TreeModel::iterator&,const TreeModel::Path&> signal_row_collapsed();

  
  /**
   * @par Prototype:
   * <tt>void %cursor_changed()</tt>
   */
  Glib::SignalProxy0<void> signal_cursor_changed();

  
  /**
   * @par Prototype:
   * <tt>void %columns_changed()</tt>
   */
  Glib::SignalProxy0<void> signal_columns_changed();


  //TODO: Don't wrap these in future. They are keybinding signals, and their API broke for GTK+ 2.2.
  
  /**
   * @par Prototype:
   * <tt>bool %move_cursor(MovementStep step, int count)</tt>
   */
  Glib::SignalProxy2<bool,MovementStep,int> signal_move_cursor();

  
  /**
   * @par Prototype:
   * <tt>bool %select_all()</tt>
   */
  Glib::SignalProxy0<bool> signal_select_all();

  
  /**
   * @par Prototype:
   * <tt>bool %unselect_all()</tt>
   */
  Glib::SignalProxy0<bool> signal_unselect_all();

  
  /**
   * @par Prototype:
   * <tt>bool %select_cursor_row(bool start_editing)</tt>
   */
  Glib::SignalProxy1<bool,bool> signal_select_cursor_row();

  
  /**
   * @par Prototype:
   * <tt>bool %toggle_cursor_row()</tt>
   */
  Glib::SignalProxy0<bool> signal_toggle_cursor_row();

  
  /**
   * @par Prototype:
   * <tt>bool %expand_collapse_cursor_row(bool logical, bool expand, bool open_all)</tt>
   */
  Glib::SignalProxy3<bool,bool,bool,bool> signal_expand_collapse_cursor_row();

  
  /**
   * @par Prototype:
   * <tt>bool %select_cursor_parent()</tt>
   */
  Glib::SignalProxy0<bool> signal_select_cursor_parent();

  
  /**
   * @par Prototype:
   * <tt>bool %start_interactive_search()</tt>
   */
  Glib::SignalProxy0<bool> signal_start_interactive_search();


  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy< Glib::RefPtr<TreeModel> > property_model();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<Adjustment*> property_hadjustment();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<Adjustment*> property_vadjustment();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<bool> property_headers_visible();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy_WriteOnly<bool> property_headers_clickable();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<TreeViewColumn*> property_expander_column();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<bool> property_reorderable();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<bool> property_rules_hint();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<bool> property_enable_search();

  /**
 * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
 * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
 * the value of the property changes. 
 */
Glib::PropertyProxy<int> property_search_column();


protected:

#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifndef GTKMM_MSC_NET
  template <class ColumnType> inline //Must be explicitly specialized.
  void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column);

  template <class ColumnType> inline //Must be explicitly specialized.
  void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column);
#else
  template<class ColumnType> friend
  void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, Gtk::TreeView*);

  template <class ColumnType> friend
  void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, Gtk::TreeView*);
#endif
  
  void _auto_store_on_cellrenderer_toggle_edited(const Glib::ustring& path_string, const Gtk::CellRendererToggle* cell_renderer, int model_column);

  template<class ColumnType> friend
  void TreeView_Private::_connect_auto_store_editable_signal_handler(TreeView*, CellRenderer*, const TreeModelColumn<ColumnType>&);
#endif //DOXYGEN_SHOULD_SKIP_THIS


};


template <class ColumnType> inline
int TreeView::append_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column)
{
  // compilation will fail if there is no appropriate TreeViewColumn
  // constructor for this model column type.
  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );

  return append_column(*pViewColumn);
}

template <class ColumnType> inline
int TreeView::append_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column)
{
  g_assert(model_column.type() != 0);

  // compilation will fail if there is no appropriate TreeViewColumn
  // constructor for this model column type.
  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );

  //connect signal handlers for auto-storing of edited cell data
  CellRenderer* pCellRender = pViewColumn->get_first_cell_renderer();
  TreeView_Private::_connect_auto_store_editable_signal_handler<ColumnType>(this, pCellRender, model_column);

  return append_column(*pViewColumn);
}

template <class ColumnType> inline
int TreeView::insert_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position)
{
  // compilation will fail if there is no appropriate TreeViewColumn
  // constructor for this model column type.
  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );

  return insert_column(*pViewColumn, position);
}

template <class ColumnType> inline
int TreeView::insert_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position)
{
  // compilation will fail if there is no appropriate TreeViewColumn
  // constructor for this model column type.
  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );

   //connect signal handlers for auto-storing of edited cell data
  CellRenderer* pCellRender = pViewColumn->get_first_cell_renderer();
  TreeView_Private::_connect_auto_store_editable_signal_handler(this, pCellRender, model_column);

  return insert_column(*pViewColumn, position);
}


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace TreeView_Private
{

//Template specializations, for different model column types:
//TODO: Move these specializations into the .ccg file - I tried, but the int specialization was not used by the compiler. murrayc.

//bool specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<bool>& model_column)
{
  Gtk::CellRendererToggle* pCellToggle = dynamic_cast<Gtk::CellRendererToggle*>(pCellRenderer);
  if(pCellToggle)
  {
    //Set the appropriate property,
    pCellToggle->property_activatable() = true;

    //Connect to the appropriate signal, sending the model_column too,
    pCellToggle->signal_toggled().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_toggle_edited), pCellToggle, model_column.index()) );
  }
}

//int specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<int>& model_column)
{
  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
  if(pCellText)
  {
    //Set the appropriate property,
    pCellText->property_editable() = true;

    //Connect to the appropriate signal, sending the model_column too,
#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_numerical<int>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_numerical<int>), model_column.index()) );
#endif
  }
}

//unsigned int specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<unsigned int>& model_column)
{
  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
  if(pCellText)
  {
    //Set the appropriate property,
    pCellText->property_editable() = true;

    //Connect to the appropriate signal, sending the model_column too,
#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_numerical<unsigned int>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_numerical<unsigned int>), model_column.index()) );
#endif
  }
}

//long specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<long>& model_column)
{
  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
  if(pCellText)
  {
    //Set the appropriate property,
    pCellText->property_editable() = true;

    //Connect to the appropriate signal, sending the model_column too,
#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_numerical<long>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_numerical<long>), model_column.index()) );
#endif
  }
}

//unsigned long specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<unsigned long>& model_column)
{
  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
  if(pCellText)
  {
    //Set the appropriate property,
    pCellText->property_editable() = true;

    //Connect to the appropriate signal, sending the model_column too,
#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_numerical<unsigned long>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_numerical<unsigned long>), model_column.index()) );
#endif
  }
}

/* TODO: We would like to add these specializations, but it's an API/ABI issue
//unsigned long specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<float>& model_column)
{
  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
  if(pCellText)
  {
    //Set the appropriate property,
    pCellText->property_editable() = true;

    //Connect to the appropriate signal, sending the model_column too,
#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_numerical<float>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_numerical<float>), model_column.index()) );
#endif
  }
}

//unsigned long specialization:
template<> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<double>& model_column)
{
  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
  if(pCellText)
  {
    //Set the appropriate property,
    pCellText->property_editable() = true;

    //Connect to the appropriate signal, sending the model_column too,
#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_numerical<double>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_numerical<double>), model_column.index()) );
#endif
  }
}
*/

} // namespace TreeView_Private
#endif //DOXYGEN_SHOULD_SKIP_THIS


#ifndef GTKMM_MSC_NET
//This is used on string model columns:
template <class ColumnType> inline
void TreeView::_auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column)
{
  Gtk::TreePath path(path_string);

  //Get the row from the path:
  Glib::RefPtr<TreeModel> refModel = get_model();
  Gtk::TreeModel::iterator iter = refModel->get_iter(path);
  if(iter)
  {
      //Store the user's new text in the model:
      Gtk::TreeRow row = *iter;
      row.set_value(model_column, (ColumnType)new_text);
  }
}

template <class ColumnType> inline
void TreeView::_auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column)
{
  //This is used on numerical model columns:

  Gtk::TreePath path(path_string);

  //Get the row from the path:
  Glib::RefPtr<TreeModel> refModel = get_model();
  Gtk::TreeModel::iterator iter = refModel->get_iter(path);
  if(iter)
  { 
    //std::istringstream astream(new_text); //Put it in a stream.
    //ColumnType new_value = ColumnType();
    //new_value << astream; //Get it out of the stream as the numerical type.
    
    //Convert the text to a number, using the same logic used by GtkCellRendererText when it stores numbers.
    char* pchEnd = 0;
    ColumnType new_value = static_cast<ColumnType>( std::strtod(new_text.c_str(), &pchEnd) );

    //Store the user's new text in the model:
    Gtk::TreeRow row = *iter;
    row.set_value(model_column, (ColumnType)new_value);
  }
}
#endif

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace TreeView_Private
{

template <class ColumnType> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<ColumnType>& model_column)
{
  g_assert(model_column.type() != 0);

  //The different CellRenderers have different "edited" signals,
  //and numerical values need to convert the text value to a number,
  //so there are specializations for this tempate.

  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);

  //Set the appropriate property,
  //and connect to the appropriate signal, sending the model_column too,
  if(pCellText)
  {
    pCellText->property_editable() = true;

#ifdef GTKMM_MSC_NET
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(_auto_store_on_cellrenderer_text_edited_string<ColumnType>), model_column.index(), this_p) );
#else
    pCellText->signal_edited().connect(
      SigC::bind( SigC::slot(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_text_edited_string<ColumnType>), model_column.index()) );
#endif
  }
}

#ifdef GTKMM_MSC_NET
template <class ColumnType> inline
void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, Gtk::TreeView* this_p)
{
  Gtk::TreePath path(path_string);

  //Get the row from the path:
  Glib::RefPtr<TreeModel> refModel = this_p->get_model();
  Gtk::TreeModel::iterator iter = refModel->get_iter(path);
  if(iter)
  {
      //Store the user's new text in the model:
      Gtk::TreeRow row = *iter;
      row.set_value(model_column, (ColumnType)new_text);
  }
}

template <class ColumnType> inline
void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, Gtk::TreeView* this_p)
{
  //This is used on numerical model columns:

  Gtk::TreePath path(path_string);

  //Get the row from the path:
  Glib::RefPtr<TreeModel> refModel = this_p->get_model();
  Gtk::TreeModel::iterator iter = refModel->get_iter(path);
  if(iter)
  { 
    //std::istringstream astream(new_text); //Put it in a stream.
    //ColumnType new_value = ColumnType();
    //new_value << astream; //Get it out of the stream as the numerical type.
    
    //Convert the text to a number, using the same logic used by GtkCellRendererText when it stores numbers.
    char* pchEnd = 0;
    ColumnType new_value = static_cast<ColumnType>( strtod(new_text.c_str(), &pchEnd) );

    //Store the user's new text in the model:
    Gtk::TreeRow row = *iter;
    row.set_value(model_column, (ColumnType)new_value);
  }
}
#endif

} // namespace TreeView_Private
#endif //DOXYGEN_SHOULD_SKIP_THIS


} // namespace Gtk


namespace Glib
{
  /** @relates Gtk::TreeView */
  Gtk::TreeView* wrap(GtkTreeView* object, bool take_copy = false);
}
#endif /* _GTKMM_TREEVIEW_H */

