]> Pileus Git - ~andy/gtk/blob - gtk/gtktoggleaction.c
Add hidden aliases for exported symbols which are used internally in order
[~andy/gtk] / gtk / gtktoggleaction.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 "gtkalias.h"
34 #include "gtkintl.h"
35 #include "gtktoggleaction.h"
36 #include "gtktoggleactionprivate.h"
37 #include "gtktoggletoolbutton.h"
38 #include "gtktogglebutton.h"
39 #include "gtkcheckmenuitem.h"
40
41 enum 
42 {
43   TOGGLED,
44   LAST_SIGNAL
45 };
46
47 enum {
48   PROP_0,
49   PROP_DRAW_AS_RADIO
50 };
51
52 static void gtk_toggle_action_init       (GtkToggleAction *action);
53 static void gtk_toggle_action_class_init (GtkToggleActionClass *class);
54
55 GType
56 gtk_toggle_action_get_type (void)
57 {
58   static GtkType type = 0;
59
60   if (!type)
61     {
62       static const GTypeInfo type_info =
63       {
64         sizeof (GtkToggleActionClass),
65         (GBaseInitFunc) NULL,
66         (GBaseFinalizeFunc) NULL,
67         (GClassInitFunc) gtk_toggle_action_class_init,
68         (GClassFinalizeFunc) NULL,
69         NULL,
70         
71         sizeof (GtkToggleAction),
72         0, /* n_preallocs */
73         (GInstanceInitFunc) gtk_toggle_action_init,
74       };
75
76       type = g_type_register_static (GTK_TYPE_ACTION,
77                                      "GtkToggleAction",
78                                      &type_info, 0);
79     }
80   return type;
81 }
82
83 static void gtk_toggle_action_activate     (GtkAction       *action);
84 static void gtk_toggle_action_real_toggled (GtkToggleAction *action);
85 static void connect_proxy                  (GtkAction       *action,
86                                             GtkWidget       *proxy);
87 static void disconnect_proxy               (GtkAction       *action,
88                                             GtkWidget       *proxy);
89 static void set_property                   (GObject         *object,
90                                             guint            prop_id,
91                                             const GValue    *value,
92                                             GParamSpec      *pspec);
93 static void get_property                   (GObject         *object,
94                                             guint            prop_id,
95                                             GValue          *value,
96                                             GParamSpec      *pspec);
97 static GtkWidget *create_menu_item         (GtkAction       *action);
98
99
100 static GObjectClass *parent_class = NULL;
101 static guint         action_signals[LAST_SIGNAL] = { 0 };
102
103 static void
104 gtk_toggle_action_class_init (GtkToggleActionClass *klass)
105 {
106   GObjectClass *gobject_class;
107   GtkActionClass *action_class;
108
109   parent_class = g_type_class_peek_parent (klass);
110   gobject_class = G_OBJECT_CLASS (klass);
111   action_class = GTK_ACTION_CLASS (klass);
112
113   gobject_class->set_property = set_property;
114   gobject_class->get_property = get_property;
115
116   action_class->activate = gtk_toggle_action_activate;
117   action_class->connect_proxy = connect_proxy;
118   action_class->disconnect_proxy = disconnect_proxy;
119
120   action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM;
121   action_class->toolbar_item_type = GTK_TYPE_TOGGLE_TOOL_BUTTON;
122
123   action_class->create_menu_item = create_menu_item;
124
125   klass->toggled = gtk_toggle_action_real_toggled;
126
127   g_object_class_install_property (gobject_class,
128                                    PROP_DRAW_AS_RADIO,
129                                    g_param_spec_boolean ("draw_as_radio",
130                                                          P_("Create the same proxies as a radio action"),
131                                                          P_("Whether the proxies for this action look like radio action proxies"),
132                                                          FALSE,
133                                                          G_PARAM_READWRITE));
134
135   action_signals[TOGGLED] =
136     g_signal_new ("toggled",
137                   G_OBJECT_CLASS_TYPE (klass),
138                   G_SIGNAL_RUN_FIRST,
139                   G_STRUCT_OFFSET (GtkToggleActionClass, toggled),
140                   NULL, NULL,
141                   g_cclosure_marshal_VOID__VOID,
142                   G_TYPE_NONE, 0);
143
144   g_type_class_add_private (gobject_class, sizeof (GtkToggleActionPrivate));
145 }
146
147 static void
148 gtk_toggle_action_init (GtkToggleAction *action)
149 {
150   action->private_data = GTK_TOGGLE_ACTION_GET_PRIVATE (action);
151   action->private_data->active = FALSE;
152   action->private_data->draw_as_radio = FALSE;
153 }
154
155 /**
156  * gtk_toggle_action_new:
157  * @name: A unique name for the action
158  * @label: The label displayed in menu items and on buttons
159  * @tooltip: A tooltip for the action
160  * @stock_id: The stock icon to display in widgets representing the action
161  *
162  * Creates a new #GtkToggleAction object. To add the action to
163  * a #GtkActionGroup and set the accelerator for the action,
164  * call gtk_action_group_add_action_with_accel().
165  *
166  * Return value: a new #GtkToggleAction
167  *
168  * Since: 2.4
169  */
170 GtkToggleAction *
171 gtk_toggle_action_new (const gchar *name,
172                        const gchar *label,
173                        const gchar *tooltip,
174                        const gchar *stock_id)
175 {
176   GtkToggleAction *action;
177
178   action = g_object_new (GTK_TYPE_TOGGLE_ACTION,
179                          "name", name,
180                          "label", label,
181                          "tooltip", tooltip,
182                          "stock_id", stock_id,
183                          NULL);
184
185   return action;
186 }
187
188 static void
189 get_property (GObject     *object,
190               guint        prop_id,
191               GValue      *value,
192               GParamSpec  *pspec)
193 {
194   GtkToggleAction *action = GTK_TOGGLE_ACTION (object);
195   
196   switch (prop_id)
197     {
198     case PROP_DRAW_AS_RADIO:
199       g_value_set_boolean (value, gtk_toggle_action_get_draw_as_radio (action));
200       break;
201     default:
202       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
203       break;
204     }
205 }
206
207 static void
208 set_property (GObject      *object,
209               guint         prop_id,
210               const GValue *value,
211               GParamSpec   *pspec)
212 {
213   GtkToggleAction *action = GTK_TOGGLE_ACTION (object);
214   
215   switch (prop_id)
216     {
217     case PROP_DRAW_AS_RADIO:
218       gtk_toggle_action_set_draw_as_radio (action, g_value_get_boolean (value));
219       break;
220     default:
221       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
222       break;
223     }
224 }
225
226 static void
227 gtk_toggle_action_activate (GtkAction *action)
228 {
229   GtkToggleAction *toggle_action;
230
231   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
232
233   toggle_action = GTK_TOGGLE_ACTION (action);
234
235   toggle_action->private_data->active = !toggle_action->private_data->active;
236
237   gtk_toggle_action_toggled (toggle_action);
238 }
239
240 static void
241 gtk_toggle_action_real_toggled (GtkToggleAction *action)
242 {
243   GSList *slist;
244
245   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
246
247   for (slist = gtk_action_get_proxies (GTK_ACTION (action)); slist; slist = slist->next)
248     {
249       GtkWidget *proxy = slist->data;
250
251       gtk_action_block_activate_from (GTK_ACTION (action), proxy);
252       if (GTK_IS_CHECK_MENU_ITEM (proxy))
253         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
254                                         action->private_data->active);
255       else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
256         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
257                                            action->private_data->active);
258       else if (GTK_IS_TOGGLE_BUTTON (proxy))
259         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
260                                       action->private_data->active);
261       else {
262         g_warning ("Don't know how to toggle `%s' widgets",
263                    G_OBJECT_TYPE_NAME (proxy));
264       }
265       gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);
266     }
267 }
268
269 static void
270 connect_proxy (GtkAction *action, 
271                GtkWidget *proxy)
272 {
273   GtkToggleAction *toggle_action;
274
275   toggle_action = GTK_TOGGLE_ACTION (action);
276
277   /* do this before hand, so that we don't call the "activate" handler */
278   if (GTK_IS_MENU_ITEM (proxy))
279     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
280                                     toggle_action->private_data->active);
281   else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
282     gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
283                                        toggle_action->private_data->active);
284   else if (GTK_IS_TOGGLE_BUTTON (proxy))
285     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
286                                   toggle_action->private_data->active);
287
288   (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
289 }
290
291 static void
292 disconnect_proxy (GtkAction *action, 
293                   GtkWidget *proxy)
294 {
295   GtkToggleAction *toggle_action;
296
297   toggle_action = GTK_TOGGLE_ACTION (action);
298
299   (* GTK_ACTION_CLASS (parent_class)->disconnect_proxy) (action, proxy);
300 }
301
302 /**
303  * gtk_toggle_action_toggled:
304  * @action: the action object
305  *
306  * Emits the "toggled" signal on the toggle action.
307  *
308  * Since: 2.4
309  */
310 void
311 gtk_toggle_action_toggled (GtkToggleAction *action)
312 {
313   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
314
315   g_signal_emit (action, action_signals[TOGGLED], 0);
316 }
317
318 /**
319  * gtk_toggle_action_set_active:
320  * @action: the action object
321  * @is_active: whether the action should be checked or not
322  *
323  * Sets the checked state on the toggle action.
324  *
325  * Since: 2.4
326  */
327 void
328 gtk_toggle_action_set_active (GtkToggleAction *action, 
329                               gboolean         is_active)
330 {
331   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
332
333   is_active = is_active != FALSE;
334
335   if (action->private_data->active != is_active)
336     {
337       _gtk_action_emit_activate (GTK_ACTION (action));
338     }
339 }
340
341 /**
342  * gtk_toggle_action_get_active:
343  * @action: the action object
344  *
345  * Returns the checked state of the toggle action.
346
347  * Returns: the checked state of the toggle action
348  *
349  * Since: 2.4
350  */
351 gboolean
352 gtk_toggle_action_get_active (GtkToggleAction *action)
353 {
354   g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE);
355
356   return action->private_data->active;
357 }
358
359
360 /**
361  * gtk_toggle_action_set_draw_as_radio:
362  * @action: the action object
363  * @draw_as_radio: whether the action should have proxies like a radio 
364  *    action
365  *
366  * Sets whether the action should have proxies like a radio action.
367  *
368  * Since: 2.4
369  */
370 void
371 gtk_toggle_action_set_draw_as_radio (GtkToggleAction *action, 
372                                      gboolean         draw_as_radio)
373 {
374   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
375
376   draw_as_radio = draw_as_radio != FALSE;
377
378   if (action->private_data->draw_as_radio != draw_as_radio)
379     {
380       action->private_data->draw_as_radio = draw_as_radio;
381       
382       g_object_notify (G_OBJECT (action), "draw_as_radio");      
383     }
384 }
385
386 /**
387  * gtk_toggle_action_get_draw_as_radio:
388  * @action: the action object
389  *
390  * Returns whether the action should have proxies like a radio action.
391  *
392  * Returns: whether the action should have proxies like a radio action.
393  *
394  * Since: 2.4
395  */
396 gboolean
397 gtk_toggle_action_get_draw_as_radio (GtkToggleAction *action)
398 {
399   g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE);
400
401   return action->private_data->draw_as_radio;
402 }
403
404 static GtkWidget *
405 create_menu_item (GtkAction *action)
406 {
407   GtkToggleAction *toggle_action = GTK_TOGGLE_ACTION (action);
408
409   return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, 
410                        "draw_as_radio", toggle_action->private_data->draw_as_radio,
411                        NULL);
412 }