]> Pileus Git - ~andy/gtk/blob - gtk/gtkactiongroup.c
Pull accelerator key from the stock item if stock_id is given, but
[~andy/gtk] / gtk / gtkactiongroup.c
1 /*
2  * GTK - The GIMP Toolkit
3  * Copyright (C) 1998, 1999 Red Hat, Inc.
4  * All rights reserved.
5  *
6  * This Library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
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  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with the Gnome Library; see the file COPYING.LIB.  If not,
18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /*
23  * Author: James Henstridge <james@daa.com.au>
24  *
25  * Modified by the GTK+ Team and others 2003.  See the AUTHORS
26  * file for a list of people on the GTK+ Team.  See the ChangeLog
27  * files for a list of changes.  These files are distributed with
28  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
29  */
30
31 #include <config.h>
32
33 #include "gtkactiongroup.h"
34 #include "gtkstock.h"
35 #include "gtktoggleaction.h"
36 #include "gtkradioaction.h"
37 #include "gtkaccelmap.h"
38 #include "gtkintl.h"
39
40 #define GTK_ACTION_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ACTION_GROUP, GtkActionGroupPrivate))
41
42 struct _GtkActionGroupPrivate 
43 {
44   gchar           *name;
45   GHashTable      *actions;
46
47   GtkTranslateFunc translate_func;
48   gpointer         translate_data;
49   GtkDestroyNotify translate_notify;   
50 };
51
52 enum 
53 {
54   PROP_0,
55   PROP_NAME
56 };
57
58 static void       gtk_action_group_init            (GtkActionGroup      *self);
59 static void       gtk_action_group_class_init      (GtkActionGroupClass *class);
60 static void       gtk_action_group_finalize        (GObject             *object);
61 static void       gtk_action_group_set_property    (GObject             *object,
62                                                     guint                prop_id,
63                                                     const GValue        *value,
64                                                     GParamSpec          *pspec);
65 static void       gtk_action_group_get_property    (GObject             *object,
66                                                     guint                prop_id,
67                                                     GValue              *value,
68                                                     GParamSpec          *pspec);
69 static GtkAction *gtk_action_group_real_get_action (GtkActionGroup      *self,
70                                                     const gchar         *name);
71
72
73 GType
74 gtk_action_group_get_type (void)
75 {
76   static GType type = 0;
77
78   if (!type)
79     {
80       static const GTypeInfo type_info =
81       {
82         sizeof (GtkActionGroupClass),
83         NULL,           /* base_init */
84         NULL,           /* base_finalize */
85         (GClassInitFunc) gtk_action_group_class_init,
86         NULL,           /* class_finalize */
87         NULL,           /* class_data */
88         sizeof (GtkActionGroup),
89         0, /* n_preallocs */
90         (GInstanceInitFunc) gtk_action_group_init,
91       };
92
93       type = g_type_register_static (G_TYPE_OBJECT, "GtkActionGroup",
94                                      &type_info, 0);
95     }
96
97   return type;
98 }
99
100 static GObjectClass *parent_class = NULL;
101
102 static void
103 gtk_action_group_class_init (GtkActionGroupClass *klass)
104 {
105   GObjectClass *gobject_class;
106
107   gobject_class = G_OBJECT_CLASS (klass);
108   parent_class = g_type_class_peek_parent (klass);
109
110   gobject_class->finalize = gtk_action_group_finalize;
111   gobject_class->set_property = gtk_action_group_set_property;
112   gobject_class->get_property = gtk_action_group_get_property;
113   klass->get_action = gtk_action_group_real_get_action;
114
115   g_object_class_install_property (gobject_class,
116                                    PROP_NAME,
117                                    g_param_spec_string ("name",
118                                                         _("Name"),
119                                                         _("A name for the action group."),
120                                                         NULL,
121                                                         G_PARAM_READWRITE |
122                                                         G_PARAM_CONSTRUCT_ONLY));
123   g_type_class_add_private (gobject_class, sizeof (GtkActionGroupPrivate));
124 }
125
126 static void
127 gtk_action_group_init (GtkActionGroup *self)
128 {
129   self->private_data = GTK_ACTION_GROUP_GET_PRIVATE (self);
130   self->private_data->name = NULL;
131   self->private_data->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
132                                                        (GDestroyNotify) g_free,
133                                                        (GDestroyNotify) g_object_unref);
134   self->private_data->translate_func = NULL;
135   self->private_data->translate_data = NULL;
136   self->private_data->translate_notify = NULL;
137 }
138
139 /**
140  * gtk_action_group_new:
141  * @name: the name of the action group.
142  *
143  * Creates a new #GtkActionGroup object. The name of the action group
144  * is used when associating <link linkend="Action-Accel">keybindings</link> 
145  * with the actions.
146  *
147  * Returns: the new #GtkActionGroup
148  *
149  * Since: 2.4
150  */
151 GtkActionGroup *
152 gtk_action_group_new (const gchar *name)
153 {
154   GtkActionGroup *self;
155
156   self = g_object_new (GTK_TYPE_ACTION_GROUP, NULL);
157   self->private_data->name = g_strdup (name);
158
159   return self;
160 }
161
162 static void
163 gtk_action_group_finalize (GObject *object)
164 {
165   GtkActionGroup *self;
166
167   self = GTK_ACTION_GROUP (object);
168
169   g_free (self->private_data->name);
170   self->private_data->name = NULL;
171
172   g_hash_table_destroy (self->private_data->actions);
173   self->private_data->actions = NULL;
174
175   if (self->private_data->translate_notify)
176     self->private_data->translate_notify (self->private_data->translate_data);
177
178   if (parent_class->finalize)
179     (* parent_class->finalize) (object);
180 }
181
182 static void
183 gtk_action_group_set_property (GObject         *object,
184                                guint            prop_id,
185                                const GValue    *value,
186                                GParamSpec      *pspec)
187 {
188   GtkActionGroup *self;
189   gchar *tmp;
190   
191   self = GTK_ACTION_GROUP (object);
192
193   switch (prop_id)
194     {
195     case PROP_NAME:
196       tmp = self->private_data->name;
197       self->private_data->name = g_value_dup_string (value);
198       g_free (tmp);
199       break;
200     default:
201       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
202       break;
203     }
204 }
205
206 static void
207 gtk_action_group_get_property (GObject    *object,
208                                guint       prop_id,
209                                GValue     *value,
210                                GParamSpec *pspec)
211 {
212   GtkActionGroup *self;
213   
214   self = GTK_ACTION_GROUP (object);
215
216   switch (prop_id)
217     {
218     case PROP_NAME:
219       g_value_set_string (value, self->private_data->name);
220       break;
221     default:
222       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
223       break;
224     }
225 }
226
227 static GtkAction *
228 gtk_action_group_real_get_action (GtkActionGroup *self,
229                                   const gchar    *action_name)
230 {
231   return g_hash_table_lookup (self->private_data->actions, action_name);
232 }
233
234 /**
235  * gtk_action_group_get_name:
236  * @action_group: the action group
237  *
238  * Gets the name of the action group.
239  *
240  * Returns: the name of the action group.
241  * 
242  * Since: 2.4
243  */
244 const gchar *
245 gtk_action_group_get_name (GtkActionGroup *action_group)
246 {
247   g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
248
249   return action_group->private_data->name;
250 }
251
252 /**
253  * gtk_action_group_get_action:
254  * @action_group: the action group
255  * @action_name: the name of the action
256  *
257  * Looks up an action in the action group by name.
258  *
259  * Returns: the action, or %NULL if no action by that name exists
260  *
261  * Since: 2.4
262  */
263 GtkAction *
264 gtk_action_group_get_action (GtkActionGroup *action_group,
265                              const gchar    *action_name)
266 {
267   g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
268   g_return_val_if_fail (GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action != NULL, NULL);
269
270   return (* GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action)
271     (action_group, action_name);
272 }
273
274 /**
275  * gtk_action_group_add_action:
276  * @action_group: the action group
277  * @action: an action
278  *
279  * Adds an action object to the action group. 
280  *
281  * Since: 2.4
282  */
283 void
284 gtk_action_group_add_action (GtkActionGroup *action_group,
285                              GtkAction      *action)
286 {
287   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
288   g_return_if_fail (GTK_IS_ACTION (action));
289   g_return_if_fail (gtk_action_get_name (action) != NULL);
290
291   g_hash_table_insert (action_group->private_data->actions, 
292                        g_strdup (gtk_action_get_name (action)),
293                        g_object_ref (action));
294 }
295
296 /**
297  * gtk_action_group_remove_action:
298  * @action_group: the action group
299  * @action: an action
300  *
301  * Removes an action object from the action group.
302  *
303  * Since: 2.4
304  */
305 void
306 gtk_action_group_remove_action (GtkActionGroup *action_group,
307                                 GtkAction      *action)
308 {
309   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
310   g_return_if_fail (GTK_IS_ACTION (action));
311   g_return_if_fail (gtk_action_get_name (action) != NULL);
312
313   /* extra protection to make sure action->name is valid */
314   g_object_ref (action);
315   g_hash_table_remove (action_group->private_data->actions, gtk_action_get_name (action));
316   g_object_unref (action);
317 }
318
319 static void
320 add_single_action (gpointer key, 
321                    gpointer value, 
322                    gpointer user_data)
323 {
324   GList **list = user_data;
325
326   *list = g_list_prepend (*list, value);
327 }
328
329 /**
330  * gtk_action_group_list_actions:
331  * @action_group: the action group
332  *
333  * Lists the actions in the action group.
334  *
335  * Returns: an allocated list of the action objects in the action group
336  * 
337  * Since: 2.4
338  */
339 GList *
340 gtk_action_group_list_actions (GtkActionGroup *action_group)
341 {
342   GList *actions = NULL;
343   g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
344   
345   g_hash_table_foreach (action_group->private_data->actions, add_single_action, &actions);
346
347   return g_list_reverse (actions);
348 }
349
350
351 /**
352  * gtk_action_group_add_actions:
353  * @action_group: the action group
354  * @entries: an array of action descriptions
355  * @n_entries: the number of entries
356  * @user_data: data to pass to the action callbacks
357  *
358  * This is a convenience function to create a number of actions and add them 
359  * to the action group.
360  *
361  * The "activate" signals of the actions are connected to the callbacks and 
362  * their accel paths are set to 
363  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.  
364  * 
365  * Since: 2.4
366  */
367 void
368 gtk_action_group_add_actions (GtkActionGroup *action_group,
369                               GtkActionEntry *entries,
370                               guint           n_entries,
371                               gpointer        user_data)
372 {
373   gtk_action_group_add_actions_full (action_group, 
374                                      entries, n_entries, 
375                                      user_data, NULL);
376 }
377
378
379 /**
380  * gtk_action_group_add_actions_full:
381  * @action_group: the action group
382  * @entries: an array of action descriptions
383  * @n_entries: the number of entries
384  * @user_data: data to pass to the action callbacks
385  * @destroy: destroy notification callback for @user_data
386  *
387  * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
388  * callback for @user_data. 
389  * 
390  * Since: 2.4
391  */
392 void
393 gtk_action_group_add_actions_full (GtkActionGroup *action_group,
394                                    GtkActionEntry *entries,
395                                    guint           n_entries,
396                                    gpointer        user_data,
397                                    GDestroyNotify  destroy)
398 {
399
400   /* Keep this in sync with the other 
401    * gtk_action_group_add_..._actions_full() functions.
402    */
403   guint i;
404   GtkTranslateFunc translate_func;
405   gpointer translate_data;
406
407   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
408
409   translate_func = action_group->private_data->translate_func;
410   translate_data = action_group->private_data->translate_data;
411
412   for (i = 0; i < n_entries; i++)
413     {
414       GtkAction *action;
415       gchar *accel_path;
416       guint accel_key = 0;
417       GdkModifierType accel_mods;
418       GtkStockItem stock_item;
419       gchar *label;
420       gchar *tooltip;
421
422       if (translate_func)
423         {
424           label = translate_func (entries[i].label, translate_data);
425           tooltip = translate_func (entries[i].tooltip, translate_data);
426         }
427       else
428         {
429           label = entries[i].label;
430           tooltip = entries[i].tooltip;
431         }
432
433       action = g_object_new (GTK_TYPE_ACTION,
434                              "name", entries[i].name,
435                              "label", label,
436                              "tooltip", tooltip,
437                              "stock_id", entries[i].stock_id,
438                              NULL);
439
440       if (entries[i].callback)
441         g_signal_connect_data (action, "activate",
442                                entries[i].callback, 
443                                user_data, (GClosureNotify)destroy, 0);
444
445       /* set the accel path for the menu item */
446       accel_path = g_strconcat ("<Actions>/", action_group->private_data->name, "/",
447                                 entries[i].name, NULL);
448
449       if (entries[i].accelerator)
450         gtk_accelerator_parse (entries[i].accelerator, &accel_key, &accel_mods);
451       else if (entries[i].stock_id &&
452                gtk_stock_lookup (entries[i].stock_id, &stock_item))
453         {
454           accel_key = stock_item.keyval;
455           accel_mods = stock_item.modifier;
456         }
457
458       if (accel_key)
459         gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
460
461       gtk_action_set_accel_path (action, accel_path);
462       g_free (accel_path);
463
464       gtk_action_group_add_action (action_group, action);
465       g_object_unref (action);
466     }
467 }
468
469 /**
470  * gtk_action_group_add_toggle_actions:
471  * @action_group: the action group
472  * @entries: an array of toggle action descriptions
473  * @n_entries: the number of entries
474  * @user_data: data to pass to the action callbacks
475  *
476  * This is a convenience function to create a number of toggle actions and add them 
477  * to the action group.
478  *
479  * The "activate" signals of the actions are connected to the callbacks and 
480  * their accel paths are set to 
481  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.  
482  * 
483  * Since: 2.4
484  */
485 void
486 gtk_action_group_add_toggle_actions (GtkActionGroup       *action_group,
487                                      GtkToggleActionEntry *entries,
488                                      guint                 n_entries,
489                                      gpointer              user_data)
490 {
491   gtk_action_group_add_toggle_actions_full (action_group, 
492                                             entries, n_entries, 
493                                             user_data, NULL);
494 }
495
496
497 /**
498  * gtk_action_group_add_toggle_actions_full:
499  * @action_group: the action group
500  * @entries: an array of toggle action descriptions
501  * @n_entries: the number of entries
502  * @user_data: data to pass to the action callbacks
503  * @destroy: destroy notification callback for @user_data
504  *
505  * This variant of gtk_action_group_add_toggle_actions() adds a 
506  * #GDestroyNotify callback for @user_data. 
507  * 
508  * Since: 2.4
509  */
510 void
511 gtk_action_group_add_toggle_actions_full (GtkActionGroup       *action_group,
512                                           GtkToggleActionEntry *entries,
513                                           guint                 n_entries,
514                                           gpointer              user_data,
515                                           GDestroyNotify        destroy)
516 {
517   /* Keep this in sync with the other 
518    * gtk_action_group_add_..._actions_full() functions.
519    */
520   guint i;
521   GtkTranslateFunc translate_func;
522   gpointer translate_data;
523
524   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
525
526   translate_func = action_group->private_data->translate_func;
527   translate_data = action_group->private_data->translate_data;
528
529   for (i = 0; i < n_entries; i++)
530     {
531       GtkAction *action;
532       gchar *accel_path;
533       guint accel_key = 0;
534       GdkModifierType accel_mods;
535       GtkStockItem stock_item;
536       gchar *label;
537       gchar *tooltip;
538
539       if (translate_func)
540         {
541           label = translate_func (entries[i].label, translate_data);
542           tooltip = translate_func (entries[i].tooltip, translate_data);
543         }
544       else
545         {
546           label = entries[i].label;
547           tooltip = entries[i].tooltip;
548         }
549
550       action = g_object_new (GTK_TYPE_TOGGLE_ACTION,
551                              "name", entries[i].name,
552                              "label", label,
553                              "tooltip", tooltip,
554                              "stock_id", entries[i].stock_id,
555                              NULL);
556
557       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), 
558                                     entries[i].is_active);
559
560       if (entries[i].callback)
561         g_signal_connect_data (action, "activate",
562                                entries[i].callback, 
563                                user_data, (GClosureNotify)destroy, 0);
564
565       /* set the accel path for the menu item */
566       accel_path = g_strconcat ("<Actions>/", action_group->private_data->name, "/",
567                                 entries[i].name, NULL);
568
569       if (entries[i].accelerator)
570         gtk_accelerator_parse (entries[i].accelerator, &accel_key, &accel_mods);
571       else if (entries[i].stock_id &&
572                gtk_stock_lookup (entries[i].stock_id, &stock_item))
573         {
574           accel_key = stock_item.keyval;
575           accel_mods = stock_item.modifier;
576         }
577
578       if (accel_key)
579         gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
580
581       gtk_action_set_accel_path (action, accel_path);
582       g_free (accel_path);
583
584       gtk_action_group_add_action (action_group, action);
585       g_object_unref (action);
586     }
587 }
588
589 /**
590  * gtk_action_group_add_radio_actions:
591  * @action_group: the action group
592  * @entries: an array of radio action descriptions
593  * @n_entries: the number of entries
594  * @value: the value of the action to activate initially, or -1 if
595  *   no action should be activated
596  * @on_change: the callback to connect to the changed signal
597  * @user_data: data to pass to the action callbacks
598  * 
599  * This is a convenience routine to create a group of radio actions and
600  * add them to the action group. 
601  *
602  * The "changed" signal of the first radio action is connected to the 
603  * @on_change callback and the accel paths of the actions are set to 
604  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.  
605  * 
606  * Since: 2.4
607  **/
608 void            
609 gtk_action_group_add_radio_actions (GtkActionGroup      *action_group,
610                                     GtkRadioActionEntry *entries,
611                                     guint                n_entries,
612                                     gint                 value,
613                                     GCallback            on_change,
614                                     gpointer             user_data)
615 {
616   gtk_action_group_add_radio_actions_full (action_group, 
617                                            entries, n_entries, 
618                                            value,
619                                            on_change, user_data, NULL);
620 }
621
622 /**
623  * gtk_action_group_add_radio_actions_full:
624  * @action_group: the action group
625  * @entries: an array of radio action descriptions
626  * @n_entries: the number of entries
627  * @value: the value of the action to activate initially, or -1 if
628  *   no action should be activated
629  * @on_change: the callback to connect to the changed signal
630  * @user_data: data to pass to the action callbacks
631  * @destroy: destroy notification callback for @user_data
632  *
633  * This variant of gtk_action_group_add_radio_actions() adds a 
634  * #GDestroyNotify callback for @user_data. 
635  * 
636  * Since: 2.4
637  **/
638 void            
639 gtk_action_group_add_radio_actions_full (GtkActionGroup      *action_group,
640                                          GtkRadioActionEntry *entries,
641                                          guint                n_entries,
642                                          gint                 value,
643                                          GCallback            on_change,
644                                          gpointer             user_data,
645                                          GDestroyNotify       destroy)
646 {
647   /* Keep this in sync with the other 
648    * gtk_action_group_add_..._actions_full() functions.
649    */
650   guint i;
651   GtkTranslateFunc translate_func;
652   gpointer translate_data;
653   GSList *group = NULL;
654   GtkAction *first_action = NULL;
655
656   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
657
658   translate_func = action_group->private_data->translate_func;
659   translate_data = action_group->private_data->translate_data;
660
661   for (i = 0; i < n_entries; i++)
662     {
663       GtkAction *action;
664       gchar *accel_path;
665       guint accel_key = 0;
666       GdkModifierType accel_mods;
667       GtkStockItem stock_item;
668       gchar *label;
669       gchar *tooltip; 
670
671       if (translate_func)
672         {
673           label = translate_func (entries[i].label, translate_data);
674           tooltip = translate_func (entries[i].tooltip, translate_data);
675         }
676       else
677         {
678           label = entries[i].label;
679           tooltip = entries[i].tooltip;
680         }
681
682       action = g_object_new (GTK_TYPE_RADIO_ACTION,
683                              "name", entries[i].name,
684                              "label", label,
685                              "tooltip", tooltip,
686                              "stock_id", entries[i].stock_id,
687                              "value", entries[i].value,
688                              NULL);
689
690       if (i == 0) 
691         first_action = action;
692
693       gtk_radio_action_set_group (GTK_RADIO_ACTION (action), group);
694       group = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
695
696       if (value == entries[i].value)
697         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
698       
699       /* set the accel path for the menu item */
700       accel_path = g_strconcat ("<Actions>/", 
701                                 action_group->private_data->name, "/",
702                                 entries[i].name, NULL);
703
704       if (entries[i].accelerator)
705         gtk_accelerator_parse (entries[i].accelerator, &accel_key, &accel_mods);
706       else if (entries[i].stock_id &&
707                gtk_stock_lookup (entries[i].stock_id, &stock_item))
708         {
709           accel_key = stock_item.keyval;
710           accel_mods = stock_item.modifier;
711         }
712
713       if (accel_key)
714         gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
715
716       gtk_action_set_accel_path (action, accel_path);
717       g_free (accel_path);
718       
719       gtk_action_group_add_action (action_group, action);
720       g_object_unref (action);
721     }
722
723   if (on_change && first_action)
724     g_signal_connect_data (first_action, "changed",
725                            on_change, user_data, 
726                            (GClosureNotify)destroy, 0);
727 }
728
729 /**
730  * gtk_action_group_set_translate_func:
731  * @action_group: a #GtkActionGroup
732  * @func: a #GtkTranslateFunc
733  * @data: data to be passed to @func and @notify
734  * @notify: a #GtkDestroyNotify function to be called when @action_group is 
735  *   destroyed and when the translation function is changed again
736  * 
737  * Sets a function to be used for translating the @label and @tooltip of 
738  * #GtkActionGroupEntry<!-- -->s added by gtk_action_group_add_actions().
739  *
740  * If you're using gettext(), it is enough to set the translation domain
741  * with gtk_action_group_set_translation_domain().
742  *
743  * Since: 2.4 
744  **/
745 void
746 gtk_action_group_set_translate_func (GtkActionGroup      *action_group,
747                                      GtkTranslateFunc     func,
748                                      gpointer             data,
749                                      GtkDestroyNotify     notify)
750 {
751   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
752   
753   if (action_group->private_data->translate_notify)
754     action_group->private_data->translate_notify (action_group->private_data->translate_data);
755       
756   action_group->private_data->translate_func = func;
757   action_group->private_data->translate_data = data;
758   action_group->private_data->translate_notify = notify;
759 }
760
761 static gchar *
762 dgettext_swapped (const gchar *msgid, 
763                   const gchar *domainname)
764 {
765   return dgettext (domainname, msgid);
766 }
767
768 /**
769  * gtk_action_group_set_translation_domain:
770  * @action_group: a #GtkActionGroup
771  * @domain: the translation domain to use for dgettext() calls
772  * 
773  * Sets the translation domain and uses dgettext() for translating the 
774  * @label and @tooltip of #GtkActionEntry<!-- -->s added by 
775  * gtk_action_group_add_actions().
776  *
777  * If you're not using gettext() for localization, see 
778  * gtk_action_group_set_translate_func().
779  *
780  * Since: 2.4
781  **/
782 void 
783 gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
784                                          const gchar    *domain)
785 {
786   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
787
788   gtk_action_group_set_translate_func (action_group, 
789                                        (GtkTranslateFunc)dgettext_swapped,
790                                        g_strdup (domain),
791                                        g_free);
792