diff --git a/ChangeLog b/ChangeLog index d451655bfb..c2d98136d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +2003-08-28 Matthias Clasen + + * gtk/gtkuimanager.c: Change the XML format: + element is replaced by , + element is replaced by , + element is replaced by , + element is replaced by , + element is gone, + verb attribute is replaced by action, + name defaults to action or the element name. + + * gtk/gtkactiongroup.[hc]: Replace GtkActionGroupEntry by GtkActionEntry + and GtkRadioActionEntry. GtkActionEntry is simplified by removing + the user_data, entry_type and extra_data fields, GtkRadioActionEntry is + further simplified by removing the callback. The user_data can now be + specified as an argument to gtk_action_group_add_actions(). There is + a new method gtk_action_group_add_radio_actions(), which is similar + to gtk_action_group_add_actions(), but takes GtkRadioActionEntrys + and a callback parameter in addition to the user_data. The callback + is connected to the ::changed signal of the first group member. + There are _full() variants taking a GDestroyNotify of + gtk_action_group_add_[radio_]actions(). + + * gtk/gtkradioaction.[hc]: Add a ::changed signal which gets emitted + on every member of the radio group when the active member is changed. + Add an integer property "value", and a getter for the value of "value" + on the currently active group member. + + * tests/testactions.c: + * tests/testmerge.c: + * tests/merge-[123].ui: + * demos/gtk-demo/appwindow.c: Adjust to these changes. + + * gtk/gtktoolbar.c (gtk_toolbar_append_element): Trivial doc fix. + 2003-08-27 Anders Carlsson * demos/gtk-demo/appwindow.c (do_appwindow): Focus the diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d451655bfb..c2d98136d7 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,38 @@ +2003-08-28 Matthias Clasen + + * gtk/gtkuimanager.c: Change the XML format: + element is replaced by , + element is replaced by , + element is replaced by , + element is replaced by , + element is gone, + verb attribute is replaced by action, + name defaults to action or the element name. + + * gtk/gtkactiongroup.[hc]: Replace GtkActionGroupEntry by GtkActionEntry + and GtkRadioActionEntry. GtkActionEntry is simplified by removing + the user_data, entry_type and extra_data fields, GtkRadioActionEntry is + further simplified by removing the callback. The user_data can now be + specified as an argument to gtk_action_group_add_actions(). There is + a new method gtk_action_group_add_radio_actions(), which is similar + to gtk_action_group_add_actions(), but takes GtkRadioActionEntrys + and a callback parameter in addition to the user_data. The callback + is connected to the ::changed signal of the first group member. + There are _full() variants taking a GDestroyNotify of + gtk_action_group_add_[radio_]actions(). + + * gtk/gtkradioaction.[hc]: Add a ::changed signal which gets emitted + on every member of the radio group when the active member is changed. + Add an integer property "value", and a getter for the value of "value" + on the currently active group member. + + * tests/testactions.c: + * tests/testmerge.c: + * tests/merge-[123].ui: + * demos/gtk-demo/appwindow.c: Adjust to these changes. + + * gtk/gtktoolbar.c (gtk_toolbar_append_element): Trivial doc fix. + 2003-08-27 Anders Carlsson * demos/gtk-demo/appwindow.c (do_appwindow): Focus the diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d451655bfb..c2d98136d7 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,38 @@ +2003-08-28 Matthias Clasen + + * gtk/gtkuimanager.c: Change the XML format: + element is replaced by , + element is replaced by , + element is replaced by , + element is replaced by , + element is gone, + verb attribute is replaced by action, + name defaults to action or the element name. + + * gtk/gtkactiongroup.[hc]: Replace GtkActionGroupEntry by GtkActionEntry + and GtkRadioActionEntry. GtkActionEntry is simplified by removing + the user_data, entry_type and extra_data fields, GtkRadioActionEntry is + further simplified by removing the callback. The user_data can now be + specified as an argument to gtk_action_group_add_actions(). There is + a new method gtk_action_group_add_radio_actions(), which is similar + to gtk_action_group_add_actions(), but takes GtkRadioActionEntrys + and a callback parameter in addition to the user_data. The callback + is connected to the ::changed signal of the first group member. + There are _full() variants taking a GDestroyNotify of + gtk_action_group_add_[radio_]actions(). + + * gtk/gtkradioaction.[hc]: Add a ::changed signal which gets emitted + on every member of the radio group when the active member is changed. + Add an integer property "value", and a getter for the value of "value" + on the currently active group member. + + * tests/testactions.c: + * tests/testmerge.c: + * tests/merge-[123].ui: + * demos/gtk-demo/appwindow.c: Adjust to these changes. + + * gtk/gtktoolbar.c (gtk_toolbar_append_element): Trivial doc fix. + 2003-08-27 Anders Carlsson * demos/gtk-demo/appwindow.c (do_appwindow): Focus the diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d451655bfb..c2d98136d7 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,38 @@ +2003-08-28 Matthias Clasen + + * gtk/gtkuimanager.c: Change the XML format: + element is replaced by , + element is replaced by , + element is replaced by , + element is replaced by , + element is gone, + verb attribute is replaced by action, + name defaults to action or the element name. + + * gtk/gtkactiongroup.[hc]: Replace GtkActionGroupEntry by GtkActionEntry + and GtkRadioActionEntry. GtkActionEntry is simplified by removing + the user_data, entry_type and extra_data fields, GtkRadioActionEntry is + further simplified by removing the callback. The user_data can now be + specified as an argument to gtk_action_group_add_actions(). There is + a new method gtk_action_group_add_radio_actions(), which is similar + to gtk_action_group_add_actions(), but takes GtkRadioActionEntrys + and a callback parameter in addition to the user_data. The callback + is connected to the ::changed signal of the first group member. + There are _full() variants taking a GDestroyNotify of + gtk_action_group_add_[radio_]actions(). + + * gtk/gtkradioaction.[hc]: Add a ::changed signal which gets emitted + on every member of the radio group when the active member is changed. + Add an integer property "value", and a getter for the value of "value" + on the currently active group member. + + * tests/testactions.c: + * tests/testmerge.c: + * tests/merge-[123].ui: + * demos/gtk-demo/appwindow.c: Adjust to these changes. + + * gtk/gtktoolbar.c (gtk_toolbar_append_element): Trivial doc fix. + 2003-08-27 Anders Carlsson * demos/gtk-demo/appwindow.c (do_appwindow): Focus the diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d451655bfb..c2d98136d7 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,38 @@ +2003-08-28 Matthias Clasen + + * gtk/gtkuimanager.c: Change the XML format: + element is replaced by , + element is replaced by , + element is replaced by , + element is replaced by , + element is gone, + verb attribute is replaced by action, + name defaults to action or the element name. + + * gtk/gtkactiongroup.[hc]: Replace GtkActionGroupEntry by GtkActionEntry + and GtkRadioActionEntry. GtkActionEntry is simplified by removing + the user_data, entry_type and extra_data fields, GtkRadioActionEntry is + further simplified by removing the callback. The user_data can now be + specified as an argument to gtk_action_group_add_actions(). There is + a new method gtk_action_group_add_radio_actions(), which is similar + to gtk_action_group_add_actions(), but takes GtkRadioActionEntrys + and a callback parameter in addition to the user_data. The callback + is connected to the ::changed signal of the first group member. + There are _full() variants taking a GDestroyNotify of + gtk_action_group_add_[radio_]actions(). + + * gtk/gtkradioaction.[hc]: Add a ::changed signal which gets emitted + on every member of the radio group when the active member is changed. + Add an integer property "value", and a getter for the value of "value" + on the currently active group member. + + * tests/testactions.c: + * tests/testmerge.c: + * tests/merge-[123].ui: + * demos/gtk-demo/appwindow.c: Adjust to these changes. + + * gtk/gtktoolbar.c (gtk_toolbar_append_element): Trivial doc fix. + 2003-08-27 Anders Carlsson * demos/gtk-demo/appwindow.c (do_appwindow): Focus the diff --git a/demos/gtk-demo/appwindow.c b/demos/gtk-demo/appwindow.c index 4e6d7e659e..841ba4dd43 100644 --- a/demos/gtk-demo/appwindow.c +++ b/demos/gtk-demo/appwindow.c @@ -32,106 +32,143 @@ activate_action (GtkAction *action) gtk_widget_show (dialog); } +static void +activate_radio_action (GtkAction *action, GtkRadioAction *current) +{ + const gchar *name = gtk_action_get_name (GTK_ACTION (current)); + const gchar *typename = G_OBJECT_TYPE_NAME (GTK_ACTION (current)); + gboolean active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (current)); + gint value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (current)); -static GtkActionGroupEntry entries[] = { - { "FileMenu", "_File" }, /* name, label */ - { "PreferencesMenu", "_Preferences" }, /* name, label */ - { "ColorMenu", "_Color" }, /* name, label */ - { "ShapeMenu", "_Shape" }, /* name, label */ - { "HelpMenu", "_Help" }, /* name, label */ - { "New", "_New", /* name, label */ - GTK_STOCK_NEW, "N", /* stock_id, accelerator */ - "Create a new file", /* tooltip */ + if (active) + { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, + "You activated radio action: \"%s\" of type \"%s\".\nCurrent value: %d", + name, typename, value); + + /* Close dialog on user response */ + g_signal_connect (dialog, + "response", + G_CALLBACK (gtk_widget_destroy), + NULL); + + gtk_widget_show (dialog); + } +} + + +static GtkActionEntry entries[] = { + { "FileMenu", NULL, "_File" }, /* name, stock id, label */ + { "PreferencesMenu", NULL, "_Preferences" }, /* name, stock id, label */ + { "ColorMenu", NULL, "_Color" }, /* name, stock id, label */ + { "ShapeMenu", NULL, "_Shape" }, /* name, stock id, label */ + { "HelpMenu", NULL, "_Help" }, /* name, stock id, label */ + { "New", GTK_STOCK_NEW, /* name, stock id */ + "_New", "N", /* label, accelerator */ + "Create a new file", /* tooltip */ G_CALLBACK (activate_action) }, - { "Open", "_Open", /* name, label */ - GTK_STOCK_OPEN, "O", /* stock_id, accelerator */ - "Open a file", /* tooltip */ + { "Open", GTK_STOCK_OPEN, /* name, stock id */ + "_Open","O", /* label, accelerator */ + "Open a file", /* tooltip */ + G_CALLBACK (activate_action) }, + { "Save", GTK_STOCK_SAVE, /* name, stock id */ + "_Save","S", /* label, accelerator */ + "Save current file", /* tooltip */ G_CALLBACK (activate_action) }, - { "Save", "_Save", /* name, label */ - GTK_STOCK_SAVE, "S", /* stock_id, accelerator */ - "Save current file", /* tooltip */ + { "SaveAs", GTK_STOCK_SAVE, /* name, stock id */ + "Save _As...", NULL, /* label, accelerator */ + "Save to a file", /* tooltip */ G_CALLBACK (activate_action) }, - { "SaveAs", "Save _As...", /* name, label */ - GTK_STOCK_SAVE, NULL, /* stock_id, accelerator */ - "Save to a file", /* tooltip */ + { "Quit", GTK_STOCK_QUIT, /* name, stock id */ + "_Quit", "Q", /* label, accelerator */ + "Quit", /* tooltip */ G_CALLBACK (activate_action) }, - { "Quit", "_Quit", /* name, label */ - GTK_STOCK_QUIT, "Q", /* stock_id, accelerator */ - "Quit", /* tooltip */ + { "About", NULL, /* name, stock id */ + "_About", "A", /* label, accelerator */ + "About", /* tooltip */ G_CALLBACK (activate_action) }, - { "Red", "_Red", /* name, label */ - NULL, "R", /* stock_id, accelerator */ - "Blood", /* tooltip */ - G_CALLBACK (activate_action), NULL, - GTK_ACTION_RADIO }, /* entry type */ - { "Green", "_Green", /* name, label */ - NULL, "G", /* stock_id, accelerator */ - "Grass", /* tooltip */ - G_CALLBACK (activate_action), NULL, - GTK_ACTION_RADIO, "Red" }, /* entry type, radio group */ - { "Blue", "_Blue", /* name, label */ - NULL, "B", /* stock_id, accelerator */ - "Sky", /* tooltip */ - G_CALLBACK (activate_action), NULL, - GTK_ACTION_RADIO, "Red" }, /* entry type, radio group */ - { "Square", "_Square", /* name, label */ - NULL, "S", /* stock_id, accelerator */ - "Square", /* tooltip */ - G_CALLBACK (activate_action), NULL, - GTK_ACTION_RADIO }, /* entry type */ - { "Rectangle", "_Rectangle", /* name, label */ - NULL, "R", /* stock_id, accelerator */ - "Rectangle", /* tooltip */ - G_CALLBACK (activate_action), NULL, - GTK_ACTION_RADIO, "Square" }, /* entry type, radio group */ - { "Oval", "_Oval", /* name, label */ - NULL, "O", /* stock_id, accelerator */ - "Egg", /* tooltip */ - G_CALLBACK (activate_action), NULL, - GTK_ACTION_RADIO, "Square" }, /* entry type, radio group */ - { "About", "_About", /* name, label */ - NULL, "A", /* stock_id, accelerator */ - "About", /* tooltip */ - G_CALLBACK (activate_action) }, - { "Logo", NULL, /* name, label */ - "demo-gtk-logo", NULL, /* stock_id, accelerator */ - "GTK+", /* tooltip */ + { "Logo", "demo-gtk-logo", /* name, stock id */ + NULL, NULL, /* label, accelerator */ + "GTK+", /* tooltip */ G_CALLBACK (activate_action) }, }; static guint n_entries = G_N_ELEMENTS (entries); +enum { + COLOR_RED, + COLOR_GREEN, + COLOR_BLUE +}; + +static GtkRadioActionEntry color_entries[] = { + { "Red", NULL, /* name, stock id */ + "_Red", "R", /* label, accelerator */ + "Blood", COLOR_RED }, /* tooltip, value */ + { "Green", NULL, /* name, stock id */ + "_Green", "G", /* label, accelerator */ + "Grass", COLOR_GREEN }, /* tooltip, value */ + { "Blue", NULL, /* name, stock id */ + "_Blue", "B", /* label, accelerator */ + "Sky", COLOR_BLUE }, /* tooltip, value */ +}; +static guint n_color_entries = G_N_ELEMENTS (color_entries); + +enum { + SHAPE_SQUARE, + SHAPE_RECTANGLE, + SHAPE_OVAL, +}; + +static GtkRadioActionEntry shape_entries[] = { + { "Square", NULL, /* name, stock id */ + "_Square", "S", /* label, accelerator */ + "Square", SHAPE_SQUARE }, /* tooltip, value */ + { "Rectangle", NULL, /* name, stock id */ + "_Rectangle", "R", /* label, accelerator */ + "Rectangle", SHAPE_RECTANGLE }, /* tooltip, value */ + { "Oval", NULL, /* name, stock id */ + "_Oval", "O", /* label, accelerator */ + "Egg", SHAPE_OVAL }, /* tooltip, value */ +}; +static guint n_shape_entries = G_N_ELEMENTS (shape_entries); + static const gchar *ui_info = "" " " -" " -" " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " +" " +" " " " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " " " -" " -" " -" " -" " +" " +" " +" " +" " " " " " -" " -" " +" " +" " " " " " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " " " ""; @@ -288,7 +325,11 @@ do_appwindow (void) */ action_group = gtk_action_group_new ("AppWindowActions"); - gtk_action_group_add_actions (action_group, entries, n_entries); + gtk_action_group_add_actions (action_group, entries, n_entries, NULL); + gtk_action_group_add_radio_actions (action_group, color_entries, n_color_entries, + G_CALLBACK (activate_radio_action), NULL); + gtk_action_group_add_radio_actions (action_group, shape_entries, n_shape_entries, + G_CALLBACK (activate_radio_action), NULL); action = gtk_action_group_get_action (action_group, "Red"); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); diff --git a/gtk/gtkactiongroup.c b/gtk/gtkactiongroup.c index 500a49efd7..32cb7bfa6e 100644 --- a/gtk/gtkactiongroup.c +++ b/gtk/gtkactiongroup.c @@ -280,6 +280,7 @@ gtk_action_group_list_actions (GtkActionGroup *action_group) * @action_group: the action group * @entries: an array of action descriptions * @n_entries: the number of entries + * @user_data: data to pass to the action callbacks * * This is a convenience routine to create a number of actions and add * them to the action group. Each member of the array describes an @@ -288,9 +289,36 @@ gtk_action_group_list_actions (GtkActionGroup *action_group) * Since: 2.4 */ void -gtk_action_group_add_actions (GtkActionGroup *action_group, - GtkActionGroupEntry *entries, - guint n_entries) +gtk_action_group_add_actions (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data) +{ + gtk_action_group_add_actions_full (action_group, + entries, n_entries, + user_data, NULL); +} + + +/** + * gtk_action_group_add_actions_full: + * @action_group: the action group + * @entries: an array of action descriptions + * @n_entries: the number of entries + * @user_data: data to pass to the action callbacks + * @destroy: destroy notification callback for @user_data + * + * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify + * callback for @user_data. + * + * Since: 2.4 + */ +void +gtk_action_group_add_actions_full (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data, + GDestroyNotify destroy) { guint i; GtkTranslateFunc translate_func; @@ -309,20 +337,10 @@ gtk_action_group_add_actions (GtkActionGroup *action_group, gchar *label; gchar *tooltip; - switch (entries[i].entry_type) { - case GTK_ACTION_NORMAL: - action_type = GTK_TYPE_ACTION; - break; - case GTK_ACTION_TOGGLE: + if (entries[i].is_toggle) action_type = GTK_TYPE_TOGGLE_ACTION; - break; - case GTK_ACTION_RADIO: - action_type = GTK_TYPE_RADIO_ACTION; - break; - default: - g_warning ("unsupported action type"); + else action_type = GTK_TYPE_ACTION; - } if (translate_func) { @@ -342,27 +360,10 @@ gtk_action_group_add_actions (GtkActionGroup *action_group, "stock_id", entries[i].stock_id, NULL); - if (entries[i].entry_type == GTK_ACTION_RADIO && - entries[i].extra_data != NULL) - { - GtkAction *radio_action; - GSList *group; - - radio_action = - gtk_action_group_get_action (GTK_ACTION_GROUP (action_group), - entries[i].extra_data); - if (radio_action) - { - group = gtk_radio_action_get_group (GTK_RADIO_ACTION (radio_action)); - gtk_radio_action_set_group (GTK_RADIO_ACTION (action), group); - } - else - g_warning (G_STRLOC " could not look up `%s'", entries[i].extra_data); - } - if (entries[i].callback) - g_signal_connect (action, "activate", - entries[i].callback, entries[i].user_data); + g_signal_connect_data (action, "activate", + entries[i].callback, + user_data, (GClosureNotify)destroy, 0); /* set the accel path for the menu item */ accel_path = g_strconcat ("/", action_group->private_data->name, "/", @@ -386,6 +387,114 @@ gtk_action_group_add_actions (GtkActionGroup *action_group, } } +/** + * gtk_action_group_add_radio_actions: + * @action_group: the action group + * @entries: an array of radio action descriptions + * @n_entries: the number of entries + * @on_change: the callback to connect to the changed signal + * @user_data: data to pass to the action callbacks + * + * This is a convenience routine to create a group of radio actions and + * add them to the action group. Each member of the array describes a + * radio action to create. + * + * Since: 2.4 + * + **/ +void +gtk_action_group_add_radio_actions (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data) +{ + gtk_action_group_add_radio_actions_full (action_group, + entries, n_entries, + on_change, user_data, NULL); +} + +void +gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data, + GDestroyNotify destroy) +{ + guint i; + GtkTranslateFunc translate_func; + gpointer translate_data; + GtkRadioAction *radio_action; + + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + + translate_func = action_group->private_data->translate_func; + translate_data = action_group->private_data->translate_data; + + for (i = 0; i < n_entries; i++) + { + GtkAction *action; + gchar *accel_path; + gchar *label; + gchar *tooltip; + + if (translate_func) + { + label = translate_func (entries[i].label, translate_data); + tooltip = translate_func (entries[i].tooltip, translate_data); + } + else + { + label = entries[i].label; + tooltip = entries[i].tooltip; + } + + action = g_object_new (GTK_TYPE_RADIO_ACTION, + "name", entries[i].name, + "label", label, + "tooltip", tooltip, + "stock_id", entries[i].stock_id, + "value", entries[i].value, + NULL); + + if (i == 0) + { + radio_action = GTK_RADIO_ACTION (action); + + if (on_change) + g_signal_connect_data (radio_action, "changed", + on_change, user_data, + (GClosureNotify)destroy, 0); + } + else + { + GSList *group = gtk_radio_action_get_group (radio_action); + gtk_radio_action_set_group (GTK_RADIO_ACTION (action), group); + } + + /* set the accel path for the menu item */ + accel_path = g_strconcat ("/", action_group->private_data->name, "/", + entries[i].name, NULL); + if (entries[i].accelerator) + { + guint accel_key = 0; + GdkModifierType accel_mods; + + gtk_accelerator_parse (entries[i].accelerator, &accel_key, + &accel_mods); + if (accel_key) + gtk_accel_map_add_entry (accel_path, accel_key, accel_mods); + } + + gtk_action_set_accel_path (action, accel_path); + g_free (accel_path); + + gtk_action_group_add_action (action_group, action); + g_object_unref (action); + } +} + /** * gtk_action_group_set_translate_func: * @action_group: a #GtkActionGroup @@ -431,7 +540,7 @@ dgettext_swapped (const gchar *msgid, * @domain: the translation domain to use for dgettext() calls * * Sets the translation domain and uses dgettext() for translating the - * @label and @tooltip of #GtkActionGroupEntrys added by + * @label and @tooltip of #GtkActionEntrys added by * gtk_action_group_add_actions(). * * If you're not using gettext() for localization, see diff --git a/gtk/gtkactiongroup.h b/gtk/gtkactiongroup.h index 6036f2e0e7..f3a01b5375 100644 --- a/gtk/gtkactiongroup.h +++ b/gtk/gtkactiongroup.h @@ -43,7 +43,8 @@ typedef struct _GtkActionGroup GtkActionGroup; typedef struct _GtkActionGroupPrivate GtkActionGroupPrivate; typedef struct _GtkActionGroupClass GtkActionGroupClass; -typedef struct _GtkActionGroupEntry GtkActionGroupEntry; +typedef struct _GtkActionEntry GtkActionEntry; +typedef struct _GtkRadioActionEntry GtkRadioActionEntry; struct _GtkActionGroup { @@ -68,26 +69,28 @@ struct _GtkActionGroupClass void (*_gtk_reserved4) (void); }; -typedef enum -{ - GTK_ACTION_NORMAL, - GTK_ACTION_TOGGLE, - GTK_ACTION_RADIO -} GtkActionGroupEntryType; - -struct _GtkActionGroupEntry +struct _GtkActionEntry { gchar *name; - gchar *label; gchar *stock_id; + gchar *label; gchar *accelerator; gchar *tooltip; GCallback callback; - gpointer user_data; - GtkActionGroupEntryType entry_type; - gchar *extra_data; + gboolean is_toggle; +}; + +struct _GtkRadioActionEntry +{ + gchar *name; + gchar *stock_id; + gchar *label; + gchar *accelerator; + gchar *tooltip; + + gint value; }; GType gtk_action_group_get_type (void); @@ -103,9 +106,26 @@ void gtk_action_group_add_action (GtkActionGroup *action_grou void gtk_action_group_remove_action (GtkActionGroup *action_group, GtkAction *action); -void gtk_action_group_add_actions (GtkActionGroup *action_group, - GtkActionGroupEntry *entries, - guint n_entries); +void gtk_action_group_add_actions (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data); +void gtk_action_group_add_radio_actions (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data); +void gtk_action_group_add_actions_full (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data, + GDestroyNotify destroy); +void gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data, + GDestroyNotify destroy); void gtk_action_group_set_translate_func (GtkActionGroup *action_group, GtkTranslateFunc func, diff --git a/gtk/gtkradioaction.c b/gtk/gtkradioaction.c index e0ea5f1f9b..52a03d36a4 100644 --- a/gtk/gtkradioaction.c +++ b/gtk/gtkradioaction.c @@ -31,17 +31,43 @@ #include #include "gtkradioaction.h" +#include "gtkradiomenuitem.h" #include "gtktoggleactionprivate.h" +#include "gtkintl.h" #define GTK_RADIO_ACTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RADIO_ACTION, GtkRadioActionPrivate)) struct _GtkRadioActionPrivate { GSList *group; + gint value; }; -static void gtk_radio_action_init (GtkRadioAction *action); -static void gtk_radio_action_class_init (GtkRadioActionClass *class); +enum +{ + CHANGED, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_VALUE +}; + +static void gtk_radio_action_init (GtkRadioAction *action); +static void gtk_radio_action_class_init (GtkRadioActionClass *class); +static void gtk_radio_action_finalize (GObject *object); +static void gtk_radio_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_radio_action_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gtk_radio_action_activate (GtkAction *action); + GType gtk_radio_action_get_type (void) @@ -71,10 +97,8 @@ gtk_radio_action_get_type (void) return type; } -static void gtk_radio_action_finalize (GObject *object); -static void gtk_radio_action_activate (GtkAction *action); - static GObjectClass *parent_class = NULL; +static guint radio_action_signals[LAST_SIGNAL] = { 0 }; static void gtk_radio_action_class_init (GtkRadioActionClass *klass) @@ -87,9 +111,51 @@ gtk_radio_action_class_init (GtkRadioActionClass *klass) action_class = GTK_ACTION_CLASS (klass); gobject_class->finalize = gtk_radio_action_finalize; + gobject_class->set_property = gtk_radio_action_set_property; + gobject_class->get_property = gtk_radio_action_get_property; action_class->activate = gtk_radio_action_activate; + /** + * GtkRadioAction:value: + * + * The value is an arbitrary integer which can be used as a + * convenient way to determine which action in the group is + * currently active in an ::activate or ::changed signal handler. + * See gtk_radio_action_get_current_value() and #GtkRadioActionEntry + * for convenient ways to get and set this property. + * + * Since: 2.4 + */ + g_object_class_install_property (gobject_class, + PROP_VALUE, + g_param_spec_int ("value", + _("The value"), + _("The value returned by gtk_radio_action_get_current_value() when this action is the current action of its group."), + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + /** + * GtkRadioAction::changed: + * @action: the action on which the signal is emitted + * @current: the member of @actions group which has just been activated + * + * The ::changed signal is emitted on every member of a radio group when the + * active member is changed. The signal gets emitted after the ::activate signals + * for the previous and current active members. + * + * Since: 2.4 + */ + radio_action_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (GtkRadioActionClass, changed), NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_RADIO_ACTION); + g_type_class_add_private (gobject_class, sizeof (GtkRadioActionPrivate)); } @@ -98,6 +164,7 @@ gtk_radio_action_init (GtkRadioAction *action) { action->private_data = GTK_RADIO_ACTION_GET_PRIVATE (action); action->private_data->group = g_slist_prepend (NULL, action); + action->private_data->value = 0; } static void @@ -124,6 +191,48 @@ gtk_radio_action_finalize (GObject *object) (* parent_class->finalize) (object); } +static void +gtk_radio_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkRadioAction *radio_action; + + radio_action = GTK_RADIO_ACTION (object); + + switch (prop_id) + { + case PROP_VALUE: + radio_action->private_data->value = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_radio_action_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkRadioAction *radio_action; + + radio_action = GTK_RADIO_ACTION (object); + + switch (prop_id) + { + case PROP_VALUE: + g_value_set_int (value, radio_action->private_data->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gtk_radio_action_activate (GtkAction *action) { @@ -167,6 +276,15 @@ gtk_radio_action_activate (GtkAction *action) break; } } + + tmp_list = radio_action->private_data->group; + while (tmp_list) + { + tmp_action = tmp_list->data; + tmp_list = tmp_list->next; + + g_signal_emit (tmp_action, radio_action_signals[CHANGED], 0, radio_action); + } } gtk_toggle_action_toggled (toggle_action); @@ -238,3 +356,35 @@ gtk_radio_action_set_group (GtkRadioAction *action, gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); } } + +/** + * gtk_radio_action_get_current_value: + * @action: a #GtkRadioAction + * + * Obtains the value property of the the currently active member of + * the group to which @action belongs. + * + * Return value: The value of the currently active group member + * + * Since: 2.4 + **/ +gint +gtk_radio_action_get_current_value (GtkRadioAction *action) +{ + GSList *slist; + + g_return_val_if_fail (GTK_IS_RADIO_ACTION (action), 0); + + if (action->private_data->group) + { + for (slist = action->private_data->group; slist; slist = slist->next) + { + GtkToggleAction *toggle_action = slist->data; + + if (toggle_action->private_data->active) + return GTK_RADIO_ACTION (toggle_action)->private_data->value; + } + } + + return action->private_data->value; +} diff --git a/gtk/gtkradioaction.h b/gtk/gtkradioaction.h index 51db941106..bfeba215e4 100644 --- a/gtk/gtkradioaction.h +++ b/gtk/gtkradioaction.h @@ -56,6 +56,8 @@ struct _GtkRadioActionClass { GtkToggleActionClass parent_class; + void (* changed) (GtkRadioAction *action, GtkRadioAction *current); + /* Padding for future expansion */ void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); @@ -63,11 +65,11 @@ struct _GtkRadioActionClass void (*_gtk_reserved4) (void); }; -GType gtk_radio_action_get_type (void); - -GSList *gtk_radio_action_get_group (GtkRadioAction *action); -void gtk_radio_action_set_group (GtkRadioAction *action, - GSList *group); +GType gtk_radio_action_get_type (void); +GSList *gtk_radio_action_get_group (GtkRadioAction *action); +void gtk_radio_action_set_group (GtkRadioAction *action, + GSList *group); +gint gtk_radio_action_get_current_value (GtkRadioAction *action); #endif /* __GTK_RADIO_ACTION_H__ */ diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index adaac5ed8d..5ead9f7045 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -3001,7 +3001,7 @@ gtk_toolbar_append_element (GtkToolbar *toolbar, * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element. * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine * the radio group for the new element. In all other cases, @widget must - * *be %NULL. + * be %NULL. * * Return value: the new toolbar element as a #GtkWidget. **/ diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c index 3932b8e3ba..cc0199f8d9 100644 --- a/gtk/gtkuimanager.c +++ b/gtk/gtkuimanager.c @@ -51,7 +51,7 @@ typedef enum GTK_UI_MANAGER_TOOLBAR, GTK_UI_MANAGER_MENU_PLACEHOLDER, GTK_UI_MANAGER_TOOLBAR_PLACEHOLDER, - GTK_UI_MANAGER_POPUPS, + GTK_UI_MANAGER_POPUP, GTK_UI_MANAGER_MENUITEM, GTK_UI_MANAGER_TOOLITEM, GTK_UI_MANAGER_SEPARATOR, @@ -215,9 +215,6 @@ gtk_ui_manager_init (GtkUIManager *self) node = get_child_node (self, NULL, "ui", 4, GTK_UI_MANAGER_ROOT, TRUE, FALSE); gtk_ui_manager_node_prepend_ui_reference (NODE_INFO (node), merge_id, 0); - node = get_child_node (self, self->private_data->root_node, "popups", 6, - GTK_UI_MANAGER_POPUPS, TRUE, FALSE); - gtk_ui_manager_node_prepend_ui_reference (NODE_INFO (node), merge_id, 0); } @@ -333,8 +330,9 @@ gtk_ui_manager_get_accel_group (GtkUIManager *self) * * Looks up a widget by following a path. The path consists of the names specified * in the XML description of the UI. separated by '/'. Elements which don't have - * a name attribute in the XML (e.g. <popups>) can be addressed by their - * XML element name (e.g. "popups"). + * a name attribute in the XML (e.g. <popup>) can be addressed by their + * XML element name (e.g. "popup"). The root element (<ui>) can be omitted in + * the path. * * Return value: the widget found by following the path, or %NULL if no widget * was found. @@ -535,7 +533,6 @@ typedef enum STATE_ROOT, STATE_MENU, STATE_TOOLBAR, - STATE_POPUPS, STATE_MENUITEM, STATE_TOOLITEM, STATE_END @@ -567,15 +564,15 @@ start_element_handler (GMarkupParseContext *context, gint i; const gchar *node_name; + const gchar *action; GQuark action_quark; gboolean top; gboolean raise_error = TRUE; gchar *error_attr = NULL; - /* work out a name for this node. Either the name attribute, or - * element name */ - node_name = element_name; + node_name = NULL; + action = NULL; action_quark = 0; top = FALSE; for (i = 0; attribute_names[i] != NULL; i++) @@ -586,6 +583,7 @@ start_element_handler (GMarkupParseContext *context, } else if (!strcmp (attribute_names[i], "action")) { + action = attribute_values[i]; action_quark = g_quark_from_string (attribute_values[i]); } else if (!strcmp (attribute_names[i], "pos")) @@ -593,9 +591,16 @@ start_element_handler (GMarkupParseContext *context, top = !strcmp (attribute_values[i], "top"); } } - /* if no action, then set it to the node's name */ - if (action_quark == 0) - action_quark = g_quark_from_string (node_name); + + /* Work out a name for this node. Either the name attribute, or + * the action, or the element name */ + if (node_name == NULL) + { + if (action != NULL) + node_name = action; + else + node_name = element_name; + } switch (element_name[0]) { @@ -663,26 +668,12 @@ start_element_handler (GMarkupParseContext *context, } break; case 'p': - if (ctx->state == STATE_ROOT && !strcmp (element_name, "popups")) - { - ctx->state = STATE_POPUPS; - ctx->current = get_child_node (self, ctx->current, - node_name, strlen (node_name), - GTK_UI_MANAGER_POPUPS, - TRUE, FALSE); - - gtk_ui_manager_node_prepend_ui_reference (NODE_INFO (ctx->current), - ctx->merge_id, action_quark); - NODE_INFO (ctx->current)->dirty = TRUE; - - raise_error = FALSE; - } - else if (ctx->state == STATE_POPUPS && !strcmp (element_name, "popup")) + if (ctx->state == STATE_ROOT && !strcmp (element_name, "popup")) { ctx->state = STATE_MENU; ctx->current = get_child_node (self, ctx->current, node_name, strlen (node_name), - GTK_UI_MANAGER_MENU, + GTK_UI_MANAGER_POPUP, TRUE, FALSE); if (NODE_INFO (ctx->current)->action_name == 0) NODE_INFO (ctx->current)->action_name = action_quark; @@ -823,10 +814,8 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_MENU: ctx->current = ctx->current->parent; - if (NODE_INFO (ctx->current)->type == GTK_UI_MANAGER_ROOT) /* menubar */ + if (NODE_INFO (ctx->current)->type == GTK_UI_MANAGER_ROOT) ctx->state = STATE_ROOT; - else if (NODE_INFO (ctx->current)->type == GTK_UI_MANAGER_POPUPS) /* popup */ - ctx->state = STATE_POPUPS; /* else, stay in STATE_MENU state */ break; case STATE_TOOLBAR: @@ -837,10 +826,6 @@ end_element_handler (GMarkupParseContext *context, ctx->state = STATE_ROOT; /* else, stay in STATE_TOOLBAR state */ break; - case STATE_POPUPS: - ctx->current = ctx->current->parent; - ctx->state = STATE_ROOT; - break; case STATE_MENUITEM: ctx->state = STATE_MENU; break; @@ -1089,6 +1074,7 @@ find_menu_position (GNode *node, pos = 0; break; case GTK_UI_MANAGER_MENU: + case GTK_UI_MANAGER_POPUP: menushell = NODE_INFO (parent)->proxy; if (GTK_IS_MENU_ITEM (menushell)) menushell = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menushell)); @@ -1281,61 +1267,58 @@ update_node (GtkUIManager *self, g_signal_emit (self, merge_signals[ADD_WIDGET], 0, info->proxy); } break; + case GTK_UI_MANAGER_POPUP: + if (info->proxy == NULL) + { + info->proxy = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (info->proxy), + self->private_data->accel_group); + } + break; case GTK_UI_MANAGER_MENU: - if (NODE_INFO (node->parent)->type == GTK_UI_MANAGER_POPUPS) - { - if (info->proxy == NULL) - { - GtkWidget *menu; - menu = gtk_menu_new (); - gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group); - info->proxy = menu; - } - } - else - { - GtkWidget *prev_submenu = NULL; - /* remove the proxy if it is of the wrong type ... */ - if (info->proxy && G_OBJECT_TYPE (info->proxy) != - GTK_ACTION_GET_CLASS (info->action)->menu_item_type) - { - prev_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy)); - if (prev_submenu) - { - g_object_ref (prev_submenu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),NULL); - } - gtk_container_remove (GTK_CONTAINER (info->proxy->parent), - info->proxy); - info->proxy = NULL; - } - /* create proxy if needed ... */ - if (info->proxy == NULL) - { - GtkWidget *menushell; - gint pos; - - if (find_menu_position (node, &menushell, &pos)) - { - GtkWidget *menu; - info->proxy = gtk_action_create_menu_item (info->action); - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu); - gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos); - } - } - else - { - gtk_action_connect_proxy (info->action, info->proxy); - } - if (prev_submenu) - { - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), - prev_submenu); - g_object_unref (prev_submenu); - } - } + { + GtkWidget *prev_submenu = NULL; + /* remove the proxy if it is of the wrong type ... */ + if (info->proxy && G_OBJECT_TYPE (info->proxy) != + GTK_ACTION_GET_CLASS (info->action)->menu_item_type) + { + prev_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy)); + if (prev_submenu) + { + g_object_ref (prev_submenu); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),NULL); + } + gtk_container_remove (GTK_CONTAINER (info->proxy->parent), + info->proxy); + info->proxy = NULL; + } + /* create proxy if needed ... */ + if (info->proxy == NULL) + { + GtkWidget *menushell; + gint pos; + + if (find_menu_position (node, &menushell, &pos)) + { + GtkWidget *menu; + info->proxy = gtk_action_create_menu_item (info->action); + menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu); + gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group); + gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos); + } + } + else + { + gtk_action_connect_proxy (info->action, info->proxy); + } + if (prev_submenu) + { + gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), + prev_submenu); + g_object_unref (prev_submenu); + } + } break; case GTK_UI_MANAGER_UNDECIDED: g_warning ("found 'undecided node!"); @@ -1414,8 +1397,6 @@ update_node (GtkUIManager *self, } } break; - case GTK_UI_MANAGER_POPUPS: - break; case GTK_UI_MANAGER_MENUITEM: /* remove the proxy if it is of the wrong type ... */ if (info->proxy && G_OBJECT_TYPE (info->proxy) != @@ -1609,15 +1590,14 @@ static const gchar *open_tag_format[] = { "%*s\n", "%*s\n", "%*s\n", - "%*s\n", + "%*s\n", "%*s\n", "%*s\n", "%*s\n", - "%*s\n", + "%*s\n", "%*s\n", "%*s\n", "%*s\n", - "%*s\n" }; static const gchar *close_tag_format[] = { @@ -1628,11 +1608,10 @@ static const gchar *close_tag_format[] = { "%*s\n", "%*s\n", "%*s\n", - "%*s\n", + "%*s\n", "", "", "", - "%*s\n" }; static void @@ -1643,16 +1622,10 @@ print_node (GtkUIManager *self, { GtkUIManagerNode *mnode; GNode *child; - guint type; mnode = node->data; - if (mnode->type == GTK_UI_MANAGER_MENU && - NODE_INFO (node->parent)->type == GTK_UI_MANAGER_POPUPS) - type = GTK_UI_MANAGER_SEPARATOR + 1; - else - type = mnode->type; - g_string_append_printf (buffer, open_tag_format[type], + g_string_append_printf (buffer, open_tag_format[mnode->type], indent_level, "", mnode->name, g_quark_to_string (mnode->action_name)); @@ -1660,7 +1633,7 @@ print_node (GtkUIManager *self, for (child = node->children; child != NULL; child = child->next) print_node (self, child, indent_level + 2, buffer); - g_string_append_printf (buffer, close_tag_format[type], + g_string_append_printf (buffer, close_tag_format[mnode->type], indent_level, ""); } diff --git a/tests/merge-1.ui b/tests/merge-1.ui index 30fac10f8c..55b3455592 100644 --- a/tests/merge-1.ui +++ b/tests/merge-1.ui @@ -1,10 +1,10 @@ - + - + diff --git a/tests/merge-2.ui b/tests/merge-2.ui index 8a059298d1..5cf2f9ce10 100644 --- a/tests/merge-2.ui +++ b/tests/merge-2.ui @@ -1,12 +1,12 @@ - + - + @@ -16,12 +16,10 @@ - - - - - - - - + + + + + + diff --git a/tests/merge-3.ui b/tests/merge-3.ui index 9fce79cb21..53ea413088 100644 --- a/tests/merge-3.ui +++ b/tests/merge-3.ui @@ -1,16 +1,22 @@ - + + + + + + + - + - + diff --git a/tests/testactions.c b/tests/testactions.c index 9a3ae08200..cae4f0ef91 100644 --- a/tests/testactions.c +++ b/tests/testactions.c @@ -1,11 +1,6 @@ #undef GTK_DISABLE_DEPRECATED #include -#ifndef _ -# define _(String) (String) -# define N_(String) (String) -#endif - static GtkActionGroup *action_group = NULL; static GtkToolbar *toolbar = NULL; @@ -28,6 +23,18 @@ toggle_action (GtkAction *action) gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); } + +static void +radio_action (GtkAction *action) +{ + const gchar *name = gtk_action_get_name (action); + const gchar *typename = G_OBJECT_TYPE_NAME (action); + + g_message ("Action %s (type=%s) activated (active=%d) (value %d)", name, typename, + gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)), + gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action))); +} + static void toggle_cnp_actions (GtkAction *action) { @@ -43,9 +50,9 @@ toggle_cnp_actions (GtkAction *action) action = gtk_action_group_get_action (action_group, "toggle-cnp"); if (sensitive) - g_object_set (action, "label", _("Disable Cut and paste ops"), NULL); + g_object_set (action, "label", "Disable Cut and paste ops", NULL); else - g_object_set (action, "label", _("Enable Cut and paste ops"), NULL); + g_object_set (action, "label", "Enable Cut and paste ops", NULL); } static void @@ -67,77 +74,74 @@ toolbar_style (GtkAction *action, } static void -toolbar_size (GtkAction *action, - gpointer user_data) +toolbar_size_small (GtkAction *action) { - GtkIconSize size; - g_return_if_fail (toolbar != NULL); - size = GPOINTER_TO_INT (user_data); - gtk_toolbar_set_icon_size (toolbar, size); + gtk_toolbar_set_icon_size (toolbar, GTK_ICON_SIZE_SMALL_TOOLBAR); +} + +static void +toolbar_size_large (GtkAction *action) +{ + g_return_if_fail (toolbar != NULL); + + gtk_toolbar_set_icon_size (toolbar, GTK_ICON_SIZE_LARGE_TOOLBAR); } /* convenience functions for declaring actions */ -static GtkActionGroupEntry entries[] = { - { "Menu1Action", N_("Menu _1"), NULL, NULL, NULL, NULL, NULL }, - { "Menu2Action", N_("Menu _2"), NULL, NULL, NULL, NULL, NULL }, +static GtkActionEntry entries[] = { + { "Menu1Action", NULL, "Menu _1" }, + { "Menu2Action", NULL, "Menu _2" }, - { "cut", N_("C_ut"), GTK_STOCK_CUT, "X", - N_("Cut the selected text to the clipboard"), - G_CALLBACK (activate_action), NULL }, - { "copy", N_("_Copy"), GTK_STOCK_COPY, "C", - N_("Copy the selected text to the clipboard"), - G_CALLBACK (activate_action), NULL }, - { "paste", N_("_Paste"), GTK_STOCK_PASTE, "V", - N_("Paste the text from the clipboard"), - G_CALLBACK (activate_action), NULL }, - { "bold", N_("_Bold"), GTK_STOCK_BOLD, "B", - N_("Change to bold face"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_TOGGLE }, - - { "justify-left", N_("_Left"), GTK_STOCK_JUSTIFY_LEFT, "L", - N_("Left justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO }, - { "justify-center", N_("C_enter"), GTK_STOCK_JUSTIFY_CENTER, "E", - N_("Center justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, "justify-left" }, - { "justify-right", N_("_Right"), GTK_STOCK_JUSTIFY_RIGHT, "R", - N_("Right justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, "justify-left" }, - { "justify-fill", N_("_Fill"), GTK_STOCK_JUSTIFY_FILL, "J", - N_("Fill justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, "justify-left" }, - { "quit", NULL, GTK_STOCK_QUIT, "Q", - N_("Quit the application"), - G_CALLBACK (gtk_main_quit), NULL }, - { "toggle-cnp", N_("Enable Cut/Copy/Paste"), NULL, NULL, - N_("Change the sensitivity of the cut, copy and paste actions"), - G_CALLBACK (toggle_cnp_actions), NULL, GTK_ACTION_TOGGLE }, - { "customise-accels", N_("Customise _Accels"), NULL, NULL, - N_("Customise keyboard shortcuts"), - G_CALLBACK (show_accel_dialog), NULL }, - { "toolbar-icons", N_("Icons"), NULL, NULL, - NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER (GTK_TOOLBAR_ICONS), - GTK_ACTION_RADIO, NULL }, - { "toolbar-text", N_("Text"), NULL, NULL, - NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER (GTK_TOOLBAR_TEXT), - GTK_ACTION_RADIO, "toolbar-icons" }, - { "toolbar-both", N_("Both"), NULL, NULL, - NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER (GTK_TOOLBAR_BOTH), - GTK_ACTION_RADIO, "toolbar-icons" }, - { "toolbar-both-horiz", N_("Both Horizontal"), NULL, NULL, - NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER(GTK_TOOLBAR_BOTH_HORIZ), - GTK_ACTION_RADIO, "toolbar-icons" }, - { "toolbar-small-icons", N_("Small Icons"), NULL, NULL, - NULL, - G_CALLBACK (toolbar_size), GINT_TO_POINTER (GTK_ICON_SIZE_SMALL_TOOLBAR) }, - { "toolbar-large-icons", N_("Large Icons"), NULL, NULL, - NULL, - G_CALLBACK (toolbar_size), GINT_TO_POINTER (GTK_ICON_SIZE_LARGE_TOOLBAR) }, + { "cut", GTK_STOCK_CUT, "C_ut", "X", + "Cut the selected text to the clipboard", G_CALLBACK (activate_action) }, + { "copy", GTK_STOCK_COPY, "_Copy", "C", + "Copy the selected text to the clipboard", G_CALLBACK (activate_action) }, + { "paste", GTK_STOCK_PASTE, "_Paste", "V", + "Paste the text from the clipboard", G_CALLBACK (activate_action) }, + { "bold", GTK_STOCK_BOLD, "_Bold", "B", + "Change to bold face", G_CALLBACK (toggle_action), TRUE }, + { "quit", GTK_STOCK_QUIT, NULL, "Q", + "Quit the application", G_CALLBACK (gtk_main_quit) }, + { "toggle-cnp", NULL, "Enable Cut/Copy/Paste", NULL, + "Change the sensitivity of the cut, copy and paste actions", G_CALLBACK (toggle_cnp_actions), TRUE }, + { "customise-accels", NULL, "Customise _Accels", NULL, + "Customise keyboard shortcuts", G_CALLBACK (show_accel_dialog) }, + { "toolbar-small-icons", NULL, "Small Icons", NULL, + NULL, G_CALLBACK (toolbar_size_small) }, + { "toolbar-large-icons", NULL, "Large Icons", NULL, + NULL, G_CALLBACK (toolbar_size_large) } }; static guint n_entries = G_N_ELEMENTS (entries); +enum { + JUSTIFY_LEFT, + JUSTIFY_CENTER, + JUSTIFY_RIGHT, + JUSTIFY_FILL +}; + +static GtkRadioActionEntry justify_entries[] = { + { "justify-left", GTK_STOCK_JUSTIFY_LEFT, "_Left", "L", + "Left justify the text", JUSTIFY_LEFT }, + { "justify-center", GTK_STOCK_JUSTIFY_CENTER, "C_enter", "E", + "Center justify the text", JUSTIFY_CENTER }, + { "justify-right", GTK_STOCK_JUSTIFY_RIGHT, "_Right", "R", + "Right justify the text", JUSTIFY_RIGHT }, + { "justify-fill", GTK_STOCK_JUSTIFY_FILL, "_Fill", "J", + "Fill justify the text", JUSTIFY_FILL } +}; +static guint n_justify_entries = G_N_ELEMENTS (justify_entries); + +static GtkRadioActionEntry toolbar_entries[] = { + { "toolbar-icons", NULL, "Icons", NULL, NULL, GTK_TOOLBAR_ICONS }, + { "toolbar-text", NULL, "Text", NULL, NULL, GTK_TOOLBAR_TEXT }, + { "toolbar-both", NULL, "Both", NULL, NULL, GTK_TOOLBAR_BOTH }, + { "toolbar-both-horiz", NULL, "Both Horizontal", NULL, NULL, GTK_TOOLBAR_BOTH_HORIZ } +}; +static guint n_toolbar_entries = G_N_ELEMENTS (toolbar_entries); + /* XML description of the menus for the test app. The parser understands * a subset of the Bonobo UI XML format, and uses GMarkup for parsing */ static const gchar *ui_info = @@ -250,9 +254,14 @@ main (int argc, char **argv) gtk_accel_map_load ("accels"); action_group = gtk_action_group_new ("TestActions"); - gtk_action_group_add_actions (action_group, entries, n_entries); + gtk_action_group_add_actions (action_group, entries, n_entries, NULL); + gtk_action_group_add_radio_actions (action_group, justify_entries, n_justify_entries, + G_CALLBACK (radio_action), NULL); + gtk_action_group_add_radio_actions (action_group, toolbar_entries, n_toolbar_entries, + G_CALLBACK (radio_action), NULL); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (action_group, "toggle-cnp")), TRUE); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (action_group, "toggle-cnp")), + FALSE); create_window (action_group); diff --git a/tests/testmerge.c b/tests/testmerge.c index 2bfd78601b..0b9e800716 100644 --- a/tests/testmerge.c +++ b/tests/testmerge.c @@ -2,11 +2,6 @@ #include #include -#ifndef _ -# define _(String) (String) -# define N_(String) (String) -#endif - struct { const gchar *filename; guint merge_id; } merge_ids[] = { { "merge-1.ui", 0 }, { "merge-2.ui", 0 }, @@ -44,43 +39,54 @@ toggle_action (GtkAction *action) } -static GtkActionGroupEntry entries[] = { - { "StockFileMenuAction", N_("_File"), NULL, NULL, NULL, NULL, NULL }, - { "StockEditMenuAction", N_("_Edit"), NULL, NULL, NULL, NULL, NULL }, - { "StockHelpMenuAction", N_("_Help"), NULL, NULL, NULL, NULL, NULL }, - { "Test", N_("Test"), NULL, NULL, NULL, NULL, NULL }, +static void +radio_action_changed (GtkAction *action, GtkRadioAction *current) +{ + g_message ("Action %s (type=%s) activated (active=%d) (value %d)", + gtk_action_get_name (GTK_ACTION (current)), + G_OBJECT_TYPE_NAME (GTK_ACTION (current)), + gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (current)), + gtk_radio_action_get_current_value (current)); +} - { "NewAction", NULL, GTK_STOCK_NEW, "n", NULL, - G_CALLBACK (activate_action), NULL }, - { "New2Action", NULL, GTK_STOCK_NEW, "m", NULL, - G_CALLBACK (activate_action), NULL }, - { "OpenAction", NULL, GTK_STOCK_OPEN, "o", NULL, - G_CALLBACK (activate_action), NULL }, - { "QuitAction", NULL, GTK_STOCK_QUIT, "q", NULL, - G_CALLBACK (gtk_main_quit), NULL }, - { "CutAction", NULL, GTK_STOCK_CUT, "x", NULL, - G_CALLBACK (activate_action), NULL }, - { "CopyAction", NULL, GTK_STOCK_COPY, "c", NULL, - G_CALLBACK (activate_action), NULL }, - { "PasteAction", NULL, GTK_STOCK_PASTE, "v", NULL, - G_CALLBACK (activate_action), NULL }, - { "justify-left", NULL, GTK_STOCK_JUSTIFY_LEFT, "L", - N_("Left justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, NULL }, - { "justify-center", NULL, GTK_STOCK_JUSTIFY_CENTER, "E", - N_("Center justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, "justify-left" }, - { "justify-right", NULL, GTK_STOCK_JUSTIFY_RIGHT, "R", - N_("Right justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, "justify-left" }, - { "justify-fill", NULL, GTK_STOCK_JUSTIFY_FILL, "J", - N_("Fill justify the text"), - G_CALLBACK (toggle_action), NULL, GTK_ACTION_RADIO, "justify-left" }, - { "AboutAction", N_("_About"), NULL, NULL, NULL, - G_CALLBACK (activate_action), NULL }, + +static GtkActionEntry entries[] = { + { "FileMenuAction", NULL, "_File" }, + { "EditMenuAction", NULL, "_Edit" }, + { "HelpMenuAction", NULL, "_Help" }, + { "JustifyMenuAction", NULL, "_Justify" }, + { "Test", NULL, "Test" }, + + { "QuitAction", GTK_STOCK_QUIT, NULL, "q", NULL, G_CALLBACK (gtk_main_quit) }, + { "NewAction", GTK_STOCK_NEW, NULL, "n", NULL, G_CALLBACK (activate_action) }, + { "New2Action", GTK_STOCK_NEW, NULL, "m", NULL, G_CALLBACK (activate_action) }, + { "OpenAction", GTK_STOCK_OPEN, NULL, "o", NULL, G_CALLBACK (activate_action) }, + { "CutAction", GTK_STOCK_CUT, NULL, "x", NULL, G_CALLBACK (activate_action) }, + { "CopyAction", GTK_STOCK_COPY, NULL, "c", NULL, G_CALLBACK (activate_action) }, + { "PasteAction", GTK_STOCK_PASTE, NULL, "v", NULL, G_CALLBACK (activate_action) }, + { "AboutAction", NULL, "_About", NULL, NULL, G_CALLBACK (activate_action) }, }; static guint n_entries = G_N_ELEMENTS (entries); +enum { + JUSTIFY_LEFT, + JUSTIFY_CENTER, + JUSTIFY_RIGHT, + JUSTIFY_FILL +}; + +static GtkRadioActionEntry radio_entries[] = { + { "justify-left", GTK_STOCK_JUSTIFY_LEFT, NULL, "L", + "Left justify the text", JUSTIFY_LEFT }, + { "justify-center", GTK_STOCK_JUSTIFY_CENTER, NULL, "E", + "Center justify the text", JUSTIFY_CENTER }, + { "justify-right", GTK_STOCK_JUSTIFY_RIGHT, NULL, "R", + "Right justify the text", JUSTIFY_RIGHT }, + { "justify-fill", GTK_STOCK_JUSTIFY_FILL, NULL, "J", + "Fill justify the text", JUSTIFY_FILL }, +}; +static guint n_radio_entries = G_N_ELEMENTS (radio_entries); + static void add_widget (GtkUIManager *merge, GtkWidget *widget, @@ -322,7 +328,7 @@ area_press (GtkWidget *drawing_area, if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { - GtkWidget *menu = gtk_ui_manager_get_widget (merge, "/popups/FileMenu"); + GtkWidget *menu = gtk_ui_manager_get_widget (merge, "/FileMenu"); if (GTK_IS_MENU (menu)) { @@ -349,7 +355,9 @@ main (int argc, char **argv) gtk_init (&argc, &argv); action_group = gtk_action_group_new ("TestActions"); - gtk_action_group_add_actions (action_group, entries, n_entries); + gtk_action_group_add_actions (action_group, entries, n_entries, NULL); + gtk_action_group_add_radio_actions (action_group, radio_entries, n_radio_entries, + G_CALLBACK (radio_action_changed), NULL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);