Commit 3e1cb9bb authored by Murray Cumming's avatar Murray Cumming Committed by Murray Cumming

Added TreeIter::set_stamp() and get_stamp(), with documentation, for use

2004-01-14  Murray Cumming  <murrayc@usa.net>

        * gtk/src/treeiter.[hg}ccg]: Added TreeIter::set_stamp() and
        get_stamp(), with documentation, for use when implementing a
        custom TreeModel.
        * gtk/src/treemodel.[hg|ccg]:
        - Hand-coded several vfuncs and their C callbacks, so that we can have
        C++ iterators instead of GtkTreeIter*s in the API, and to reorder some
        parameters.
        - Added 2 extra vfuncs for information about root nodes. The C
        versions of these vfuncs provide root node information when the iter
        is NULL, but it is nicer in C++ to just have an extra vfunc without
        that parameter. This requires an extra if() in the _vfunc_callback()
        implementation.
        - Added documentation for the vfuncs but gmmproc does not yet put the
        documentation in the right place for the generated vfuncs.
        * gtk/src/cellrenderer.hg: Added docuemntation for the vfuncs, but
        gmmproc does not put this documentation in the right place yet.
        * examples/: Added treemodelcustom to show a derived TreeModel, which
        overrides those vfuncs, based on the example by Christof Pettig.
