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


#include <glibmm.h>

/* $Id: datamodel.hg,v 1.32 2006/12/15 15:02:27 murrayc Exp $ */
// -*- C++ -*- //

/* datamodel.h
 *
 * Copyright 2003 libgdamm 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 <glibmm/object.h>
#include <libgdamm/datamodeliter.h>
#include <libgdamm/column.h>
#include <libgdamm/value.h>
#include <libgda/gda-data-model.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GdaDataModel GdaDataModel;
typedef struct _GdaDataModelClass GdaDataModelClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{ class DataModel_Class; } // namespace Gda

} // namespace Gnome
namespace Gnome
{

namespace Gda
{

class Row;
class ServerProvider;

/** Exception class for Gda connection errors.
 */
class DataModelError : public Glib::Error
{
public:
  enum Code
  {
    DATA_MODEL_ROW_OUT_OF_RANGE_ERROR,
    DATA_MODEL_COLUMN_OUT_OF_RANGE_ERROR,
    DATA_MODEL_VALUES_LIST_ERROR,
    DATA_MODEL_VALUE_TYPE_ERROR,
    DATA_MODEL_ROW_NOT_FOUND_ERROR,
    DATA_MODEL_ACCESS_ERROR,
    DATA_MODEL_FEATURE_NON_SUPPORTED_ERROR,
    DATA_MODEL_FILE_EXIST_ERROR,
    DATA_MODEL_XML_FORMAT_ERROR
  };

  DataModelError(Code error_code, const Glib::ustring& error_message);
  explicit DataModelError(GError* gobject);
  Code code() const;

#ifndef DOXYGEN_SHOULD_SKIP_THIS
private:

  static void throw_func(GError* gobject);

  friend void wrap_init(); // uses throw_func()
#endif //DOXYGEN_SHOULD_SKIP_THIS
};

} // namespace Gda

} // namespace Gnome

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::DataModelError::Code> : public Glib::Value_Enum<Gnome::Gda::DataModelError::Code>
{
public:
  static GType value_type() G_GNUC_CONST;
};

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


