/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002 The Inti Development Team.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library 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.
 */

//! @file inti/gtk/accelmap.h
//! @brief A GtkAccelMap C++ wrapper interface.

#ifndef INTI_GTK_ACCEL_MAP_H
#define INTI_GTK_ACCEL_MAP_H

#ifndef INTI_SLOT_H
#include <inti/slot.h>
#endif

#ifndef INTI_GTK_ACCEL_GROUP_H
#include <inti/gtk/accelgroup.h>
#endif

#ifndef __GTK_ACCEL_MAP_H__
#include <gtk/gtkaccelmap.h>
#endif

namespace Inti {

namespace G {
class Scanner;
}

namespace Gtk {

//! @class AccelMap accelmap.h inti/gtk/accelmap.h
//! @brief A GtkAccelMap C++ wrapper class.

class AccelMap
{
public:
	typedef Slot3<void, const char*, const AccelKey&, bool> ForeachSlot;
	//!< Signature for the callback slot to be called on each entry in the accelerator map.
	//!< <B>Example:</B> Method signature for ForeachSlot.
	//!< @code
	//!< void method(const char *accel_path, const AccelKey& accel_key, bool changed);
	//!<
	//!< // accel_path: The accelerator path for the entry.
	//!< // accel_key: An AccelKey object that holds the entry's accelerator key and modifiers.
	//!< // changed: Whether the accelerator was changed during runtime and would need saving.
	//!< @endcode

	static bool lookup_entry(const char *accel_path, AccelKey *accel_key = 0);
	//!< Looks up the accelerator entry for accel_path and fills in accel_key.
	//!< @param accel_path A valid accelerator path.
	//!< @param accel_key The accelerator key to be filled in (optional).
	//!< @return <EM>true</EM> if accel_path is known, <EM>false</EM> otherwise.

	static void add_entry(const char *accel_path, const AccelKey& accel_key);
	//!< Registers a new accelerator with the global accelerator map.
	//!< @param accel_path A valid accelerator path.
	//!< @param accel_key An AccelKey specifying the accelerator key value and modifiers.
	//!<
	//!< <BR>This function should only be called once per accel_path with the canonical
	//!< accelerator key value and modifiers for this path. To change the accelerator
	//!< during runtime programatically, use change_entry(). The accelerator path must
	//!< consist of "\<WINDOWTYPE\>/Category1/Category2/.../Action", where \<WINDOWTYPE\>
	//!< should be a unique application-specific identifier, that corresponds to the
	//!< kind of window the accelerator is being used in, e.g. "Gimp-Image",
	//!< "Abiword-Document" or "Gnumeric-Settings". The Category1/.../Action portion
	//!< is most appropriately chosen by the action the accelerator triggers, i.e. for
	//!< accelerators on menu items, choose the item's menu path, e.g. "File/Save As",
	//!< "Image/View/Zoom" or "Edit/Select All". So a full valid accelerator path may 
	//!< look like: "\<Gimp-Toolbox\>/File/Dialogs/Tool Options...".

	static bool change_entry(const char *accel_path, const AccelKey& accel_key, bool replace);
	//!< Changes the key value and modifiers currently associated with accel_path.
	//!< @param accel_path A valid accelerator path.
	//!< @param accel_key An AccelKey specifying the accelerator key value and modifiers.
	//!< @param replace Set <EM>true</EM> if other accelerators may be deleted upon conflicts.
	//!< @return <EM>true</EM> if the accelerator could be changed, <EM>false</EM> otherwise.
	//!<
	//!< <BR>Due to conflicts with other accelerators, a change may not always be possible,
	//!< replace indicates whether other accelerators may be deleted to resolve such conflicts.
	//!< A change will only occur if all conflicts could be resolved (which might not be the 
	//!< case if conflicting accelerators are locked). Successful changes are indicated by a
	//!< <EM>true</EM> return value.

	static void load(const String& filename);
	//!< Parses a file previously saved with save() for accelerator specifications, 
	//!< and propagates them accordingly.
	//!< @param filename A file containing accelerator specifications.

	static void load(int file_descriptor);
	//!< Filedescriptor variant of load().
	//!< @param file_descriptor A valid readable file descriptor.
	//!<
	//!< <BR>Note that the file descriptor will not be closed by this function.

	static void load(G::Scanner& scanner);
	//!< G::Scanner variant of load().
	//!< @param scanner A G::Scanner which has already been provided with an input file.
	
	static void save(const String& filename);
	//!< Saves current accelerator specifications (accelerator path, key and modifiers) to
	//!< file_name. 
	//!< @param filename A file to contain accelerator specifications.
	//!<
	//!< <BR>The file is written in a format suitable to be read back in by load().

	static void save(int file_descriptor);
	//!< Filedescriptor variant of save().
	//!< @param file_descriptor A valid writable file descriptor.
	
	static void foreach(const ForeachSlot *slot);
	//!< Loops over the entries in the accelerator map whose accel_path doesn't match any
	//!< of the filters added with add_filter(), and calls <EM>slot</EM> on each.
	//!< @param slot Ahe ForeachSlot to be called for each map entry not filtered out.
	//!<
	//!< <BR>The signature for the ForeachSlot is typedef'd above, the changed parameter indicates
	//!< whether this accelerator was changed during runtime (thus, would need saving during
	//!< an accelerator map dump).
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_ACCEL_MAP_H