parent a7506b57
2004-01-14 Murray Cumming <murrayc@usa.net>
* gtk/src/treeiter.[hg}ccg]: Added TreeIter::set_stamp() and
get_stamp(), with documentation, for use when implementing a
custom TreeModel.
* gtk/src/treemodel.[hg|ccg]:
- Hand-coded several vfuncs and their C callbacks, so that we can have
C++ iterators instead of GtkTreeIter*s in the API, and to reorder some
parameters.
- Added 2 extra vfuncs for information about root nodes. The C
versions of these vfuncs provide root node information when the iter
is NULL, but it is nicer in C++ to just have an extra vfunc without
that parameter. This requires an extra if() in the _vfunc_callback()
implementation.
- Added documentation for the vfuncs but gmmproc does not yet put the
documentation in the right place for the generated vfuncs.
* gtk/src/cellrenderer.hg: Added docuemntation for the vfuncs, but
gmmproc does not put this documentation in the right place yet.
* examples/: Added treemodelcustom to show a derived TreeModel, which
overrides those vfuncs, based on the example by Christof Pettig.
2004-01-12 Murray Cumming <murrayc@usa.net>
* demos/gtk-demo/example_uimanager.cc: Removed extra comma to fix
......
......@@ -335,6 +335,7 @@ AC_CONFIG_FILES([
examples/statusbar/Makefile
examples/stock/Makefile
examples/tictactoe/Makefile
examples/treemodelcustom/Makefile
examples/window/Makefile
])
......
......@@ -11,6 +11,7 @@ rulers \
statusbar \
stock \
tictactoe \
treemodelcustom \
window
SUBDIRS = $(example_dirs)
......
*.lo
.deps
.libs
Makefile.in
Makefile
cellrenderertoggle
testpopup
include $(top_srcdir)/examples/Makefile.am_fragment
#Build the executable, but don't install it.
noinst_PROGRAMS = example
example_SOURCES = examplewindow.h examplewindow.cc exampletreemodel.h exampletreemodel.cc main.cc
//$Id$ -*- c++ -*-
/* gtkmm example Copyright (C) 2002 gtkmm development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <iostream>
#include "exampletreemodel.h"
ExampleTreeModel::ExampleTreeModel()
: Glib::ObjectBase( typeid(ExampleTreeModel) ), //register a custom GType.
Glib::Object(), //The custom GType is actually registered here.
m_stamp(1) //When the model's stamp != the iterator's stamp then that iterator is invalid and should be ignored. Also, 0=invalid
{
//We need to specify a particular get_type() from one of the virtual base classes, but they should
//both return the same piece of data.
Gtk::TreeModel::add_interface( Glib::Object::get_type() );
//Initialize our underlying data:
const typeListOfRows::size_type rows_count = 100;
const typeRow::size_type columns_count = 10;
m_rows.resize(rows_count); //100 rows.
for(unsigned int row_number = 0; row_number < rows_count; ++row_number)
{
//Create the row:
m_rows[row_number].resize(columns_count); // 10 cells (columns) for each row.
for(unsigned int column_number = 0; column_number < columns_count; ++column_number)
{
// Set the data in the row cells:
// It is more likely that you would be reusing existing data from some other data structure,
// instead of generating the data here.
char buffer[20]; //You could use a std::stringstream instead.
g_snprintf(buffer, sizeof(buffer), "%d, %d", row_number, column_number);
(m_rows[row_number])[column_number] = buffer; //Note that all 10 columns here are of the same type.
}
}
//The Column information that can be used with TreeView::append(), TreeModel::iterator[], etc.
m_listModelColumns.resize(columns_count);
for(unsigned int column_number = 0; column_number < columns_count; ++column_number)
{
m_column_record.add( m_listModelColumns[column_number] );
}
}
ExampleTreeModel::~ExampleTreeModel()
{
}
//static:
Glib::RefPtr<ExampleTreeModel> ExampleTreeModel::create()
{
return Glib::RefPtr<ExampleTreeModel>( new ExampleTreeModel );
}
Gtk::TreeModelFlags ExampleTreeModel::get_flags_vfunc()
{
return Gtk::TreeModelFlags(0);
}
int ExampleTreeModel::get_n_columns_vfunc()
{
return m_rows[0].size(); //The number of columns in the first (same as every one) row.
}
GType ExampleTreeModel::get_column_type_vfunc(int index)
{
if(index <= (int)m_listModelColumns.size())
return m_listModelColumns[index].type();
else
return 0;
}
void ExampleTreeModel::get_value_vfunc(const TreeModel::iterator& iter, int column, Glib::ValueBase& value)
{
if(check_treeiter_validity(iter))
{
if(column <= (int)m_listModelColumns.size())
{
//Get the correct ValueType from the Gtk::TreeModel::Column's type, so we don't have to repeat it here:
typeModelColumn::ValueType value_specific;
value_specific.init( typeModelColumn::ValueType::value_type() ); //TODO: Is there any way to avoid this step?
//Or, instead of asking the compiler for the TreeModelColumn's ValueType:
//Glib::Value< Glib::ustring > value_specific;
//value_specific.init( Glib::Value< Glib::ustring >::value_type() ); //TODO: Is there any way to avoid this step?
typeListOfRows::iterator dataRowIter = get_data_row_iter_from_tree_row_iter(iter);
if(dataRowIter != m_rows.end())
{
typeRow& dataRow = *dataRowIter;
Glib::ustring result = dataRow[column];
value_specific.set(result); //The compiler would complain if the type was wrong.
value.init( Glib::Value< Glib::ustring >::value_type() ); //TODO: Is there any way to avoid this step? Can't it copy the type as well as the value?
value = value_specific;
}
}
}
}
bool ExampleTreeModel::iter_next_vfunc(const iterator& iter, iterator& iter_next) const
{
if( check_treeiter_validity(iter) )
{
//Start with an iter to the same row:
iter_next = iter;
//Make the GtkTreeIter represent the next row:
typeListOfRows::size_type row_index = (typeListOfRows::size_type)iter_next.gobj()->user_data;
row_index++;
if( row_index < m_rows.size() )
{
//Put the index of the next row in the iter, replacing the previous row index:
//TODO: Discover how to associate more complex data with the iterator. Memory management seems difficult. murrayc
iter_next.gobj()->user_data = (void*)row_index;
return true; //success
}
}
else
iter_next = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false; //There is no next row.
}
bool ExampleTreeModel::iter_children_vfunc(const iterator& parent, iterator& iter)
{
return iter_nth_child_vfunc(parent, 0, iter);
}
bool ExampleTreeModel::iter_has_child_vfunc(const iterator& iter) const
{
return (iter_n_children_vfunc(iter) > 0);
}
int ExampleTreeModel::iter_n_children_vfunc(const iterator& iter) const
{
if(!check_treeiter_validity(iter))
return 0;
return 0; //There are no children
}
int ExampleTreeModel::iter_n_root_children_vfunc() const
{
return 0; //There are no children
}
bool ExampleTreeModel::iter_nth_child_vfunc(const iterator& parent, int /* n */, iterator& iter) const
{
if(!check_treeiter_validity(parent))
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false;
}
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false; //There are no children.
}
bool ExampleTreeModel::iter_nth_root_child_vfunc(int /* n */, iterator& iter) const
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false; //There are no children.
}
bool ExampleTreeModel::iter_parent_vfunc(const iterator& child, iterator& iter) const
{
if(!check_treeiter_validity(child))
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false;
}
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false; //There are no children, so no parents.
}
Gtk::TreeModel::Path ExampleTreeModel::get_path_vfunc(const iterator& /* iter */)
{
//TODO:
return Path();
}
bool ExampleTreeModel::get_iter_vfunc(const Path& path, iterator& iter) const
{
unsigned sz = path.size();
if(!sz)
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false;
}
if(sz > 1) //There are no children.
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false;
}
//This is a new GtkTreeIter, so it needs the current stamp value.
//See the comment in the constructor.
iter = iterator(); //clear the input parameter.
iter.set_stamp(m_stamp);
//Store the row_index in the GtkTreeIter:
//See also iter_next_vfunc()
//TODO: Store a pointer to some more complex data type such as a typeListOfRows::iterator.
unsigned row_index = path[0];
iter.gobj()->user_data = (void*)row_index;
return true;
}
Gtk::TreeModelColumn< Glib::ustring >& ExampleTreeModel::get_model_column(int column)
{
return m_listModelColumns[column];
}
ExampleTreeModel::typeListOfRows::iterator ExampleTreeModel::get_data_row_iter_from_tree_row_iter(const iterator& iter)
{
typeListOfRows::size_type row_index = (typeListOfRows::size_type)iter.gobj()->user_data;
if( row_index > m_rows.size() )
return m_rows.end();
else
return m_rows.begin() + row_index; //TODO: Performance.
}
bool ExampleTreeModel::check_treeiter_validity(const iterator& iter) const
{
// Anything that modifies the model's structure should change the model's stamp,
// so that old iters are ignored.
return m_stamp == iter.get_stamp();
}
bool ExampleTreeModel::iter_is_valid(const iterator& iter) const
{
if(!check_treeiter_validity(iter))
return false;
return Gtk::TreeModel::iter_is_valid(iter);
}
//$Id$ -*- c++ -*-
/* gtkmm example Copyright (C) 2002 gtkmm development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef GTKMM_EXAMPLETREEMODEL_H
#define GTKMM_EXAMPLETREEMODEL_H
#include <gtkmm.h>
class ExampleTreeModel
: public Glib::Object,
public Gtk::TreeModel
{
public:
ExampleTreeModel();
virtual ~ExampleTreeModel();
static Glib::RefPtr<ExampleTreeModel> create();
Gtk::TreeModelColumn< Glib::ustring >& get_model_column(int column);
protected:
// Overrides:
virtual Gtk::TreeModelFlags get_flags_vfunc();
virtual int get_n_columns_vfunc();
virtual GType get_column_type_vfunc(int index);
virtual void get_value_vfunc(const TreeModel::iterator& iter, int column, Glib::ValueBase& value);
bool iter_next_vfunc(const iterator& iter, iterator& iter_next) const;
//TODO: Make sure that we make all of these const when we have made them all const in the TreeModel:
virtual bool iter_children_vfunc(const iterator& parent, iterator& iter);
virtual bool iter_has_child_vfunc(const iterator& iter) const;
virtual int iter_n_children_vfunc(const iterator& iter) const;
virtual int iter_n_root_children_vfunc() const;
virtual bool iter_nth_child_vfunc(const iterator& parent, int n, iterator& iter) const;
virtual bool iter_nth_root_child_vfunc(int n, iterator& iter) const;
virtual bool iter_parent_vfunc(const iterator& child, iterator& iter) const;
virtual Path get_path_vfunc(const iterator& iter);
virtual bool get_iter_vfunc(const Path& path, iterator& iter) const;
virtual bool iter_is_valid(const iterator& iter) const;
private:
typedef std::vector< Glib::ustring> typeRow; //X columns, all of type string.
typedef std::vector< typeRow > typeListOfRows; //Y rows.
typeListOfRows::iterator get_data_row_iter_from_tree_row_iter(const iterator& iter);
bool check_treeiter_validity(const iterator& iter) const;
//The data:
typeListOfRows m_rows;
//Column information:
ColumnRecord m_column_record;
typedef Gtk::TreeModelColumn<Glib::ustring> typeModelColumn;
// Usually you would have different types for each column -
// then you would want a vector of pointers to the model columns.
typedef std::vector< typeModelColumn > typeListOfModelColumns;
typeListOfModelColumns m_listModelColumns;
int m_stamp; //When the model's stamp and the TreeIter's stamp are equal, the TreeIter is valid.
};
#endif //GTKMM_EXAMPLETREEMODEL_H
//$Id$ -*- c++ -*-
/* gtkmm example Copyright (C) 2002 gtkmm development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <iostream>
#include "examplewindow.h"
ExampleWindow::ExampleWindow()
: m_Button_Quit("Quit")
{
set_title("Gtk::TreeView (TreeStore) example");
set_border_width(5);
set_default_size(400, 200);
add(m_VBox);
//Add the TreeView, inside a ScrolledWindow, with the button underneath:
m_ScrolledWindow.add(m_TreeView);
//Only show the scrollbars when they are necessary:
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_VBox.pack_start(m_ScrolledWindow);
m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK);
m_ButtonBox.set_border_width(5);
m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
m_Button_Quit.signal_clicked().connect( SigC::slot(*this, &ExampleWindow::on_button_quit) );
//Create the Tree model:
m_refTreeModel = ExampleTreeModel::create();
m_TreeView.set_model(m_refTreeModel);
//Add the TreeView's view columns, to render some of the model's columns:
m_TreeView.append_column( "one", m_refTreeModel->get_model_column(0) );
m_TreeView.append_column( "two", m_refTreeModel->get_model_column(1) );
m_TreeView.append_column( "three", m_refTreeModel->get_model_column(2) );
show_all_children();
}
ExampleWindow::~ExampleWindow()
{
}
void ExampleWindow::on_button_quit()
{
hide();
}
//$Id$ -*- c++ -*-
/* gtkmm example Copyright (C) 2002 gtkmm development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H
#include "exampletreemodel.h"
class ExampleWindow : public Gtk::Window
{
public:
ExampleWindow();
virtual ~ExampleWindow();
protected:
//Signal handlers:
virtual void on_button_quit();
//Child widgets:
Gtk::VBox m_VBox;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::TreeView m_TreeView;
//Our custom tree model:
Glib::RefPtr<ExampleTreeModel> m_refTreeModel;
Gtk::HButtonBox m_ButtonBox;
Gtk::Button m_Button_Quit;
};
#endif //GTKMM_EXAMPLEWINDOW_H
//$Id$ -*- c++ -*-
/* gtkmm example Copyright (C) 2002 gtkmm development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <gtkmm/main.h>
#include "examplewindow.h"
int main(int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
ExampleWindow window;
Gtk::Main::run(window); //Shows the window and returns when it is closed.
return 0;
}
......@@ -102,6 +102,23 @@ public:
protected:
_CTOR_DEFAULT()
//TODO: Make this appear next to the actual _vunc in the .h file:
/** Override this in derived CellRenderers.
*
* Obtains the width and height needed to render the cell. Used by view widgets
* to determine the appropriate size for the cell_area passed to
* render(). If @a cell_area is not 0, fills in the x and y
* offsets (if set) of the cell relative to this location. Please note that the
* values set in @width and @height, as well as those in @x_offset and @y_offset
* are inclusive of the xpad and ypad properties.
*
* @param widget The widget the renderer is rendering to.
* @param cell_area The area a cell will be allocated, or 0.
* @output x_offset x offset of cell relative to @a cell_area.
* @output y_offset y offset of cell relative to @a cell_area.
* @output width Width needed to render a cell.
* @output height Height needed to render a cell.
**/
_WRAP_VFUNC(void get_size(
Widget& widget,
const Gdk::Rectangle* cell_area,
......
......@@ -861,7 +861,7 @@
(define-vfunc iter_n_children
(of-object "GtkTreeModel")
(return-type "gboolean")
(return-type "int")
(parameters
'("GtkTreeIter*" "iter")
)
......
......@@ -35,7 +35,7 @@ TreeModel::iterator ListStore::erase(const iterator& iter)
{
g_assert(iter.get_gobject_if_not_end() != 0);
iterator next (iter);
iterator next(iter);
++next;
GtkTreeIter tmp = *iter.gobj();
......@@ -46,7 +46,7 @@ TreeModel::iterator ListStore::erase(const iterator& iter)
TreeModel::iterator ListStore::insert(const iterator& iter)
{
iterator new_pos (this);
iterator new_pos(this);
// get_gobject_if_not_end() returns 0 if iter is an end iterator, which
// is turn interpreted by gtk_list_store_insert_before() as request to
......
......@@ -145,6 +145,17 @@ GtkTreeModel* TreeIter::get_model_gobject() const
}
int TreeIter::get_stamp() const
{
return gobj()->stamp;
}
void TreeIter::set_stamp(int stamp)
{
gobj()->stamp = stamp;
}
/**** Gtk::TreeRow *********************************************************/
const TreeNodeChildren& TreeRow::children() const
......
......@@ -117,6 +117,21 @@ public:
*/
operator bool() const;
/** This is only useful when implementing a custom Gtk::TreeModel class.
* Compare the iterator's stamp with your model's stamp to discover whether it is valid.
* @see set_stamp().
* @result The iterator's stamp.
*/
int get_stamp() const;
/** This is only useful when implementing a custom Gtk::TreeModel class.
* Set the stamp to be equal to your model's stamp, to mark the iterator as valid.
* When your model's structure changes, you should increment your model's stamp
* to mark all older iterators as invalid. They will be recognised as invalid because
* they will then have an incorrect stamp.
*/
void set_stamp(int stamp);
#ifndef DOXYGEN_SHOULD_SKIP_THIS
explicit TreeIter(TreeModel* model); // used in TreeModel methods
......@@ -156,7 +171,7 @@ protected:
friend class Gtk::TreeNodeChildren;
friend class Gtk::TreeModel;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
#endif // DOXYGEN_SHOULD_SKIP_THIS
};
/** @relates Gtk::TreeIter */
......
......@@ -81,12 +81,15 @@ gboolean proxy_foreach_path_and_iter_callback(GtkTreeModel* model, GtkTreePath*
} //anonymous namespace
//Help the code generator, so that it doesn't have to fully qualify this type:
typedef Gtk::TreeModel::iterator iterator;
namespace Gtk
{
TreeModel::iterator TreeModel::get_iter(const Path& path)
{
iterator iter (this);
iterator iter(this);
gtk_tree_model_get_iter(gobj(), iter.gobj(), const_cast<GtkTreePath*>(path.gobj()));
return iter;
}
......@@ -150,6 +153,459 @@ bool TreeModel::iter_is_valid(const iterator& iter) const
// gtktreestore.c.
return (!iter.is_end_ && iter.gobj()->stamp != 0);
}
// Custom vfunc callbacks, because the C++ vfuncs have different parameters and return types
// that can not be generated automatically:
gboolean TreeModel_Class::iter_next_vfunc_callback(GtkTreeModel* self, GtkTreeIter* iter)
{
CppObjectType *const obj = dynamic_cast<CppObjectType*>(
Glib::ObjectBase::_get_current_wrapper((GObject*)self));
// Non-gtkmmproc-generated custom classes implicitly call the default
// Glib::ObjectBase constructor, which sets is_derived_. But gtkmmproc-
// generated classes can use this optimisation, which avoids the unnecessary
// parameter conversions if there is no possibility of the virtual function
// being overridden:
if(obj && obj->is_derived_())
{
try // Trap C++ exceptions which would normally be lost because this is a C callback.
{
// Call the virtual member method, which derived classes might override.
TreeModel::iterator iter_input = TreeModel::iterator(self, iter);
TreeModel::iterator iter_next( self, iter ); //Copies iter by value.
gboolean test = obj->iter_next_vfunc(iter_input, iter_next);
//Copy the new iter value to the C output parameter:
if(test)
*iter = *(iter_next.gobj());
return test;
}
catch(...)
{
Glib::exception_handlers_invoke();
}
}
else
{
BaseClassType *const base = static_cast<BaseClassType*>(
g_type_interface_peek_parent( // Get the parent interface of the interface (The original underlying C interface).
g_type_interface_peek(G_OBJECT_GET_CLASS(self), CppObjectType::get_type()) // Get the interface.
)
);
// Call the original underlying C function:
if(base && base->iter_next)
return (*base->iter_next)(self, iter);
}
typedef gboolean RType;
return RType();
}
bool TreeModel::iter_next_vfunc(const iterator& iter, iterator& iter_next) const
{
//Call the default C implementation:
BaseClassType *const base = static_cast<BaseClassType*>(