namespace Gnome
{

namespace Gda
{


/** @addtogroup libgdammEnums libgdamm Enums and Flags */

/**
 * @ingroup libgdammEnums
 * @par Bitwise operators:
 * <tt>%DataModelAccessFlags operator|(DataModelAccessFlags, DataModelAccessFlags)</tt><br>
 * <tt>%DataModelAccessFlags operator&(DataModelAccessFlags, DataModelAccessFlags)</tt><br>
 * <tt>%DataModelAccessFlags operator^(DataModelAccessFlags, DataModelAccessFlags)</tt><br>
 * <tt>%DataModelAccessFlags operator~(DataModelAccessFlags)</tt><br>
 * <tt>%DataModelAccessFlags& operator|=(DataModelAccessFlags&, DataModelAccessFlags)</tt><br>
 * <tt>%DataModelAccessFlags& operator&=(DataModelAccessFlags&, DataModelAccessFlags)</tt><br>
 * <tt>%DataModelAccessFlags& operator^=(DataModelAccessFlags&, DataModelAccessFlags)</tt><br>
 */
enum DataModelAccessFlags
{
  DATA_MODEL_ACCESS_RANDOM = 1 << 0,
  DATA_MODEL_ACCESS_CURSOR_FORWARD = 1 << 1,
  DATA_MODEL_ACCESS_CURSOR_BACKWARD = 1 << 2,
  DATA_MODEL_ACCESS_CURSOR = 0x6,
  DATA_MODEL_ACCESS_INSERT = 1 << 3,
  DATA_MODEL_ACCESS_UPDATE = 1 << 4,
  DATA_MODEL_ACCESS_DELETE = 1 << 5,
  DATA_MODEL_ACCESS_WRITE = 0x38
};

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

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

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

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

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

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

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

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::DataModelAccessFlags> : public Glib::Value_Flags<Gnome::Gda::DataModelAccessFlags>
{
public:
  static GType value_type() G_GNUC_CONST;
};

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


namespace Gnome
{

namespace Gda
{

/**
 * @ingroup libgdammEnums
 */
enum DataModelHint
{
  DATA_MODEL_HINT_START_BATCH_UPDATE,
  DATA_MODEL_HINT_END_BATCH_UPDATE,
  DATA_MODEL_HINT_REFRESH
};

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::DataModelHint> : public Glib::Value_Enum<Gnome::Gda::DataModelHint>
{
public:
  static GType value_type() G_GNUC_CONST;
};

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


namespace Gnome
{

namespace Gda
{

/**
 * @ingroup libgdammEnums
 */
enum DataModelIOFormat
{
  DATA_MODEL_IO_DATA_ARRAY_XML,
  DATA_MODEL_IO_TEXT_SEPARATED
};

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::DataModelIOFormat> : public Glib::Value_Enum<Gnome::Gda::DataModelIOFormat>
{
public:
  static GType value_type() G_GNUC_CONST;
};

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


namespace Gnome
{

namespace Gda
{


typedef GdaValueAttribute ValueAttribute;

/** @defgroup DataModels Data Models
 */

/** Abstract DataModel (Base class for all DataModels).
 *
 * A DataModel represents an array of values organized in rows and columns. 
 * All the data in the same column have the same type, and all the data in each row have the same semantic meaning. 
 * The DataModel is actually an interface implemented by other objects to support various kinds of data storage and 
 * operations.
 *
 * Depending on the real implementation, the contents of data models may be modified by the user by using functions 
 * provided by the model. The actual operations that a data model permits can be discovered using the 
 * get_access_flags() method.
 *
 * Again, depending on the real implementation, data retreival can be done either by accessing direct random values 
 * located by their row and column, or by using a DataModelIter cursor, or both. Use the get_access_flags() method to 
 * discover how the data model can be accessed. Note that a Datamodel which can be accessed in a random way can also 
 * be accessed using cursors (and several cusrors may be used at the same time), whereas a data model which can only 
 * be accessed using cursors can only have one cursor for iterating.
 *
 * Random access data models are easier to use since picking a value is very simple by using the get_value_at(), 
 * but they consume more memory since all the accessible values must generally be present in memory even if they 
 * are not used. Thus, if a data model must handle large quantities of data, it is generally wiser to use a data 
 * model which can be only accessed using a cursor.
 *
 * As a side note there are also data models which wrap other data models such as:
 * - The DataProxy data model which stores temporary modifications and shows only some parts of the wrapped data model.
 * - The DataAccessWrapper data model which offers memory-efficient random access on top of a wrapped cursor based access data model.
 *
 * @ingroup DataModels
 */

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

public:
  typedef DataModel CppObjectType;
  typedef DataModel_Class CppClassType;
  typedef GdaDataModel BaseObjectType;
  typedef GdaDataModelIface BaseClassType;

private:
  friend class DataModel_Class;
  static CppClassType datamodel_class_;

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

protected:
  DataModel(); // 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 DataModel(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 DataModel(GdaDataModel* castitem);

protected:
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~DataModel();

  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.
  GdaDataModel*       gobj()       { return reinterpret_cast<GdaDataModel*>(gobject_); }

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

private:

public:
  // This does not belong into this class
  

  /** Disables notifications of changes on the given data model. To
   * re-enable notifications again, you should call the
   * #gda_data_model_thaw function.
   */
  void freeze();  
  
  /** Re-enables notifications of changes on the given data model.
   */
  void thaw();

  
  /** 
   * @return The number of rows in the given data model, or -1 if the number of rows is not known.
   */
  int get_n_rows() const;
  
