1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
5
* Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
#include "libgimpbase/gimpbase.h"
27
#include "libgimpwidgets/gimpwidgets.h"
29
#include "widgets-types.h"
31
#include "core/gimp.h"
32
#include "core/gimpviewable.h"
34
#include "gimpactiongroup.h"
35
#include "gimpaction.h"
36
#include "gimpenumaction.h"
37
#include "gimppluginaction.h"
38
#include "gimpstringaction.h"
40
#include "gimp-intl.h"
53
static void gimp_action_group_init (GimpActionGroup *group);
54
static void gimp_action_group_class_init (GimpActionGroupClass *klass);
56
static GObject * gimp_action_group_constructor (GType type,
58
GObjectConstructParam *params);
59
static void gimp_action_group_dispose (GObject *object);
60
static void gimp_action_group_finalize (GObject *object);
61
static void gimp_action_group_set_property (GObject *object,
65
static void gimp_action_group_get_property (GObject *object,
71
static GtkActionGroupClass *parent_class = NULL;
75
gimp_action_group_get_type (void)
77
static GType type = 0;
81
static const GTypeInfo type_info =
83
sizeof (GimpActionGroupClass),
85
NULL, /* base_finalize */
86
(GClassInitFunc) gimp_action_group_class_init,
87
NULL, /* class_finalize */
88
NULL, /* class_data */
89
sizeof (GimpActionGroup),
91
(GInstanceInitFunc) gimp_action_group_init,
94
type = g_type_register_static (GTK_TYPE_ACTION_GROUP,
103
gimp_action_group_class_init (GimpActionGroupClass *klass)
105
GObjectClass *object_class = G_OBJECT_CLASS (klass);
107
parent_class = g_type_class_peek_parent (klass);
109
object_class->constructor = gimp_action_group_constructor;
110
object_class->dispose = gimp_action_group_dispose;
111
object_class->finalize = gimp_action_group_finalize;
112
object_class->set_property = gimp_action_group_set_property;
113
object_class->get_property = gimp_action_group_get_property;
115
g_object_class_install_property (object_class, PROP_GIMP,
116
g_param_spec_object ("gimp",
120
G_PARAM_CONSTRUCT_ONLY));
122
g_object_class_install_property (object_class, PROP_LABEL,
123
g_param_spec_string ("label",
127
G_PARAM_CONSTRUCT_ONLY));
129
g_object_class_install_property (object_class, PROP_STOCK_ID,
130
g_param_spec_string ("stock-id",
134
G_PARAM_CONSTRUCT_ONLY));
136
g_object_class_install_property (object_class, PROP_MNEMONICS,
137
g_param_spec_boolean ("mnemonics",
141
G_PARAM_CONSTRUCT_ONLY));
143
klass->groups = g_hash_table_new_full (g_str_hash, g_str_equal,
148
gimp_action_group_init (GimpActionGroup *group)
153
gimp_action_group_constructor (GType type,
155
GObjectConstructParam *params)
158
GimpActionGroup *group;
161
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
163
group = GIMP_ACTION_GROUP (object);
165
g_assert (GIMP_IS_GIMP (group->gimp));
167
name = gtk_action_group_get_name (GTK_ACTION_GROUP (object));
171
GimpActionGroupClass *group_class;
174
group_class = GIMP_ACTION_GROUP_GET_CLASS (object);
176
list = g_hash_table_lookup (group_class->groups, name);
178
list = g_list_append (list, object);
180
g_hash_table_replace (group_class->groups,
181
g_strdup (name), list);
188
gimp_action_group_dispose (GObject *object)
192
name = gtk_action_group_get_name (GTK_ACTION_GROUP (object));
196
GimpActionGroupClass *group_class;
199
group_class = GIMP_ACTION_GROUP_GET_CLASS (object);
201
list = g_hash_table_lookup (group_class->groups, name);
205
list = g_list_remove (list, object);
208
g_hash_table_replace (group_class->groups,
209
g_strdup (name), list);
211
g_hash_table_remove (group_class->groups, name);
215
G_OBJECT_CLASS (parent_class)->dispose (object);
219
gimp_action_group_finalize (GObject *object)
221
GimpActionGroup *group = GIMP_ACTION_GROUP (object);
225
g_free (group->label);
231
g_free (group->stock_id);
232
group->stock_id = NULL;
235
G_OBJECT_CLASS (parent_class)->finalize (object);
239
gimp_action_group_set_property (GObject *object,
244
GimpActionGroup *group = GIMP_ACTION_GROUP (object);
249
group->gimp = g_value_get_object (value);
252
group->label = g_value_dup_string (value);
255
group->stock_id = g_value_dup_string (value);
258
group->mnemonics = g_value_get_boolean (value);
261
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
267
gimp_action_group_get_property (GObject *object,
272
GimpActionGroup *group = GIMP_ACTION_GROUP (object);
277
g_value_set_object (value, group->gimp);
280
g_value_set_string (value, group->label);
283
g_value_set_string (value, group->stock_id);
286
g_value_set_boolean (value, group->mnemonics);
289
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
295
* gimp_action_group_new:
296
* @gimp: the @Gimp instance this action group belongs to
297
* @name: the name of the action group.
298
* @label: the user visible label of the action group.
299
* @stock_id: the icon of the action group.
300
* @mnemonics: whether or not to show mnemonics.
301
* @user_data: the user_data for #GtkAction callbacks.
302
* @update_func: the function that will be called on
303
* gimp_action_group_update().
305
* Creates a new #GimpActionGroup object. The name of the action group
306
* is used when associating <link linkend="Action-Accel">keybindings</link>
309
* Returns: the new #GimpActionGroup
312
gimp_action_group_new (Gimp *gimp,
315
const gchar *stock_id,
318
GimpActionGroupUpdateFunc update_func)
320
GimpActionGroup *group;
322
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
323
g_return_val_if_fail (name != NULL, NULL);
325
group = g_object_new (GIMP_TYPE_ACTION_GROUP,
329
"stock-id", stock_id,
330
"mnemonics", mnemonics,
333
group->user_data = user_data;
334
group->update_func = update_func;
340
gimp_action_groups_from_name (const gchar *name)
342
GimpActionGroupClass *group_class;
345
g_return_val_if_fail (name != NULL, NULL);
347
group_class = g_type_class_ref (GIMP_TYPE_ACTION_GROUP);
349
list = g_hash_table_lookup (group_class->groups, name);
351
g_type_class_unref (group_class);
357
gimp_action_group_update (GimpActionGroup *group,
358
gpointer update_data)
360
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
362
if (group->update_func)
363
group->update_func (group, update_data);
367
gimp_action_group_add_actions (GimpActionGroup *group,
368
GimpActionEntry *entries,
373
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
375
for (i = 0; i < n_entries; i++)
379
const gchar *tooltip;
381
label = gettext (entries[i].label);
382
tooltip = gettext (entries[i].tooltip);
384
if (! group->mnemonics)
385
label = gimp_strip_uline (label);
387
action = gimp_action_new (entries[i].name, label, tooltip,
388
entries[i].stock_id);
390
if (! group->mnemonics)
393
if (entries[i].callback)
394
g_signal_connect (action, "activate",
398
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
400
entries[i].accelerator);
402
if (entries[i].help_id)
403
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
404
g_strdup (entries[i].help_id),
405
(GDestroyNotify) g_free);
407
g_object_unref (action);
412
gimp_action_group_add_toggle_actions (GimpActionGroup *group,
413
GimpToggleActionEntry *entries,
418
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
420
for (i = 0; i < n_entries; i++)
422
GtkToggleAction *action;
424
const gchar *tooltip;
426
label = gettext (entries[i].label);
427
tooltip = gettext (entries[i].tooltip);
429
if (! group->mnemonics)
430
label = gimp_strip_uline (label);
432
action = gtk_toggle_action_new (entries[i].name, label, tooltip,
433
entries[i].stock_id);
435
if (! group->mnemonics)
438
gtk_toggle_action_set_active (action, entries[i].is_active);
440
if (entries[i].callback)
441
g_signal_connect (action, "toggled",
445
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
447
entries[i].accelerator);
449
if (entries[i].help_id)
450
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
451
g_strdup (entries[i].help_id),
452
(GDestroyNotify) g_free);
454
g_object_unref (action);
459
gimp_action_group_add_radio_actions (GimpActionGroup *group,
460
GimpRadioActionEntry *entries,
465
GtkRadioAction *first_action = NULL;
466
GSList *radio_group = NULL;
469
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
471
for (i = 0; i < n_entries; i++)
473
GtkRadioAction *action;
475
const gchar *tooltip;
477
label = gettext (entries[i].label);
478
tooltip = gettext (entries[i].tooltip);
480
if (! group->mnemonics)
481
label = gimp_strip_uline (label);
483
action = gtk_radio_action_new (entries[i].name, label, tooltip,
487
if (! group->mnemonics)
491
first_action = action;
493
gtk_radio_action_set_group (action, radio_group);
494
radio_group = gtk_radio_action_get_group (action);
496
if (value == entries[i].value)
497
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
499
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
501
entries[i].accelerator);
503
if (entries[i].help_id)
504
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
505
g_strdup (entries[i].help_id),
506
(GDestroyNotify) g_free);
508
g_object_unref (action);
511
if (callback && first_action)
512
g_signal_connect (first_action, "changed",
518
gimp_action_group_add_enum_actions (GimpActionGroup *group,
519
GimpEnumActionEntry *entries,
525
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
527
for (i = 0; i < n_entries; i++)
529
GimpEnumAction *action;
531
const gchar *tooltip;
533
label = gettext (entries[i].label);
534
tooltip = gettext (entries[i].tooltip);
536
if (! group->mnemonics)
537
label = gimp_strip_uline (label);
539
action = gimp_enum_action_new (entries[i].name, label, tooltip,
542
entries[i].value_variable);
544
if (! group->mnemonics)
548
g_signal_connect (action, "selected",
552
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
554
entries[i].accelerator);
556
if (entries[i].help_id)
557
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
558
g_strdup (entries[i].help_id),
559
(GDestroyNotify) g_free);
561
g_object_unref (action);
566
gimp_action_group_add_string_actions (GimpActionGroup *group,
567
GimpStringActionEntry *entries,
573
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
575
for (i = 0; i < n_entries; i++)
577
GimpStringAction *action;
579
const gchar *tooltip;
581
label = gettext (entries[i].label);
582
tooltip = gettext (entries[i].tooltip);
584
if (! group->mnemonics)
585
label = gimp_strip_uline (label);
587
action = gimp_string_action_new (entries[i].name, label, tooltip,
591
if (! group->mnemonics)
595
g_signal_connect (action, "selected",
599
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
601
entries[i].accelerator);
603
if (entries[i].help_id)
604
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
605
g_strdup (entries[i].help_id),
606
(GDestroyNotify) g_free);
608
g_object_unref (action);
613
gimp_action_group_add_plug_in_actions (GimpActionGroup *group,
614
GimpPlugInActionEntry *entries,
620
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
622
for (i = 0; i < n_entries; i++)
624
GimpPlugInAction *action;
627
label = (gchar *) entries[i].label;
629
if (! group->mnemonics)
630
label = gimp_strip_uline (label);
632
action = gimp_plug_in_action_new (entries[i].name,
636
entries[i].proc_def);
638
if (! group->mnemonics)
642
g_signal_connect (action, "selected",
646
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
648
entries[i].accelerator);
650
if (entries[i].help_id)
651
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
652
g_strdup (entries[i].help_id),
653
(GDestroyNotify) g_free);
655
g_object_unref (action);
660
gimp_action_group_set_action_visible (GimpActionGroup *group,
661
const gchar *action_name,
666
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
667
g_return_if_fail (action_name != NULL);
669
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
673
g_warning ("%s: Unable to set visibility of action "
674
"which doesn't exist: %s",
675
G_STRFUNC, action_name);
679
g_object_set (action, "visible", visible ? TRUE : FALSE, NULL);
683
gimp_action_group_set_action_sensitive (GimpActionGroup *group,
684
const gchar *action_name,
689
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
690
g_return_if_fail (action_name != NULL);
692
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
696
g_warning ("%s: Unable to set sensitivity of action "
697
"which doesn't exist: %s",
698
G_STRFUNC, action_name);
702
g_object_set (action, "sensitive", sensitive ? TRUE : FALSE, NULL);
706
gimp_action_group_set_action_active (GimpActionGroup *group,
707
const gchar *action_name,
712
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
713
g_return_if_fail (action_name != NULL);
715
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
719
g_warning ("%s: Unable to set \"active\" of action "
720
"which doesn't exist: %s",
721
G_STRFUNC, action_name);
725
if (! GTK_IS_TOGGLE_ACTION (action))
727
g_warning ("%s: Unable to set \"active\" of action "
728
"which is not a GtkToggleAction: %s",
729
G_STRFUNC, action_name);
733
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
734
active ? TRUE : FALSE);
738
gimp_action_group_set_action_label (GimpActionGroup *group,
739
const gchar *action_name,
745
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
746
g_return_if_fail (action_name != NULL);
748
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
752
g_warning ("%s: Unable to set label of action "
753
"which doesn't exist: %s",
754
G_STRFUNC, action_name);
758
if (! group->mnemonics)
759
stripped = gimp_strip_uline (label);
761
stripped = (gchar *) label;
763
g_object_set (action, "label", stripped, NULL);
765
if (! group->mnemonics)
770
gimp_action_group_set_action_color (GimpActionGroup *group,
771
const gchar *action_name,
772
const GimpRGB *color,
777
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
778
g_return_if_fail (action_name != NULL);
780
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
784
g_warning ("%s: Unable to set color of action "
785
"which doesn't exist: %s",
786
G_STRFUNC, action_name);
790
if (! GIMP_IS_ACTION (action))
792
g_warning ("%s: Unable to set \"color\" of action "
793
"which is not a GimpAction: %s",
794
G_STRFUNC, action_name);
803
label = g_strdup_printf (_("RGBA (%0.3f, %0.3f, %0.3f, %0.3f)"),
804
color->r, color->g, color->b, color->a);
806
label = g_strdup (_("(none)"));
808
g_object_set (action,
816
g_object_set (action, "color", color, NULL);
821
gimp_action_group_set_action_viewable (GimpActionGroup *group,
822
const gchar *action_name,
823
GimpViewable *viewable)
827
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
828
g_return_if_fail (action_name != NULL);
829
g_return_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable));
831
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
835
g_warning ("%s: Unable to set viewable of action "
836
"which doesn't exist: %s",
837
G_STRFUNC, action_name);
841
if (! GIMP_IS_ACTION (action))
843
g_warning ("%s: Unable to set \"viewable\" of action "
844
"which is not a GimpAction: %s",
845
G_STRFUNC, action_name);
849
g_object_set (action, "viewable", viewable, NULL);
853
gimp_action_group_set_action_important (GimpActionGroup *group,
854
const gchar *action_name,
855
gboolean is_important)
859
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
860
g_return_if_fail (action_name != NULL);
862
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
866
g_warning ("%s: Unable to set \"is-important\" of action "
867
"which doesn't exist: %s",
868
G_STRFUNC, action_name);
872
g_object_set (action, "is-important", is_important ? TRUE : FALSE, NULL);