{-# LINE 2 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
-- -*-haskell-*-
-- GIMP Toolkit (GTK) Widget ActionGroup
--
-- Author : Duncan Coutts
--
-- Created: 6 April 2005
--
-- Copyright (C) 2005 Duncan Coutts
--
-- 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.
--
-- |
-- Maintainer : gtk2hs-users@lists.sourceforge.net
-- Stability : provisional
-- Portability : portable (depends on GHC)
--
-- A group of actions
--
-- * Module available since Gtk+ version 2.4
--
module Graphics.UI.Gtk.ActionMenuToolbar.ActionGroup (
-- * Detail
--
-- | Actions are organised into groups. An action group is essentially a map
-- from names to 'Action' objects.
--
-- All actions that would make sense to use in a particular context should
-- be in a single group. Multiple action groups may be used for a particular
-- user interface. In fact, it is expected that most nontrivial applications
-- will make use of multiple groups. For example, in an application that can
-- edit multiple documents, one group holding global actions (e.g. quit, about,
-- new), and one group per document holding actions that act on that document
-- (eg. save, cut\/copy\/paste, etc). Each window's menus would be constructed
-- from a combination of two action groups.
--
-- Accelerators are handled by the Gtk+ accelerator map. All actions are
-- assigned an accelerator path (which normally has the form
-- @\<Actions>\/group-name\/action-name@) and a shortcut is associated with
-- this accelerator path. All menuitems and toolitems take on this accelerator
-- path. The Gtk+ accelerator map code makes sure that the correct shortcut is
-- displayed next to the menu item.

-- * Class Hierarchy
-- |
-- @
-- | 'GObject'
-- | +----ActionGroup
-- @


-- * Types
  ActionGroup,
  ActionGroupClass,
  castToActionGroup, gTypeActionGroup,
  toActionGroup,
  ActionEntry(..),
  ToggleActionEntry(..),
  RadioActionEntry(..),

-- * Constructors
  actionGroupNew,

-- * Methods
  actionGroupGetName,
  actionGroupGetSensitive,
  actionGroupSetSensitive,
  actionGroupGetVisible,
  actionGroupSetVisible,
  actionGroupGetAction,
  actionGroupListActions,
  actionGroupAddAction,
  actionGroupAddActionWithAccel,
  actionGroupRemoveAction,
  actionGroupAddActions,
  actionGroupAddToggleActions,
  actionGroupAddRadioActions,
  actionGroupSetTranslateFunc,
  actionGroupSetTranslationDomain,

  actionGroupTranslateString,


-- * Attributes
  actionGroupName,
  actionGroupSensitive,
  actionGroupVisible,

-- * Signals
-- onConnectProxy,
-- afterConnectProxy,
-- onDisconnectProxy,
-- afterDisconnectProxy,
-- onPreActivate,
-- afterPreActivate,
-- onPostActivate,
-- afterPostActivate,

  ) where

import Control.Monad (liftM, foldM, when)

import System.Glib.FFI
import System.Glib.UTFString
import System.Glib.GList
import System.Glib.Attributes
import System.Glib.Properties
import System.Glib.GObject (wrapNewGObject,
      makeNewGObject, destroyFunPtr)
import Graphics.UI.Gtk.Types
{-# LINE 119 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
import System.Glib.Signals (on)

import Graphics.UI.Gtk.ActionMenuToolbar.Action
import Graphics.UI.Gtk.ActionMenuToolbar.ToggleAction
import Graphics.UI.Gtk.ActionMenuToolbar.RadioAction


{-# LINE 126 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}


--------------------
-- Constructors

-- | Creates a new 'ActionGroup' object. The name of the action group is used
-- when associating keybindings with the actions.
--
actionGroupNew ::
    String -- ^ @name@ - the name of the action group.
 -> IO ActionGroup
actionGroupNew name =
  wrapNewGObject mkActionGroup $
  withUTFString name $ \namePtr ->
  gtk_action_group_new
{-# LINE 141 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    namePtr

--------------------
-- Methods

-- | Gets the name of the action group.
--
actionGroupGetName :: ActionGroup
 -> IO String -- ^ returns the name of the action group.
actionGroupGetName self =
  (\(ActionGroup arg1) -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_get_name argPtr1)
{-# LINE 152 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
  >>= peekUTFString

-- | Returns @True@ if the group is sensitive. The constituent actions can
-- only be logically sensitive (see 'actionIsSensitive') if they are sensitive
-- (see 'actionGetSensitive') and their group is sensitive.
--
actionGroupGetSensitive :: ActionGroup -> IO Bool
actionGroupGetSensitive self =
  liftM toBool $
  (\(ActionGroup arg1) -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_get_sensitive argPtr1)
{-# LINE 163 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self

-- | Changes the sensitivity of @actionGroup@
--
actionGroupSetSensitive :: ActionGroup -> Bool -> IO ()
actionGroupSetSensitive self sensitive =
  (\(ActionGroup arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_set_sensitive argPtr1 arg2)
{-# LINE 170 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    (fromBool sensitive)

-- | Returns @True@ if the group is visible. The constituent actions can only
-- be logically visible (see 'actionIsVisible') if they are visible (see
-- 'actionGetVisible') and their group is visible.
--
actionGroupGetVisible :: ActionGroup -> IO Bool
actionGroupGetVisible self =
  liftM toBool $
  (\(ActionGroup arg1) -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_get_visible argPtr1)
{-# LINE 181 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self

-- | Changes the visible of @actionGroup@.
--
actionGroupSetVisible :: ActionGroup -> Bool -> IO ()
actionGroupSetVisible self visible =
  (\(ActionGroup arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_set_visible argPtr1 arg2)
{-# LINE 188 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    (fromBool visible)

-- | Looks up an action in the action group by name.
--
actionGroupGetAction :: ActionGroup
 -> String -- ^ @actionName@ - the name of the action
 -> IO (Maybe Action) -- ^ returns the action, or @Nothing@ if no action by
                      -- that name exists
actionGroupGetAction self actionName =
  maybeNull (makeNewGObject mkAction) $
  withUTFString actionName $ \actionNamePtr ->
  (\(ActionGroup arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_get_action argPtr1 arg2)
{-# LINE 201 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    actionNamePtr

-- | Lists the actions in the action group.
--
actionGroupListActions :: ActionGroup
 -> IO [Action] -- ^ returns a list of the action objects in the action group
actionGroupListActions self =
  (\(ActionGroup arg1) -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_list_actions argPtr1)
{-# LINE 210 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
  >>= fromGList
  >>= mapM (\elemPtr -> makeNewGObject mkAction (return elemPtr))

-- | Adds an action object to the action group. Note that this function does
-- not set up the accel path of the action, which can lead to problems if a
-- user tries to modify the accelerator of a menuitem associated with the
-- action. Therefore you must either set the accel path yourself with
-- 'actionSetAccelPath', or use @'actionGroupAddActionWithAccel' ... Nothing@.
--
actionGroupAddAction :: ActionClass action => ActionGroup -> action -> IO ()
actionGroupAddAction self action =
  (\(ActionGroup arg1) (Action arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gtk_action_group_add_action argPtr1 argPtr2)
{-# LINE 223 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    (toAction action)

-- | Adds an action object to the action group and sets up the accelerator.
--
-- If @accelerator@ is @Nothing@, attempts to use the accelerator associated
-- with the stock id of the action.
--
-- Accel paths are set to @\<Actions>\/group-name\/action-name@.
--
actionGroupAddActionWithAccel :: ActionClass action => ActionGroup
 -> action -- ^ @action@ - the action to add
 -> Maybe String -- ^ @accelerator@ - the accelerator for the action, in the
                 -- format understood by 'acceleratorParse', or \"\" for no
                 -- accelerator, or @Nothing@ to use the stock accelerator
 -> IO ()
actionGroupAddActionWithAccel self action accelerator =
  maybeWith withUTFString accelerator $ \acceleratorPtr ->
  (\(ActionGroup arg1) (Action arg2) arg3 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gtk_action_group_add_action_with_accel argPtr1 argPtr2 arg3)
{-# LINE 242 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    (toAction action)
    acceleratorPtr

-- | Removes an action object from the action group.
--
actionGroupRemoveAction :: ActionClass action => ActionGroup -> action -> IO ()
actionGroupRemoveAction self action =
  (\(ActionGroup arg1) (Action arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gtk_action_group_remove_action argPtr1 argPtr2)
{-# LINE 251 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    (toAction action)

-- Note: for these next few funtions we cannot use the C version because the
-- callback doesn't allow for propper memory management. So like pygtk we
-- implement them natively since they are only convenience functions afterall.


-- | A description of an action.
data ActionEntry = ActionEntry {
       actionEntryName :: String,
       actionEntryLabel :: String,
       actionEntryStockId :: Maybe String,
       actionEntryAccelerator :: Maybe String,
       actionEntryTooltip :: Maybe String,
       actionEntryCallback :: IO ()
     }

-- | This is a convenience function to create a number of actions and add them
-- to the action group.
--
-- The 'actionActivated' signals of the actions are connected to the callbacks
-- and their accel paths are set to @\<Actions>\/group-name\/action-name@.
--
actionGroupAddActions :: ActionGroup
 -> [ActionEntry] -- ^ @entries@ - a list of action descriptions
 -> IO ()
actionGroupAddActions self entries =
  flip mapM_ entries $ \(ActionEntry name label stockId
                        accelerator tooltip callback) -> do
    action <- actionNew name label tooltip stockId
    action `on` actionActivated $ callback
    actionGroupAddActionWithAccel self action accelerator

-- | A description of an action for an entry that can be toggled.
data ToggleActionEntry = ToggleActionEntry {
       toggleActionName :: String,
       toggleActionLabel :: String,
       toggleActionStockId :: Maybe String,
       toggleActionAccelerator :: Maybe String,
       toggleActionTooltip :: Maybe String,
       toggleActionCallback :: IO (),
       toggleActionIsActive :: Bool
     }

-- | This is a convenience function to create a number of toggle actions and
-- add them to the action group.
--
-- The 'actionActivated' signals of the actions are connected to the callbacks
-- and their accel paths are set to @\<Actions>\/group-name\/action-name@.
--
actionGroupAddToggleActions :: ActionGroup
 -> [ToggleActionEntry] -- ^ @entries@ - a list of toggle action descriptions
 -> IO ()
actionGroupAddToggleActions self entries =
  flip mapM_ entries $ \(ToggleActionEntry name label stockId
                        accelerator tooltip callback isActive) -> do
    action <- toggleActionNew name label tooltip stockId
    toggleActionSetActive action isActive
    action `on` actionActivated $ callback
    actionGroupAddActionWithAccel self action accelerator

-- | A description of an action for an entry that provides a multiple choice.
data RadioActionEntry = RadioActionEntry {
       radioActionName :: String,
       radioActionLabel :: String,
       radioActionStockId :: Maybe String,
       radioActionAccelerator :: Maybe String,
       radioActionTooltip :: Maybe String,
       radioActionValue :: Int
     }

-- | This is a convenience routine to create a group of radio actions and add
-- them to the action group.
--
-- The 'radioActionChanged' signal of the first radio action is connected to the
-- @onChange@ callback and the accel paths of the actions are set to
-- @\<Actions>\/group-name\/action-name@.
--
actionGroupAddRadioActions :: ActionGroup
 -> [RadioActionEntry] -- ^ @entries@ - a list of radio action descriptions
 -> Int -- ^ @value@ - the value of the action to activate
                       -- initially, or -1 if no action should be activated
 -> (RadioAction -> IO ()) -- ^ @onChange@ - the callback for the changed signal
 -> IO ()
actionGroupAddRadioActions self entries value onChange = do
  group <- foldM
    (\group (n, RadioActionEntry name label stockId
               accelerator tooltip value) -> do
    action <- radioActionNew name label tooltip stockId value
    case group of
      Nothing -> return ()
      Just group -> radioActionSetGroup action group
    when (n == value) (toggleActionSetActive action True)
    actionGroupAddActionWithAccel self action accelerator
    return (Just action))
    Nothing (zip [0..] entries)
  case group of
      Nothing -> return ()
      Just group -> do
        group `on` radioActionChanged $ onChange
        return ()

-- | Sets a function to be used for translating the @label@ and @tooltip@ of
-- 'ActionEntry's added by 'actionGroupAddActions'.
--
-- If you\'re using \'gettext\', it is enough to set the translation domain
-- with 'actionGroupSetTranslationDomain'.
--
actionGroupSetTranslateFunc :: ActionGroup
 -> (String -> IO String) -- ^ @(\label -> ...)@ - a translation function
 -> IO ()
actionGroupSetTranslateFunc self func = do
  funcPtr <- mkTranslateFunc $ \strPtr _ -> do
               str <- peekUTFString strPtr
               translatedStr <- func str
               newUTFString translatedStr
  (\(ActionGroup arg1) arg2 arg3 arg4 -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_set_translate_func argPtr1 arg2 arg3 arg4)
{-# LINE 369 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    funcPtr
    (castFunPtrToPtr funcPtr)
    destroyFunPtr

type TranslateFunc = FunPtr (((Ptr CChar) -> ((Ptr ()) -> (IO (Ptr CChar)))))
{-# LINE 375 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}

foreign import ccall "wrapper" mkTranslateFunc ::
  (CString -> Ptr () -> IO CString) -> IO TranslateFunc

-- | Sets the translation domain and uses \'dgettext\' for translating the
-- @label@ and @tooltip@ of 'ActionEntry's added by 'actionGroupAddActions'.
--
-- If you\'re not using \'gettext\' for localization, see
-- 'actionGroupSetTranslateFunc'.
--
actionGroupSetTranslationDomain :: ActionGroup
 -> String -- ^ @domain@ - the translation domain to use for \'dgettext\'
                -- calls
 -> IO ()
actionGroupSetTranslationDomain self domain =
  withUTFString domain $ \domainPtr ->
  (\(ActionGroup arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_set_translation_domain argPtr1 arg2)
{-# LINE 392 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    domainPtr


-- | Translates a string.
--
-- * Available since Gtk+ version 2.6
--
actionGroupTranslateString :: ActionGroup
 -> String -- ^ @string@ - a string
 -> IO String -- ^ returns the translation of @string@
actionGroupTranslateString self string =
  withUTFString string $ \stringPtr ->
  (\(ActionGroup arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gtk_action_group_translate_string argPtr1 arg2)
{-# LINE 406 "./Graphics/UI/Gtk/ActionMenuToolbar/ActionGroup.chs" #-}
    self
    stringPtr
  >>= peekUTFString


--------------------
-- Attributes

-- | A name for the action group.
--
-- Default value: \"\"
--
actionGroupName :: Attr ActionGroup String
actionGroupName = newAttrFromStringProperty "name"

-- | Whether the action group is enabled.
--
-- Default value: @True@
--
actionGroupSensitive :: Attr ActionGroup Bool
actionGroupSensitive = newAttr
  actionGroupGetSensitive
  actionGroupSetSensitive

-- | Whether the action group is visible.
--
-- Default value: @True@
--
actionGroupVisible :: Attr ActionGroup Bool
actionGroupVisible = newAttr
  actionGroupGetVisible
  actionGroupSetVisible

--------------------
-- Signals

{-
-- | The connect_proxy signal is emitted after connecting a proxy to an action
-- in the group. Note that the proxy may have been connected to a different
-- action before.
--
-- This is intended for simple customizations for which a custom action
-- class would be too clumsy, e.g. showing tooltips for menuitems in the
-- statusbar.
--
onConnectProxy, afterConnectProxy :: ActionGroupClass self => self
 -> ({-GtkAction-} -> {-GtkWidget-} -> IO ())
 -> IO (ConnectId self)
onConnectProxy = connect_{-GtkAction-}_{-GtkWidget-}__NONE "connect_proxy" False
afterConnectProxy = connect_{-GtkAction-}_{-GtkWidget-}__NONE "connect_proxy" True

-- | The disconnect_proxy signal is emitted after disconnecting a proxy from
-- an action in the group.
--
onDisconnectProxy, afterDisconnectProxy :: ActionGroupClass self => self
 -> ({-GtkAction-} -> {-GtkWidget-} -> IO ())
 -> IO (ConnectId self)
onDisconnectProxy = connect_{-GtkAction-}_{-GtkWidget-}__NONE "disconnect_proxy" False
afterDisconnectProxy = connect_{-GtkAction-}_{-GtkWidget-}__NONE "disconnect_proxy" True

-- | The pre_activate signal is emitted just before the @action@ in the
-- @actionGroup@ is activated
--
-- This is intended for 'UIManager' to proxy the signal and provide global
-- notification just before any action is activated.
--
onPreActivate, afterPreActivate :: ActionGroupClass self => self
 -> ({-GtkAction-} -> IO ())
 -> IO (ConnectId self)
onPreActivate = connect_{-GtkAction-}__NONE "pre_activate" False
afterPreActivate = connect_{-GtkAction-}__NONE "pre_activate" True

-- | The post_activate signal is emitted just after the @action@ in the
-- @actionGroup@ is activated
--
-- This is intended for 'UIManager' to proxy the signal and provide global
-- notification just after any action is activated.
--
onPostActivate, afterPostActivate :: ActionGroupClass self => self
 -> ({-GtkAction-} -> IO ())
 -> IO (ConnectId self)
onPostActivate = connect_{-GtkAction-}__NONE "post_activate" False
afterPostActivate = connect_{-GtkAction-}__NONE "post_activate" True
-}

foreign import ccall safe "gtk_action_group_new"
  gtk_action_group_new :: ((Ptr CChar) -> (IO (Ptr ActionGroup)))

foreign import ccall safe "gtk_action_group_get_name"
  gtk_action_group_get_name :: ((Ptr ActionGroup) -> (IO (Ptr CChar)))

foreign import ccall safe "gtk_action_group_get_sensitive"
  gtk_action_group_get_sensitive :: ((Ptr ActionGroup) -> (IO CInt))

foreign import ccall safe "gtk_action_group_set_sensitive"
  gtk_action_group_set_sensitive :: ((Ptr ActionGroup) -> (CInt -> (IO ())))

foreign import ccall safe "gtk_action_group_get_visible"
  gtk_action_group_get_visible :: ((Ptr ActionGroup) -> (IO CInt))

foreign import ccall safe "gtk_action_group_set_visible"
  gtk_action_group_set_visible :: ((Ptr ActionGroup) -> (CInt -> (IO ())))

foreign import ccall safe "gtk_action_group_get_action"
  gtk_action_group_get_action :: ((Ptr ActionGroup) -> ((Ptr CChar) -> (IO (Ptr Action))))

foreign import ccall safe "gtk_action_group_list_actions"
  gtk_action_group_list_actions :: ((Ptr ActionGroup) -> (IO (Ptr ())))

foreign import ccall safe "gtk_action_group_add_action"
  gtk_action_group_add_action :: ((Ptr ActionGroup) -> ((Ptr Action) -> (IO ())))

foreign import ccall safe "gtk_action_group_add_action_with_accel"
  gtk_action_group_add_action_with_accel :: ((Ptr ActionGroup) -> ((Ptr Action) -> ((Ptr CChar) -> (IO ()))))

foreign import ccall safe "gtk_action_group_remove_action"
  gtk_action_group_remove_action :: ((Ptr ActionGroup) -> ((Ptr Action) -> (IO ())))

foreign import ccall safe "gtk_action_group_set_translate_func"
  gtk_action_group_set_translate_func :: ((Ptr ActionGroup) -> ((FunPtr ((Ptr CChar) -> ((Ptr ()) -> (IO (Ptr CChar))))) -> ((Ptr ()) -> ((FunPtr ((Ptr ()) -> (IO ()))) -> (IO ())))))

foreign import ccall safe "gtk_action_group_set_translation_domain"
  gtk_action_group_set_translation_domain :: ((Ptr ActionGroup) -> ((Ptr CChar) -> (IO ())))

foreign import ccall safe "gtk_action_group_translate_string"
  gtk_action_group_translate_string :: ((Ptr ActionGroup) -> ((Ptr CChar) -> (IO (Ptr CChar))))