Blame gtk/gtkmnemonichash.c

Packit Service fb6fa5
/* gtkmnemonichash.c: Sets of mnemonics with cycling
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * GTK - The GIMP Toolkit
Packit Service fb6fa5
 * Copyright (C) 2002, Red Hat Inc.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "gtkmnemonichash.h"
Packit Service fb6fa5
#include "gtkalias.h"
Packit Service fb6fa5
Packit Service fb6fa5
struct _GtkMnemnonicHash
Packit Service fb6fa5
{
Packit Service fb6fa5
  GHashTable *hash;
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
GtkMnemonicHash *
Packit Service fb6fa5
_gtk_mnemonic_hash_new (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkMnemonicHash *mnemonic_hash = g_new (GtkMnemonicHash, 1);
Packit Service fb6fa5
Packit Service fb6fa5
  mnemonic_hash->hash = g_hash_table_new (g_direct_hash, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return mnemonic_hash;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
mnemonic_hash_free_foreach (gpointer	key,
Packit Service fb6fa5
			    gpointer	value,
Packit Service fb6fa5
			    gpointer	user)
Packit Service fb6fa5
{
Packit Service fb6fa5
  guint keyval = GPOINTER_TO_UINT (key);
Packit Service fb6fa5
  GSList *targets = value;
Packit Service fb6fa5
Packit Service fb6fa5
  gchar *name = gtk_accelerator_name (keyval, 0);
Packit Service fb6fa5
      
Packit Service fb6fa5
  g_warning ("mnemonic \"%s\" wasn't removed for widget (%p)",
Packit Service fb6fa5
	     name, targets->data);
Packit Service fb6fa5
  g_free (name);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_slist_free (targets);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gtk_mnemonic_hash_free (GtkMnemonicHash *mnemonic_hash)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_hash_table_foreach (mnemonic_hash->hash,
Packit Service fb6fa5
			mnemonic_hash_free_foreach,
Packit Service fb6fa5
			NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  g_hash_table_destroy (mnemonic_hash->hash);
Packit Service fb6fa5
  g_free (mnemonic_hash);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gtk_mnemonic_hash_add (GtkMnemonicHash *mnemonic_hash,
Packit Service fb6fa5
			guint            keyval,
Packit Service fb6fa5
			GtkWidget       *target)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gpointer key = GUINT_TO_POINTER (keyval);
Packit Service fb6fa5
  GSList *targets, *new_targets;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (target));
Packit Service fb6fa5
  
Packit Service fb6fa5
  targets = g_hash_table_lookup (mnemonic_hash->hash, key);
Packit Service fb6fa5
  g_return_if_fail (g_slist_find (targets, target) == NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  new_targets = g_slist_append (targets, target);
Packit Service fb6fa5
  if (new_targets != targets)
Packit Service fb6fa5
    g_hash_table_insert (mnemonic_hash->hash, key, new_targets);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gtk_mnemonic_hash_remove (GtkMnemonicHash *mnemonic_hash,
Packit Service fb6fa5
			   guint           keyval,
Packit Service fb6fa5
			   GtkWidget      *target)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gpointer key = GUINT_TO_POINTER (keyval);
Packit Service fb6fa5
  GSList *targets, *new_targets;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (target));
Packit Service fb6fa5
  
Packit Service fb6fa5
  targets = g_hash_table_lookup (mnemonic_hash->hash, key);
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (targets && g_slist_find (targets, target) != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  new_targets = g_slist_remove (targets, target);
Packit Service fb6fa5
  if (new_targets != targets)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (new_targets == NULL)
Packit Service fb6fa5
	g_hash_table_remove (mnemonic_hash->hash, key);
Packit Service fb6fa5
      else
Packit Service fb6fa5
	g_hash_table_insert (mnemonic_hash->hash, key, new_targets);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gtk_mnemonic_hash_activate (GtkMnemonicHash *mnemonic_hash,
Packit Service fb6fa5
			     guint            keyval)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GSList *list, *targets;
Packit Service fb6fa5
  GtkWidget *widget, *chosen_widget;
Packit Service fb6fa5
  gboolean overloaded;
Packit Service fb6fa5
Packit Service fb6fa5
  targets = g_hash_table_lookup (mnemonic_hash->hash,
Packit Service fb6fa5
				 GUINT_TO_POINTER (keyval));
Packit Service fb6fa5
  if (!targets)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  overloaded = FALSE;
Packit Service fb6fa5
  chosen_widget = NULL;
Packit Service fb6fa5
  for (list = targets; list; list = list->next)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      widget = GTK_WIDGET (list->data);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (gtk_widget_is_sensitive (widget) &&
Packit Service fb6fa5
	  gtk_widget_get_mapped (widget) &&
Packit Service fb6fa5
          widget->window &&
Packit Service fb6fa5
	  gdk_window_is_viewable (widget->window))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (chosen_widget)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      overloaded = TRUE;
Packit Service fb6fa5
	      break;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    chosen_widget = widget;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (chosen_widget)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* For round robin we put the activated entry on
Packit Service fb6fa5
       * the end of the list after activation
Packit Service fb6fa5
       */
Packit Service fb6fa5
      targets = g_slist_remove (targets, chosen_widget);
Packit Service fb6fa5
      targets = g_slist_append (targets, chosen_widget);
Packit Service fb6fa5
      g_hash_table_insert (mnemonic_hash->hash,
Packit Service fb6fa5
			   GUINT_TO_POINTER (keyval),
Packit Service fb6fa5
			   targets);
Packit Service fb6fa5
Packit Service fb6fa5
      return gtk_widget_mnemonic_activate (chosen_widget, overloaded);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GSList *
Packit Service fb6fa5
_gtk_mnemonic_hash_lookup (GtkMnemonicHash *mnemonic_hash,
Packit Service fb6fa5
			   guint            keyval)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return g_hash_table_lookup (mnemonic_hash->hash, GUINT_TO_POINTER (keyval));
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
mnemonic_hash_foreach_func (gpointer key,
Packit Service fb6fa5
			    gpointer value,
Packit Service fb6fa5
			    gpointer data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct {
Packit Service fb6fa5
    GtkMnemonicHashForeach func;
Packit Service fb6fa5
    gpointer func_data;
Packit Service fb6fa5
  } *info = data;
Packit Service fb6fa5
Packit Service fb6fa5
  guint keyval = GPOINTER_TO_UINT (key);
Packit Service fb6fa5
  GSList *targets = value;
Packit Service fb6fa5
  
Packit Service fb6fa5
  (*info->func) (keyval, targets, info->func_data);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gtk_mnemonic_hash_foreach (GtkMnemonicHash       *mnemonic_hash,
Packit Service fb6fa5
			    GtkMnemonicHashForeach func,
Packit Service fb6fa5
			    gpointer               func_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct {
Packit Service fb6fa5
    GtkMnemonicHashForeach func;
Packit Service fb6fa5
    gpointer func_data;
Packit Service fb6fa5
  } info;
Packit Service fb6fa5
  
Packit Service fb6fa5
  info.func = func;
Packit Service fb6fa5
  info.func_data = func_data;
Packit Service fb6fa5
Packit Service fb6fa5
  g_hash_table_foreach (mnemonic_hash->hash,
Packit Service fb6fa5
			mnemonic_hash_foreach_func,
Packit Service fb6fa5
			&info;;
Packit Service fb6fa5
}