]> Pileus Git - ~andy/gtk/blob - gtk/gtkactiongroup.c
Remove the redundant name and stock_id parameters, adjust all callers.
[~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_add_action_with_accel:
298  * @action_group: the action group 
299  * @action: the action to add 
300  * @accelerator: the accelerator for the action, in
301  *   the format understood by gtk_accelerator_parse(), or %NULL to use the
302  *   stock accelerator 
303  *
304  * Adds an action object to the action group and sets up the accelerator.
305  *
306  * If @accelerator is %NULL, attempts to use the accelerator associated 
307  * with the stock_id of the action.
308  *
309  * Accel paths are set to
310  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
311  *
312  * Since: 2.4
313  */
314 void
315 gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
316                                         GtkAction *action,
317                                         const gchar *accelerator)
318 {
319   gchar *accel_path;
320   guint  accel_key = 0;
321   GdkModifierType accel_mods;
322   GtkStockItem stock_item;
323   const gchar *name;
324   const gchar *stock_id;
325   
326   g_object_get (action, "name", &name, "stock_id", &stock_id, NULL);
327
328   accel_path = g_strconcat ("<Actions>/",
329                             action_group->private_data->name, "/", name, NULL);
330
331   if (accelerator)
332     gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
333   else if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
334     {
335       accel_key = stock_item.keyval;
336       accel_mods = stock_item.modifier;
337     }
338
339   if (accel_key)
340     gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
341
342   gtk_action_set_accel_path (action, accel_path);
343   g_free (accel_path);
344
345   gtk_action_group_add_action (action_group, action);
346 }
347
348 /**
349  * gtk_action_group_remove_action:
350  * @action_group: the action group
351  * @action: an action
352  *
353  * Removes an action object from the action group.
354  *
355  * Since: 2.4
356  */
357 void
358 gtk_action_group_remove_action (GtkActionGroup *action_group,
359                                 GtkAction      *action)
360 {
361   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
362   g_return_if_fail (GTK_IS_ACTION (action));
363   g_return_if_fail (gtk_action_get_name (action) != NULL);
364
365   /* extra protection to make sure action->name is valid */
366   g_object_ref (action);
367   g_hash_table_remove (action_group->private_data->actions, gtk_action_get_name (action));
368   g_object_unref (action);
369 }
370
371 static void
372 add_single_action (gpointer key, 
373                    gpointer value, 
374                    gpointer user_data)
375 {
376   GList **list = user_data;
377
378   *list = g_list_prepend (*list, value);
379 }
380
381 /**
382  * gtk_action_group_list_actions:
383  * @action_group: the action group
384  *
385  * Lists the actions in the action group.
386  *
387  * Returns: an allocated list of the action objects in the action group
388  * 
389  * Since: 2.4
390  */
391 GList *
392 gtk_action_group_list_actions (GtkActionGroup *action_group)
393 {
394   GList *actions = NULL;
395   g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
396   
397   g_hash_table_foreach (action_group->private_data->actions, add_single_action, &actions);
398
399   return g_list_reverse (actions);
400 }
401
402
403 /**
404  * gtk_action_group_add_actions:
405  * @action_group: the action group
406  * @entries: an array of action descriptions
407  * @n_entries: the number of entries
408  * @user_data: data to pass to the action callbacks
409  *
410  * This is a convenience function to create a number of actions and add them 
411  * to the action group.
412  *
413  * The "activate" signals of the actions are connected to the callbacks and 
414  * their accel paths are set to 
415  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.  
416  * 
417  * Since: 2.4
418  */
419 void
420 gtk_action_group_add_actions (GtkActionGroup *action_group,
421                               GtkActionEntry *entries,
422                               guint           n_entries,
423                               gpointer        user_data)
424 {
425   gtk_action_group_add_actions_full (action_group, 
426                                      entries, n_entries, 
427                                      user_data, NULL);
428 }
429
430
431 /**
432  * gtk_action_group_add_actions_full:
433  * @action_group: the action group
434  * @entries: an array of action descriptions
435  * @n_entries: the number of entries
436  * @user_data: data to pass to the action callbacks
437  * @destroy: destroy notification callback for @user_data
438  *
439  * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
440  * callback for @user_data. 
441  * 
442  * Since: 2.4
443  */
444 void
445 gtk_action_group_add_actions_full (GtkActionGroup *action_group,
446                                    GtkActionEntry *entries,
447                                    guint           n_entries,
448                                    gpointer        user_data,
449                                    GDestroyNotify  destroy)
450 {
451
452   /* Keep this in sync with the other 
453    * gtk_action_group_add_..._actions_full() functions.
454    */
455   guint i;
456   GtkTranslateFunc translate_func;
457   gpointer translate_data;
458
459   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
460
461   translate_func = action_group->private_data->translate_func;
462   translate_data = action_group->private_data->translate_data;
463
464   for (i = 0; i < n_entries; i++)
465     {
466       GtkAction *action;
467       const gchar *label;
468       const gchar *tooltip;
469
470       if (translate_func)
471         {
472           label = translate_func (entries[i].label, translate_data);
473           tooltip = translate_func (entries[i].tooltip, translate_data);
474         }
475       else
476         {
477           label = entries[i].label;
478           tooltip = entries[i].tooltip;
479         }
480
481       action = gtk_action_new (entries[i].name,
482                                label,
483                                tooltip,
484                                entries[i].stock_id);
485
486       if (entries[i].callback)
487         g_signal_connect_data (action, "activate",
488                                entries[i].callback, 
489                                user_data, (GClosureNotify)destroy, 0);
490
491       gtk_action_group_add_action_with_accel (action_group, 
492                                               action,
493                                               entries[i].accelerator);
494       g_object_unref (action);
495     }
496 }
497
498 /**
499  * gtk_action_group_add_toggle_actions:
500  * @action_group: the action group
501  * @entries: an array of toggle action descriptions
502  * @n_entries: the number of entries
503  * @user_data: data to pass to the action callbacks
504  *
505  * This is a convenience function to create a number of toggle actions and add them 
506  * to the action group.
507  *
508  * The "activate" signals of the actions are connected to the callbacks and 
509  * their accel paths are set to 
510  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.  
511  * 
512  * Since: 2.4
513  */
514 void
515 gtk_action_group_add_toggle_actions (GtkActionGroup       *action_group,
516                                      GtkToggleActionEntry *entries,
517                                      guint                 n_entries,
518                                      gpointer              user_data)
519 {
520   gtk_action_group_add_toggle_actions_full (action_group, 
521                                             entries, n_entries, 
522                                             user_data, NULL);
523 }
524
525
526 /**
527  * gtk_action_group_add_toggle_actions_full:
528  * @action_group: the action group
529  * @entries: an array of toggle action descriptions
530  * @n_entries: the number of entries
531  * @user_data: data to pass to the action callbacks
532  * @destroy: destroy notification callback for @user_data
533  *
534  * This variant of gtk_action_group_add_toggle_actions() adds a 
535  * #GDestroyNotify callback for @user_data. 
536  * 
537  * Since: 2.4
538  */
539 void
540 gtk_action_group_add_toggle_actions_full (GtkActionGroup       *action_group,
541                                           GtkToggleActionEntry *entries,
542                                           guint                 n_entries,
543                                           gpointer              user_data,
544                                           GDestroyNotify        destroy)
545 {
546   /* Keep this in sync with the other 
547    * gtk_action_group_add_..._actions_full() functions.
548    */
549   guint i;
550   GtkTranslateFunc translate_func;
551   gpointer translate_data;
552
553   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
554
555   translate_func = action_group->private_data->translate_func;
556   translate_data = action_group->private_data->translate_data;
557
558   for (i = 0; i < n_entries; i++)
559     {
560       GtkToggleAction *action;
561       const gchar *label;
562       const gchar *tooltip;
563
564       if (translate_func)
565         {
566           label = translate_func (entries[i].label, translate_data);
567           tooltip = translate_func (entries[i].tooltip, translate_data);
568         }
569       else
570         {
571           label = entries[i].label;
572           tooltip = entries[i].tooltip;
573         }
574
575       action = gtk_toggle_action_new (entries[i].name,
576                                       label,
577                                       tooltip,
578                                       entries[i].stock_id);
579
580       gtk_toggle_action_set_active (action, entries[i].is_active);
581
582       if (entries[i].callback)
583         g_signal_connect_data (action, "activate",
584                                entries[i].callback, 
585                                user_data, (GClosureNotify)destroy, 0);
586
587       gtk_action_group_add_action_with_accel (action_group, 
588                                               action,
589                                               entries[i].accelerator);
590       g_object_unref (action);
591     }
592 }
593
594 /**
595  * gtk_action_group_add_radio_actions:
596  * @action_group: the action group
597  * @entries: an array of radio action descriptions
598  * @n_entries: the number of entries
599  * @value: the value of the action to activate initially, or -1 if
600  *   no action should be activated
601  * @on_change: the callback to connect to the changed signal
602  * @user_data: data to pass to the action callbacks
603  * 
604  * This is a convenience routine to create a group of radio actions and
605  * add them to the action group. 
606  *
607  * The "changed" signal of the first radio action is connected to the 
608  * @on_change callback and the accel paths of the actions are set to 
609  * <literal>&lt;Actions&gt;/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.  
610  * 
611  * Since: 2.4
612  **/
613 void            
614 gtk_action_group_add_radio_actions (GtkActionGroup      *action_group,
615                                     GtkRadioActionEntry *entries,
616                                     guint                n_entries,
617                                     gint                 value,
618                                     GCallback            on_change,
619                                     gpointer             user_data)
620 {
621   gtk_action_group_add_radio_actions_full (action_group, 
622                                            entries, n_entries, 
623                                            value,
624                                            on_change, user_data, NULL);
625 }
626
627 /**
628  * gtk_action_group_add_radio_actions_full:
629  * @action_group: the action group
630  * @entries: an array of radio action descriptions
631  * @n_entries: the number of entries
632  * @value: the value of the action to activate initially, or -1 if
633  *   no action should be activated
634  * @on_change: the callback to connect to the changed signal
635  * @user_data: data to pass to the action callbacks
636  * @destroy: destroy notification callback for @user_data
637  *
638  * This variant of gtk_action_group_add_radio_actions() adds a 
639  * #GDestroyNotify callback for @user_data. 
640  * 
641  * Since: 2.4
642  **/
643 void            
644 gtk_action_group_add_radio_actions_full (GtkActionGroup      *action_group,
645                                          GtkRadioActionEntry *entries,
646                                          guint                n_entries,
647                                          gint                 value,
648                                          GCallback            on_change,
649                                          gpointer             user_data,
650                                          GDestroyNotify       destroy)
651 {
652   /* Keep this in sync with the other 
653    * gtk_action_group_add_..._actions_full() functions.
654    */
655   guint i;
656   GtkTranslateFunc translate_func;
657   gpointer translate_data;
658   GSList *group = NULL;
659   GtkAction *first_action = NULL;
660
661   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
662
663   translate_func = action_group->private_data->translate_func;
664   translate_data = action_group->private_data->translate_data;
665
666   for (i = 0; i < n_entries; i++)
667     {
668       GtkRadioAction *action;
669       const gchar *label;
670       const gchar *tooltip; 
671
672       if (translate_func)
673         {
674           label = translate_func (entries[i].label, translate_data);
675           tooltip = translate_func (entries[i].tooltip, translate_data);
676         }
677       else
678         {
679           label = entries[i].label;
680           tooltip = entries[i].tooltip;
681         }
682
683       action = gtk_radio_action_new (entries[i].name,
684                                      label,
685                                      tooltip,
686                                      entries[i].stock_id,
687                                      value);
688
689       if (i == 0) 
690         first_action = action;
691
692       gtk_radio_action_set_group (action, group);
693       group = gtk_radio_action_get_group (action);
694
695       if (value == entries[i].value)
696         gtk_toggle_action_set_active (action, TRUE);
697
698       gtk_action_group_add_action_with_accel (action_group, 
699                                               action,
700                                               entries[i].accelerator);
701       g_object_unref (action);
702     }
703
704   if (on_change && first_action)
705     g_signal_connect_data (first_action, "changed",
706                            on_change, user_data, 
707                            (GClosureNotify)destroy, 0);
708 }
709
710 /**
711  * gtk_action_group_set_translate_func:
712  * @action_group: a #GtkActionGroup
713  * @func: a #GtkTranslateFunc
714  * @data: data to be passed to @func and @notify
715  * @notify: a #GtkDestroyNotify function to be called when @action_group is 
716  *   destroyed and when the translation function is changed again
717  * 
718  * Sets a function to be used for translating the @label and @tooltip of 
719  * #GtkActionGroupEntry<!-- -->s added by gtk_action_group_add_actions().
720  *
721  * If you're using gettext(), it is enough to set the translation domain
722  * with gtk_action_group_set_translation_domain().
723  *
724  * Since: 2.4 
725  **/
726 void
727 gtk_action_group_set_translate_func (GtkActionGroup      *action_group,
728                                      GtkTranslateFunc     func,
729                                      gpointer             data,
730                                      GtkDestroyNotify     notify)
731 {
732   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
733   
734   if (action_group->private_data->translate_notify)
735     action_group->private_data->translate_notify (action_group->private_data->translate_data);
736       
737   action_group->private_data->translate_func = func;
738   action_group->private_data->translate_data = data;
739   action_group->private_data->translate_notify = notify;
740 }
741
742 static gchar *
743 dgettext_swapped (const gchar *msgid, 
744                   const gchar *domainname)
745 {
746   return dgettext (domainname, msgid);
747 }
748
749 /**
750  * gtk_action_group_set_translation_domain:
751  * @action_group: a #GtkActionGroup
752  * @domain: the translation domain to use for dgettext() calls
753  * 
754  * Sets the translation domain and uses dgettext() for translating the 
755  * @label and @tooltip of #GtkActionEntry<!-- -->s added by 
756  * gtk_action_group_add_actions().
757  *
758  * If you're not using gettext() for localization, see 
759  * gtk_action_group_set_translate_func().
760  *
761  * Since: 2.4
762  **/
763 void 
764 gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
765                                          const gchar    *domain)
766 {
767   g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
768
769   gtk_action_group_set_translate_func (action_group, 
770                                        (GtkTranslateFunc)dgettext_swapped,
771                                        g_strdup (domain),
772                                        g_free);
773