/* Copyright (C) 2010 The giomm 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, see . */ _CONFIGINCLUDE(giommconfig.h) #include #include #include //To declare g_action_group_get_action_state_type(). _DEFS(giomm,gio) _PINCLUDE(glibmm/private/interface_p.h) _PINCLUDE(gio/gio.h) #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef struct _GActionGroupInterface GActionGroupInterface; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ namespace Glib { class GIOMM_API VariantBase; class GIOMM_API VariantContainerBase; class GIOMM_API VariantType; } namespace Gio { /** ActionGroup - a group of actions. * ActionGroup represents a group of actions. * * Each action in the group has a unique name (which is a string). All method * calls, except list_actions() take the name of an action as an argument. * * The GActionGroup API is meant to be the 'public' API to the action group. * The calls here are exactly the interaction that 'external forces' (eg: UI, * incoming D-Bus messages, etc.) are supposed to have with actions. * 'Internal' APIs (ie: ones meant only to be accessed by the action group * implementation) are found on subclasses. This is why you will find -- for * example -- get_action_enabled() but not an equivalent @c set() call. * * Signals are emitted on the action group in response to state changes on * individual actions. */ class GIOMM_API ActionGroup : public Glib::Interface { _CLASS_INTERFACE(ActionGroup, GActionGroup, G_ACTION_GROUP, GActionGroupInterface, , , GIOMM_API) public: _WRAP_METHOD(bool has_action(const Glib::ustring& action_name) const, g_action_group_has_action) #m4 _CONVERSION(`gchar**',`std::vector',`Glib::ArrayHandler::array_to_vector($3, Glib::OWNERSHIP_DEEP)') _WRAP_METHOD(std::vector list_actions() const, g_action_group_list_actions) //TODO: Add templated method, renaming this to query_action_variant). _WRAP_METHOD(bool query_action(const Glib::ustring& action_name, bool& enabled{>>}, Glib::VariantType& parameter_type{>>?}, Glib::VariantBase& state_hint{.>>}, Glib::VariantType& state_type{.>>?}, Glib::VariantBase& state{.>>?}), g_action_group_query_action) _WRAP_METHOD(bool get_action_enabled(const Glib::ustring& action_name) const, g_action_group_get_action_enabled) _WRAP_METHOD(Glib::VariantType get_action_parameter_type(const Glib::ustring& action_name) const, g_action_group_get_action_parameter_type) _WRAP_METHOD(Glib::VariantType get_action_state_type(const Glib::ustring& action_name) const, g_action_group_get_action_state_type) //TODO: How do we check for a nullptr Variant? /** * Requests a hint about the valid range of values for the state of the * named action within the action group * * If a null Variant is returned it either means that the action is not stateful * or that there is no hint about the valid range of values for the * state of the action. * * If a ariant array is returned then each item in the array is a * possible value for the state. If Variant pair (ie: two-tuple) is * returned then the tuple specifies the inclusive lower and upper bound * of valid values for the state. * * In any case, the information is merely a hint. It may be possible to * have a state value outside of the hinted range and setting a value * within the range may fail. * * @param action_name The name of the action to query. * @param value This will be set to the state range hint. */ template void get_action_state_hint(const Glib::ustring& action_name, T_Value& value) const; _WRAP_METHOD(Glib::VariantContainerBase get_action_state_hint_variant(const Glib::ustring& action_name) const, g_action_group_get_action_state_hint) //TODO: How do we check for a nullptr Variant? /** Queries the current state of the named action within the action group. * * If the action is not stateful then a null Variant will be returned. If the * action is stateful then the type of the return value is the type * given by get_action_state_type(). * * @param action_name The name of the action to query. * @param value This will be set to the current state of the action. */ template void get_action_state(const Glib::ustring& action_name, T_Value& value) const; _WRAP_METHOD(Glib::VariantBase get_action_state_variant(const Glib::ustring& action_name) const, g_action_group_get_action_state) //TODO: Add templated method, renaming this to change_action_state_variant(). _WRAP_METHOD(void change_action_state(const Glib::ustring& action_name, const Glib::VariantBase& value), g_action_group_change_action_state) //TODO: Add templated method, renaming this to activate_action_variant(). _WRAP_METHOD(void activate_action(const Glib::ustring& action_name, const Glib::VariantBase& parameter{?}), g_action_group_activate_action) _WRAP_METHOD(void action_added(const Glib::ustring& action_name), g_action_group_action_added) _WRAP_METHOD(void action_removed(const Glib::ustring& action_name), g_action_group_action_removed) _WRAP_METHOD(void action_enabled_changed(const Glib::ustring& action_name, bool enabled), g_action_group_action_enabled_changed) //TODO: Add templated method, renaming this to action_state_changed_variant). _WRAP_METHOD(void action_state_changed (const Glib::ustring& action_name, const Glib::VariantBase& state), g_action_group_action_state_changed) _WRAP_SIGNAL(void action_added(const Glib::ustring& action_name), "action-added", detail_name action_name) _WRAP_SIGNAL(void action_enabled_changed(const Glib::ustring& action_name, bool enabled), "action-enabled-changed", detail_name action_name) _WRAP_SIGNAL(void action_removed(const Glib::ustring& action_name), "action-removed", detail_name action_name) #m4 _CONVERSION(`GVariant*', `const Glib::VariantBase&', `Glib::wrap($3, true)') _WRAP_SIGNAL(void action_state_changed(const Glib::ustring& action_name, const Glib::VariantBase& value), "action-state-changed", detail_name action_name) protected: _WRAP_VFUNC(bool has_action(const Glib::ustring& name) const, "has_action") #m4 _CONVERSION(`std::vector',`gchar**',`g_strdupv(const_cast(Glib::ArrayHandler::vector_to_array($3).data()))') _WRAP_VFUNC(std::vector list_actions() const, "list_actions") _WRAP_VFUNC(bool get_action_enabled(const Glib::ustring& name) const, "get_action_enabled") #m4 _CONVERSION(`Glib::VariantType',`const GVariantType*',`$3.gobj()') _WRAP_VFUNC(Glib::VariantType get_action_parameter_type(const Glib::ustring& name) const, "get_action_parameter_type", keep_return) _WRAP_VFUNC(Glib::VariantType get_action_state_type(const Glib::ustring& name) const, "get_action_state_type", keep_return) _WRAP_VFUNC(Glib::VariantBase get_action_state_hint(const Glib::ustring& name) const, "get_action_state_hint", refreturn_ctype) _WRAP_VFUNC(Glib::VariantBase get_action_state(const Glib::ustring& name) const, "get_action_state", refreturn_ctype) _WRAP_VFUNC(void change_action_state(const Glib::ustring& name, const Glib::VariantBase& value), "change_action_state") _WRAP_VFUNC(void activate_action(const Glib::ustring& name, const Glib::VariantBase& parameter), "activate_action") }; template void ActionGroup::get_action_state(const Glib::ustring& action_name, T_Value& value) const { value = T_Value(); //Make sure that it is initialized. using type_glib_variant = Glib::Variant; g_return_if_fail( g_variant_type_equal(g_action_group_get_action_state_type(const_cast(gobj()), action_name.c_str()), type_glib_variant::variant_type().gobj())); const auto variantBase = get_action_state_variant(action_name); //TODO: Add a bool return instead of letting a std::bad_cast from the cast_dynamic() be thrown up to the caller? const auto variantDerived = variantBase.cast_dynamic(variantBase); value = variantDerived.get(); } template void ActionGroup::get_action_state_hint(const Glib::ustring& action_name, T_Value& value) const { value = T_Value(); //Make sure that it is initialized. using type_glib_variant = Glib::Variant; const auto variantBase = get_action_state_hint_variant(action_name); // We can't check the type (a range) that will be returned before getting the range hint. g_return_if_fail( variantBase.is_of_type(type_glib_variant::variant_type()) ); const auto variantDerived = variantBase.cast_dynamic(variantBase); value = variantDerived.get(); } } // namespace Gio