/* $Id: action.hg,v 1.19 2006/05/10 20:59:27 murrayc Exp $ */

/* Copyright (C) 2003 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 <gtkmm/widget.h>
#include <gtkmm/accelgroup.h>
#include <gtkmm/stockid.h>

_DEFS(gtkmm,gtk)
_PINCLUDE(glibmm/private/object_p.h)


namespace Gtk
{

class Menu;
class MenuItem;
class ToolItem;
class Image;

/** An action which can be triggered by a menu or toolbar item.
 *
 * Actions represent operations that the user can perform, along with 
 * some information about how it should be presented in the user interface. 
 * Each action provides methods to create icons, menu items and toolbar 
 * items representing itself.
 *
 * As well as the callback that is called when the action is activated, 
 * the following is also associated with the action:
 *
 *  - a name (not translated, for path lookup)
 *  - a label (translated, for display)
 *  - an accelerator
 *  - whether the label indicates a stock id
 *  - a tooltip (optional, translated)
 *  - a toolbar label (optional, shorter than label)
 *
 * The action will also have some state information:
 *
 *  - visible (shown/hidden)
 *  - sensitive (enabled/disabled)
 *
 * Apart from regular actions, there are toggle actions, 
 * which can be toggled between two states and radio actions, 
 * of which only one in a group can be in the "active" state. 
 * Other actions can be implemented as Gtk::Action subclasses.
 * 
 * Each action can have one or more proxy menu item, toolbar button or other proxy widgets. 
 * Proxies mirror the state of the action (text label, tooltip, icon, visible, sensitive, etc), and should change when the action's state changes. When the proxy is activated, it should activate its action.
 */
class Action : public Glib::Object
{
  _CLASS_GOBJECT(Action, GtkAction, GTK_ACTION, Glib::Object, GObject)
 
protected:
 _CTOR_DEFAULT
  explicit Action(const Glib::ustring& name, const StockID& stock_id, const Glib::ustring& label = Glib::ustring(), const Glib::ustring& tooltip = Glib::ustring());

public:
  _WRAP_CREATE()
  static Glib::RefPtr<Action> create(const Glib::ustring& name, const Glib::ustring& label =  Glib::ustring(), const Glib::ustring& tooltip =  Glib::ustring());
  static Glib::RefPtr<Action> create(const Glib::ustring& name, const Gtk::StockID& stock_id, const Glib::ustring& label =  Glib::ustring(), const Glib::ustring& tooltip =  Glib::ustring());

  _WRAP_METHOD(Glib::ustring get_name() const, gtk_action_get_name)

  _WRAP_METHOD(bool is_sensitive() const, gtk_action_is_sensitive)
  _WRAP_METHOD(bool get_sensitive() const, gtk_action_get_sensitive)

   void set_tooltip(const Glib::ustring& tooltip);

  _WRAP_METHOD(void set_sensitive(bool sensitive = true), gtk_action_set_sensitive)

  _WRAP_METHOD(bool is_visible() const, gtk_action_is_visible)
  _WRAP_METHOD(bool get_visible() const, gtk_action_get_visible)
  _WRAP_METHOD(void set_visible(bool visible = true), gtk_action_set_visible)

  _WRAP_METHOD(void activate(), gtk_action_activate)
  _WRAP_METHOD(Image* create_icon(IconSize icon_size), gtk_action_create_icon)
  _WRAP_METHOD(MenuItem* create_menu_item(), gtk_action_create_menu_item)
  _WRAP_METHOD(ToolItem* create_tool_item(), gtk_action_create_tool_item)
  _WRAP_METHOD(Menu* create_menu(), gtk_action_create_menu)
  _WRAP_METHOD(void connect_proxy(Widget& proxy), gtk_action_connect_proxy)
  _WRAP_METHOD(void disconnect_proxy(Widget& proxy), gtk_action_disconnect_proxy)

#m4 dnl // This isn't in convert_gtk.m4, and the default behaviour is wrong.
#m4 _CONVERSION(`GSList*', `Glib::SListHandle<Widget*>', `$2($3, Glib::OWNERSHIP_NONE)')
#m4 _CONVERSION(`GSList*', `Glib::SListHandle<const Widget*>', `$2($3, Glib::OWNERSHIP_NONE)')

  _WRAP_METHOD(Glib::SListHandle<Widget*> get_proxies(), gtk_action_get_proxies)
  _WRAP_METHOD(Glib::SListHandle<const Widget*> get_proxies() const, gtk_action_get_proxies)

  _WRAP_METHOD(void connect_accelerator(), gtk_action_connect_accelerator)
  _WRAP_METHOD(void disconnect_accelerator(), gtk_action_disconnect_accelerator)
  
  _WRAP_METHOD(Glib::ustring get_accel_path() const, gtk_action_get_accel_path)

  /// For instance, void on_activate();
  typedef sigc::slot<void> SlotActivate;
  
  /** The "activate" signal is emitted when the action is activated.
   */
  _WRAP_SIGNAL(void activate(), "activate")

  //Used by AccelGroup:
  _WRAP_METHOD(void set_accel_path(const Glib::ustring& accel_path), gtk_action_set_accel_path)
  _WRAP_METHOD(void set_accel_group(const Glib::RefPtr<AccelGroup>& accel_group), gtk_action_set_accel_group)

  _WRAP_PROPERTY("name", Glib::ustring)
  _WRAP_PROPERTY("label", Glib::ustring)
  _WRAP_PROPERTY("short_label", Glib::ustring)
  _WRAP_PROPERTY("tooltip", Glib::ustring)
  _WRAP_PROPERTY("stock_id", StockID)
  _WRAP_PROPERTY("visible_horizontal", bool)
  _WRAP_PROPERTY("visible_vertical", bool)
  _WRAP_PROPERTY("is_important", bool)
  _WRAP_PROPERTY("hide_if_empty", bool)
  _WRAP_PROPERTY("sensitive", bool)
  _WRAP_PROPERTY("visible", bool)

           
protected:
  //For use by child actions:  
  _WRAP_METHOD(void block_activate_from(Widget& proxy), gtk_action_block_activate_from)
  _WRAP_METHOD(void unblock_activate_from(Widget& proxy), gtk_action_unblock_activate_from)


protected: 
  //Widget-creation routines:
  _WRAP_VFUNC(Widget* create_menu_item(), "create_menu_item")
  _WRAP_VFUNC(Widget* create_tool_item(), "create_tool_item")
  _WRAP_VFUNC(void connect_proxy(Widget* proxy), "connect_proxy")
  _WRAP_VFUNC(void disconnect_proxy(Widget* proxy), "disconnect_proxy")
};

} // namespace Gtk

