1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 */
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is EGE Select One Action.
18 *
19 * The Initial Developer of the Original Code is
20 * Jon A. Cruz.
21 * Portions created by the Initial Developer are Copyright (C) 2007
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
40 /* Note: this file should be kept compilable as both .cpp and .c */
42 #include <string.h>
44 #include <gtk/gtkhbox.h>
45 #include <gtk/gtklabel.h>
46 #include <gtk/gtktoolitem.h>
47 #include <gtk/gtkcombobox.h>
48 #include <gtk/gtkcellrenderertext.h>
49 #include <gtk/gtkcelllayout.h>
50 #include <gtk/gtkradioaction.h>
51 #include <gtk/gtkradiomenuitem.h>
52 #include <gtk/gtktable.h>
54 #include "ege-select-one-action.h"
56 enum {
57 CHANGED = 0,
58 LAST_SIGNAL};
61 static void ege_select_one_action_class_init( EgeSelectOneActionClass* klass );
62 static void ege_select_one_action_init( EgeSelectOneAction* action );
63 static void ege_select_one_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
64 static void ege_select_one_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
66 static void resync_active( EgeSelectOneAction* act, gint active );
67 static void combo_changed_cb( GtkComboBox* widget, gpointer user_data );
68 static void menu_toggled_cb( GtkWidget* obj, gpointer data );
69 static void proxy_action_chagned_cb( GtkRadioAction* action, GtkRadioAction* current, gpointer user_data );
71 static GtkWidget* create_menu_item( GtkAction* action );
72 static GtkWidget* create_tool_item( GtkAction* action );
73 static void connect_proxy( GtkAction *action, GtkWidget *proxy );
74 static void disconnect_proxy( GtkAction *action, GtkWidget *proxy );
76 static GtkActionClass* gParentClass = 0;
77 static guint signals[LAST_SIGNAL] = {0};
78 static GQuark gDataName = 0;
81 enum {
82 APPEARANCE_UNKNOWN = -1,
83 APPEARANCE_NONE = 0,
84 APPEARANCE_FULL,
85 APPEARANCE_COMPACT,
86 APPEARANCE_MINIMAL,
87 };
89 struct _EgeSelectOneActionPrivate
90 {
91 gint active;
92 gint labelColumn;
93 gint iconColumn;
94 gint tooltipColumn;
95 gint appearanceMode;
96 GType radioActionType;
97 GtkTreeModel* model;
98 gchar* iconProperty;
99 gchar* appearance;
100 };
102 #define EGE_SELECT_ONE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionPrivate ) )
104 enum {
105 PROP_MODEL = 1,
106 PROP_ACTIVE,
107 PROP_LABEL_COLUMN,
108 PROP_ICON_COLUMN,
109 PROP_TOOLTIP_COLUMN,
110 PROP_ICON_PROP,
111 PROP_APPEARANCE
112 };
114 GType ege_select_one_action_get_type( void )
115 {
116 static GType myType = 0;
117 if ( !myType ) {
118 static const GTypeInfo myInfo = {
119 sizeof( EgeSelectOneActionClass ),
120 NULL, /* base_init */
121 NULL, /* base_finalize */
122 (GClassInitFunc)ege_select_one_action_class_init,
123 NULL, /* class_finalize */
124 NULL, /* class_data */
125 sizeof( EgeSelectOneAction ),
126 0, /* n_preallocs */
127 (GInstanceInitFunc)ege_select_one_action_init,
128 NULL
129 };
131 myType = g_type_register_static( GTK_TYPE_ACTION, "EgeSelectOneAction", &myInfo, (GTypeFlags)0 );
132 }
134 return myType;
135 }
137 void ege_select_one_action_class_init( EgeSelectOneActionClass* klass )
138 {
139 if ( klass ) {
140 gParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) );
141 GObjectClass* objClass = G_OBJECT_CLASS( klass );
143 gDataName = g_quark_from_string("ege-select1-action");
145 objClass->get_property = ege_select_one_action_get_property;
146 objClass->set_property = ege_select_one_action_set_property;
148 klass->parent_class.create_menu_item = create_menu_item;
149 klass->parent_class.create_tool_item = create_tool_item;
150 klass->parent_class.connect_proxy = connect_proxy;
151 klass->parent_class.disconnect_proxy = disconnect_proxy;
153 g_object_class_install_property( objClass,
154 PROP_MODEL,
155 g_param_spec_object( "model",
156 "Tree Model",
157 "Tree model of possible items",
158 GTK_TYPE_TREE_MODEL,
159 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
161 g_object_class_install_property( objClass,
162 PROP_ACTIVE,
163 g_param_spec_int( "active",
164 "Active Selection",
165 "The index of the selected item",
166 0, 20, 0,
167 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
169 g_object_class_install_property( objClass,
170 PROP_LABEL_COLUMN,
171 g_param_spec_int( "label-column",
172 "Display Column",
173 "The column of the model that holds display strings",
174 0, 20, 0,
175 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
177 g_object_class_install_property( objClass,
178 PROP_ICON_COLUMN,
179 g_param_spec_int( "icon-column",
180 "Icon Column",
181 "The column of the model that holds display icon name",
182 -1, 20, -1,
183 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
185 g_object_class_install_property( objClass,
186 PROP_TOOLTIP_COLUMN,
187 g_param_spec_int( "tooltip-column",
188 "Tooltip Column",
189 "The column of the model that holds tooltip strings",
190 -1, 20, -1,
191 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
193 g_object_class_install_property( objClass,
194 PROP_ICON_PROP,
195 g_param_spec_string( "icon-property",
196 "Icon Property",
197 "Target icon property",
198 "",
199 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
201 g_object_class_install_property( objClass,
202 PROP_APPEARANCE,
203 g_param_spec_string( "appearance",
204 "Appearance hint",
205 "A hint for how to display",
206 "",
207 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
209 signals[CHANGED] = g_signal_new( "changed",
210 G_TYPE_FROM_CLASS(klass),
211 G_SIGNAL_RUN_FIRST,
212 G_STRUCT_OFFSET(EgeSelectOneActionClass, changed),
213 NULL, NULL,
214 g_cclosure_marshal_VOID__VOID,
215 G_TYPE_NONE, 0);
217 g_type_class_add_private( klass, sizeof(EgeSelectOneActionClass) );
218 }
219 }
222 void ege_select_one_action_init( EgeSelectOneAction* action )
223 {
224 action->private_data = EGE_SELECT_ONE_ACTION_GET_PRIVATE( action );
225 action->private_data->active = 0;
226 action->private_data->labelColumn = 0;
227 action->private_data->iconColumn = -1;
228 action->private_data->tooltipColumn = -1;
229 action->private_data->appearanceMode = APPEARANCE_NONE;
230 action->private_data->radioActionType = 0;
231 action->private_data->model = 0;
232 action->private_data->iconProperty = g_strdup("stock-id");
233 action->private_data->appearance = 0;
235 /* g_signal_connect( action, "notify", G_CALLBACK( fixup_labels ), NULL ); */
236 }
238 EgeSelectOneAction* ege_select_one_action_new( const gchar *name,
239 const gchar *label,
240 const gchar *tooltip,
241 const gchar *stock_id,
242 GtkTreeModel* model )
243 {
244 GObject* obj = (GObject*)g_object_new( EGE_SELECT_ONE_ACTION_TYPE,
245 "name", name,
246 "label", label,
247 "tooltip", tooltip,
248 "stock_id", stock_id,
249 "model", model,
250 "active", 0,
251 "icon-property", "stock-id",
252 NULL );
254 EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
256 return action;
257 }
260 gint ege_select_one_action_get_active( EgeSelectOneAction* action )
261 {
262 g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
263 return action->private_data->active;
264 }
266 void ege_select_one_action_set_active( EgeSelectOneAction* action, gint val )
267 {
268 g_object_set( G_OBJECT(action), "active", val, NULL );
269 }
271 gint ege_select_one_action_get_label_column( EgeSelectOneAction* action )
272 {
273 g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
274 return action->private_data->labelColumn;
275 }
277 void ege_select_one_action_set_label_column( EgeSelectOneAction* action, gint col )
278 {
279 g_object_set( G_OBJECT(action), "label-column", col, NULL );
280 }
282 gint ege_select_one_action_get_icon_column( EgeSelectOneAction* action )
283 {
284 g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
285 return action->private_data->iconColumn;
286 }
288 void ege_select_one_action_set_icon_column( EgeSelectOneAction* action, gint col )
289 {
290 g_object_set( G_OBJECT(action), "icon-column", col, NULL );
291 }
293 gint ege_select_one_action_get_tooltip_column( EgeSelectOneAction* action )
294 {
295 g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
296 return action->private_data->tooltipColumn;
297 }
299 void ege_select_one_action_set_tooltip_column( EgeSelectOneAction* action, gint col )
300 {
301 g_object_set( G_OBJECT(action), "tooltip-column", col, NULL );
302 }
304 void ege_select_one_action_set_appearance( EgeSelectOneAction* action, gchar const* val )
305 {
306 g_object_set( G_OBJECT(action), "appearance", val, NULL );
307 }
309 void ege_select_one_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
310 {
311 EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
312 switch ( propId ) {
313 case PROP_MODEL:
314 g_value_set_object( value, action->private_data->model );
315 break;
317 case PROP_ACTIVE:
318 g_value_set_int( value, action->private_data->active );
319 break;
321 case PROP_LABEL_COLUMN:
322 g_value_set_int( value, action->private_data->labelColumn );
323 break;
325 case PROP_ICON_COLUMN:
326 g_value_set_int( value, action->private_data->iconColumn );
327 break;
329 case PROP_TOOLTIP_COLUMN:
330 g_value_set_int( value, action->private_data->tooltipColumn );
331 break;
333 case PROP_ICON_PROP:
334 g_value_set_string( value, action->private_data->iconProperty );
335 break;
337 case PROP_APPEARANCE:
338 g_value_set_string( value, action->private_data->appearance );
339 break;
341 default:
342 G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
343 }
344 }
346 void ege_select_one_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
347 {
348 EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
349 switch ( propId ) {
350 case PROP_MODEL:
351 {
352 action->private_data->model = GTK_TREE_MODEL( g_value_get_object( value ) );
353 }
354 break;
356 case PROP_ACTIVE:
357 {
358 resync_active( action, g_value_get_int( value ) );
359 }
360 break;
362 case PROP_LABEL_COLUMN:
363 {
364 action->private_data->labelColumn = g_value_get_int( value );
365 }
366 break;
368 case PROP_ICON_COLUMN:
369 {
370 action->private_data->iconColumn = g_value_get_int( value );
371 }
372 break;
374 case PROP_TOOLTIP_COLUMN:
375 {
376 action->private_data->tooltipColumn = g_value_get_int( value );
377 }
378 break;
380 case PROP_ICON_PROP:
381 {
382 gchar* tmp = action->private_data->iconProperty;
383 gchar* newVal = g_value_dup_string( value );
384 action->private_data->iconProperty = newVal;
385 g_free( tmp );
386 }
387 break;
389 case PROP_APPEARANCE:
390 {
391 gchar* tmp = action->private_data->appearance;
392 gchar* newVal = g_value_dup_string( value );
393 action->private_data->appearance = newVal;
394 g_free( tmp );
396 if ( !action->private_data->appearance || (strcmp("", newVal) == 0) ) {
397 action->private_data->appearanceMode = APPEARANCE_NONE;
398 } else if ( strcmp("full", newVal) == 0 ) {
399 action->private_data->appearanceMode = APPEARANCE_FULL;
400 } else if ( strcmp("compact", newVal) == 0 ) {
401 action->private_data->appearanceMode = APPEARANCE_COMPACT;
402 } else if ( strcmp("minimal", newVal) == 0 ) {
403 action->private_data->appearanceMode = APPEARANCE_MINIMAL;
404 } else {
405 action->private_data->appearanceMode = APPEARANCE_UNKNOWN;
406 }
407 }
408 break;
410 default:
411 G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
412 }
413 }
415 GtkWidget* create_menu_item( GtkAction* action )
416 {
417 GtkWidget* item = 0;
419 if ( IS_EGE_SELECT_ONE_ACTION(action) ) {
420 EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION( action );
421 gchar* sss = 0;
422 gboolean valid = FALSE;
423 gint index = 0;
424 GtkTreeIter iter;
425 GSList* group = 0;
426 GtkWidget* subby = gtk_menu_new();
428 g_object_get( G_OBJECT(action), "label", &sss, NULL );
430 item = gtk_menu_item_new_with_label( sss );
432 valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
433 while ( valid ) {
434 gchar* str = 0;
435 gtk_tree_model_get( act->private_data->model, &iter,
436 act->private_data->labelColumn, &str,
437 -1 );
439 GtkWidget *item = gtk_radio_menu_item_new_with_label( group, str );
440 group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) );
441 gtk_menu_shell_append( GTK_MENU_SHELL(subby), item );
442 g_object_set_qdata( G_OBJECT(item), gDataName, act );
444 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), index == act->private_data->active );
446 g_free(str);
448 g_signal_connect( G_OBJECT(item), "toggled", G_CALLBACK(menu_toggled_cb), GINT_TO_POINTER(index) );
450 index++;
451 valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
452 }
454 gtk_menu_item_set_submenu( GTK_MENU_ITEM(item), subby );
455 gtk_widget_show_all( subby );
457 g_free(sss);
458 } else {
459 item = gParentClass->create_menu_item( action );
460 }
462 return item;
463 }
466 void ege_select_one_action_set_radio_action_type( EgeSelectOneAction* action, GType radioActionType )
467 {
468 (void)action;
470 if ( g_type_is_a( radioActionType, GTK_TYPE_RADIO_ACTION ) ) {
471 action->private_data->radioActionType = radioActionType;
472 } else {
473 g_warning("Passed in type '%s' is not derived from '%s'", g_type_name(radioActionType), g_type_name(GTK_TYPE_RADIO_ACTION) );
474 }
475 }
477 GtkWidget* create_tool_item( GtkAction* action )
478 {
479 GtkWidget* item = 0;
481 if ( IS_EGE_SELECT_ONE_ACTION(action) && EGE_SELECT_ONE_ACTION(action)->private_data->model )
482 {
483 EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(action);
484 item = GTK_WIDGET( gtk_tool_item_new() );
486 if ( act->private_data->appearanceMode == APPEARANCE_FULL ) {
487 GtkWidget* holder = gtk_hbox_new( FALSE, 0 );
489 GtkRadioAction* ract = 0;
490 GtkWidget* sub = 0;
491 GSList* group = 0;
492 GtkTreeIter iter;
493 gboolean valid = FALSE;
494 gint index = 0;
495 GtkTooltips* tooltips = gtk_tooltips_new();
497 valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
498 while ( valid ) {
499 gchar* str = 0;
500 gchar* tip = 0;
501 gchar* iconId = 0;
502 /*
503 gint size = 0;
504 */
505 gtk_tree_model_get( act->private_data->model, &iter,
506 act->private_data->labelColumn, &str,
507 -1 );
508 if ( act->private_data->iconColumn >= 0 ) {
509 gtk_tree_model_get( act->private_data->model, &iter,
510 act->private_data->iconColumn, &iconId,
511 -1 );
512 }
513 if ( act->private_data->tooltipColumn >= 0 ) {
514 gtk_tree_model_get( act->private_data->model, &iter,
515 act->private_data->tooltipColumn, &tip,
516 -1 );
517 }
519 if ( act->private_data->radioActionType ) {
520 void* obj = g_object_new( act->private_data->radioActionType,
521 "name", "Name 1",
522 "label", str,
523 "tooltip", tip,
524 "value", index,
525 /*
526 "iconId", iconId,
527 "iconSize", size,
528 */
529 NULL );
530 if ( iconId ) {
531 g_object_set( G_OBJECT(obj), act->private_data->iconProperty, iconId, NULL );
532 }
534 ract = GTK_RADIO_ACTION(obj);
535 } else {
536 ract = gtk_radio_action_new( "Name 1", str, tip, iconId, index );
537 }
539 gtk_radio_action_set_group( ract, group );
540 group = gtk_radio_action_get_group( ract );
542 if ( index == act->private_data->active ) {
543 gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(ract), TRUE );
544 }
545 g_signal_connect( G_OBJECT(ract), "changed", G_CALLBACK( proxy_action_chagned_cb ), act );
547 sub = gtk_action_create_tool_item( GTK_ACTION(ract) );
548 gtk_action_connect_proxy( GTK_ACTION(ract), sub );
549 gtk_tool_item_set_tooltip( GTK_TOOL_ITEM(sub), tooltips, tip, NULL );
551 gtk_box_pack_start( GTK_BOX(holder), sub, FALSE, FALSE, 0 );
553 g_free( str );
554 g_free( tip );
555 g_free( iconId );
557 index++;
558 valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
559 }
561 g_object_set_data( G_OBJECT(holder), "ege-proxy_action-group", group );
562 g_object_set_data( G_OBJECT(holder), "ege-tooltips", tooltips );
564 gtk_container_add( GTK_CONTAINER(item), holder );
565 } else {
566 GtkWidget* holder = gtk_table_new( 1, 3, FALSE );
567 GtkWidget* normal = gtk_combo_box_new_with_model( act->private_data->model );
569 GtkCellRenderer * renderer = gtk_cell_renderer_text_new();
570 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE );
571 gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT(normal), renderer, "text", act->private_data->labelColumn, (gchar*)0);
573 gtk_combo_box_set_active( GTK_COMBO_BOX(normal), act->private_data->active );
575 g_signal_connect( G_OBJECT(normal), "changed", G_CALLBACK(combo_changed_cb), action );
577 g_object_set_data( G_OBJECT(holder), "ege-combo-box", normal );
579 GtkWidget* lbl = gtk_label_new(" ");
580 gtk_table_attach( GTK_TABLE(holder), lbl, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
581 gtk_table_attach( GTK_TABLE(holder), normal, 1, 2, 0, 1, GTK_FILL, GTK_EXPAND, 0, 0 );
582 lbl = gtk_label_new(" ");
583 gtk_table_attach( GTK_TABLE(holder), lbl, 2, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
584 gtk_container_add( GTK_CONTAINER(item), holder );
585 }
587 gtk_widget_show_all( item );
588 } else {
589 item = gParentClass->create_tool_item( action );
590 }
592 return item;
593 }
596 void connect_proxy( GtkAction *action, GtkWidget *proxy )
597 {
598 gParentClass->connect_proxy( action, proxy );
599 }
601 void disconnect_proxy( GtkAction *action, GtkWidget *proxy )
602 {
603 gParentClass->disconnect_proxy( action, proxy );
604 }
607 void resync_active( EgeSelectOneAction* act, gint active )
608 {
609 if ( act->private_data->active != active ) {
610 act->private_data->active = active;
611 GSList* proxies = gtk_action_get_proxies( GTK_ACTION(act) );
612 while ( proxies ) {
613 if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
614 /* Search for the things we built up in create_tool_item() */
615 GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) );
616 if ( children && children->data ) {
617 gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" );
618 if ( GTK_IS_COMBO_BOX(combodata) ) {
619 GtkComboBox* combo = GTK_COMBO_BOX(combodata);
620 if ( gtk_combo_box_get_active(combo) != active ) {
621 gtk_combo_box_set_active( combo, active );
622 }
623 } else if ( GTK_IS_HBOX(children->data) ) {
624 gpointer data = g_object_get_data( G_OBJECT(children->data), "ege-proxy_action-group" );
625 if ( data ) {
626 GSList* group = (GSList*)data;
627 GtkRadioAction* oneAction = GTK_RADIO_ACTION(group->data);
628 gint hot = gtk_radio_action_get_current_value( oneAction );
629 if ( hot != active ) {
630 /*gtk_radio_action_set_current_value( oneAction, active );*/
631 gint value = 0;
632 while ( group ) {
633 GtkRadioAction* possible = GTK_RADIO_ACTION(group->data);
634 g_object_get( G_OBJECT(possible), "value", &value, NULL );
635 if ( value == active ) {
636 /* Found the group member to set active */
637 gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(possible), TRUE );
638 break;
639 }
641 group = g_slist_next(group);
642 }
643 }
644 }
645 }
646 }
647 } else if ( GTK_IS_MENU_ITEM(proxies->data) ) {
648 GtkWidget* subMenu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(proxies->data) );
649 GList* children = gtk_container_get_children( GTK_CONTAINER(subMenu) );
650 if ( children && (g_list_length(children) > (guint)active) ) {
651 gpointer data = g_list_nth_data( children, active );
652 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(data), TRUE );
653 }
654 }
656 proxies = g_slist_next( proxies );
657 }
659 g_signal_emit( G_OBJECT(act), signals[CHANGED], 0);
660 }
661 }
663 void combo_changed_cb( GtkComboBox* widget, gpointer user_data )
664 {
665 EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(user_data);
666 gint newActive = gtk_combo_box_get_active(widget);
667 if (newActive != act->private_data->active) {
668 g_object_set( G_OBJECT(act), "active", newActive, NULL );
669 }
670 }
672 void menu_toggled_cb( GtkWidget* obj, gpointer data )
673 {
674 GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(obj);
675 EgeSelectOneAction* act = (EgeSelectOneAction*)g_object_get_qdata( G_OBJECT(obj), gDataName );
676 gint newActive = GPOINTER_TO_INT(data);
677 if ( gtk_check_menu_item_get_active(item) && (newActive != act->private_data->active) ) {
678 g_object_set( G_OBJECT(act), "active", newActive, NULL );
679 }
680 }
682 void proxy_action_chagned_cb( GtkRadioAction* action, GtkRadioAction* current, gpointer user_data )
683 {
684 (void)current;
685 if ( gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(action) ) ) {
686 EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(user_data);
687 gint newActive = gtk_radio_action_get_current_value( action );
688 if ( newActive != act->private_data->active ) {
689 g_object_set( G_OBJECT(act), "active", newActive, NULL );
690 }
691 }
692 }