  /** 
   * @return The number of columns in the given data model.
   */
  int get_n_columns() const;

  
  /** Get the index of the first column named @a name in @a model.
   * @param name A column name.
   * @return The column index, or -1 if no column named @a name was found.
   */
  int get_column_index(const Glib::ustring& name);
    
  
  /** Queries the underlying data model implementation for a description
   * of a given column. That description is returned in the form of
   * a Gda::Column structure, which contains all the information
   * about the given column in the data model.
   * 
   * WARNING: the returned Gda::Column object belongs to the @a model model and
   * and should not be destroyed; any modification will affect the whole data model.
   * @param col Column number.
   * @return The description of the column.
   */
  Glib::RefPtr<Column> describe_column(int col);
  
  /** Queries the underlying data model implementation for a description
   * of a given column. That description is returned in the form of
   * a Gda::Column structure, which contains all the information
   * about the given column in the data model.
   * 
   * WARNING: the returned Gda::Column object belongs to the @a model model and
   * and should not be destroyed; any modification will affect the whole data model.
   * @param col Column number.
   * @return The description of the column.
   */
  Glib::RefPtr<const Column> describe_column(int col) const;

  
  /** 
   * @param col Column number.
   * @return The title for the given column in a data model object.
   */
  Glib::ustring get_column_title(int col) const;
  
  /** Sets the @a title of the given @a col in @a model.
   * @param col Column number.
   * @param title Title for the given column.
   */
  void set_column_title(int col, const Glib::ustring& title);

  
  /** Retrieves the data stored in the given position (identified by
   * the @a col and @a row parameters) on a data model.
   * 
   * Upon errors <tt>0</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * 
   * This is the main function for accessing data in a model which allows random access to its data.
   * To access data in a data model using a cursor, use a Gda::DataModelIter object, obtained using
   * create_iter().
   * 
   * @note the returned Value must not be modified directly (unexpected behaviours may
   * occur if you do so).
   * 
   * @note the returned value may become invalid as soon as any Libgda part is executed again,
   * which means if you want to keep the value, a copy must be made, however it will remain valid
   * as long as the only Libgda usage is calling get_value_at() for different values
   * of the same row.
   * 
   * If you want to modify a value stored in a Gda::DataModel, use the set_value_at() or 
   * set_values() methods.
   * 
   * Upon errors <tt>0</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param col A valid column number.
   * @param row A valid row number.
   * @return A Value containing the value stored in the given
   * position, or <tt>0</tt> on error (out-of-bound position, etc).
   */
  Value get_value_at(int col, int row) const;
  
  /** Upon errors <tt>0</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * 
   * This method is similar to get_value_at(), except that it also allows one to specify the expected
   * Type of the value to get: if the data model returned a Value of a type different than the expected one, then
   * this method returns <tt>0</tt> and an error code.
   * 
   * @note the same limitations and usage instructions apply as for get_value_at().
   * 
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param col A valid column number.
   * @param row A valid row number.
   * @param expected_type The expected data type of the returned value.
   * @param nullok If <tt>true</tt>, then <tt>0</tt> values (value of type Gda::TYPE_<tt>0</tt>) will not generate any error.
   * @return A Value containing the value stored in the given
   * position, or <tt>0</tt> on error (out-of-bound position, wrong data type, etc).
   */
  Value get_typed_value_at(int col, int row, GType expected_type, bool nullok) const;
  
  /** Get the attributes of the value stored at (row, col) in @a model, which
   * is an ORed value of Gda::ValueAttribute flags. As a special case, if
   *  @a row is -1, then the attributes returned correspond to a "would be" value
   * if a row was added to @a model.
   * @param col A valid column number.
   * @param row A valid row number, or -1.
   * @return The attributes as an ORed value of Gda::ValueAttribute.
   */
  ValueAttribute get_attributes_at(int col, int row);

  
  /** Creates a new iterator object Gda::DataModelIter object which can be used to iterate through
   * rows in @a model.
   * 
   * Depending on the data model's implementation, a new Gda::DataModelIter object may be created,
   * or a reference to an already existing Gda::DataModelIter may be returned.
   * 
   * If a new Gda::DataModelIter is created, then the row it represents is undefined.
   * 
   * For models which can be accessed 
   * randomly, any row can be set using Gda::DataModelIter::move_to_row(), 
   * and for models which are accessible sequentially only then use
   * Gda::DataModelIter::move_next() (and Gda::DataModelIter::move_prev() if
   * supported).
   * @return A Gda::DataModelIter object, or <tt>0</tt> if an error occurred.
   */
  Glib::RefPtr<DataModelIter> create_iter();
   
