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


#include <glibmm.h>

// -*- Mode: C++; c-basic-offset: 4 -*-
/* $Id: client.hg,v 1.25 2005/03/03 13:17:47 murrayc Exp $ */

/* client.hg
 * 
 * Copyright (C) 2000-2002 GConfmm 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 <gconf/gconf-client.h>

#include <glibmm/object.h>

#include <glibmm/error.h>
#include <gconfmm/value.h>
#include <gconfmm/callback.h>
#include <gconfmm/entry.h>
#include <gconfmm/schema.h>
#include <gconfmm/setinterface.h>
#include <gconfmm/changeset.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GConfClient GConfClient;
typedef struct _GConfClientClass GConfClientClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Conf
{ class Client_Class; } // namespace Conf

} // namespace Gnome
namespace Gnome
{
namespace Conf
{

/** @addtogroup gconfmmEnums gconfmm Enums and Flags */

/**
 * @ingroup gconfmmEnums
 */
enum ClientErrorHandlingMode
{
  CLIENT_HANDLE_NONE,
  CLIENT_HANDLE_UNRETURNED,
  CLIENT_HANDLE_ALL
};

} // namespace Conf

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Conf
{

/**
 * @ingroup gconfmmEnums
 */
enum ClientPreloadType
{
  CLIENT_PRELOAD_NONE,
  CLIENT_PRELOAD_ONELEVEL,
  CLIENT_PRELOAD_RECURSIVE
};

} // namespace Conf

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Conf
{


/** Exception class for Gnome::Conf::Client errors.
 */
class Error : public Glib::Error
{
public:
  enum Code
  {
    SUCCESS = 0,
    NO_SERVER = 2,
    NO_PERMISSION = 3,
    BAD_ADDRESS = 4,
    PARSE_ERROR = 6,
    CORRUPT = 7,
    TYPE_MISMATCH = 8,
    IS_DIR = 9,
    IS_KEY = 10,
    OVERRIDDEN = 11,
    OAF_ERROR = 12,
    LOCAL_ENGINE = 13,
    LOCK_FAILED = 14,
    NO_WRITABLE_DATABASE = 15,
    IN_SHUTDOWN = 16
  };

  Error(Code error_code, const Glib::ustring& error_message);
  explicit Error(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 Conf

} // namespace Gnome

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Conf
{


#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T>
struct BasicTypeTraits 
{
  typedef T CppType;
  typedef CppType* CType;
  typedef CppType* CTypeNonConst;

  static CType to_c_type(CppType val)
  {
    CType pVal = new CppType;
    *pVal = val;
    return pVal;
  }

  static CType to_c_type(CType ptr)
  { return ptr; } 
  
  static CppType to_cpp_type(CType ptr)
  {
    if(ptr)
    {
      return *ptr;
    }
    else
      return CppType();
  }
  
  static void release_c_type(CType ptr)
  {
    if(ptr)
      delete ptr;
  }
};


//Template specialization:
template <>
struct BasicTypeTraits<int> 
{
  typedef int CppType;
  typedef CppType* CType;
  typedef CppType* CTypeNonConst;

  static CType to_c_type(CppType val)
  { return (int*)GINT_TO_POINTER(val); }

  static CType to_c_type(CType ptr)
  { return ptr; } 
  
  static CppType to_cpp_type(CType ptr)
  {
    if(ptr)
    {
      return GPOINTER_TO_INT(ptr);
    }
    else
      return CppType();
  }
  
  static void release_c_type(CType /* ptr */)
  {
  }
};

template <>
struct BasicTypeTraits<bool> 
{
  typedef bool CppType;
  typedef gboolean* CType;
  typedef gboolean* CTypeNonConst;

  static CType to_c_type(CppType val)
  {
    return (int*)GINT_TO_POINTER(val);
  }

  static CType to_c_type(CType ptr)
  { return ptr; } 
  
  static CppType to_cpp_type(CType ptr)
  {
    if(ptr)
    {
      //We use this for gboolean too, because it is actually an int.
      return GPOINTER_TO_INT(ptr);
    }
    else
      return CppType();
  }
  
  static void release_c_type(CType /* ptr */)
  {

  }
};

#endif //DOXYGEN_SHOULD_SKIP_THIS


/** The main Gnome::Conf object.
 * This class allows you to interface withe the Gnome configuration system.
 * Generally, it stores key-value pairs. The keys have an hierarchical
 * namespace, with elements separated by slashes. The values are either
 * typed primitives (int, bool, string, float or a @c Schema), or lists of
 * primitives or pairs of primitives (for limits on the compound values,
 * see Value). For conventions on the names of keys, see the GConf
 * documentation.
 */

class Client : public Glib::Object, public SetInterface
{
    
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Client CppObjectType;
  typedef Client_Class CppClassType;
  typedef GConfClient BaseObjectType;
  typedef GConfClientClass BaseClassType;

private:  friend class Client_Class;
  static CppClassType client_class_;

private:
  // noncopyable
  Client(const Client&);
  Client& operator=(const Client&);

protected:
  explicit Client(const Glib::ConstructParams& construct_params);
  explicit Client(GConfClient* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Client();

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

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

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GConfClient* gobj_copy();

private:

    
public:
    
    /** Get the default client object for this application.
     * The object is a Singleton, so you will always get the same instance.
     * Most applications should use this. */
    static Glib::RefPtr<Client> get_default_client();
    static Glib::RefPtr<Client> get_client_for_engine(GConfEngine* engine);
    
    
  /** Add a directory to the list of directories the Client will watch.
     * Any changes to keys below this directory will cause the "value_changed" signal
     * to be emitted. When you add the directory, you can request that the Client
     * preloads its contents - see ClientPreloadType for details.
     * 
     * Added directories may not overlap. That is, if you add "/foo", you may not
     * add "/foo/bar". However you can add "/foo" and "/bar". You can also add "/foo" 
     * multiple times; if you add a directory multiple times, it will not be removed 
     * until you call remove_dir() an equal number of times.
     * @param dir: the directory to watch.
     * @param preload: the preload type (if any) to be performed.
   */
  void add_dir(const Glib::ustring& dir, ClientPreloadType preload =  CLIENT_PRELOAD_NONE);

    
  /** Remove a directory from the list of directories the Client will watch.
     * @see add_dir()
   */
  void remove_dir(const Glib::ustring& dir);

    // API-TODO: Should this return a Connection ?
    /** Request notification of changes to namespace_section. 
     * This includes the key @p namespace_section itself, and any keys below it.
     * For the notification to happen, @p namespace_section must be equal to or
     * below one of the directories added with add_dir(). 
     * You can still call notify_add() for other directories, 
     * but no notification will be received until you add a directory above 
     * or equal to @p namespace_section. One implication of this is that remove_dir() 
     * temporarily disables notifications that were below the removed directory.
     * 
     * The callback will be called with the key that changed and the Entry that
     * holds the new Value. If the Value has a type of VALUE_INVALID, then the key has been unset.
     *
     * The function returns a connection ID you can use when calling notify_remove().
     *
     * @param namespace_section: the namespace section for which notification is required.
     * @param callback: the sigc::slot to call when the a key under namespace_section changes.
     * @return a connection id that can be passed to notify_remove() to cancel the notification request.
     */
    guint notify_add(const Glib::ustring& namespace_section, Callback callback);
    
    
  /** Cancel a notification request.
     * @param cnxn: a connection id, previously returned by notify_add()
     * @see notify_add()
   */
  void notify_remove(guint cnxn);

    
  /** Emits the value_changed signal and notifies listeners as if @a key had been changed.
     * @param key The key that has changed.
     *
     * @newin2p24
   */
  void notify(const Glib::ustring& key);
    
    
  void set_error_handling(ClientErrorHandlingMode mode);
    
    
  /** Clear the client-side cache
   */
  void clear_cache();
    
    
  /** Preloads a directory.
     * Normally this happens automatically with add_dir(), but if you've called clear_cache()
     * you may need to do it again.
     * @see add_dir()
   */
  void preload(const Glib::ustring& dirname, ClientPreloadType type);
    
    
  /** Get the value of a configuration key.
     * @parameter key: the configuration key to retrieve.
     * @return the Value of the key.
     * @throw Gnome::Conf::Error.
   */
  Value get(const Glib::ustring& key) const;

    
  /** Get the value of a configuration key, without falling back to the default if
     * the key has not been set. In that case, the type of the value will be 
     * VALUE_INVALID.
     * @param key: the configuration key to retrieve.
     * @return the Value of the key.
     * @throw Gnome::Conf::Error.
   */
  Value get_without_default(const Glib::ustring& key) const;

    
  /** Get the default value of this key by looking it up in the appropriate schema.
     * @parameter key: the configuration key to retrieve.
     * @return the default Value of the key.
     * @throw Gnome::Conf::Error.
   */
  Value get_default_from_schema(const Glib::ustring& key) const;

     /** Get the complete Entry of the specified key.
     * Uses the default locale
     * @param key the configuration key to retrieve.
     * @param use_schema_default whether to fall back to the Schema default value if the specified configuration key
     * has not been set.
     * @return an Entry for the corresponding configuration key.
     * @throw Gnome::Conf::Error.
     */
    Entry get_entry(const Glib::ustring& key, bool use_schema_default = true) const;
      
    
  /** Get the complete Entry of the specified key.
     * @param key the configuration key to retrieve.
     * @param locale the locale for the user-visible strings in the Entry's Schema. Use 0 to use the default.
     * @param use_schema_default whether to fall back to the Schema default value if the specified configuration key 
     * has not been set.
     * @return an Entry for the corresponding configuration key.
     * @throw Gnome::Conf::Error.
   */
  Entry get_entry(const Glib::ustring& key, const char* locale, bool use_schema_default =  true) const;
    
    
  /** Unset a configuration key.
     * @param key the configuration key to unset.
     * @throw Gnome::Conf::Error.
   */
  void unset(const Glib::ustring& key);

    
  /** Unsets all keys below @a key, including @a key itself.
     * If any unset fails, it continues on to unset as much as it can. The first failure is then thrown as an exception.
     * @param key The configuration key to unset.
     * @param flags Change how the unset is done.
     * @throw Gnome::Conf::Error.
     *
     * @newin2p24
   */
  void recursive_unset(const Glib::ustring& key, UnsetFlags flags =  UNSET_INCLUDING_SCHEMA_NAMES);
    
    
  /** Retrieve all keys in the given configuration directory.
     * Get all the configuration keys in the given directory, without recursion.
     * @param dir: the configuration directory to scan.
     * @return a container with the names of the configuration keys.
     * @throw Gnome::Conf::Error.
   */
  Glib::SListHandle<Entry> all_entries(const Glib::ustring& dir) const;

    
  /** Retrieve all subdirectories of a given configuration directory.
     * @param dir: the configuration directory to scan.
     * @return a container with the names of the subdirectories.
     * @throw Gnome::Conf::Error.
   */
  Glib::SListHandle<Glib::ustring> all_dirs(const Glib::ustring& dir) const;
    
    
  /** Suggest to the GConf server that a sync of cached data to 
     * stable storage would be appropriate now. 
     * @throw Gnome::Conf::Error.
   */
  void suggest_sync();

    
  /** Determine whether a given configuration directory exists.
     * @return true if the directory exists.
     * @throw Gnome::Conf::Error.
   */
  bool dir_exists(const Glib::ustring& p1) const;

    
  /** Determine whether a given configuration key is writeable by the application.
     * @return true if the key is writeable.
     * @throw Gnome::Conf::Error.
   */
  bool key_is_writable(const Glib::ustring& p1) const;
    
    
  /** Get the float value at the given configuration key.
     * Throws an error if the key does not contain the appropriate type.
     * @param key: the configuration key to fetch.
     * @return the value at the specified configuration key.
     * @throw Gnome::Conf::Error
   */
  double get_float(const Glib::ustring& key) const;

    
  /** Get the integer at the given configuration key.
     * @copydoc Client::get_float(const Glib::ustring&)
   */
  gint get_int(const Glib::ustring& key) const;

    
  /** Get the boolean at the given configuration key.
     * @copydoc Client::get_float(const Glib::ustring&)
   */
  bool get_bool(const Glib::ustring& key) const;

    
  /** Get the string at the given configuration key.
     * @copydoc Client::get_float(const Glib::ustring&)
   */
  Glib::ustring get_string(const Glib::ustring& key) const;

    
  /** Get the Schema at the given configuration key.
     * @copydoc Client::get_float(const Glib::ustring&)
   */
  Schema get_schema(const Glib::ustring& key) const;

    /** Get the list of integers at the given configuration key.
     * If the given key is not a list, or the list elements are not of the appropriate type,
     * an error will be thrown.
     * @param key the configuration key that contains the list.
     * @return a Glib::SListHandle of the appropriate type.
     * @throw Gnome::Conf::Error
     */
    SListHandle_ValueInt    get_int_list(const Glib::ustring& key) const;

    /** Get the list of booleans at the given configuration key.
     * @copydoc Client::get_int_list(const Glib::ustring&) */
    SListHandle_ValueBool   get_bool_list(const Glib::ustring& key) const;

    /** Get the list of doubles at the given configuration key.
     * @copydoc Client::get_int_list(const Glib::ustring&) */
    SListHandle_ValueFloat  get_float_list(const Glib::ustring& key) const;

    /** Get the list of Schemas at the given configuration key.
     * @copydoc Client::get_int_list(const Glib::ustring&) */
    SListHandle_ValueSchema get_schema_list(const Glib::ustring& key) const;

    /** Get the list of strings at the given configuration key.
     * @copydoc Client::get_int_list(const Glib::ustring&) */
    SListHandle_ValueString get_string_list(const Glib::ustring& key) const;
    
    
    /** Get the pair at the given configuration key.
     * The pair's elements must have the types given in @p types respectively.
     * If the value is not a pair or the types do not match, an error will be thrown.
     * @param key the configuration key that contains the pair.
     * @param types a pair of the expected types of the values.
     * @return a ValuePair.
     * @throw Gnome::Conf::Error
     */
    ValuePair get_pair(const Glib::ustring& key, ValueTypePair types) const;
    
    
  /** Set the given configuration key to the specified integer value.
     * @param key the configuration key to set.
     * @param what the value to set it to.
     * @throw Gnome::Conf::Error
   */
  void set(const Glib::ustring& key, int what);

    
  /** Set the given configuration key to the specified boolean value.
     * @copydoc Client::set(const Glib::ustring& key, int what)
   */
  void set(const Glib::ustring& key, bool what);

    
  /** Set the given configuration key to the specified double value.
     * @copydoc Client::set(const Glib::ustring& key, int what)
   */
  void set(const Glib::ustring& key, double what);

    
  /** Set the given configuration key to the specified string.
     * @copydoc Client::set(const Glib::ustring& key, int what)
   */
  void set(const Glib::ustring& key, const Glib::ustring& what);

    
  /** Set the given configuration key to the specified Schema.
     * @copydoc Client::set(const Glib::ustring& key, int what)
   */
  void set(const Glib::ustring& key, const Schema& what);

    
  /** Set the given configuration key to the specified Value.
     * @copydoc Client::set(const Glib::ustring& key, int what)
   */
  void set(const Glib::ustring& key, const Value& what);
    

    typedef Glib::SListHandle< int, BasicTypeTraits<int> > SListHandleInts;
    void set_int_list(const Glib::ustring& key, const SListHandleInts& what);
    
    typedef Glib::SListHandle< bool, BasicTypeTraits<bool> > SListHandleBools;
    void set_bool_list(const Glib::ustring& key, const SListHandleBools& what);
    
    typedef Glib::SListHandle< double, BasicTypeTraits<double> > SListHandleFloats;
    void set_float_list(const Glib::ustring& key, const SListHandleFloats& what);
    
    void set_schema_list(const Glib::ustring& key, const Glib::SListHandle<Schema>& what);
    void set_string_list(const Glib::ustring& key, const Glib::SListHandle<Glib::ustring>& what);
    
    
  /** Create a ChangeSet from the current values of the configuration database.
     * Creates a ChangeSet containing the current values of all the keys listed in
     * the @p set. For instance, this could be used in a preferences dialog as an undo operation.
     * @param set A container of the configuration keys to backup.
     * @return the ChangeSet with the current values.
     * @throw Gnome::Conf::Error
     * @see ChangeSet
   */
  ChangeSet change_set_from_current(const Glib::SArray& set);
    

  /** Commit the ChangeSet to the configuration database.
     * Commits the configuration changes in the ChangeSet to the database.
     * If @p remove_commited is @c true, all successfully commited keys will be removed from the
     * ChangeSet. If an error occurs, a Gnome::Conf::Error will be thrown. This operation is
     * not atomic - an error will be thrown on the first error.
     * @param set the ChangeSet to commit.
     * @param remove_commited whether to remove successfully-commited keys from the ChangeSet.
     * @throw Gnome::Conf::Error
     * @see ChangeSet
   */
  void change_set_commit(ChangeSet& set, bool remove_commited);

    
  /** Creates a ChangeSet to reverse the effects of the given ChangeSet.
     * Creates a ChangeSet that contains the current values of the keys in @p set,
     * effectively creating a back-up of the values in the database that will be modifed
     * when the @p set will be commited. For instance, this allows you to create a back-up changeset
     * to use in case of errors, or an undo facility for preferences.
     * @param set the ChangeSet to reverse.
     * @return the reverse ChangeSet.
     * @throw Gnome::Conf::Error
     * @see ChangeSet
   */
  ChangeSet change_set_reverse(const ChangeSet& set);

 
    /** A signal emitted when a value changes.
     * This signal will only be called for directories added with add_dir().
    *
   * @par Prototype:
   * <tt>void on_my_%value_changed(const Glib::ustring& key, const Value& value)</tt>
   */

  Glib::SignalProxy2< void,const Glib::ustring&,const Value& > signal_value_changed();

    
  void value_changed(const Glib::ustring& key, const Value& value);

#ifndef DOXYGEN_SHOULD_SKIP_THIS
    // unreturned_error will never be called, as gconfmm
    // catches all GError's and throw()s them as Gnome::Conf::Error's.
    
  /**
   * @par Prototype:
   * <tt>void on_my_%unreturned_error(const Glib::Error& error)</tt>
   */

  Glib::SignalProxy1< void,const Glib::Error& > signal_unreturned_error();

    
  void unreturned_error(const Glib::Error& error);
#endif

    /** A signal emitted when an error occurs.
     * This signal will be emitted when an error occurs, right before the throw() of the error.
     *
   * @par Prototype:
   * <tt>void on_my_%error(const Glib::Error& error)</tt>
   */

  Glib::SignalProxy1< void,const Glib::Error& > signal_error();

    
  void error(const Glib::Error& error);
    
private:
    void handle_error(GError* pError) const;
    
    GSList* get_list(const Glib::ustring& key, GConfValueType list_type) const;


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_value_changed(const Glib::ustring& key, const Value& value);
  virtual void on_unreturned_error(const Glib::Error& error);
  virtual void on_error(const Glib::Error& error);


};

} /* namespace Conf */
} /* 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::Conf::Client
   */
  Glib::RefPtr<Gnome::Conf::Client> wrap(GConfClient* object, bool take_copy = false);
}


#endif /* _GCONFMM_CLIENT_H */

