1 /* gtkmnemonichash.c: Sets of mnemonics with cycling
3 * GTK - The GIMP Toolkit
4 * Copyright (C) 2002, Red Hat Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "gtkmnemonichash.h"
24 struct _GtkMnemnonicHash
31 _gtk_mnemonic_hash_new (void)
33 GtkMnemonicHash *mnemonic_hash = g_new (GtkMnemonicHash, 1);
35 mnemonic_hash->hash = g_hash_table_new (g_direct_hash, NULL);
41 mnemonic_hash_free_foreach (gpointer key,
45 guint keyval = GPOINTER_TO_UINT (key);
46 GSList *targets = value;
48 gchar *name = gtk_accelerator_name (keyval, 0);
50 g_warning ("mnemonic \"%s\" wasn't removed for widget (%p)",
54 g_slist_free (targets);
58 _gtk_mnemonic_hash_free (GtkMnemonicHash *mnemonic_hash)
60 g_hash_table_foreach (mnemonic_hash->hash,
61 mnemonic_hash_free_foreach,
64 g_hash_table_destroy (mnemonic_hash->hash);
65 g_free (mnemonic_hash);
69 _gtk_mnemonic_hash_add (GtkMnemonicHash *mnemonic_hash,
73 gpointer key = GUINT_TO_POINTER (keyval);
74 GSList *targets, *new_targets;
76 g_return_if_fail (GTK_IS_WIDGET (target));
78 targets = g_hash_table_lookup (mnemonic_hash->hash, key);
79 g_return_if_fail (g_slist_find (targets, target) == NULL);
81 new_targets = g_slist_append (targets, target);
82 if (new_targets != targets)
83 g_hash_table_insert (mnemonic_hash->hash, key, new_targets);
87 _gtk_mnemonic_hash_remove (GtkMnemonicHash *mnemonic_hash,
91 gpointer key = GUINT_TO_POINTER (keyval);
92 GSList *targets, *new_targets;
94 g_return_if_fail (GTK_IS_WIDGET (target));
96 targets = g_hash_table_lookup (mnemonic_hash->hash, key);
98 g_return_if_fail (targets && g_slist_find (targets, target) != NULL);
100 new_targets = g_slist_remove (targets, target);
101 if (new_targets != targets)
103 if (new_targets == NULL)
104 g_hash_table_remove (mnemonic_hash->hash, key);
106 g_hash_table_insert (mnemonic_hash->hash, key, new_targets);
111 _gtk_mnemonic_hash_activate (GtkMnemonicHash *mnemonic_hash,
114 GSList *list, *targets;
115 GtkWidget *widget, *chosen_widget;
119 targets = g_hash_table_lookup (mnemonic_hash->hash,
120 GUINT_TO_POINTER (keyval));
125 chosen_widget = NULL;
126 for (list = targets; list; list = list->next)
128 widget = GTK_WIDGET (list->data);
129 window = gtk_widget_get_window (widget);
131 if (gtk_widget_is_sensitive (widget) &&
132 gtk_widget_get_mapped (widget) &&
133 window && gdk_window_is_viewable (window))
141 chosen_widget = widget;
147 /* For round robin we put the activated entry on
148 * the end of the list after activation
150 targets = g_slist_remove (targets, chosen_widget);
151 targets = g_slist_append (targets, chosen_widget);
152 g_hash_table_insert (mnemonic_hash->hash,
153 GUINT_TO_POINTER (keyval),
156 return gtk_widget_mnemonic_activate (chosen_widget, overloaded);
162 _gtk_mnemonic_hash_lookup (GtkMnemonicHash *mnemonic_hash,
165 return g_hash_table_lookup (mnemonic_hash->hash, GUINT_TO_POINTER (keyval));
169 mnemonic_hash_foreach_func (gpointer key,
174 GtkMnemonicHashForeach func;
178 guint keyval = GPOINTER_TO_UINT (key);
179 GSList *targets = value;
181 (*info->func) (keyval, targets, info->func_data);
185 _gtk_mnemonic_hash_foreach (GtkMnemonicHash *mnemonic_hash,
186 GtkMnemonicHashForeach func,
190 GtkMnemonicHashForeach func;
195 info.func_data = func_data;
197 g_hash_table_foreach (mnemonic_hash->hash,
198 mnemonic_hash_foreach_func,