  //Ignore private functions:
  

  /** Modifies a value in @a model, at ( @a col, @a row).
   * 
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param col Column number.
   * @param row Row number.
   * @param value A Value (not <tt>0</tt>).
   * @return <tt>true</tt> if the value in the data model has been updated and no error occurred.
   */
  bool set_value_at(int col, int row, const Value& value);

  typedef std::vector<Value> ValueVector;

   
  /** In a similar way to set_value_at(), this method modifies a data model's contents
   * by setting several values at once.
   * 
   * If any value in @a values is actually <tt>0</tt>, then the value in the corresponding column is left
   * unchanged.
   *  
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param row Row number.
   * @param values A list of Value, one for at most the number of columns of @a model.
   * @return <tt>true</tt> if the value in the data model has been updated and no error occurred.
   */
  bool set_values(int row, const ValueList& values);

  
  /** Get the attributes of @a model such as how to access the data it contains if it's modifiable, etc.
   * @return An ORed value of Gda::DataModelAccessFlags flags.
   */
  DataModelAccessFlags get_access_flags() const;

   
  /** Appends a row to the given data model. If any value in @a values is actually <tt>0</tt>, then 
   * it is considered as a default value.
   * 
   * Upon errors -1 will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param values List of Value* representing the row to add.  The
   * length must match model's column count.  These Value
   * are value-copied (the user is still responsible for freeing them).
   * @return The number of the added row, or -1 if an error occurred.
   */
  int append_values(const ValueList& values);

  
  /** Appends a row to the data model (the new row will possibly have <tt>0</tt> values for all columns,
   * or some other values depending on the data model implementation)
   * 
   * Upon errors -1 will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @return The number of the added row, or -1 if an error occurred.
   */
  bool append_row();
  
  /** Removes a row from the data model.
   * 
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param row The row number to be removed.
   * @return <tt>true</tt> if successful, <tt>false</tt> otherwise.
   */
  bool remove_row(int row);

  //TODO: Maybe wrap the two input parameters (list of values, and list of their column indexes) as a map,
  //but it's not urgent. murrayc.
   

  /** Returns the first row where all the values in @a values at the columns identified at
   *  @a cols_index match. If the row can't be identified, then returns -1;
   * 
   * NOTE: the @a cols_index array MUST contain a column index for each value in @a values
   * @param values A list of Value values (no <tt>0</tt> is allowed).
   * @param cols_index An array of <tt>int</tt> containing the column number to match each value of @a values.
   * @return The requested row number, of -1 if not found.
   */
  int get_row_from_values(const ValueVector& values, const std::vector<int>& cols_index);

  
  /** Sends a hint to the data model. The hint may or may not be handled by the data
   * model, depending on its implementation
   * @param hint A hint to send to the model.
   * @param hint_value An optional value to specify the hint, or <tt>0</tt>.
   */
  void send_hint(DataModelHint hint, const Value& hint_value);


