add GActionMuxer and observer interfaces
These were destined for GLib, but they don't really make sense as a public API. Instead, we'll copy/paste them around between the various codebases that need to render menus.
This commit is contained in:
		@ -390,6 +390,9 @@ gtk_private_type_h_sources = \
 | 
			
		||||
 | 
			
		||||
# GTK+ header files that don't get installed
 | 
			
		||||
gtk_private_h_sources =		\
 | 
			
		||||
	gactionmuxer.h		\
 | 
			
		||||
	gactionobserver.h	\
 | 
			
		||||
	gactionobservable.h	\
 | 
			
		||||
	gtkaccelgroupprivate.h	\
 | 
			
		||||
	gtkanimationdescription.h \
 | 
			
		||||
	gtkappchooserprivate.h	\
 | 
			
		||||
@ -503,6 +506,9 @@ deprecated_c_sources = 			\
 | 
			
		||||
 | 
			
		||||
gtk_base_c_sources = 		\
 | 
			
		||||
	$(deprecated_c_sources)	\
 | 
			
		||||
	gactionmuxer.c		\
 | 
			
		||||
	gactionobserver.c	\
 | 
			
		||||
	gactionobservable.c	\
 | 
			
		||||
	gtkquery.c		\
 | 
			
		||||
	gtksearchengine.c	\
 | 
			
		||||
	gtksearchenginesimple.c	\
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										505
									
								
								gtk/gactionmuxer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										505
									
								
								gtk/gactionmuxer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,505 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2011 Canonical Limited
 | 
			
		||||
 *
 | 
			
		||||
 * 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 of the licence, 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., 59 Temple Place - Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Ryan Lortie <desrt@desrt.ca>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "gactionmuxer.h"
 | 
			
		||||
 | 
			
		||||
#include "gactionobservable.h"
 | 
			
		||||
#include "gactionobserver.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:gactionmuxer
 | 
			
		||||
 * @short_description: Aggregate and monitor several action groups
 | 
			
		||||
 *
 | 
			
		||||
 * #GActionMuxer is a #GActionGroup and #GActionObservable that is
 | 
			
		||||
 * capable of containing other #GActionGroup instances.
 | 
			
		||||
 *
 | 
			
		||||
 * The typical use is aggrgating all of the actions applicable to a
 | 
			
		||||
 * particular context into a single action group, with namespacing.
 | 
			
		||||
 *
 | 
			
		||||
 * Consider the case of two action groups -- one containing actions
 | 
			
		||||
 * applicable to an entire application (such as 'quit') and one
 | 
			
		||||
 * containing actions applicable to a particular window in the
 | 
			
		||||
 * application (such as 'fullscreen').
 | 
			
		||||
 *
 | 
			
		||||
 * In this case, each of these action groups could be added to a
 | 
			
		||||
 * #GActionMuxer with the prefixes "app" and "win", respectively.  This
 | 
			
		||||
 * would expose the actions as "app.quit" and "win.fullscreen" on the
 | 
			
		||||
 * #GActionGroup interface presented by the #GActionMuxer.
 | 
			
		||||
 *
 | 
			
		||||
 * Activations and state change requests on the #GActionMuxer are wired
 | 
			
		||||
 * through to the underlying action group in the expected way.
 | 
			
		||||
 *
 | 
			
		||||
 * This class is typically only used at the site of "consumption" of
 | 
			
		||||
 * actions (eg: when displaying a menu that contains many actions on
 | 
			
		||||
 * different objects).
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
static void     g_action_muxer_group_iface_init         (GActionGroupInterface      *iface);
 | 
			
		||||
static void     g_action_muxer_observable_iface_init    (GActionObservableInterface *iface);
 | 
			
		||||
 | 
			
		||||
typedef GObjectClass GActionMuxerClass;
 | 
			
		||||
 | 
			
		||||
struct _GActionMuxer
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  GHashTable *actions;
 | 
			
		||||
  GHashTable *groups;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_iface_init)
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVABLE, g_action_muxer_observable_iface_init))
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer;
 | 
			
		||||
  GSList       *watchers;
 | 
			
		||||
  gchar        *fullname;
 | 
			
		||||
} Action;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer;
 | 
			
		||||
  GActionGroup *group;
 | 
			
		||||
  gchar        *prefix;
 | 
			
		||||
  gulong        handler_ids[4];
 | 
			
		||||
} Group;
 | 
			
		||||
 | 
			
		||||
static gchar **
 | 
			
		||||
g_action_muxer_list_actions (GActionGroup *action_group)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (action_group);
 | 
			
		||||
 | 
			
		||||
  return (gchar **) muxer->groups;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Group *
 | 
			
		||||
