GtkWidget* create_menu_item( GtkAction* action )
{
    GtkWidget* item = 0;

    if ( IS_EGE_SELECT_ONE_ACTION(action) ) {
        EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION( action );
        gchar*  sss = 0;
        gint index = 0;
        GtkTreeIter iter;
        GSList* group = 0;
        GtkWidget* subby = gtk_menu_new();

        g_object_get( G_OBJECT(action), "label", &sss, NULL );

        item = gtk_menu_item_new_with_label( sss );

        gboolean valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
        while ( valid ) {
            gchar* str = 0;
            gtk_tree_model_get( act->private_data->model, &iter,
                                act->private_data->labelColumn, &str,
                                -1 );

            GtkWidget *item = gtk_radio_menu_item_new_with_label( group, str );
            group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) );
            gtk_menu_shell_append( GTK_MENU_SHELL(subby), item );
            g_object_set_qdata( G_OBJECT(item), gDataName, act );

            gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), index == act->private_data->active );

            g_free(str);
            str = 0;

            g_signal_connect( G_OBJECT(item), "toggled", G_CALLBACK(menu_toggled_cb), GINT_TO_POINTER(index) );

            index++;
            valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
        }

        gtk_menu_item_set_submenu( GTK_MENU_ITEM(item), subby );
        gtk_widget_show_all( subby );

        g_free(sss);
    } else {
        item = GTK_ACTION_CLASS(ege_select_one_action_parent_class)->create_menu_item( action );
    }

    return item;
}
void ege_select_one_action_set_active_text( EgeSelectOneAction* action, gchar const *text )
{
    g_return_if_fail( IS_EGE_SELECT_ONE_ACTION(action) );

    if (action->private_data->activeText) {
        g_free( action->private_data->activeText );
    }
    action->private_data->activeText = g_strdup(text);

    if (action->private_data->active != -1) {
        g_object_set( G_OBJECT(action), "active", -1, NULL );
    } else {
        resync_active( action, -1, TRUE );
    }
}
gchar *ege_select_one_action_get_active_text( EgeSelectOneAction* action )
{
    GtkTreeIter iter;
    gchar *str = 0;
    g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );

    if ( action->private_data->active >= 0) {
        if ( gtk_tree_model_iter_nth_child( action->private_data->model, &iter, NULL, action->private_data->active ) ) {
            gtk_tree_model_get( action->private_data->model, &iter,
                                action->private_data->labelColumn, &str,
                                -1 );
        }
    } else if ( (action->private_data->active == -1) && action->private_data->activeText ) {
        str = g_strdup(action->private_data->activeText);
    }

    return str;
}
void UnitTracker::_setActive( gint active )
{
    if ( active != _active || (_activeUnit == 0) ) {
        gint oldActive = _active;

        GtkTreeIter iter;
        gboolean found = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(_store), &iter, NULL, oldActive );
        if ( found ) {
            SPUnit* unit = 0;
            gtk_tree_model_get( GTK_TREE_MODEL(_store), &iter, COLUMN_SPUNIT, &unit, -1 );

            found = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(_store), &iter, NULL, active );
            if ( found ) {
                SPUnit* newUnit = 0;
                gtk_tree_model_get( GTK_TREE_MODEL(_store), &iter, COLUMN_SPUNIT, &newUnit, -1 );
                _activeUnit = newUnit;

                if ( _adjList ) {
                    _fixupAdjustments( unit, newUnit );
                }

            } else {
                g_warning("Did not find new unit");
            }
        } else {
            g_warning("Did not find old unit");
        }

        _active = active;

        for ( GSList* cur = _actionList; cur; cur = g_slist_next(cur) ) {
            if ( IS_EGE_SELECT_ONE_ACTION( cur->data ) ) {
                EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION( cur->data );
                ege_select_one_action_set_active( act, active );
            }
        }
    }
}
GtkWidget* create_tool_item( GtkAction* action )
{
    GtkWidget* item = 0;

    if ( IS_EGE_SELECT_ONE_ACTION(action) && EGE_SELECT_ONE_ACTION(action)->private_data->model )
    {
        EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(action);
        item = GTK_WIDGET( gtk_tool_item_new() );

        if ( act->private_data->appearanceMode == APPEARANCE_FULL ) {
#if GTK_CHECK_VERSION(3,0,0)
            GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
            gtk_box_set_homogeneous(GTK_BOX(holder), FALSE);
#else
            GtkWidget* holder = gtk_hbox_new( FALSE, 0 );
#endif

            GtkRadioAction* ract = 0;
            GSList* group = 0;
            GtkTreeIter iter;
            gboolean valid = FALSE;
            gint index = 0;

            {
                gchar*  sss = 0;
                g_object_get( G_OBJECT(action), "short_label", &sss, NULL );
                // If short_label not defined, g_object_get will return label.
                // This hack allows a label to be used with a drop-down menu when
                // no label is used with a set of icons that are self-explanatory.
                if (sss && strcmp( sss, "NotUsed" ) != 0 ) {
                    GtkWidget* lbl = gtk_label_new(sss);
                    gtk_box_pack_start( GTK_BOX(holder), lbl, FALSE, FALSE, 4 );
                }
                g_free( sss );
                sss = 0;
            }

            valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
            while ( valid ) {
                gchar* str = 0;
                gchar* tip = 0;
                gchar* iconId = 0;
                gboolean sens = true;
                /*
                gint size = 0;
                */
                gtk_tree_model_get( act->private_data->model, &iter,
                                    act->private_data->labelColumn, &str,
                                    -1 );
                if ( act->private_data->iconColumn >= 0 ) {
                    gtk_tree_model_get( act->private_data->model, &iter,
                                        act->private_data->iconColumn, &iconId,
                                        -1 );
                }
                if ( act->private_data->tooltipColumn >= 0 ) {
                    gtk_tree_model_get( act->private_data->model, &iter,
                                        act->private_data->tooltipColumn, &tip,
                                        -1 );
                }
                if ( act->private_data->sensitiveColumn >= 0 ) {
                    gtk_tree_model_get( act->private_data->model, &iter,
                                        act->private_data->sensitiveColumn, &sens,
                                        -1 );
                }

                if ( act->private_data->radioActionType ) {
                    void* obj = g_object_new( act->private_data->radioActionType,
                                              "name", "Name 1",
                                              "label", str,
                                              "tooltip", tip,
                                              "value", index,
                                              /*
                                              "iconId", iconId,
                                              "iconSize", size,
                                              */
                                              NULL );
                    if ( iconId ) {
                        g_object_set( G_OBJECT(obj), act->private_data->iconProperty, iconId, NULL );
                    }

                    if ( act->private_data->iconProperty ) {
                        /* TODO get this string to be set instead of hardcoded */
                        if ( act->private_data->iconSize >= 0 ) {
                            g_object_set( G_OBJECT(obj), "iconSize", act->private_data->iconSize, NULL );
                        }
                    }

                    ract = GTK_RADIO_ACTION(obj);
                } else {
                    ract = gtk_radio_action_new( "Name 1", str, tip, iconId, index );
                }

                if ( act->private_data->sensitiveColumn >= 0 ) {
                    gtk_action_set_sensitive( GTK_ACTION(ract), sens );
                }

                gtk_radio_action_set_group( ract, group );
                group = gtk_radio_action_get_group( ract );

                if ( index == act->private_data->active ) {
                    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(ract), TRUE );
                }
                g_signal_connect( G_OBJECT(ract), "changed", G_CALLBACK( proxy_action_chagned_cb ), act );

                GtkWidget* sub = gtk_action_create_tool_item( GTK_ACTION(ract) );
                gtk_activatable_set_related_action( GTK_ACTIVATABLE (sub), GTK_ACTION(ract) );
                gtk_tool_item_set_tooltip_text( GTK_TOOL_ITEM(sub), tip );

                gtk_box_pack_start( GTK_BOX(holder), sub, FALSE, FALSE, 0 );

                g_free( str );
                g_free( tip );
                g_free( iconId );

                index++;
                valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
            }

            g_object_set_data( G_OBJECT(holder), "ege-proxy_action-group", group );

            gtk_container_add( GTK_CONTAINER(item), holder );
        } else {
#if GTK_CHECK_VERSION(3,0,0)
            GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
            gtk_box_set_homogeneous(GTK_BOX(holder), FALSE);
#else
            GtkWidget *holder = gtk_hbox_new( FALSE, 4 );
#endif

            GtkEntry *entry = 0;
            GtkWidget *normal;

            if (act->private_data->selectionMode == SELECTION_OPEN) {
	            normal = gtk_combo_box_new_with_model_and_entry (act->private_data->model);
	            gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (normal), act->private_data->labelColumn);

                GtkWidget *child = gtk_bin_get_child( GTK_BIN(normal) );
                if (GTK_IS_ENTRY(child)) {
                    int maxUsed = scan_max_width( act->private_data->model, act->private_data->labelColumn );
                    GtkEntryCompletion *complete = 0;
                    entry = GTK_ENTRY(child);
                    gtk_entry_set_width_chars(entry, maxUsed); /* replace with property */

                    complete = gtk_entry_completion_new();
                    gtk_entry_completion_set_model( complete, act->private_data->model );
                    gtk_entry_completion_set_text_column( complete, act->private_data->labelColumn );
                    gtk_entry_completion_set_inline_completion( complete, FALSE );
                    gtk_entry_completion_set_inline_selection( complete, FALSE );
                    gtk_entry_completion_set_popup_completion( complete, TRUE );
                    gtk_entry_completion_set_popup_set_width( complete, FALSE );
                    gtk_entry_set_completion( entry, complete );

                    g_signal_connect( G_OBJECT(child), "activate", G_CALLBACK(combo_entry_changed_cb), act );
                    g_signal_connect( G_OBJECT(child), "focus-out-event", G_CALLBACK(combo_entry_focus_lost_cb), act );
                }
            } 
	    else {
                GtkCellRenderer * renderer = NULL;
                normal = gtk_combo_box_new_with_model( act->private_data->model );
                if ( act->private_data->iconColumn >= 0 ) {
                    renderer = gtk_cell_renderer_pixbuf_new();
                    gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE );

                    /* "icon-name" */
                    gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(normal), renderer, "stock-id", act->private_data->iconColumn );
                }

                renderer = gtk_cell_renderer_text_new();
                gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE );
                gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(normal), renderer, "text", act->private_data->labelColumn );
            }

            gtk_combo_box_set_active( GTK_COMBO_BOX(normal), act->private_data->active );
            if ( entry && (act->private_data->active == -1) ) {
                gtk_entry_set_text( entry, act->private_data->activeText );
            }

            g_signal_connect( G_OBJECT(normal), "changed", G_CALLBACK(combo_changed_cb), action );

            g_object_set_data( G_OBJECT(holder), "ege-combo-box", normal );
            g_object_set_data( G_OBJECT(act), "ege-combo-box", normal );

            if (act->private_data->appearanceMode == APPEARANCE_COMPACT) {
                gchar*  sss = 0;
                g_object_get( G_OBJECT(action), "short_label", &sss, NULL );
                if (sss) {
                    GtkWidget* lbl = gtk_label_new(sss);
                    gtk_box_pack_start( GTK_BOX(holder), lbl, FALSE, FALSE, 4 );
                    g_free( sss );
                    sss = 0;
                }
            }

            gtk_box_pack_start( GTK_BOX(holder), normal, FALSE, FALSE, 0 );

            {
#if GTK_CHECK_VERSION(3,0,0)
                gtk_widget_set_halign(holder, GTK_ALIGN_START);
                gtk_container_add(GTK_CONTAINER(item), holder);
#else
                GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0);
                gtk_container_add( GTK_CONTAINER(align), holder);
                gtk_container_add( GTK_CONTAINER(item), align );
#endif
            }
        }

        gtk_widget_show_all( item );
    } else {
        item = GTK_ACTION_CLASS(ege_select_one_action_parent_class)->create_tool_item( action );
    }

    return item;
}
gint ege_select_one_action_get_sensitive_column( EgeSelectOneAction* action )
{
    g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
    return action->private_data->sensitiveColumn;
}
gint ege_select_one_action_get_icon_size( EgeSelectOneAction* action )
{
    g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
    return action->private_data->iconSize;
}