  /** Exports data contained in @a model to the a string; the format is specified using the @a format argument.
   *
   * Specifically, the parameters in the @options list can be:
   * - SEPARATOR: a string value of which the first character is used as a separator in case of CSV export.
   * -"NAME: a string value used to name the exported data if the export format is XML.
   * - OVERWRITE: a boolean value which tells if the file must be over-written if it already exists.  
   *
   * @param format The format in which to export data.
   * @param cols An array containing which columns of @model will be exported.
   * @param rows An array containing which rows of @model will be exported.
   * @param options List of options for the export.
   * @result The string.
   */
  Glib::ustring export_to_string(DataModelIOFormat format, const std::vector<int>& cols, const std::vector<int>& rows, const Glib::RefPtr<Set>& options);
  
    
  /** Exports data contained in @a model to the @a file; the format is specified using the @a format argument.
   *
   * Specifically, the parameters in the @options list can be:
   * - SEPARATOR: a string value of which the first character is used as a separator in case of CSV export.
   * -"NAME: a string value used to name the exported data if the export format is XML.
   * - OVERWRITE: a boolean value which tells if the file must be over-written if it already exists.  
   *
   * @param format The format in which to export data.
   * @param file The filename to export to.
   * @param cols An array containing which columns of @model will be exported.
   * @param rows An array containing which rows of @model will be exported.
   * @param options List of options for the export.
   * @result true if no error occurred.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool export_to_file(DataModelIOFormat format, const std::string& file, const std::vector<int>& cols, const std::vector<int>& rows, const Glib::RefPtr<Set>& options);
#else
  bool export_to_file(DataModelIOFormat format, const std::string& file, const std::vector<int>& cols, const std::vector<int>& rows, const Glib::RefPtr<Set>& options, std::auto_ptr<Glib::Error>& error);
#endif
  

  //TODO: Avoid use of C GHashTable? 
  
  /** Copy the contents of the @a from data model to the @a to data model. The copy stops as soon as an error
   * orrurs.
   * 
   * The @a cols_trans is a hash table for which keys are @a to columns numbers and the values are
   * the corresponding column numbers in the @a from data model. To set the values of a column in @a to to <tt>0</tt>,
   * create an entry in the hash table with a negative value.
   * 
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param from The source Gda::DataModel.
   * @param overwrite <tt>true</tt> if @a to is completely overwritten by @a from's data, and <tt>false</tt> if @a from's data is appended to @a to.
   * @param cols_trans A HashTable for columns translating, or <tt>0</tt>.
   * @return <tt>true</tt> if no error occurred.
   */
  bool import_from_model(const Glib::RefPtr<DataModel>& from,  bool overwrite, GHashTable *cols_trans);
  
  /** Loads the data from @a string into @a model.
   * 
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param string The string to import data from.
   * @param cols_trans A hash table containing which columns of @a model will be imported, or <tt>0</tt> for all columns, see import_from_model().
   * @param options List of options for the export.
   * @return <tt>true</tt> if no error occurred.
   */
  bool import_from_string(const Glib::ustring& string, GHashTable *cols_trans, const Glib::RefPtr<const Set>& options);
  
  /** Imports data contained in the @a file file into @a model; the format is detected.
   * 
   * Upon errors <tt>false</tt> will be returned and @a error will be assigned a
   * Error from the Gda::DATA_MODEL_ERROR domain.
   * @param file The filename to import from.
   * @param cols_trans A HashTable for columns translating, or <tt>0</tt>, see import_from_model().
   * @param options List of options for the export.
   * @return <tt>true</tt> if no error occurred.
   */
  bool import_from_file(const std::string& file, GHashTable *cols_trans, const Glib::RefPtr<const Set>& options);

  //Let's not wrap these. They are ugly and do not seem useful. murrayc.
  
  //_WRAP_METHOD(xmlNodePtr to_xml(const GLib::ustring& name), gda_data_model_to_xml_node)
  //_WRAP_METHOD(bool add_data(xmlNodePtr node), gda_data_model_add_data_from_xml_node)

  
  /** Dumps a textual representation of the @a model to the @a to_stream stream
   * 
   * The following environment variables can affect the resulting output:
   * <itemizedlist>
   * <listitem>GDA_DATA_MODEL_DUMP_ROW_NUMBERS: if set, the first column of the output will contain row numbers</listitem>
   * <listitem>GDA_DATA_MODEL_DUMP_ATTRIBUTES: if set, also dump the data model's columns' types and value's attributes</listitem>
   * <listitem>GDA_DATA_MODEL_DUMP_TITLE: if set, also dump the data model's title</listitem>
   * <listitem>GDA_DATA_MODEL_DUMP_NULL_AS_EMPTY: if set, replace the '<tt>0</tt>' string with an empty string for <tt>0</tt> values </listitem>
   * </itemizedlist>
   * @param to_stream Where to dump the data model.
   */
  void dump(FILE* to_stream) const;
  