g_action_muxer_find_group (GActionMuxer  *muxer,
 | 
			
		||||
                              const gchar     **name)
 | 
			
		||||
{
 | 
			
		||||
  const gchar *dot;
 | 
			
		||||
  gchar *prefix;
 | 
			
		||||
  Group *group;
 | 
			
		||||
 | 
			
		||||
  dot = strchr (*name, '.');
 | 
			
		||||
 | 
			
		||||
  if (!dot)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  prefix = g_strndup (*name, dot - *name);
 | 
			
		||||
  group = g_hash_table_lookup (muxer->groups, prefix);
 | 
			
		||||
  g_free (prefix);
 | 
			
		||||
 | 
			
		||||
  *name = dot + 1;
 | 
			
		||||
 | 
			
		||||
  return group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Action *
 | 
			
		||||
g_action_muxer_lookup_action (GActionMuxer  *muxer,
 | 
			
		||||
                              const gchar   *prefix,
 | 
			
		||||
                              const gchar   *action_name,
 | 
			
		||||
                              gchar        **fullname)
 | 
			
		||||
{
 | 
			
		||||
  Action *action;
 | 
			
		||||
 | 
			
		||||
  *fullname = g_strconcat (prefix, ".", action_name, NULL);
 | 
			
		||||
  action = g_hash_table_lookup (muxer->actions, *fullname);
 | 
			
		||||
 | 
			
		||||
  return action;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_action_enabled_changed (GActionGroup *action_group,
 | 
			
		||||
                                       const gchar  *action_name,
 | 
			
		||||
                                       gboolean      enabled,
 | 
			
		||||
                                       gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  Group *group = user_data;
 | 
			
		||||
  gchar *fullname;
 | 
			
		||||
  Action *action;
 | 
			
		||||
  GSList *node;
 | 
			
		||||
 | 
			
		||||
  g_print ("feeling changes\n");
 | 
			
		||||
 | 
			
		||||
  action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
 | 
			
		||||
  for (node = action ? action->watchers : NULL; node; node = node->next)
 | 
			
		||||
    g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, enabled);
 | 
			
		||||
  g_action_group_action_enabled_changed (G_ACTION_GROUP (group->muxer), fullname, enabled);
 | 
			
		||||
  g_free (fullname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_action_state_changed (GActionGroup *action_group,
 | 
			
		||||
                                     const gchar  *action_name,
 | 
			
		||||
                                     GVariant     *state,
 | 
			
		||||
                                     gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  Group *group = user_data;
 | 
			
		||||
  gchar *fullname;
 | 
			
		||||
  Action *action;
 | 
			
		||||
  GSList *node;
 | 
			
		||||
 | 
			
		||||
  action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
 | 
			
		||||
  for (node = action ? action->watchers : NULL; node; node = node->next)
 | 
			
		||||
    g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, state);
 | 
			
		||||
  g_action_group_action_state_changed (G_ACTION_GROUP (group->muxer), fullname, state);
 | 
			
		||||
  g_free (fullname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_action_added (GActionGroup *action_group,
 | 
			
		||||
                             const gchar  *action_name,
 | 
			
		||||
                             gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  const GVariantType *parameter_type;
 | 
			
		||||
  Group *group = user_data;
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
  GVariant *state;
 | 
			
		||||
 | 
			
		||||
  if (g_action_group_query_action (group->group, action_name, &enabled, ¶meter_type, NULL, NULL, &state))
 | 
			
		||||
    {
 | 
			
		||||
      gchar *fullname;
 | 
			
		||||
      Action *action;
 | 
			
		||||
      GSList *node;
 | 
			
		||||
 | 
			
		||||
      action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
 | 
			
		||||
 | 
			
		||||
      for (node = action ? action->watchers : NULL; node; node = node->next)
 | 
			
		||||
        g_action_observer_action_added (node->data,
 | 
			
		||||
                                        G_ACTION_OBSERVABLE (group->muxer),
 | 
			
		||||
                                        fullname, parameter_type, enabled, state);
 | 
			
		||||
 | 
			
		||||
      g_action_group_action_added (G_ACTION_GROUP (group->muxer), fullname);
 | 
			
		||||
 | 
			
		||||
      if (state)
 | 
			
		||||
        g_variant_unref (state);
 | 
			
		||||
 | 
			
		||||
      g_free (fullname);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_action_removed (GActionGroup *action_group,
 | 
			
		||||
                               const gchar  *action_name,
 | 
			
		||||
                               gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  Group *group = user_data;
 | 
			
		||||
  gchar *fullname;
 | 
			
		||||
  Action *action;
 | 
			
		||||
  GSList *node;
 | 
			
		||||
 | 
			
		||||
  action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
 | 
			
		||||
  for (node = action ? action->watchers : NULL; node; node = node->next)
 | 
			
		||||
    g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname);
 | 
			
		||||
  g_action_group_action_removed (G_ACTION_GROUP (group->muxer), fullname);
 | 
			
		||||
  g_free (fullname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_action_muxer_query_action (GActionGroup        *action_group,
 | 
			
		||||
                             const gchar         *action_name,
 | 
			
		||||
                             gboolean            *enabled,
 | 
			
		||||
                             const GVariantType **parameter_type,
 | 
			
		||||
                             const GVariantType **state_type,
 | 
			
		||||
                             GVariant           **state_hint,
 | 
			
		||||
                             GVariant           **state)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (action_group);
 | 
			
		||||
  Group *group;
 | 
			
		||||
 | 
			
		||||
  group = g_action_muxer_find_group (muxer, &action_name);
 | 
			
		||||
 | 
			
		||||
  if (!group)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return g_action_group_query_action (group->group, action_name, enabled,
 | 
			
		||||
                                      parameter_type, state_type, state_hint, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_activate_action (GActionGroup *action_group,
 | 
			
		||||
                                const gchar  *action_name,
 | 
			
		||||
                                GVariant     *parameter)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (action_group);
 | 
			
		||||
  Group *group;
 | 
			
		||||
 | 
			
		||||
  group = g_action_muxer_find_group (muxer, &action_name);
 | 
			
		||||
 | 
			
		||||
  if (group)
 | 
			
		||||
    g_action_group_activate_action (group->group, action_name, parameter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_change_action_state (GActionGroup *action_group,
 | 
			
		||||
                                    const gchar  *action_name,
 | 
			
		||||
                                    GVariant     *state)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (action_group);
 | 
			
		||||
  Group *group;
 | 
			
		||||
 | 
			
		||||
  group = g_action_muxer_find_group (muxer, &action_name);
 | 
			
		||||
 | 
			
		||||
  if (group)
 | 
			
		||||
    g_action_group_change_action_state (group->group, action_name, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_unregister_internal (Action   *action,
 | 
			
		||||
                                    gpointer  observer)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = action->muxer;
 | 
			
		||||
  GSList **ptr;
 | 
			
		||||
 | 
			
		||||
  for (ptr = &action->watchers; *ptr; ptr = &(*ptr)->next)
 | 
			
		||||
    if ((*ptr)->data == observer)
 | 
			
		||||
      {
 | 
			
		||||
        *ptr = g_slist_remove (*ptr, observer);
 | 
			
		||||
 | 
			
		||||
        if (action->watchers == NULL)
 | 
			
		||||
          {
 | 
			
		||||
            g_hash_table_remove (muxer->actions, action->fullname);
 | 
			
		||||
            g_free (action->fullname);
 | 
			
		||||
 | 
			
		||||
            g_slice_free (Action, action);
 | 
			
		||||
 | 
			
		||||
            g_object_unref (muxer);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_weak_notify (gpointer  data,
 | 
			
		||||
                            GObject  *where_the_object_was)
 | 
			
		||||
{
 | 
			
		||||
  Action *action = data;
 | 
			
		||||
 | 
			
		||||
  g_action_muxer_unregister_internal (action, where_the_object_was);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_register_observer (GActionObservable *observable,
 | 
			
		||||
                                  const gchar       *name,
 | 
			
		||||
                                  GActionObserver   *observer)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (observable);
 | 
			
		||||
  Action *action;
 | 
			
		||||
 | 
			
		||||
  action = g_hash_table_lookup (muxer->actions, name);
 | 
			
		||||
 | 
			
		||||
  if (action == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      action = g_slice_new (Action);
 | 
			
		||||
      action->muxer = g_object_ref (muxer);
 | 
			
		||||
      action->fullname = g_strdup (name);
 | 
			
		||||
      action->watchers = NULL;
 | 
			
		||||
 | 
			
		||||
      g_hash_table_insert (muxer->actions, action->fullname, action);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  action->watchers = g_slist_prepend (action->watchers, observer);
 | 
			
		||||
  g_object_weak_ref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_unregister_observer (GActionObservable *observable,
 | 
			
		||||
                                    const gchar       *name,
 | 
			
		||||
                                    GActionObserver   *observer)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (observable);
 | 
			
		||||
  Action *action;
 | 
			
		||||
 | 
			
		||||
  action = g_hash_table_lookup (muxer->actions, name);
 | 
			
		||||
  g_object_weak_unref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
 | 
			
		||||
  g_action_muxer_unregister_internal (action, observer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_free_group (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  Group *group = data;
 | 
			
		||||
 | 
			
		||||
  g_object_unref (group->group);
 | 
			
		||||
  g_free (group->prefix);
 | 
			
		||||
 | 
			
		||||
  g_slice_free (Group, group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GActionMuxer *muxer = G_ACTION_MUXER (object);
 | 
			
		||||
 | 
			
		||||
  g_assert_cmpint (g_hash_table_size (muxer->actions), ==, 0);
 | 
			
		||||
  g_hash_table_unref (muxer->actions);
 | 
			
		||||
  g_hash_table_unref (muxer->groups);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (g_action_muxer_parent_class)
 | 
			
		||||
    ->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_init (GActionMuxer *muxer)
 | 
			
		||||
{
 | 
			
		||||
  muxer->actions = g_hash_table_new (g_str_hash, g_str_equal);
 | 
			
		||||
  muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_observable_iface_init (GActionObservableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->register_observer = g_action_muxer_register_observer;
 | 
			
		||||
  iface->unregister_observer = g_action_muxer_unregister_observer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_group_iface_init (GActionGroupInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->list_actions = g_action_muxer_list_actions;
 | 
			
		||||
  iface->query_action = g_action_muxer_query_action;
 | 
			
		||||
  iface->activate_action = g_action_muxer_activate_action;
 | 
			
		||||
  iface->change_action_state = g_action_muxer_change_action_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_action_muxer_class_init (GObjectClass *class)
 | 
			
		||||
{
 | 
			
		||||
  class->finalize = g_action_muxer_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_muxer_insert:
 | 
			
		||||
 * @muxer: a #GActionMuxer
 | 
			
		||||
 * @prefix: the prefix string for the action group
 | 
			
		||||
 * @action_group: a #GActionGroup
 | 
			
		||||
 *
 | 
			
		||||
 * Adds the actions in @action_group to the list of actions provided by
 | 
			
		||||
 * @muxer.  @prefix is prefixed to each action name, such that for each
 | 
			
		||||
 * action <varname>x</varname> in @action_group, there is an equivalent
 | 
			
		||||
 * action @prefix<literal>.</literal><varname>x</varname> in @muxer.
 | 
			
		||||
 *
 | 
			
		||||
 * For example, if @prefix is "<literal>app</literal>" and @action_group
 | 
			
		||||
 * contains an action called "<literal>quit</literal>", then @muxer will
 | 
			
		||||
 * now contain an action called "<literal>app.quit</literal>".
 | 
			
		||||
 *
 | 
			
		||||
 * If any #GActionObservers are registered for actions in the group,
 | 
			
		||||
 * "action_added" notifications will be emitted, as appropriate.
 | 
			
		||||
 *
 | 
			
		||||
 * @prefix must not contain a dot ('.').
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_muxer_insert (GActionMuxer *muxer,
 | 
			
		||||
                       const gchar  *prefix,
 | 
			
		||||
                       GActionGroup *action_group)
 | 
			
		||||
{
 | 
			
		||||
  gchar **actions;
 | 
			
		||||
  Group *group;
 | 
			
		||||
  gint i;
 | 
			
		||||
 | 
			
		||||
  /* TODO: diff instead of ripout and replace */
 | 
			
		||||
  g_action_muxer_remove (muxer, prefix);
 | 
			
		||||
 | 
			
		||||
  group = g_slice_new (Group);
 | 
			
		||||
  group->muxer = muxer;
 | 
			
		||||
  group->group = g_object_ref (action_group);
 | 
			
		||||
  group->prefix = g_strdup (prefix);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (muxer->groups, group->prefix, group);
 | 
			
		||||
 | 
			
		||||
  actions = g_action_group_list_actions (group->group);
 | 
			
		||||
  for (i = 0; actions[i]; i++)
 | 
			
		||||
    g_action_muxer_action_added (group->group, actions[i], group);
 | 
			
		||||
  g_strfreev (actions);
 | 
			
		||||
 | 
			
		||||
  group->handler_ids[0] = g_signal_connect (group->group, "action-added",
 | 
			
		||||
                                            G_CALLBACK (g_action_muxer_action_added), group);
 | 
			
		||||
  group->handler_ids[1] = g_signal_connect (group->group, "action-removed",
 | 
			
		||||
                                            G_CALLBACK (g_action_muxer_action_removed), group);
 | 
			
		||||
  group->handler_ids[2] = g_signal_connect (group->group, "action-enabled-changed",
 | 
			
		||||
                                            G_CALLBACK (g_action_muxer_action_enabled_changed), group);
 | 
			
		||||
  group->handler_ids[3] = g_signal_connect (group->group, "action-state-changed",
 | 
			
		||||
                                            G_CALLBACK (g_action_muxer_action_state_changed), group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_muxer_remove:
 | 
			
		||||
 * @muxer: a #GActionMuxer
 | 
			
		||||
 * @prefix: the prefix of the action group to remove
 | 
			
		||||
 *
 | 
			
		||||
 * Removes a #GActionGroup from the #GActionMuxer.
 | 
			
		||||
 *
 | 
			
		||||
 * If any #GActionObservers are registered for actions in the group,
 | 
			
		||||
 * "action_removed" notifications will be emitted, as appropriate.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_muxer_remove (GActionMuxer *muxer,
 | 
			
		||||
                       const gchar  *prefix)
 | 
			
		||||
{
 | 
			
		||||
  Group *group;
 | 
			
		||||
 | 
			
		||||
  group = g_hash_table_lookup (muxer->groups, prefix);
 | 
			
		||||
 | 
			
		||||
  if (group != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      gchar **actions;
 | 
			
		||||
      gint i;
 | 
			
		||||
 | 
			
		||||
      g_hash_table_steal (muxer->groups, prefix);
 | 
			
		||||
 | 
			
		||||
      actions = g_action_group_list_actions (group->group);
 | 
			
		||||
      for (i = 0; actions[i]; i++)
 | 
			
		||||
        g_action_muxer_action_removed (group->group, actions[i], group);
 | 
			
		||||
      g_strfreev (actions);
 | 
			
		||||
 | 
			
		||||
      /* 'for loop' or 'four loop'? */
 | 
			
		||||
      for (i = 0; i < 4; i++)
 | 
			
		||||
        g_signal_handler_disconnect (group->group, group->handler_ids[i]);
 | 
			
		||||
 | 
			
		||||
      g_action_muxer_free_group (group);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_muxer_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new #GActionMuxer.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
GActionMuxer *
 | 
			
		||||
g_action_muxer_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (G_TYPE_ACTION_MUXER, NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								gtk/gactionmuxer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								gtk/gactionmuxer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2011 Canonical Limited
 | 
			
		||||
 *
 | 
			
		||||
 * 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 of the licence, 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., 59 Temple Place - Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Ryan Lortie <desrt@desrt.ca>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_ACTION_MUXER_H__
 | 
			
		||||
#define __G_ACTION_MUXER_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_ACTION_MUXER                                 (g_action_muxer_get_type ())
 | 
			
		||||
#define G_ACTION_MUXER(inst)                                (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
 | 
			
		||||
                                                             G_TYPE_ACTION_MUXER, GActionMuxer))
 | 
			
		||||
#define G_IS_ACTION_MUXER(inst)                             (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
 | 
			
		||||
                                                             G_TYPE_ACTION_MUXER))
 | 
			
		||||
 | 
			
		||||
typedef struct _GActionMuxer                                GActionMuxer;
 | 
			
		||||
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
GType                   g_action_muxer_get_type                         (void);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
GActionMuxer *          g_action_muxer_new                              (void);
 | 
			
		||||
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_muxer_insert                           (GActionMuxer *muxer,
 | 
			
		||||
                                                                         const gchar  *prefix,
 | 
			
		||||
                                                                         GActionGroup *group);
 | 
			
		||||
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_muxer_remove                           (GActionMuxer *muxer,
 | 
			
		||||
                                                                         const gchar  *prefix);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ACTION_MUXER_H__ */
 | 
			
		||||
							
								
								
									
										86
									
								
								gtk/gactionobservable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								gtk/gactionobservable.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,86 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2011 Canonical Limited
 | 
			
		||||
 *
 | 
			
		||||
 * This program 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 of the
 | 
			
		||||
 * licence 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 | 
			
		||||
 * USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Ryan Lortie <desrt@desrt.ca>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "gactionobservable.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_INTERFACE (GActionObservable, g_action_observable, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:gactionobserable
 | 
			
		||||
 * @short_description: an interface implemented by objects that report
 | 
			
		||||
 *                     changes to actions
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_action_observable_default_init (GActionObservableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_observable_register_observer:
 | 
			
		||||
 * @observable: a #GActionObservable
 | 
			
		||||
 * @action_name: the name of the action
 | 
			
		||||
 * @observer: the #GActionObserver to which the events will be reported
 | 
			
		||||
 *
 | 
			
		||||
 * Registers @observer as being interested in changes to @action_name on
 | 
			
		||||
 * @observable.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_observable_register_observer (GActionObservable *observable,
 | 
			
		||||
                                       const gchar       *action_name,
 | 
			
		||||
                                       GActionObserver   *observer)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_ACTION_OBSERVABLE (observable));
 | 
			
		||||
 | 
			
		||||
  G_ACTION_OBSERVABLE_GET_IFACE (observable)
 | 
			
		||||
    ->register_observer (observable, action_name, observer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_observable_unregister_observer:
 | 
			
		||||
 * @observable: a #GActionObservable
 | 
			
		||||
 * @action_name: the name of the action
 | 
			
		||||
 * @observer: the #GActionObserver to which the events will be reported
 | 
			
		||||
 *
 | 
			
		||||
 * Removes the registration of @observer as being interested in changes
 | 
			
		||||
 * to @action_name on @observable.
 | 
			
		||||
 *
 | 
			
		||||
 * If the observer was registered multiple times, it must be
 | 
			
		||||
 * unregistered an equal number of times.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_observable_unregister_observer (GActionObservable *observable,
 | 
			
		||||
                                         const gchar       *action_name,
 | 
			
		||||
                                         GActionObserver   *observer)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_ACTION_OBSERVABLE (observable));
 | 
			
		||||
 | 
			
		||||
  G_ACTION_OBSERVABLE_GET_IFACE (observable)
 | 
			
		||||
    ->unregister_observer (observable, action_name, observer);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								gtk/gactionobservable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								gtk/gactionobservable.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2011 Canonical Limited
 | 
			
		||||
 *
 | 
			
		||||
 * This program 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 of the
 | 
			
		||||
 * licence 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 | 
			
		||||
 * USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Ryan Lortie <desrt@desrt.ca>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_ACTION_OBSERVABLE_H__
 | 
			
		||||
#define __G_ACTION_OBSERVABLE_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gactionobserver.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_ACTION_OBSERVABLE                            (g_action_observable_get_type ())
 | 
			
		||||
#define G_ACTION_OBSERVABLE(inst)                           (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
 | 
			
		||||
                                                             G_TYPE_ACTION_OBSERVABLE, GActionObservable))
 | 
			
		||||
#define G_IS_ACTION_OBSERVABLE(inst)                        (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
 | 
			
		||||
                                                             G_TYPE_ACTION_OBSERVABLE))
 | 
			
		||||
#define G_ACTION_OBSERVABLE_GET_IFACE(inst)                 (G_TYPE_INSTANCE_GET_INTERFACE ((inst),                  \
 | 
			
		||||
                                                             G_TYPE_ACTION_OBSERVABLE, GActionObservableInterface))
 | 
			
		||||
 | 
			
		||||
typedef struct _GActionObservableInterface                  GActionObservableInterface;
 | 
			
		||||
 | 
			
		||||
struct _GActionObservableInterface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  void (* register_observer)   (GActionObservable *observable,
 | 
			
		||||
                                const gchar       *action_name,
 | 
			
		||||
                                GActionObserver   *observer);
 | 
			
		||||
  void (* unregister_observer) (GActionObservable *observable,
 | 
			
		||||
                                const gchar       *action_name,
 | 
			
		||||
                                GActionObserver   *observer);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
GType                   g_action_observable_get_type                    (void);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_observable_register_observer           (GActionObservable  *observable,
 | 
			
		||||
                                                                         const gchar        *action_name,
 | 
			
		||||
                                                                         GActionObserver    *observer);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_observable_unregister_observer         (GActionObservable  *observable,
 | 
			
		||||
                                                                         const gchar        *action_name,
 | 
			
		||||
                                                                         GActionObserver    *observer);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ACTION_OBSERVABLE_H__ */
 | 
			
		||||
							
								
								
									
										171
									
								
								gtk/gactionobserver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								gtk/gactionobserver.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,171 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2011 Canonical Limited
 | 
			
		||||
 *
 | 
			
		||||
 * This program 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 of the
 | 
			
		||||
 * licence 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 | 
			
		||||
 * USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Ryan Lortie <desrt@desrt.ca>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "gactionobserver.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_INTERFACE (GActionObserver, g_action_observer, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:gactionobserver
 | 
			
		||||
 * @short_description: an interface implemented by objects that are
 | 
			
		||||
 *                     interested in monitoring actions for changes
 | 
			
		||||
 *
 | 
			
		||||
 * GActionObserver is a simple interface allowing objects that wish to
 | 
			
		||||
 * be notified of changes to actions to be notified of those changes.
 | 
			
		||||
 *
 | 
			
		||||
 * It is also possible to monitor changes to action groups using
 | 
			
		||||
 * #GObject signals, but there are a number of reasons that this
 | 
			
		||||
 * approach could become problematic:
 | 
			
		||||
 *
 | 
			
		||||
 *  - there are four separate signals that must be manually connected
 | 
			
		||||
 *    and disconnected
 | 
			
		||||
 *
 | 
			
		||||
 *  - when a large number of different observers wish to monitor a
 | 
			
		||||
 *    (usually disjoint) set of actions within the same action group,
 | 
			
		||||
 *    there is only one way to avoid having all notifications delivered
 | 
			
		||||
 *    to all observers: signal detail.  In order to use signal detail,
 | 
			
		||||
 *    each action name must be quarked, which is not always practical.
 | 
			
		||||
 *
 | 
			
		||||
 *  - even if quarking is acceptable, #GObject signal details are
 | 
			
		||||
 *    implemented by scanning a linked list, so there is no real
 | 
			
		||||
 *    decrease in complexity
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_action_observer_default_init (GActionObserverInterface *class)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_observer_action_added:
 | 
			
		||||
 * @observer: a #GActionObserver
 | 
			
		||||
 * @observable: the source of the event
 | 
			
		||||
 * @action_name: the name of the action
 | 
			
		||||
 * @enabled: %TRUE if the action is now enabled
 | 
			
		||||
 * @parameter_type: the parameter type for action invocations, or %NULL
 | 
			
		||||
 *                  if no parameter is required
 | 
			
		||||
 * @state: the current state of the action, or %NULL if the action is
 | 
			
		||||
 *         stateless
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called when an action that the observer is
 | 
			
		||||
 * registered to receive events for is added.
 | 
			
		||||
 *
 | 
			
		||||
 * This function should only be called by objects with which the
 | 
			
		||||
 * observer has explicitly registered itself to receive events.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_observer_action_added (GActionObserver    *observer,
 | 
			
		||||
                                GActionObservable  *observable,
 | 
			
		||||
                                const gchar        *action_name,
 | 
			
		||||
                                const GVariantType *parameter_type,
 | 
			
		||||
                                gboolean            enabled,
 | 
			
		||||
                                GVariant           *state)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
 | 
			
		||||
 | 
			
		||||
  G_ACTION_OBSERVER_GET_IFACE (observer)
 | 
			
		||||
    ->action_added (observer, observable, action_name, parameter_type, enabled, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_observer_action_enabled_changed:
 | 
			
		||||
 * @observer: a #GActionObserver
 | 
			
		||||
 * @observable: the source of the event
 | 
			
		||||
 * @action_name: the name of the action
 | 
			
		||||
 * @enabled: %TRUE if the action is now enabled
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called when an action that the observer is
 | 
			
		||||
 * registered to receive events for becomes enabled or disabled.
 | 
			
		||||
 *
 | 
			
		||||
 * This function should only be called by objects with which the
 | 
			
		||||
 * observer has explicitly registered itself to receive events.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_observer_action_enabled_changed (GActionObserver   *observer,
 | 
			
		||||
                                          GActionObservable *observable,
 | 
			
		||||
                                          const gchar       *action_name,
 | 
			
		||||
                                          gboolean           enabled)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
 | 
			
		||||
 | 
			
		||||
  G_ACTION_OBSERVER_GET_IFACE (observer)
 | 
			
		||||
    ->action_enabled_changed (observer, observable, action_name, enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_observer_action_state_changed:
 | 
			
		||||
 * @observer: a #GActionObserver
 | 
			
		||||
 * @observable: the source of the event
 | 
			
		||||
 * @action_name: the name of the action
 | 
			
		||||
 * @state: the new state of the action
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called when an action that the observer is
 | 
			
		||||
 * registered to receive events for changes its state.
 | 
			
		||||
 *
 | 
			
		||||
 * This function should only be called by objects with which the
 | 
			
		||||
 * observer has explicitly registered itself to receive events.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_observer_action_state_changed (GActionObserver   *observer,
 | 
			
		||||
                                        GActionObservable *observable,
 | 
			
		||||
                                        const gchar       *action_name,
 | 
			
		||||
                                        GVariant          *state)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
 | 
			
		||||
 | 
			
		||||
  G_ACTION_OBSERVER_GET_IFACE (observer)
 | 
			
		||||
    ->action_state_changed (observer, observable, action_name, state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_action_observer_action_removed:
 | 
			
		||||
 * @observer: a #GActionObserver
 | 
			
		||||
 * @observable: the source of the event
 | 
			
		||||
 * @action_name: the name of the action
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called when an action that the observer is
 | 
			
		||||
 * registered to receive events for is removed.
 | 
			
		||||
 *
 | 
			
		||||
 * This function should only be called by objects with which the
 | 
			
		||||
 * observer has explicitly registered itself to receive events.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.32
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_action_observer_action_removed (GActionObserver   *observer,
 | 
			
		||||
                                  GActionObservable *observable,
 | 
			
		||||
                                  const gchar       *action_name)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
 | 
			
		||||
 | 
			
		||||
  G_ACTION_OBSERVER_GET_IFACE (observer)
 | 
			
		||||
    ->action_removed (observer, observable, action_name);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								gtk/gactionobserver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								gtk/gactionobserver.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2011 Canonical Limited
 | 
			
		||||
 *
 | 
			
		||||
 * This program 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 of the
 | 
			
		||||
 * licence 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 | 
			
		||||
 * USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Ryan Lortie <desrt@desrt.ca>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_ACTION_OBSERVER_H__
 | 
			
		||||
#define __G_ACTION_OBSERVER_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_ACTION_OBSERVER                              (g_action_observer_get_type ())
 | 
			
		||||
#define G_ACTION_OBSERVER(inst)                             (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
 | 
			
		||||
                                                             G_TYPE_ACTION_OBSERVER, GActionObserver))
 | 
			
		||||
#define G_IS_ACTION_OBSERVER(inst)                          (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
 | 
			
		||||
                                                             G_TYPE_ACTION_OBSERVER))
 | 
			
		||||
#define G_ACTION_OBSERVER_GET_IFACE(inst)                   (G_TYPE_INSTANCE_GET_INTERFACE ((inst),                  \
 | 
			
		||||
                                                             G_TYPE_ACTION_OBSERVER, GActionObserverInterface))
 | 
			
		||||
 | 
			
		||||
typedef struct _GActionObserverInterface                    GActionObserverInterface;
 | 
			
		||||
typedef struct _GActionObservable                           GActionObservable;
 | 
			
		||||
typedef struct _GActionObserver                             GActionObserver;
 | 
			
		||||
 | 
			
		||||
struct _GActionObserverInterface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  void (* action_added)           (GActionObserver    *observer,
 | 
			
		||||
                                   GActionObservable  *observable,
 | 
			
		||||
                                   const gchar        *action_name,
 | 
			
		||||
                                   const GVariantType *parameter_type,
 | 
			
		||||
                                   gboolean            enabled,
 | 
			
		||||
                                   GVariant           *state);
 | 
			
		||||
  void (* action_enabled_changed) (GActionObserver    *observer,
 | 
			
		||||
                                   GActionObservable  *observable,
 | 
			
		||||
                                   const gchar        *action_name,
 | 
			
		||||
                                   gboolean            enabled);
 | 
			
		||||
  void (* action_state_changed)   (GActionObserver    *observer,
 | 
			
		||||
                                   GActionObservable  *observable,
 | 
			
		||||
                                   const gchar        *action_name,
 | 
			
		||||
                                   GVariant           *state);
 | 
			
		||||
  void (* action_removed)         (GActionObserver    *observer,
 | 
			
		||||
                                   GActionObservable  *observable,
 | 
			
		||||
                                   const gchar        *action_name);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
GType                   g_action_observer_get_type                      (void);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_observer_action_added                  (GActionObserver    *observer,
 | 
			
		||||
                                                                         GActionObservable  *observable,
 | 
			
		||||
                                                                         const gchar        *action_name,
 | 
			
		||||
                                                                         const GVariantType *parameter_type,
 | 
			
		||||
                                                                         gboolean            enabled,
 | 
			
		||||
                                                                         GVariant           *state);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_observer_action_enabled_changed        (GActionObserver    *observer,
 | 
			
		||||
                                                                         GActionObservable  *observable,
 | 
			
		||||
                                                                         const gchar        *action_name,
 | 
			
		||||
                                                                         gboolean            enabled);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_observer_action_state_changed          (GActionObserver    *observer,
 | 
			
		||||
                                                                         GActionObservable  *observable,
 | 
			
		||||
                                                                         const gchar        *action_name,
 | 
			
		||||
                                                                         GVariant           *state);
 | 
			
		||||
G_GNUC_INTERNAL
 | 
			
		||||
void                    g_action_observer_action_removed                (GActionObserver    *observer,
 | 
			
		||||
                                                                         GActionObservable  *observable,
 | 
			
		||||
                                                                         const gchar        *action_name);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ACTION_OBSERVER_H__ */
 | 
			
		||||
		Reference in New Issue
	
	Block a user