  /** Dumps a textual representation of the @a model into a new string
   * 
   * The following environment variables can affect the resulting output:
   * <itemizedlist>
   * <listitem>GDA_DATA_MODEL_DUMP_ROW_NUMBERS: if set, the first column of the output will contain row numbers</listitem>
   * <listitem>GDA_DATA_MODEL_DUMP_TITLE: if set, also dump the data model's title</listitem>
   * <listitem>GDA_DATA_MODEL_DUMP_NULL_AS_EMPTY: if set, replace the '<tt>0</tt>' string with an empty string for <tt>0</tt> values </listitem>
   * </itemizedlist>
   * @return A new string.
   */
  Glib::ustring dump_as_string() const;

  //These are from gda-datamodel-extra.h:
  //TODO: Are these meant to be public API?
  //See http://bugzilla.gnome.org/show_bug.cgi?id=513543 (wrong bug number? murrayc)
  /* Let's assume not. It's safer to add them later if necessary:
  _WRAP_METHOD(void signal_emit_changed(), gda_data_model_signal_emit_changed)
  _WRAP_METHOD(void row_inserted(int row), gda_data_model_row_inserted)
  _WRAP_METHOD(void row_updated(int row), gda_data_model_row_updated)
  _WRAP_METHOD(void row_removed(int row), gda_data_model_row_removed)
  */

  
  /** Sets the @a name of the given @a col in @a model, and if its title is not set, also sets the
   * title to @a name.
   * 
   * @newin{3,2}
   * @param col Column number.
   * @param name Name for the given column.
   */
  void set_column_name(int col, const Glib::ustring& name);
  
  /** @newin{3,2}
   * @param col Column number.
   * @return The name for the given column in a data model object.
   */
  Glib::ustring get_column_name(int col) const;      
  
  // It is a bit strange that those are int GdaDataModel and not in GdaDataModelIter
  
  /** 
   */
  bool iter_move_next_default(const Glib::RefPtr<DataModelIter>& iter);
  
  /** 
   */
  bool iter_move_prev_default(const Glib::RefPtr<DataModelIter>& iter);    
  
  /** 
   */
  bool iter_move_to_row_default(const Glib::RefPtr<DataModelIter>& iter, int row);    
    
  //These are in a private header. Ignore them:
  

  /**
   * @par Prototype:
   * <tt>void on_my_%row_inserted(int row)</tt>
   */

  Glib::SignalProxy1< void,int > signal_row_inserted();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%row_updated(int row)</tt>
   */

  Glib::SignalProxy1< void,int > signal_row_updated();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%row_removed(int row)</tt>
   */

  Glib::SignalProxy1< void,int > signal_row_removed();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%reset()</tt>
   */

  Glib::SignalProxy0< void > signal_reset();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%changed()</tt>
   */

  Glib::SignalProxy0< void > signal_changed();


protected:

  //We don't wrap the vfuncs because they are only useful for creating new backends,
  //and they have a high code-size and per-object memory cost.


public:

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

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

  //Default Signal Handlers::
  virtual void on_row_inserted(int row);
  virtual void on_row_updated(int row);
  virtual void on_row_removed(int row);
  virtual void on_reset();
  virtual void on_changed();


};

} // namespace Gda
} // namespace Gnome


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 Gnome::Gda::DataModel
   */
  Glib::RefPtr<Gnome::Gda::DataModel> wrap(GdaDataModel* object, bool take_copy = false);

} // namespace Glib


#endif /* _LIBGDAMM_DATAMODEL_H */

