diff options
author | Timm Bäder <mail@baedert.org> | 2016-10-16 19:28:11 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-10-18 00:34:41 +0200 |
commit | d963ede6685368d9c5ec393556194116bd9708af (patch) | |
tree | a99496a727f8b2d4ffed4abc36a7bcee089fa7c9 | |
parent | 62b2949fa27660e6cfae00229acf7607341a28aa (diff) | |
download | gtk+-d963ede6685368d9c5ec393556194116bd9708af.tar.gz |
Remove GtkUIManager
-rw-r--r-- | docs/reference/gtk/gtk4-sections.txt | 36 | ||||
-rw-r--r-- | gtk/deprecated/Makefile.inc | 6 | ||||
-rw-r--r-- | gtk/deprecated/gtkuimanager.c | 3190 | ||||
-rw-r--r-- | gtk/deprecated/gtkuimanager.h | 185 | ||||
-rw-r--r-- | gtk/gtk.h | 1 | ||||
-rw-r--r-- | gtk/gtkaccelgroup.c | 5 | ||||
-rw-r--r-- | gtk/gtkaccelmap.c | 4 | ||||
-rw-r--r-- | gtk/gtkbuildable.h | 4 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 8 | ||||
-rw-r--r-- | tests/Makefile.am | 8 | ||||
-rw-r--r-- | tests/testactions.c | 160 | ||||
-rw-r--r-- | tests/testmerge.c | 678 | ||||
-rw-r--r-- | testsuite/gtk/action.c | 6 | ||||
-rw-r--r-- | testsuite/gtk/builder.c | 80 | ||||
-rw-r--r-- | testsuite/gtk/notify.c | 3 |
15 files changed, 14 insertions, 4360 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 1dbf54db93..313fe3f6f5 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -2092,42 +2092,6 @@ gtk_menu_item_get_type </SECTION> <SECTION> -<FILE>gtkuimanager</FILE> -<TITLE>GtkUIManager</TITLE> -GtkUIManager -gtk_ui_manager_new -gtk_ui_manager_set_add_tearoffs -gtk_ui_manager_get_add_tearoffs -gtk_ui_manager_insert_action_group -gtk_ui_manager_remove_action_group -gtk_ui_manager_get_action_groups -gtk_ui_manager_get_accel_group -gtk_ui_manager_get_widget -gtk_ui_manager_get_toplevels -gtk_ui_manager_get_action -gtk_ui_manager_add_ui_from_resource -gtk_ui_manager_add_ui_from_string -gtk_ui_manager_add_ui_from_file -gtk_ui_manager_new_merge_id -GtkUIManagerItemType -gtk_ui_manager_add_ui -gtk_ui_manager_remove_ui -gtk_ui_manager_get_ui -gtk_ui_manager_ensure_update -<SUBSECTION Standard> -GTK_TYPE_UI_MANAGER -GTK_UI_MANAGER -GTK_UI_MANAGER_CLASS -GTK_IS_UI_MANAGER -GTK_IS_UI_MANAGER_CLASS -GTK_UI_MANAGER_GET_CLASS -GtkUIManagerClass -<SUBSECTION Private> -gtk_ui_manager_get_type -GtkUIManagerPrivate -</SECTION> - -<SECTION> <FILE>gtkmenushell</FILE> <TITLE>GtkMenuShell</TITLE> GtkMenuShell diff --git a/gtk/deprecated/Makefile.inc b/gtk/deprecated/Makefile.inc index b7ae68a5be..c3809b479e 100644 --- a/gtk/deprecated/Makefile.inc +++ b/gtk/deprecated/Makefile.inc @@ -3,8 +3,7 @@ deprecated_h_sources = \ deprecated/gtkactiongroup.h \ deprecated/gtkgradient.h \ deprecated/gtkrecentaction.h \ - deprecated/gtksymboliccolor.h \ - deprecated/gtkuimanager.h + deprecated/gtksymboliccolor.h deprecated_private_h_sources = \ deprecated/gtkgradientprivate.h \ @@ -15,5 +14,4 @@ deprecated_c_sources = \ deprecated/gtkactiongroup.c \ deprecated/gtkgradient.c \ deprecated/gtkrecentaction.c \ - deprecated/gtksymboliccolor.c \ - deprecated/gtkuimanager.c + deprecated/gtksymboliccolor.c diff --git a/gtk/deprecated/gtkuimanager.c b/gtk/deprecated/gtkuimanager.c deleted file mode 100644 index 7cd61211ff..0000000000 --- a/gtk/deprecated/gtkuimanager.c +++ /dev/null @@ -1,3190 +0,0 @@ -/* - * GTK - The GIMP Toolkit - * Copyright (C) 1998, 1999 Red Hat, Inc. - * All rights reserved. - * - * This Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Author: James Henstridge <james@daa.com.au> - * - * Modified by the GTK+ Team and others 2003. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" - -#define GDK_DISABLE_DEPRECATION_WARNINGS - -#include <string.h> -#include "gtkaccellabel.h" -#include "gtkbuildable.h" -#include "gtkintl.h" -#include "gtkmarshalers.h" -#include "gtkmenu.h" -#include "gtkmenushellprivate.h" -#include "gtkmenubar.h" -#include "gtkmenutoolbutton.h" -#include "gtkseparatormenuitem.h" -#include "gtkseparatortoolitem.h" -#include "gtktoolbar.h" -#include "gtkwindow.h" -#include "gtkprivate.h" - -#include "gtkuimanager.h" - -/** - * SECTION:gtkuimanager - * @Short_description: Constructing menus and toolbars from an XML description - * @Title: GtkUIManager - * @See_also:#GtkBuilder - * - * A #GtkUIManager constructs a user interface (menus and toolbars) from - * one or more UI definitions, which reference actions from one or more - * action groups. - * - * # UI Definitions # {#XML-UI} - * - * The UI definitions are specified in an XML format which can be - * roughly described by the following DTD. - * - * > Do not confuse the GtkUIManager UI Definitions described here with - * > the similarly named [GtkBuilder UI Definitions][BUILDER-UI]. - * - * |[ - * <!ELEMENT ui (menubar|toolbar|popup|accelerator)* > - * <!ELEMENT menubar (menuitem|separator|placeholder|menu)* > - * <!ELEMENT menu (menuitem|separator|placeholder|menu)* > - * <!ELEMENT popup (menuitem|separator|placeholder|menu)* > - * <!ELEMENT toolbar (toolitem|separator|placeholder)* > - * <!ELEMENT placeholder (menuitem|toolitem|separator|placeholder|menu)* > - * <!ELEMENT menuitem EMPTY > - * <!ELEMENT toolitem (menu?) > - * <!ELEMENT separator EMPTY > - * <!ELEMENT accelerator EMPTY > - * <!ATTLIST menubar name #IMPLIED - * action #IMPLIED > - * <!ATTLIST toolbar name #IMPLIED - * action #IMPLIED > - * <!ATTLIST popup name #IMPLIED - * action #IMPLIED - * accelerators (true|false) #IMPLIED > - * <!ATTLIST placeholder name #IMPLIED - * action #IMPLIED > - * <!ATTLIST separator name #IMPLIED - * action #IMPLIED - * expand (true|false) #IMPLIED > - * <!ATTLIST menu name #IMPLIED - * action #REQUIRED - * position (top|bot) #IMPLIED > - * <!ATTLIST menuitem name #IMPLIED - * action #REQUIRED - * position (top|bot) #IMPLIED - * always-show-image (true|false) #IMPLIED > - * <!ATTLIST toolitem name #IMPLIED - * action #REQUIRED - * position (top|bot) #IMPLIED > - * <!ATTLIST accelerator name #IMPLIED - * action #REQUIRED > - * ]| - * - * There are some additional restrictions beyond those specified in the - * DTD, e.g. every toolitem must have a toolbar in its anchestry and - * every menuitem must have a menubar or popup in its anchestry. Since - * a #GMarkupParser is used to parse the UI description, it must not only - * be valid XML, but valid markup. - * - * If a name is not specified, it defaults to the action. If an action is - * not specified either, the element name is used. The name and action - * attributes must not contain “/” characters after parsing (since that - * would mess up path lookup) and must be usable as XML attributes when - * enclosed in doublequotes, thus they must not “"” characters or references - * to the " entity. - * - * # A UI definition # - * - * |[ - * <ui> - * <menubar> - * <menu name="FileMenu" action="FileMenuAction"> - * <menuitem name="New" action="New2Action" /> - * <placeholder name="FileMenuAdditions" /> - * </menu> - * <menu name="JustifyMenu" action="JustifyMenuAction"> - * <menuitem name="Left" action="justify-left"/> - * <menuitem name="Centre" action="justify-center"/> - * <menuitem name="Right" action="justify-right"/> - * <menuitem name="Fill" action="justify-fill"/> - * </menu> - * </menubar> - * <toolbar action="toolbar1"> - * <placeholder name="JustifyToolItems"> - * <separator/> - * <toolitem name="Left" action="justify-left"/> - * <toolitem name="Centre" action="justify-center"/> - * <toolitem name="Right" action="justify-right"/> - * <toolitem name="Fill" action="justify-fill"/> - * <separator/> - * </placeholder> - * </toolbar> - * </ui> - * ]| - * - * The constructed widget hierarchy is very similar to the element tree - * of the XML, with the exception that placeholders are merged into their - * parents. The correspondence of XML elements to widgets should be - * almost obvious: - * - * - menubar - * - * a #GtkMenuBar - * - * - toolbar - * - * a #GtkToolbar - * - * - popup - * - * a toplevel #GtkMenu - * - * - menu - * - * a #GtkMenu attached to a menuitem - * - * - menuitem - * - * a #GtkMenuItem subclass, the exact type depends on the action - * - * - toolitem - * - * a #GtkToolItem subclass, the exact type depends on the - * action. Note that toolitem elements may contain a menu element, - * but only if their associated action specifies a - * #GtkMenuToolButton as proxy. - * - * - separator - * - * a #GtkSeparatorMenuItem or #GtkSeparatorToolItem - * - * - accelerator - * - * a keyboard accelerator - * - * The “position” attribute determines where a constructed widget is positioned - * wrt. to its siblings in the partially constructed tree. If it is - * “top”, the widget is prepended, otherwise it is appended. - * - * # UI Merging # {#UI-Merging} - * - * The most remarkable feature of #GtkUIManager is that it can overlay a set - * of menuitems and toolitems over another one, and demerge them later. - * - * Merging is done based on the names of the XML elements. Each element is - * identified by a path which consists of the names of its anchestors, separated - * by slashes. For example, the menuitem named “Left” in the example above - * has the path `/ui/menubar/JustifyMenu/Left` and the - * toolitem with the same name has path - * `/ui/toolbar1/JustifyToolItems/Left`. - * - * # Accelerators # - * - * Every action has an accelerator path. Accelerators are installed together - * with menuitem proxies, but they can also be explicitly added with - * <accelerator> elements in the UI definition. This makes it possible to - * have accelerators for actions even if they have no visible proxies. - * - * # Smart Separators # {#Smart-Separators} - * - * The separators created by #GtkUIManager are “smart”, i.e. they do not show up - * in the UI unless they end up between two visible menu or tool items. Separators - * which are located at the very beginning or end of the menu or toolbar - * containing them, or multiple separators next to each other, are hidden. This - * is a useful feature, since the merging of UI elements from multiple sources - * can make it hard or impossible to determine in advance whether a separator - * will end up in such an unfortunate position. - * - * For separators in toolbars, you can set `expand="true"` to - * turn them from a small, visible separator to an expanding, invisible one. - * Toolitems following an expanding separator are effectively right-aligned. - * - * # Empty Menus - * - * Submenus pose similar problems to separators inconnection with merging. It is - * impossible to know in advance whether they will end up empty after merging. - * #GtkUIManager offers two ways to treat empty submenus: - * - * - make them disappear by hiding the menu item they’re attached to - * - * - add an insensitive “Empty” item - * - * The behaviour is chosen based on the “hide_if_empty” property of the action - * to which the submenu is associated. - * - * # GtkUIManager as GtkBuildable # {#GtkUIManager-BUILDER-UI} - * - * The GtkUIManager implementation of the GtkBuildable interface accepts - * GtkActionGroup objects as <child> elements in UI definitions. - * - * A GtkUIManager UI definition as described above can be embedded in - * an GtkUIManager <object> element in a GtkBuilder UI definition. - * - * The widgets that are constructed by a GtkUIManager can be embedded in - * other parts of the constructed user interface with the help of the - * “constructor” attribute. See the example below. - * - * ## An embedded GtkUIManager UI definition - * - * |[ - * <object class="GtkUIManager" id="uiman"> - * <child> - * <object class="GtkActionGroup" id="actiongroup"> - * <child> - * <object class="GtkAction" id="file"> - * <property name="label">_File</property> - * </object> - * </child> - * </object> - * </child> - * <ui> - * <menubar name="menubar1"> - * <menu action="file"> - * </menu> - * </menubar> - * </ui> - * </object> - * <object class="GtkWindow" id="main-window"> - * <child> - * <object class="GtkMenuBar" id="menubar1" constructor="uiman"/> - * </child> - * </object> - * ]| - */ - -typedef enum -{ - NODE_TYPE_UNDECIDED, - NODE_TYPE_ROOT, - NODE_TYPE_MENUBAR, - NODE_TYPE_MENU, - NODE_TYPE_TOOLBAR, - NODE_TYPE_MENU_PLACEHOLDER, - NODE_TYPE_TOOLBAR_PLACEHOLDER, - NODE_TYPE_POPUP, - NODE_TYPE_MENUITEM, - NODE_TYPE_TOOLITEM, - NODE_TYPE_SEPARATOR, - NODE_TYPE_ACCELERATOR -} NodeType; - -typedef struct _Node Node; - -struct _Node { - NodeType type; - - gchar *name; - - GQuark action_name; - GtkAction *action; - GtkWidget *proxy; - GtkWidget *extra; /* second separator for placeholders */ - - GList *uifiles; - - guint dirty : 1; - guint expand : 1; /* used for separators */ - guint popup_accels : 1; - guint always_show_image_set : 1; /* used for menu items */ - guint always_show_image : 1; /* used for menu items */ -}; - - -struct _GtkUIManagerPrivate -{ - GtkAccelGroup *accel_group; - - GNode *root_node; - GList *action_groups; - - guint last_merge_id; - - guint update_tag; -}; - -#define NODE_INFO(node) ((Node *)node->data) - -typedef struct _NodeUIReference NodeUIReference; - -struct _NodeUIReference -{ - guint merge_id; - GQuark action_quark; -}; - -static void gtk_ui_manager_finalize (GObject *object); -static void gtk_ui_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_ui_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static GtkWidget * gtk_ui_manager_real_get_widget (GtkUIManager *manager, - const gchar *path); -static GtkAction * gtk_ui_manager_real_get_action (GtkUIManager *manager, - const gchar *path); -static void queue_update (GtkUIManager *manager); -static void dirty_all_nodes (GtkUIManager *manager); -static void mark_node_dirty (GNode *node); -static GNode * get_child_node (GtkUIManager *manager, - GNode *parent, - GNode *sibling, - const gchar *childname, - gint childname_length, - NodeType node_type, - gboolean create, - gboolean top); -static GNode * get_node (GtkUIManager *manager, - const gchar *path, - NodeType node_type, - gboolean create); -static gboolean free_node (GNode *node); -static void node_prepend_ui_reference (GNode *node, - guint merge_id, - GQuark action_quark); -static void node_remove_ui_reference (GNode *node, - guint merge_id); - -/* GtkBuildable */ -static void gtk_ui_manager_buildable_init (GtkBuildableIface *iface); -static void gtk_ui_manager_buildable_add_child (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *type); -static GObject* gtk_ui_manager_buildable_construct_child (GtkBuildable *buildable, - GtkBuilder *builder, - const gchar *name); -static gboolean gtk_ui_manager_buildable_custom_tag_start (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - GMarkupParser *parser, - gpointer *data); -static void gtk_ui_manager_buildable_custom_tag_end (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer *data); - - - -enum -{ - ADD_WIDGET, - ACTIONS_CHANGED, - CONNECT_PROXY, - DISCONNECT_PROXY, - PRE_ACTIVATE, - POST_ACTIVATE, - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_UI -}; - -static guint ui_manager_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE_WITH_CODE (GtkUIManager, gtk_ui_manager, G_TYPE_OBJECT, - G_ADD_PRIVATE (GtkUIManager) - G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, - gtk_ui_manager_buildable_init)) - -static void -gtk_ui_manager_class_init (GtkUIManagerClass *klass) -{ - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = gtk_ui_manager_finalize; - gobject_class->set_property = gtk_ui_manager_set_property; - gobject_class->get_property = gtk_ui_manager_get_property; - klass->get_widget = gtk_ui_manager_real_get_widget; - klass->get_action = gtk_ui_manager_real_get_action; - - g_object_class_install_property (gobject_class, - PROP_UI, - g_param_spec_string ("ui", - P_("Merged UI definition"), - P_("An XML string describing the merged UI"), - "<ui>\n</ui>\n", - GTK_PARAM_READABLE)); - - - /** - * GtkUIManager::add-widget: - * @manager: a #GtkUIManager - * @widget: the added widget - * - * The ::add-widget signal is emitted for each generated menubar and toolbar. - * It is not emitted for generated popup menus, which can be obtained by - * gtk_ui_manager_get_widget(). - * - * Since: 2.4 - * - * Deprecated: 3.10 - */ - ui_manager_signals[ADD_WIDGET] = - g_signal_new (I_("add-widget"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (GtkUIManagerClass, add_widget), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_WIDGET); - - /** - * GtkUIManager::actions-changed: - * @manager: a #GtkUIManager - * - * The ::actions-changed signal is emitted whenever the set of actions - * changes. - * - * Since: 2.4 - * - * Deprecated: 3.10 - */ - ui_manager_signals[ACTIONS_CHANGED] = - g_signal_new (I_("actions-changed"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (GtkUIManagerClass, actions_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * GtkUIManager::connect-proxy: - * @manager: the ui manager - * @action: the action - * @proxy: the proxy - * - * The ::connect-proxy signal is emitted after connecting a proxy to - * an action in the group. - * - * This is intended for simple customizations for which a custom action - * class would be too clumsy, e.g. showing tooltips for menuitems in the - * statusbar. - * - * Since: 2.4 - * - * Deprecated: 3.10 - */ - ui_manager_signals[CONNECT_PROXY] = - g_signal_new (I_("connect-proxy"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (GtkUIManagerClass, connect_proxy), - NULL, NULL, - _gtk_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, - GTK_TYPE_ACTION, - GTK_TYPE_WIDGET); - - /** - * GtkUIManager::disconnect-proxy: - * @manager: the ui manager - * @action: the action - * @proxy: the proxy - * - * The ::disconnect-proxy signal is emitted after disconnecting a proxy - * from an action in the group. - * - * Since: 2.4 - * - * Deprecated: 3.10 - */ - ui_manager_signals[DISCONNECT_PROXY] = - g_signal_new (I_("disconnect-proxy"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (GtkUIManagerClass, disconnect_proxy), - NULL, NULL, - _gtk_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, - GTK_TYPE_ACTION, - GTK_TYPE_WIDGET); - - /** - * GtkUIManager::pre-activate: - * @manager: the ui manager - * @action: the action - * - * The ::pre-activate signal is emitted just before the @action - * is activated. - * - * This is intended for applications to get notification - * just before any action is activated. - * - * Since: 2.4 - * - * Deprecated: 3.10 - */ - ui_manager_signals[PRE_ACTIVATE] = - g_signal_new (I_("pre-activate"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (GtkUIManagerClass, pre_activate), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_ACTION); - - /** - * GtkUIManager::post-activate: - * @manager: the ui manager - * @action: the action - * - * The ::post-activate signal is emitted just after the @action - * is activated. - * - * This is intended for applications to get notification - * just after any action is activated. - * - * Since: 2.4 - * - * Deprecated: 3.10 - */ - ui_manager_signals[POST_ACTIVATE] = - g_signal_new (I_("post-activate"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (GtkUIManagerClass, post_activate), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_ACTION); - - klass->add_widget = NULL; - klass->actions_changed = NULL; - klass->connect_proxy = NULL; - klass->disconnect_proxy = NULL; - klass->pre_activate = NULL; - klass->post_activate = NULL; -} - -static void -gtk_ui_manager_init (GtkUIManager *manager) -{ - guint merge_id; - GNode *node; - - manager->private_data = gtk_ui_manager_get_instance_private (manager); - - manager->private_data->accel_group = gtk_accel_group_new (); - - manager->private_data->root_node = NULL; - manager->private_data->action_groups = NULL; - - manager->private_data->last_merge_id = 0; - - merge_id = gtk_ui_manager_new_merge_id (manager); - node = get_child_node (manager, NULL, NULL, "ui", 2, - NODE_TYPE_ROOT, TRUE, FALSE); - node_prepend_ui_reference (node, merge_id, 0); -} - -static void -gtk_ui_manager_finalize (GObject *object) -{ - GtkUIManager *manager = GTK_UI_MANAGER (object); - - if (manager->private_data->update_tag != 0) - { - g_source_remove (manager->private_data->update_tag); - manager->private_data->update_tag = 0; - } - - g_node_traverse (manager->private_data->root_node, - G_POST_ORDER, G_TRAVERSE_ALL, -1, - (GNodeTraverseFunc)free_node, NULL); - g_node_destroy (manager->private_data->root_node); - manager->private_data->root_node = NULL; - - g_list_free_full (manager->private_data->action_groups, g_object_unref); - manager->private_data->action_groups = NULL; - - g_object_unref (manager->private_data->accel_group); - manager->private_data->accel_group = NULL; - - G_OBJECT_CLASS (gtk_ui_manager_parent_class)->finalize (object); -} - -static void -gtk_ui_manager_buildable_init (GtkBuildableIface *iface) -{ - iface->add_child = gtk_ui_manager_buildable_add_child; - iface->construct_child = gtk_ui_manager_buildable_construct_child; - iface->custom_tag_start = gtk_ui_manager_buildable_custom_tag_start; - iface->custom_tag_end = gtk_ui_manager_buildable_custom_tag_end; -} - -static void -gtk_ui_manager_buildable_add_child (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *type) -{ - GtkUIManager *manager = GTK_UI_MANAGER (buildable); - guint pos; - - g_return_if_fail (GTK_IS_ACTION_GROUP (child)); - - pos = g_list_length (manager->private_data->action_groups); - - gtk_ui_manager_insert_action_group (manager, - GTK_ACTION_GROUP (child), - pos); -} - -static void -child_hierarchy_changed_cb (GtkWidget *widget, - GtkWidget *unused, - GtkUIManager *uimgr) -{ - GtkWidget *toplevel; - GtkAccelGroup *group; - GSList *groups; - - toplevel = gtk_widget_get_toplevel (widget); - if (!toplevel || !GTK_IS_WINDOW (toplevel)) - return; - - group = gtk_ui_manager_get_accel_group (uimgr); - groups = gtk_accel_groups_from_object (G_OBJECT (toplevel)); - if (g_slist_find (groups, group) == NULL) - gtk_window_add_accel_group (GTK_WINDOW (toplevel), group); - - g_signal_handlers_disconnect_by_func (widget, - child_hierarchy_changed_cb, - uimgr); -} - -static GObject * -gtk_ui_manager_buildable_construct_child (GtkBuildable *buildable, - GtkBuilder *builder, - const gchar *id) -{ - GtkWidget *widget; - char *name; - - name = g_strdup_printf ("ui/%s", id); - widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER (buildable), name); - if (!widget) - { - g_error ("Unknown ui manager child: %s", name); - g_free (name); - return NULL; - } - g_free (name); - - g_signal_connect (widget, "hierarchy-changed", - G_CALLBACK (child_hierarchy_changed_cb), - GTK_UI_MANAGER (buildable)); - return g_object_ref (widget); -} - -static void -gtk_ui_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_ui_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkUIManager *manager = GTK_UI_MANAGER (object); - - switch (prop_id) - { - case PROP_UI: - g_value_take_string (value, gtk_ui_manager_get_ui (manager)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GtkWidget * -gtk_ui_manager_real_get_widget (GtkUIManager *manager, - const gchar *path) -{ - GNode *node; - - /* ensure that there are no pending updates before we get the - * widget */ - gtk_ui_manager_ensure_update (manager); - - node = get_node (manager, path, NODE_TYPE_UNDECIDED, FALSE); - - if (node == NULL) - return NULL; - - return NODE_INFO (node)->proxy; -} - -static GtkAction * -gtk_ui_manager_real_get_action (GtkUIManager *manager, - const gchar *path) -{ - GNode *node; - - /* ensure that there are no pending updates before we get - * the action */ - gtk_ui_manager_ensure_update (manager); - - node = get_node (manager, path, NODE_TYPE_UNDECIDED, FALSE); - - if (node == NULL) - return NULL; - - return NODE_INFO (node)->action; -} - - -/** - * gtk_ui_manager_new: - * - * Creates a new ui manager object. - * - * Returns: a new ui manager object. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -GtkUIManager* -gtk_ui_manager_new (void) -{ - return g_object_new (GTK_TYPE_UI_MANAGER, NULL); -} - -static void -cb_proxy_connect_proxy (GtkActionGroup *group, - GtkAction *action, - GtkWidget *proxy, - GtkUIManager *manager) -{ - g_signal_emit (manager, ui_manager_signals[CONNECT_PROXY], 0, action, proxy); -} - -static void -cb_proxy_disconnect_proxy (GtkActionGroup *group, - GtkAction *action, - GtkWidget *proxy, - GtkUIManager *manager) -{ - g_signal_emit (manager, ui_manager_signals[DISCONNECT_PROXY], 0, action, proxy); -} - -static void -cb_proxy_pre_activate (GtkActionGroup *group, - GtkAction *action, - GtkUIManager *manager) -{ - g_signal_emit (manager, ui_manager_signals[PRE_ACTIVATE], 0, action); -} - -static void -cb_proxy_post_activate (GtkActionGroup *group, - GtkAction *action, - GtkUIManager *manager) -{ - g_signal_emit (manager, ui_manager_signals[POST_ACTIVATE], 0, action); -} - -/** - * gtk_ui_manager_insert_action_group: - * @manager: a #GtkUIManager object - * @action_group: the action group to be inserted - * @pos: the position at which the group will be inserted. - * - * Inserts an action group into the list of action groups associated - * with @manager. Actions in earlier groups hide actions with the same - * name in later groups. - * - * If @pos is larger than the number of action groups in @manager, or - * negative, @action_group will be inserted at the end of the internal - * list. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -void -gtk_ui_manager_insert_action_group (GtkUIManager *manager, - GtkActionGroup *action_group, - gint pos) -{ -#ifdef G_ENABLE_DEBUG - GList *l; - const char *group_name; -#endif - - g_return_if_fail (GTK_IS_UI_MANAGER (manager)); - g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); - g_return_if_fail (g_list_find (manager->private_data->action_groups, - action_group) == NULL); - -#ifdef G_ENABLE_DEBUG - group_name = gtk_action_group_get_name (action_group); - - for (l = manager->private_data->action_groups; l; l = l->next) - { - GtkActionGroup *group = l->data; - - if (strcmp (gtk_action_group_get_name (group), group_name) == 0) - { - g_warning ("Inserting action group '%s' into UI manager which " - "already has a group with this name", group_name); - break; - } - } -#endif /* G_ENABLE_DEBUG */ - - g_object_ref (action_group); - manager->private_data->action_groups = - g_list_insert (manager->private_data->action_groups, action_group, pos); - g_object_connect (action_group, - "object-signal::connect-proxy", G_CALLBACK (cb_proxy_connect_proxy), manager, - "object-signal::disconnect-proxy", G_CALLBACK (cb_proxy_disconnect_proxy), manager, - "object-signal::pre-activate", G_CALLBACK (cb_proxy_pre_activate), manager, - "object-signal::post-activate", G_CALLBACK (cb_proxy_post_activate), manager, - NULL); - - /* dirty all nodes, as action bindings may change */ - dirty_all_nodes (manager); - - g_signal_emit (manager, ui_manager_signals[ACTIONS_CHANGED], 0); -} - -/** - * gtk_ui_manager_remove_action_group: - * @manager: a #GtkUIManager object - * @action_group: the action group to be removed - * - * Removes an action group from the list of action groups associated - * with @manager. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -void -gtk_ui_manager_remove_action_group (GtkUIManager *manager, - GtkActionGroup *action_group) -{ - g_return_if_fail (GTK_IS_UI_MANAGER (manager)); - g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); - g_return_if_fail (g_list_find (manager->private_data->action_groups, - action_group) != NULL); - - manager->private_data->action_groups = - g_list_remove (manager->private_data->action_groups, action_group); - - g_object_disconnect (action_group, - "any-signal::connect-proxy", G_CALLBACK (cb_proxy_connect_proxy), manager, - "any-signal::disconnect-proxy", G_CALLBACK (cb_proxy_disconnect_proxy), manager, - "any-signal::pre-activate", G_CALLBACK (cb_proxy_pre_activate), manager, - "any-signal::post-activate", G_CALLBACK (cb_proxy_post_activate), manager, - NULL); - g_object_unref (action_group); - - /* dirty all nodes, as action bindings may change */ - dirty_all_nodes (manager); - - g_signal_emit (manager, ui_manager_signals[ACTIONS_CHANGED], 0); -} - -/** - * gtk_ui_manager_get_action_groups: - * @manager: a #GtkUIManager object - * - * Returns the list of action groups associated with @manager. - * - * Returns: (element-type GtkActionGroup) (transfer none): a #GList of - * action groups. The list is owned by GTK+ - * and should not be modified. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -GList * -gtk_ui_manager_get_action_groups (GtkUIManager *manager) -{ - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL); - - return manager->private_data->action_groups; -} - -/** - * gtk_ui_manager_get_accel_group: - * @manager: a #GtkUIManager object - * - * Returns the #GtkAccelGroup associated with @manager. - * - * Returns: (transfer none): the #GtkAccelGroup. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -GtkAccelGroup * -gtk_ui_manager_get_accel_group (GtkUIManager *manager) -{ - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL); - - return manager->private_data->accel_group; -} - -/** - * gtk_ui_manager_get_widget: - * @manager: a #GtkUIManager - * @path: a path - * - * 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 or action 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. - * - * Note that the widget found by following a path that ends in a <menu>; - * element is the menuitem to which the menu is attached, not the menu it - * manages. - * - * Also note that the widgets constructed by a ui manager are not tied to - * the lifecycle of the ui manager. If you add the widgets returned by this - * function to some container or explicitly ref them, they will survive the - * destruction of the ui manager. - * - * Returns: (transfer none): the widget found by following the path, - * or %NULL if no widget was found - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -GtkWidget * -gtk_ui_manager_get_widget (GtkUIManager *manager, - const gchar *path) -{ - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL); - g_return_val_if_fail (path != NULL, NULL); - - return GTK_UI_MANAGER_GET_CLASS (manager)->get_widget (manager, path); -} - -typedef struct { - GtkUIManagerItemType types; - GSList *list; -} ToplevelData; - -static void -collect_toplevels (GNode *node, - gpointer user_data) -{ - ToplevelData *data = user_data; - - if (NODE_INFO (node)->proxy) - { - switch (NODE_INFO (node)->type) - { - case NODE_TYPE_MENUBAR: - if (data->types & GTK_UI_MANAGER_MENUBAR) - data->list = g_slist_prepend (data->list, NODE_INFO (node)->proxy); - break; - case NODE_TYPE_TOOLBAR: - if (data->types & GTK_UI_MANAGER_TOOLBAR) - data->list = g_slist_prepend (data->list, NODE_INFO (node)->proxy); - break; - case NODE_TYPE_POPUP: - if (data->types & GTK_UI_MANAGER_POPUP) - data->list = g_slist_prepend (data->list, NODE_INFO (node)->proxy); - break; - default: ; - } - } -} - -/** - * gtk_ui_manager_get_toplevels: - * @manager: a #GtkUIManager - * @types: specifies the types of toplevel widgets to include. Allowed - * types are #GTK_UI_MANAGER_MENUBAR, #GTK_UI_MANAGER_TOOLBAR and - * #GTK_UI_MANAGER_POPUP. - * - * Obtains a list of all toplevel widgets of the requested types. - * - * Returns: (element-type GtkWidget) (transfer container): a newly-allocated #GSList of - * all toplevel widgets of the requested types. Free the returned list with g_slist_free(). - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -GSList * -gtk_ui_manager_get_toplevels (GtkUIManager *manager, - GtkUIManagerItemType types) -{ - ToplevelData data; - - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL); - g_return_val_if_fail ((~(GTK_UI_MANAGER_MENUBAR | - GTK_UI_MANAGER_TOOLBAR | - GTK_UI_MANAGER_POPUP) & types) == 0, NULL); - - - data.types = types; - data.list = NULL; - - g_node_children_foreach (manager->private_data->root_node, - G_TRAVERSE_ALL, - collect_toplevels, &data); - - return data.list; -} - - -/** - * gtk_ui_manager_get_action: - * @manager: a #GtkUIManager - * @path: a path - * - * Looks up an action by following a path. See gtk_ui_manager_get_widget() - * for more information about paths. - * - * Returns: (transfer none): the action whose proxy widget is found by following the path, - * or %NULL if no widget was found. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -GtkAction * -gtk_ui_manager_get_action (GtkUIManager *manager, - const gchar *path) -{ - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL); - g_return_val_if_fail (path != NULL, NULL); - - return GTK_UI_MANAGER_GET_CLASS (manager)->get_action (manager, path); -} - -static gboolean -node_is_dead (GNode *node) -{ - GNode *child; - - if (NODE_INFO (node)->uifiles != NULL) - return FALSE; - - for (child = node->children; child != NULL; child = child->next) - { - if (!node_is_dead (child)) - return FALSE; - } - - return TRUE; -} - -static GNode * -get_child_node (GtkUIManager *manager, - GNode *parent, - GNode *sibling, - const gchar *childname, - gint childname_length, - NodeType node_type, - gboolean create, - gboolean top) -{ - GNode *child = NULL; - - if (parent) - { - if (childname) - { - for (child = parent->children; child != NULL; child = child->next) - { - if (NODE_INFO (child)->name && - strlen (NODE_INFO (child)->name) == childname_length && - !strncmp (NODE_INFO (child)->name, childname, childname_length)) - { - /* if undecided about node type, set it */ - if (NODE_INFO (child)->type == NODE_TYPE_UNDECIDED) - NODE_INFO (child)->type = node_type; - - /* warn about type mismatch */ - if (NODE_INFO (child)->type != NODE_TYPE_UNDECIDED && - node_type != NODE_TYPE_UNDECIDED && - NODE_INFO (child)->type != node_type) - g_warning ("node type doesn't match %d (%s is type %d)", - node_type, - NODE_INFO (child)->name, - NODE_INFO (child)->type); - - if (node_is_dead (child)) - { - /* This node was removed but is still dirty so - * it is still in the tree. We want to treat this - * as if it didn't exist, which means we move it - * to the position it would have been created at. - */ - g_node_unlink (child); - goto insert_child; - } - - return child; - } - } - } - if (!child && create) - { - Node *mnode; - - mnode = g_slice_new0 (Node); - mnode->type = node_type; - mnode->name = g_strndup (childname, childname_length); - - child = g_node_new (mnode); - insert_child: - if (sibling) - { - if (top) - g_node_insert_before (parent, sibling, child); - else - g_node_insert_after (parent, sibling, child); - } - else - { - if (top) - g_node_prepend (parent, child); - else - g_node_append (parent, child); - } - - mark_node_dirty (child); - } - } - else - { - /* handle root node */ - if (manager->private_data->root_node) - { - child = manager->private_data->root_node; - if (strncmp (NODE_INFO (child)->name, childname, childname_length) != 0) - g_warning ("root node name '%s' doesn't match '%s'", - childname, NODE_INFO (child)->name); - if (NODE_INFO (child)->type != NODE_TYPE_ROOT) - g_warning ("base element must be of type ROOT"); - } - else if (create) - { - Node *mnode; - - mnode = g_slice_new0 (Node); - mnode->type = node_type; - mnode->name = g_strndup (childname, childname_length); - mnode->dirty = TRUE; - - child = manager->private_data->root_node = g_node_new (mnode); - } - } - - return child; -} - -static GNode * -get_node (GtkUIManager *manager, - const gchar *path, - NodeType node_type, - gboolean create) -{ - const gchar *pos, *end; - GNode *parent, *node; - - if (strncmp ("/ui", path, 3) == 0) - path += 3; - - end = path + strlen (path); - pos = path; - parent = node = NULL; - while (pos < end) - { - const gchar *slash; - gsize length; - - slash = strchr (pos, '/'); - if (slash) - length = slash - pos; - else - length = strlen (pos); - - node = get_child_node (manager, parent, NULL, pos, length, NODE_TYPE_UNDECIDED, - create, FALSE); - if (!node) - return NULL; - - pos += length + 1; /* move past the node name and the slash too */ - parent = node; - } - - if (node != NULL && NODE_INFO (node)->type == NODE_TYPE_UNDECIDED) - NODE_INFO (node)->type = node_type; - - return node; -} - -static void -node_ui_reference_free (gpointer data) -{ - g_slice_free (NodeUIReference, data); -} - -static gboolean -free_node (GNode *node) -{ - Node *info = NODE_INFO (node); - - g_list_free_full (info->uifiles, node_ui_reference_free); - info->uifiles = NULL; - - g_clear_object (&info->action); - g_clear_object (&info->proxy); - g_clear_object (&info->extra); - g_clear_pointer (&info->name, g_free); - g_slice_free (Node, info); - node->data = NULL; - - return FALSE; -} - -/** - * gtk_ui_manager_new_merge_id: - * @manager: a #GtkUIManager - * - * Returns an unused merge id, suitable for use with - * gtk_ui_manager_add_ui(). - * - * Returns: an unused merge id. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -guint -gtk_ui_manager_new_merge_id (GtkUIManager *manager) -{ - manager->private_data->last_merge_id++; - - return manager->private_data->last_merge_id; -} - -static void -node_prepend_ui_reference (GNode *gnode, - guint merge_id, - GQuark action_quark) -{ - Node *node = NODE_INFO (gnode); - NodeUIReference *reference = NULL; - - if (node->uifiles && - ((NodeUIReference *)node->uifiles->data)->merge_id == merge_id) - reference = node->uifiles->data; - else - { - reference = g_slice_new (NodeUIReference); - node->uifiles = g_list_prepend (node->uifiles, reference); - } - - reference->merge_id = merge_id; - reference->action_quark = action_quark; - - mark_node_dirty (gnode); -} - -static void -node_remove_ui_reference (GNode *gnode, - guint merge_id) -{ - Node *node = NODE_INFO (gnode); - GList *p; - - for (p = node->uifiles; p != NULL; p = p->next) - { - NodeUIReference *reference = p->data; - - if (reference->merge_id == merge_id) - { - if (p == node->uifiles) - mark_node_dirty (gnode); - node->uifiles = g_list_delete_link (node->uifiles, p); - g_slice_free (NodeUIReference, reference); - - break; - } - } -} - -/* -------------------- The UI file parser -------------------- */ - -typedef enum -{ - STATE_START, - STATE_ROOT, - STATE_MENU, - STATE_TOOLBAR, - STATE_MENUITEM, - STATE_TOOLITEM, - STATE_ACCELERATOR, - STATE_END -} ParseState; - -typedef struct _ParseContext ParseContext; -struct _ParseContext -{ - ParseState state; - ParseState prev_state; - - GtkUIManager *manager; - - GNode *current; - - guint merge_id; -}; - -static void -start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ParseContext *ctx = user_data; - GtkUIManager *manager = ctx->manager; - - gint i; - const gchar *node_name; - const gchar *action; - GQuark action_quark; - gboolean top; - gboolean expand = FALSE; - gboolean accelerators = FALSE; - gboolean always_show_image_set = FALSE, always_show_image = FALSE; - - gboolean raise_error = TRUE; - - node_name = NULL; - action = NULL; - action_quark = 0; - top = FALSE; - - for (i = 0; attribute_names[i] != NULL; i++) - { - if (!strcmp (attribute_names[i], "name")) - { - node_name = attribute_values[i]; - } - 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], "position")) - { - top = !strcmp (attribute_values[i], "top"); - } - else if (!strcmp (attribute_names[i], "expand")) - { - expand = !strcmp (attribute_values[i], "true"); - } - else if (!strcmp (attribute_names[i], "accelerators")) - { - accelerators = !strcmp (attribute_values[i], "true"); - } - else if (!strcmp (attribute_names[i], "always-show-image")) - { - always_show_image_set = TRUE; - always_show_image = !strcmp (attribute_values[i], "true"); - } - /* else silently skip unknown attributes to be compatible with - * future additional attributes. - */ - } - - /* 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]) - { - case 'a': - if (ctx->state == STATE_ROOT && !strcmp (element_name, "accelerator")) - { - ctx->state = STATE_ACCELERATOR; - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_ACCELERATOR, - TRUE, FALSE); - if (NODE_INFO (ctx->current)->action_name == 0) - NODE_INFO (ctx->current)->action_name = action_quark; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - break; - case 'u': - if (ctx->state == STATE_START && !strcmp (element_name, "ui")) - { - ctx->state = STATE_ROOT; - ctx->current = manager->private_data->root_node; - raise_error = FALSE; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - } - break; - case 'm': - if (ctx->state == STATE_ROOT && !strcmp (element_name, "menubar")) - { - ctx->state = STATE_MENU; - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_MENUBAR, - TRUE, FALSE); - if (NODE_INFO (ctx->current)->action_name == 0) - NODE_INFO (ctx->current)->action_name = action_quark; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - mark_node_dirty (ctx->current); - - raise_error = FALSE; - } - else if (ctx->state == STATE_MENU && !strcmp (element_name, "menu")) - { - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_MENU, - TRUE, top); - if (NODE_INFO (ctx->current)->action_name == 0) - NODE_INFO (ctx->current)->action_name = action_quark; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - else if (ctx->state == STATE_TOOLITEM && !strcmp (element_name, "menu")) - { - ctx->state = STATE_MENU; - - ctx->current = get_child_node (manager, g_node_last_child (ctx->current), NULL, - node_name, strlen (node_name), - NODE_TYPE_MENU, - TRUE, top); - if (NODE_INFO (ctx->current)->action_name == 0) - NODE_INFO (ctx->current)->action_name = action_quark; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - else if (ctx->state == STATE_MENU && !strcmp (element_name, "menuitem")) - { - GNode *node; - - ctx->state = STATE_MENUITEM; - node = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_MENUITEM, - TRUE, top); - if (NODE_INFO (node)->action_name == 0) - NODE_INFO (node)->action_name = action_quark; - - NODE_INFO (node)->always_show_image_set = always_show_image_set; - NODE_INFO (node)->always_show_image = always_show_image; - - node_prepend_ui_reference (node, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - break; - case 'p': - if (ctx->state == STATE_ROOT && !strcmp (element_name, "popup")) - { - ctx->state = STATE_MENU; - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_POPUP, - TRUE, FALSE); - - NODE_INFO (ctx->current)->popup_accels = accelerators; - - if (NODE_INFO (ctx->current)->action_name == 0) - NODE_INFO (ctx->current)->action_name = action_quark; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - else if ((ctx->state == STATE_MENU || ctx->state == STATE_TOOLBAR) && - !strcmp (element_name, "placeholder")) - { - if (ctx->state == STATE_TOOLBAR) - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_TOOLBAR_PLACEHOLDER, - TRUE, top); - else - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_MENU_PLACEHOLDER, - TRUE, top); - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - break; - case 's': - if ((ctx->state == STATE_MENU || ctx->state == STATE_TOOLBAR) && - !strcmp (element_name, "separator")) - { - GNode *node; - gint length; - - if (ctx->state == STATE_TOOLBAR) - ctx->state = STATE_TOOLITEM; - else - ctx->state = STATE_MENUITEM; - if (!strcmp (node_name, "separator")) - { - node_name = NULL; - length = 0; - } - else - length = strlen (node_name); - node = get_child_node (manager, ctx->current, NULL, - node_name, length, - NODE_TYPE_SEPARATOR, - TRUE, top); - - NODE_INFO (node)->expand = expand; - - if (NODE_INFO (node)->action_name == 0) - NODE_INFO (node)->action_name = action_quark; - - node_prepend_ui_reference (node, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - break; - case 't': - if (ctx->state == STATE_ROOT && !strcmp (element_name, "toolbar")) - { - ctx->state = STATE_TOOLBAR; - ctx->current = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_TOOLBAR, - TRUE, FALSE); - if (NODE_INFO (ctx->current)->action_name == 0) - NODE_INFO (ctx->current)->action_name = action_quark; - - node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - else if (ctx->state == STATE_TOOLBAR && !strcmp (element_name, "toolitem")) - { - GNode *node; - - ctx->state = STATE_TOOLITEM; - node = get_child_node (manager, ctx->current, NULL, - node_name, strlen (node_name), - NODE_TYPE_TOOLITEM, - TRUE, top); - if (NODE_INFO (node)->action_name == 0) - NODE_INFO (node)->action_name = action_quark; - - node_prepend_ui_reference (node, ctx->merge_id, action_quark); - - raise_error = FALSE; - } - break; - default: - break; - } - if (raise_error) - { - gint line_number, char_number; - - g_markup_parse_context_get_position (context, - &line_number, &char_number); - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ELEMENT, - _("Unexpected start tag '%s' on line %d char %d"), - element_name, - line_number, char_number); - } -} - -static void -end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - ParseContext *ctx = user_data; - - switch (ctx->state) - { - case STATE_START: - case STATE_END: - /* no need to GError here, GMarkup already catches this */ - break; - case STATE_ROOT: - ctx->current = NULL; - ctx->state = STATE_END; - break; - case STATE_MENU: - case STATE_TOOLBAR: - case STATE_ACCELERATOR: - ctx->current = ctx->current->parent; - if (NODE_INFO (ctx->current)->type == NODE_TYPE_ROOT) - ctx->state = STATE_ROOT; - else if (NODE_INFO (ctx->current)->type == NODE_TYPE_TOOLITEM) - { - ctx->current = ctx->current->parent; - ctx->state = STATE_TOOLITEM; - } - /* else, stay in same state */ - break; - case STATE_MENUITEM: - ctx->state = STATE_MENU; - break; - case STATE_TOOLITEM: - ctx->state = STATE_TOOLBAR; - break; - } -} - -static void -cleanup (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - ParseContext *ctx = user_data; - - ctx->current = NULL; - /* should also walk through the tree and get rid of nodes related to - * this UI file's tag */ - - gtk_ui_manager_remove_ui (ctx->manager, ctx->merge_id); -} - -static gboolean -xml_isspace (char c) -{ - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; -} - -static void -text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ - const gchar *p; - const gchar *end; - - p = text; - end = text + text_len; - while (p != end && xml_isspace (*p)) - ++p; - - if (p != end) - { - gint line_number, char_number; - - g_markup_parse_context_get_position (context, - &line_number, &char_number); - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - _("Unexpected character data on line %d char %d"), - line_number, char_number); - } -} - - -static const GMarkupParser ui_parser = { - start_element_handler, - end_element_handler, - text_handler, - NULL, - cleanup -}; - -static guint -add_ui_from_string (GtkUIManager *manager, - const gchar *buffer, - gssize length, - gboolean needs_root, - GError **error) -{ - ParseContext ctx = { 0 }; - GMarkupParseContext *context; - - ctx.state = STATE_START; - ctx.manager = manager; - ctx.current = NULL; - ctx.merge_id = gtk_ui_manager_new_merge_id (manager); - - context = g_markup_parse_context_new (&ui_parser, 0, &ctx, NULL); - - if (needs_root) - if (!g_markup_parse_context_parse (context, "<ui>", -1, error)) - goto out; - - if (!g_markup_parse_context_parse (context, buffer, length, error)) - goto out; - - if (needs_root) - if (!g_markup_parse_context_parse (context, "</ui>", -1, error)) - goto out; - - if (!g_markup_parse_context_end_parse (context, error)) - goto out; - - g_markup_parse_context_free (context); - - queue_update (manager); - - g_object_notify (G_OBJECT (manager), "ui"); - - return ctx.merge_id; - - out: - - g_markup_parse_context_free (context); - - return 0; -} - -/** - * gtk_ui_manager_add_ui_from_string: - * @manager: a #GtkUIManager object - * @buffer: the string to parse - * @length: the length of @buffer (may be -1 if @buffer is nul-terminated) - * @error: return location for an error - * - * Parses a string containing a [UI definition][XML-UI] and merges it with - * the current contents of @manager. An enclosing <ui> element is added if - * it is missing. - * - * Returns: The merge id for the merged UI. The merge id can be used - * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, - * the return value is 0. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -guint -gtk_ui_manager_add_ui_from_string (GtkUIManager *manager, - const gchar *buffer, - gssize length, - GError **error) -{ - gboolean needs_root = TRUE; - const gchar *p; - const gchar *end; - - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), 0); - g_return_val_if_fail (buffer != NULL, 0); - - if (length < 0) - length = strlen (buffer); - - p = buffer; - end = buffer + length; - while (p != end && xml_isspace (*p)) - ++p; - - if (end - p >= 4 && strncmp (p, "<ui>", 4) == 0) - needs_root = FALSE; - - return add_ui_from_string (manager, buffer, length, needs_root, error); -} - -/** - * gtk_ui_manager_add_ui_from_file: - * @manager: a #GtkUIManager object - * @filename: (type filename): the name of the file to parse - * @error: return location for an error - * - * Parses a file containing a [UI definition][XML-UI] and - * merges it with the current contents of @manager. - * - * Returns: The merge id for the merged UI. The merge id can be used - * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, - * the return value is 0. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -guint -gtk_ui_manager_add_ui_from_file (GtkUIManager *manager, - const gchar *filename, - GError **error) -{ - gchar *buffer; - gsize length; - guint res; - - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), 0); - - if (!g_file_get_contents (filename, &buffer, &length, error)) - return 0; - - res = add_ui_from_string (manager, buffer, length, FALSE, error); - g_free (buffer); - - return res; -} - -/** - * gtk_ui_manager_add_ui_from_resource: - * @manager: a #GtkUIManager object - * @resource_path: the resource path of the file to parse - * @error: return location for an error - * - * Parses a resource file containing a [UI definition][XML-UI] and - * merges it with the current contents of @manager. - * - * Returns: The merge id for the merged UI. The merge id can be used - * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, - * the return value is 0. - * - * Since: 3.4 - * - * Deprecated: 3.10 - **/ -guint -gtk_ui_manager_add_ui_from_resource (GtkUIManager *manager, - const gchar *resource_path, - GError **error) -{ - GBytes *data; - guint res; - - g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), 0); - - data = g_resources_lookup_data (resource_path, 0, error); - if (data == NULL) - return 0; - - res = add_ui_from_string (manager, g_bytes_get_data (data, NULL), g_bytes_get_size (data), FALSE, error); - g_bytes_unref (data); - - return res; -} - -/** - * gtk_ui_manager_add_ui: - * @manager: a #GtkUIManager - * @merge_id: the merge id for the merged UI, see gtk_ui_manager_new_merge_id() - * @path: a path - * @name: the name for the added UI element - * @action: (allow-none): the name of the action to be proxied, or %NULL to add a separator - * @type: the type of UI element to add. - * @top: if %TRUE, the UI element is added before its siblings, otherwise it - * is added after its siblings. - * - * Adds a UI element to the current contents of @manager. - * - * If @type is %GTK_UI_MANAGER_AUTO, GTK+ inserts a menuitem, toolitem or - * separator if such an element can be inserted at the place determined by - * @path. Otherwise @type must indicate an element that can be inserted at - * the place determined by @path. - * - * If @path points to a menuitem or toolitem, the new element will be inserted - * before or after this item, depending on @top. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -void -gtk_ui_manager_add_ui (GtkUIManager *manager, - guint merge_id, - const gchar *path, - const gchar *name, - const gchar *action, - GtkUIManagerItemType type, - gboolean top) -{ - GNode *node; - GNode *sibling; - GNode *child; - NodeType node_type; - GQuark action_quark = 0; - - g_return_if_fail (GTK_IS_UI_MANAGER (manager)); - g_return_if_fail (merge_id > 0); - g_return_if_fail (name != NULL || type == GTK_UI_MANAGER_SEPARATOR); - - node = get_node (manager, path, NODE_TYPE_UNDECIDED, FALSE); - sibling = NULL; - - if (node == NULL) - return; - - node_type = NODE_TYPE_UNDECIDED; - - reswitch: - switch (NODE_INFO (node)->type) - { - case NODE_TYPE_SEPARATOR: - case NODE_TYPE_MENUITEM: - case NODE_TYPE_TOOLITEM: - sibling = node; - node = node->parent; - goto reswitch; - case NODE_TYPE_MENUBAR: - case NODE_TYPE_MENU: - case NODE_TYPE_POPUP: - case NODE_TYPE_MENU_PLACEHOLDER: - switch (type) - { - case GTK_UI_MANAGER_AUTO: - if (action != NULL) - node_type = NODE_TYPE_MENUITEM; - else - node_type = NODE_TYPE_SEPARATOR; - break; - case GTK_UI_MANAGER_MENU: - node_type = NODE_TYPE_MENU; - break; - case GTK_UI_MANAGER_MENUITEM: - node_type = NODE_TYPE_MENUITEM; - break; - case GTK_UI_MANAGER_SEPARATOR: - node_type = NODE_TYPE_SEPARATOR; - break; - case GTK_UI_MANAGER_PLACEHOLDER: - node_type = NODE_TYPE_MENU_PLACEHOLDER; - break; - default: ; - /* do nothing */ - } - break; - case NODE_TYPE_TOOLBAR: - case NODE_TYPE_TOOLBAR_PLACEHOLDER: - switch (type) - { - case GTK_UI_MANAGER_AUTO: - if (action != NULL) - node_type = NODE_TYPE_TOOLITEM; - else - node_type = NODE_TYPE_SEPARATOR; - break; - case GTK_UI_MANAGER_TOOLITEM: - node_type = NODE_TYPE_TOOLITEM; - break; - case GTK_UI_MANAGER_SEPARATOR: - node_type = NODE_TYPE_SEPARATOR; - break; - case GTK_UI_MANAGER_PLACEHOLDER: - node_type = NODE_TYPE_TOOLBAR_PLACEHOLDER; - break; - default: ; - /* do nothing */ - } - break; - case NODE_TYPE_ROOT: - switch (type) - { - case GTK_UI_MANAGER_MENUBAR: - node_type = NODE_TYPE_MENUBAR; - break; - case GTK_UI_MANAGER_TOOLBAR: - node_type = NODE_TYPE_TOOLBAR; - break; - case GTK_UI_MANAGER_POPUP: - case GTK_UI_MANAGER_POPUP_WITH_ACCELS: - node_type = NODE_TYPE_POPUP; - break; - case GTK_UI_MANAGER_ACCELERATOR: - node_type = NODE_TYPE_ACCELERATOR; - break; - default: ; - /* do nothing */ - } - break; - default: ; - /* do nothing */ - } - - if (node_type == NODE_TYPE_UNDECIDED) - { - g_warning ("item type %d not suitable for adding at '%s'", type, path); - return; - } - - child = get_child_node (manager, node, sibling, - name, name ? strlen (name) : 0, - node_type, TRUE, top); - - if (type == GTK_UI_MANAGER_POPUP_WITH_ACCELS) - NODE_INFO (child)->popup_accels = TRUE; - - if (action != NULL) - action_quark = g_quark_from_string (action); - - node_prepend_ui_reference (child, merge_id, action_quark); - - if (NODE_INFO (child)->action_name == 0) - NODE_INFO (child)->action_name = action_quark; - - queue_update (manager); - - g_object_notify (G_OBJECT (manager), "ui"); -} - -static gboolean -remove_ui (GNode *node, - gpointer user_data) -{ - guint merge_id = GPOINTER_TO_UINT (user_data); - - node_remove_ui_reference (node, merge_id); - - return FALSE; /* continue */ -} - -/** - * gtk_ui_manager_remove_ui: - * @manager: a #GtkUIManager object - * @merge_id: a merge id as returned by gtk_ui_manager_add_ui_from_string() - * - * Unmerges the part of @manager's content identified by @merge_id. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -void -gtk_ui_manager_remove_ui (GtkUIManager *manager, - guint merge_id) -{ - g_return_if_fail (GTK_IS_UI_MANAGER (manager)); - - g_node_traverse (manager->private_data->root_node, - G_POST_ORDER, G_TRAVERSE_ALL, -1, - remove_ui, GUINT_TO_POINTER (merge_id)); - - queue_update (manager); - - g_object_notify (G_OBJECT (manager), "ui"); -} - -/* -------------------- Updates -------------------- */ - - -static GtkAction * -get_action_by_name (GtkUIManager *merge, - const gchar *action_name) -{ - GList *tmp; - - if (!action_name) - return NULL; - - /* lookup name */ - for (tmp = merge->private_data->action_groups; tmp != NULL; tmp = tmp->next) - { - GtkActionGroup *action_group = tmp->data; - GtkAction *action; - - action = gtk_action_group_get_action (action_group, action_name); - - if (action) - return action; - } - - return NULL; -} - -static gboolean -find_menu_position (GNode *node, - GtkWidget **menushell_p, - gint *pos_p) -{ - GtkWidget *menushell; - gint pos = 0; - - g_return_val_if_fail (node != NULL, FALSE); - g_return_val_if_fail (NODE_INFO (node)->type == NODE_TYPE_MENU || - NODE_INFO (node)->type == NODE_TYPE_POPUP || - NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || - NODE_INFO (node)->type == NODE_TYPE_MENUITEM || - NODE_INFO (node)->type == NODE_TYPE_SEPARATOR, - FALSE); - - /* first sibling -- look at parent */ - if (node->prev == NULL) - { - GNode *parent; - - parent = node->parent; - switch (NODE_INFO (parent)->type) - { - case NODE_TYPE_MENUBAR: - case NODE_TYPE_POPUP: - menushell = NODE_INFO (parent)->proxy; - pos = 0; - break; - case NODE_TYPE_MENU: - menushell = NODE_INFO (parent)->proxy; - if (GTK_IS_MENU_ITEM (menushell)) - menushell = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menushell)); - break; - case NODE_TYPE_MENU_PLACEHOLDER: - menushell = gtk_widget_get_parent (NODE_INFO (parent)->proxy); - g_return_val_if_fail (GTK_IS_MENU_SHELL (menushell), FALSE); - pos = g_list_index (GTK_MENU_SHELL (menushell)->priv->children, - NODE_INFO (parent)->proxy) + 1; - break; - default: - g_warning ("%s: bad parent node type %d", G_STRLOC, - NODE_INFO (parent)->type); - return FALSE; - } - } - else - { - GtkWidget *prev_child; - GNode *sibling; - - sibling = node->prev; - if (NODE_INFO (sibling)->type == NODE_TYPE_MENU_PLACEHOLDER) - prev_child = NODE_INFO (sibling)->extra; /* second Separator */ - else - prev_child = NODE_INFO (sibling)->proxy; - - if (!GTK_IS_WIDGET (prev_child)) - return FALSE; - - menushell = gtk_widget_get_parent (prev_child); - if (!GTK_IS_MENU_SHELL (menushell)) - return FALSE; - - pos = g_list_index (GTK_MENU_SHELL (menushell)->priv->children, prev_child) + 1; - } - - if (menushell_p) - *menushell_p = menushell; - if (pos_p) - *pos_p = pos; - - return TRUE; -} - -static gboolean -find_toolbar_position (GNode *node, - GtkWidget **toolbar_p, - gint *pos_p) -{ - GtkWidget *toolbar; - gint pos; - - g_return_val_if_fail (node != NULL, FALSE); - g_return_val_if_fail (NODE_INFO (node)->type == NODE_TYPE_TOOLBAR || - NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER || - NODE_INFO (node)->type == NODE_TYPE_TOOLITEM || - NODE_INFO (node)->type == NODE_TYPE_SEPARATOR, - FALSE); - - /* first sibling -- look at parent */ - if (node->prev == NULL) - { - GNode *parent; - - parent = node->parent; - switch (NODE_INFO (parent)->type) - { - case NODE_TYPE_TOOLBAR: - toolbar = NODE_INFO (parent)->proxy; - pos = 0; - break; - case NODE_TYPE_TOOLBAR_PLACEHOLDER: - toolbar = gtk_widget_get_parent (NODE_INFO (parent)->proxy); - g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE); - pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (NODE_INFO (parent)->proxy)) + 1; - break; - default: - g_warning ("%s: bad parent node type %d", G_STRLOC, - NODE_INFO (parent)->type); - return FALSE; - } - } - else - { - GtkWidget *prev_child; - GNode *sibling; - - sibling = node->prev; - if (NODE_INFO (sibling)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER) - prev_child = NODE_INFO (sibling)->extra; /* second Separator */ - else - prev_child = NODE_INFO (sibling)->proxy; - - if (!GTK_IS_WIDGET (prev_child)) - return FALSE; - - toolbar = gtk_widget_get_parent (prev_child); - if (!GTK_IS_TOOLBAR (toolbar)) - return FALSE; - - pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (prev_child)) + 1; - } - - if (toolbar_p) - *toolbar_p = toolbar; - if (pos_p) - *pos_p = pos; - - return TRUE; -} - -enum { - SEPARATOR_MODE_SMART, - SEPARATOR_MODE_VISIBLE, - SEPARATOR_MODE_HIDDEN -}; - -static void -update_smart_separators (GtkWidget *proxy) -{ - GtkWidget *parent = NULL; - - if (GTK_IS_MENU (proxy) || GTK_IS_TOOLBAR (proxy)) - parent = proxy; - else if (GTK_IS_MENU_ITEM (proxy) || GTK_IS_TOOL_ITEM (proxy)) - parent = gtk_widget_get_parent (proxy); - - if (parent) - { - gboolean visible; - gboolean empty; - GList *children, *cur, *last; - GtkWidget *filler; - - children = gtk_container_get_children (GTK_CONTAINER (parent)); - - visible = FALSE; - last = NULL; - empty = TRUE; - filler = NULL; - - cur = children; - while (cur) - { - if (g_object_get_data (cur->data, "gtk-empty-menu-item")) - { - filler = cur->data; - } - else if (GTK_IS_SEPARATOR_MENU_ITEM (cur->data) || - GTK_IS_SEPARATOR_TOOL_ITEM (cur->data)) - { - gint mode = - GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cur->data), - "gtk-separator-mode")); - switch (mode) - { - case SEPARATOR_MODE_VISIBLE: - gtk_widget_show (GTK_WIDGET (cur->data)); - last = NULL; - visible = FALSE; - break; - case SEPARATOR_MODE_HIDDEN: - gtk_widget_hide (GTK_WIDGET (cur->data)); - break; - case SEPARATOR_MODE_SMART: - if (visible) - { - gtk_widget_show (GTK_WIDGET (cur->data)); - last = cur; - visible = FALSE; - } - else - gtk_widget_hide (GTK_WIDGET (cur->data)); - break; - } - } - else if (gtk_widget_get_visible (cur->data)) - { - last = NULL; - - if (cur->data == filler) - visible = FALSE; - else - { - visible = TRUE; - empty = FALSE; - } - - } - - cur = cur->next; - } - - if (last) - gtk_widget_hide (GTK_WIDGET (last->data)); - - if (GTK_IS_MENU (parent)) - { - GtkWidget *item; - - item = gtk_menu_get_attach_widget (GTK_MENU (parent)); - if (GTK_IS_MENU_ITEM (item)) - _gtk_action_sync_menu_visible (NULL, item, empty); - if (GTK_IS_WIDGET (filler)) - { - if (empty) - gtk_widget_show (filler); - else - gtk_widget_hide (filler); - } - } - - g_list_free (children); - } -} - -static void -update_node (GtkUIManager *manager, - GNode *node, - gboolean in_popup, - gboolean popup_accels) -{ - Node *info; - GNode *child; - GtkAction *action; - const gchar *action_name; - NodeUIReference *ref; - - g_return_if_fail (node != NULL); - g_return_if_fail (NODE_INFO (node) != NULL); - - info = NODE_INFO (node); - - if (!info->dirty) - return; - - if (info->type == NODE_TYPE_POPUP) - { - in_popup = TRUE; - popup_accels = info->popup_accels; - } - - if (info->uifiles == NULL) { - /* We may need to remove this node. - * This must be done in post order - */ - goto recurse_children; - } - - ref = info->uifiles->data; - action_name = g_quark_to_string (ref->action_quark); - action = get_action_by_name (manager, action_name); - - info->dirty = FALSE; - - /* Check if the node doesn't have an action and must have an action */ - if (action == NULL && - info->type != NODE_TYPE_ROOT && - info->type != NODE_TYPE_MENUBAR && - info->type != NODE_TYPE_TOOLBAR && - info->type != NODE_TYPE_POPUP && - info->type != NODE_TYPE_SEPARATOR && - info->type != NODE_TYPE_MENU_PLACEHOLDER && - info->type != NODE_TYPE_TOOLBAR_PLACEHOLDER) - { - g_warning ("%s: missing action %s", info->name, action_name); - - return; - } - - if (action) - gtk_action_set_accel_group (action, manager->private_data->accel_group); - - /* If the widget already has a proxy and the action hasn't changed, then - * we only have to update the tearoff menu items. - */ - if (info->proxy != NULL && action == info->action) - goto recurse_children; - - switch (info->type) - { - case NODE_TYPE_MENUBAR: - if (info->proxy == NULL) - { - info->proxy = gtk_menu_bar_new (); - g_object_ref_sink (info->proxy); - gtk_widget_set_name (info->proxy, info->name); - gtk_widget_show (info->proxy); - g_signal_emit (manager, ui_manager_signals[ADD_WIDGET], 0, info->proxy); - } - break; - case NODE_TYPE_POPUP: - if (info->proxy == NULL) - { - info->proxy = gtk_menu_new (); - g_object_ref_sink (info->proxy); - } - gtk_widget_set_name (info->proxy, info->name); - break; - case NODE_TYPE_MENU: - { - GtkWidget *prev_submenu = NULL; - GtkWidget *menu = NULL; - - /* remove the proxy if it is of the wrong type ... */ - if (info->proxy && - G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->menu_item_type) - { - if (GTK_IS_MENU_ITEM (info->proxy)) - { - 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 (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - - /* create proxy if needed ... */ - if (info->proxy == NULL) - { - /* ... if the action already provides a menu, then use - * that menu instead of creating an empty one - */ - if ((NODE_INFO (node->parent)->type == NODE_TYPE_TOOLITEM || - NODE_INFO (node->parent)->type == NODE_TYPE_MENUITEM) && - GTK_ACTION_GET_CLASS (action)->create_menu) - { - menu = gtk_action_create_menu (action); - } - - if (!menu) - { - GtkWidget *filler; - - menu = gtk_menu_new (); - gtk_widget_set_name (menu, info->name); - - filler = gtk_menu_item_new_with_label (_("Empty")); - g_object_set_data (G_OBJECT (filler), - I_("gtk-empty-menu-item"), - GINT_TO_POINTER (TRUE)); - gtk_widget_set_sensitive (filler, FALSE); - gtk_widget_set_no_show_all (filler, TRUE); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), filler); - } - - if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLITEM) - { - info->proxy = menu; - g_object_ref_sink (info->proxy); - gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (NODE_INFO (node->parent)->proxy), - menu); - } - else - { - GtkWidget *menushell; - gint pos; - - if (find_menu_position (node, &menushell, &pos)) - { - info->proxy = gtk_action_create_menu_item (action); - g_object_ref_sink (info->proxy); - g_signal_connect (info->proxy, "notify::visible", - G_CALLBACK (update_smart_separators), NULL); - gtk_widget_set_name (info->proxy, info->name); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos); - } - } - } - - if (prev_submenu) - { - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), - prev_submenu); - g_object_unref (prev_submenu); - } - - if (GTK_IS_MENU (info->proxy)) - menu = info->proxy; - else - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy)); - } - break; - case NODE_TYPE_UNDECIDED: - g_warning ("found undecided node!"); - break; - case NODE_TYPE_ROOT: - break; - case NODE_TYPE_TOOLBAR: - if (info->proxy == NULL) - { - info->proxy = gtk_toolbar_new (); - g_object_ref_sink (info->proxy); - gtk_widget_set_name (info->proxy, info->name); - gtk_widget_show (info->proxy); - g_signal_emit (manager, ui_manager_signals[ADD_WIDGET], 0, info->proxy); - } - break; - case NODE_TYPE_MENU_PLACEHOLDER: - /* create menu items for placeholders if necessary ... */ - if (!GTK_IS_SEPARATOR_MENU_ITEM (info->proxy) || - !GTK_IS_SEPARATOR_MENU_ITEM (info->extra)) - { - if (info->proxy) - { - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - if (info->extra) - { - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->extra)), - info->extra); - g_object_unref (info->extra); - info->extra = NULL; - } - } - if (info->proxy == NULL) - { - GtkWidget *menushell; - gint pos; - - if (find_menu_position (node, &menushell, &pos)) - { - info->proxy = gtk_separator_menu_item_new (); - g_object_ref_sink (info->proxy); - g_object_set_data (G_OBJECT (info->proxy), - I_("gtk-separator-mode"), - GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)); - gtk_widget_set_no_show_all (info->proxy, TRUE); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), - NODE_INFO (node)->proxy, pos); - - info->extra = gtk_separator_menu_item_new (); - g_object_ref_sink (info->extra); - g_object_set_data (G_OBJECT (info->extra), - I_("gtk-separator-mode"), - GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)); - gtk_widget_set_no_show_all (info->extra, TRUE); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), - NODE_INFO (node)->extra, pos + 1); - } - } - break; - case NODE_TYPE_TOOLBAR_PLACEHOLDER: - /* create toolbar items for placeholders if necessary ... */ - if (!GTK_IS_SEPARATOR_TOOL_ITEM (info->proxy) || - !GTK_IS_SEPARATOR_TOOL_ITEM (info->extra)) - { - if (info->proxy) - { - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - if (info->extra) - { - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->extra)), - info->extra); - g_object_unref (info->extra); - info->extra = NULL; - } - } - if (info->proxy == NULL) - { - GtkWidget *toolbar; - gint pos; - GtkToolItem *item; - - if (find_toolbar_position (node, &toolbar, &pos)) - { - item = gtk_separator_tool_item_new (); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos); - info->proxy = GTK_WIDGET (item); - g_object_ref_sink (info->proxy); - g_object_set_data (G_OBJECT (info->proxy), - I_("gtk-separator-mode"), - GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)); - gtk_widget_set_no_show_all (info->proxy, TRUE); - - item = gtk_separator_tool_item_new (); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos+1); - info->extra = GTK_WIDGET (item); - g_object_ref_sink (info->extra); - g_object_set_data (G_OBJECT (info->extra), - I_("gtk-separator-mode"), - GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)); - gtk_widget_set_no_show_all (info->extra, TRUE); - } - } - break; - case NODE_TYPE_MENUITEM: - /* remove the proxy if it is of the wrong type ... */ - if (info->proxy && - G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->menu_item_type) - { - g_signal_handlers_disconnect_by_func (info->proxy, - G_CALLBACK (update_smart_separators), - NULL); - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - /* create proxy if needed ... */ - if (info->proxy == NULL) - { - GtkWidget *menushell; - gint pos; - - if (find_menu_position (node, &menushell, &pos)) - { - info->proxy = gtk_action_create_menu_item (action); - g_object_ref_sink (info->proxy); - gtk_widget_set_name (info->proxy, info->name); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), - info->proxy, pos); - } - } - else - { - g_signal_handlers_disconnect_by_func (info->proxy, - G_CALLBACK (update_smart_separators), - NULL); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), NULL); - } - - if (info->proxy) - { - g_signal_connect (info->proxy, "notify::visible", - G_CALLBACK (update_smart_separators), NULL); - if (in_popup && !popup_accels) - { - /* don't show accels in popups */ - GtkWidget *c = gtk_bin_get_child (GTK_BIN (info->proxy)); - if (GTK_IS_ACCEL_LABEL (c)) - g_object_set (c, "accel-closure", NULL, NULL); - } - } - - break; - case NODE_TYPE_TOOLITEM: - /* remove the proxy if it is of the wrong type ... */ - if (info->proxy && - G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->toolbar_item_type) - { - g_signal_handlers_disconnect_by_func (info->proxy, - G_CALLBACK (update_smart_separators), - NULL); - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - /* create proxy if needed ... */ - if (info->proxy == NULL) - { - GtkWidget *toolbar; - gint pos; - - if (find_toolbar_position (node, &toolbar, &pos)) - { - info->proxy = gtk_action_create_tool_item (action); - g_object_ref_sink (info->proxy); - gtk_widget_set_name (info->proxy, info->name); - - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (info->proxy), pos); - } - } - else - { - g_signal_handlers_disconnect_by_func (info->proxy, - G_CALLBACK (update_smart_separators), - NULL); - } - - if (info->proxy) - { - g_signal_connect (info->proxy, "notify::visible", - G_CALLBACK (update_smart_separators), NULL); - } - break; - case NODE_TYPE_SEPARATOR: - if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR || - NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER) - { - GtkWidget *toolbar; - gint pos; - gint separator_mode; - GtkToolItem *item; - - if (GTK_IS_SEPARATOR_TOOL_ITEM (info->proxy)) - { - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - - if (find_toolbar_position (node, &toolbar, &pos)) - { - item = gtk_separator_tool_item_new (); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos); - info->proxy = GTK_WIDGET (item); - g_object_ref_sink (info->proxy); - gtk_widget_set_no_show_all (info->proxy, TRUE); - if (info->expand) - { - gtk_tool_item_set_expand (GTK_TOOL_ITEM (item), TRUE); - gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE); - separator_mode = SEPARATOR_MODE_VISIBLE; - } - else - separator_mode = SEPARATOR_MODE_SMART; - - g_object_set_data (G_OBJECT (info->proxy), - I_("gtk-separator-mode"), - GINT_TO_POINTER (separator_mode)); - gtk_widget_show (info->proxy); - } - } - else - { - GtkWidget *menushell; - gint pos; - - if (GTK_IS_SEPARATOR_MENU_ITEM (info->proxy)) - { - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (info->proxy)), - info->proxy); - g_object_unref (info->proxy); - info->proxy = NULL; - } - - if (find_menu_position (node, &menushell, &pos)) - { - info->proxy = gtk_separator_menu_item_new (); - g_object_ref_sink (info->proxy); - gtk_widget_set_no_show_all (info->proxy, TRUE); - g_object_set_data (G_OBJECT (info->proxy), - I_("gtk-separator-mode"), - GINT_TO_POINTER (SEPARATOR_MODE_SMART)); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), - info->proxy, pos); - gtk_widget_show (info->proxy); - } - } - break; - case NODE_TYPE_ACCELERATOR: - gtk_action_connect_accelerator (action); - break; - } - - if (action) - g_object_ref (action); - if (info->action) - g_object_unref (info->action); - info->action = action; - - recurse_children: - /* process children */ - child = node->children; - while (child) - { - GNode *current; - - current = child; - child = current->next; - update_node (manager, current, in_popup, popup_accels); - } - - if (info->proxy) - { - if (info->type == NODE_TYPE_MENU && GTK_IS_MENU_ITEM (info->proxy)) - update_smart_separators (gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy))); - else if (info->type == NODE_TYPE_MENU || - info->type == NODE_TYPE_TOOLBAR || - info->type == NODE_TYPE_POPUP) - update_smart_separators (info->proxy); - } - - /* handle cleanup of dead nodes */ - if (node->children == NULL && info->uifiles == NULL) - { - if (info->proxy) - gtk_widget_destroy (info->proxy); - if (info->extra) - gtk_widget_destroy (info->extra); - if (info->type == NODE_TYPE_ACCELERATOR && info->action != NULL) - gtk_action_disconnect_accelerator (info->action); - free_node (node); - g_node_destroy (node); - } -} - -static gboolean -do_updates (GtkUIManager *manager) -{ - /* this function needs to check through the tree for dirty nodes. - * For such nodes, it needs to do the following: - * - * 1) check if they are referenced by any loaded UI files anymore. - * In which case, the proxy widget should be destroyed, unless - * there are any subnodes. - * - * 2) lookup the action for this node again. If it is different to - * the current one (or if no previous action has been looked up), - * the proxy is reconnected to the new action (or a new proxy widget - * is created and added to the parent container). - */ - update_node (manager, manager->private_data->root_node, FALSE, FALSE); - - manager->private_data->update_tag = 0; - - return FALSE; -} - -static gboolean -do_updates_idle (GtkUIManager *manager) -{ - do_updates (manager); - - return FALSE; -} - -static void -queue_update (GtkUIManager *manager) -{ - if (manager->private_data->update_tag != 0) - return; - - manager->private_data->update_tag = gdk_threads_add_idle ( - (GSourceFunc)do_updates_idle, - manager); - g_source_set_name_by_id (manager->private_data->update_tag, "[gtk+] do_updates_idle"); -} - - -/** - * gtk_ui_manager_ensure_update: - * @manager: a #GtkUIManager - * - * Makes sure that all pending updates to the UI have been completed. - * - * This may occasionally be necessary, since #GtkUIManager updates the - * UI in an idle function. A typical example where this function is - * useful is to enforce that the menubar and toolbar have been added to - * the main window before showing it: - * |[<!-- language="C" --> - * gtk_container_add (GTK_CONTAINER (window), vbox); - * g_signal_connect (merge, "add-widget", - * G_CALLBACK (add_widget), vbox); - * gtk_ui_manager_add_ui_from_file (merge, "my-menus"); - * gtk_ui_manager_add_ui_from_file (merge, "my-toolbars"); - * gtk_ui_manager_ensure_update (merge); - * gtk_widget_show (window); - * ]| - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -void -gtk_ui_manager_ensure_update (GtkUIManager *manager) -{ - if (manager->private_data->update_tag != 0) - { - g_source_remove (manager->private_data->update_tag); - do_updates (manager); - } -} - -static gboolean -dirty_traverse_func (GNode *node, - gpointer data) -{ - NODE_INFO (node)->dirty = TRUE; - return FALSE; -} - -static void -dirty_all_nodes (GtkUIManager *manager) -{ - g_node_traverse (manager->private_data->root_node, - G_PRE_ORDER, G_TRAVERSE_ALL, -1, - dirty_traverse_func, NULL); - queue_update (manager); -} - -static void -mark_node_dirty (GNode *node) -{ - GNode *p; - - /* FIXME could optimize this */ - for (p = node; p; p = p->parent) - NODE_INFO (p)->dirty = TRUE; -} - -static void -print_node (GtkUIManager *manager, - GNode *node, - gint indent_level, - GString *buffer) -{ - Node *mnode; - GNode *child; - - mnode = node->data; - - switch (mnode->type) - { - case NODE_TYPE_UNDECIDED: - g_string_append_printf (buffer, "%*s<UNDECIDED", indent_level, ""); - break; - case NODE_TYPE_ROOT: - g_string_append_printf (buffer, "%*s<ui", indent_level, ""); - break; - case NODE_TYPE_MENUBAR: - g_string_append_printf (buffer, "%*s<menubar", indent_level, ""); - break; - case NODE_TYPE_MENU: - g_string_append_printf (buffer, "%*s<menu", indent_level, ""); - break; - case NODE_TYPE_TOOLBAR: - g_string_append_printf (buffer, "%*s<toolbar", indent_level, ""); - break; - case NODE_TYPE_MENU_PLACEHOLDER: - case NODE_TYPE_TOOLBAR_PLACEHOLDER: - g_string_append_printf (buffer, "%*s<placeholder", indent_level, ""); - break; - case NODE_TYPE_POPUP: - g_string_append_printf (buffer, "%*s<popup", indent_level, ""); - break; - case NODE_TYPE_MENUITEM: - g_string_append_printf (buffer, "%*s<menuitem", indent_level, ""); - break; - case NODE_TYPE_TOOLITEM: - g_string_append_printf (buffer, "%*s<toolitem", indent_level, ""); - break; - case NODE_TYPE_SEPARATOR: - g_string_append_printf (buffer, "%*s<separator", indent_level, ""); - break; - case NODE_TYPE_ACCELERATOR: - g_string_append_printf (buffer, "%*s<accelerator", indent_level, ""); - break; - default: - ;; /* Nothing */ - } - - if (mnode->type != NODE_TYPE_ROOT) - { - if (mnode->name) - g_string_append_printf (buffer, " name=\"%s\"", mnode->name); - - if (mnode->action_name) - g_string_append_printf (buffer, " action=\"%s\"", - g_quark_to_string (mnode->action_name)); - } - - switch (mnode->type) - { - case NODE_TYPE_UNDECIDED: - case NODE_TYPE_ROOT: - case NODE_TYPE_MENUBAR: - case NODE_TYPE_MENU: - case NODE_TYPE_TOOLBAR: - case NODE_TYPE_MENU_PLACEHOLDER: - case NODE_TYPE_TOOLBAR_PLACEHOLDER: - case NODE_TYPE_POPUP: - g_string_append (buffer, ">\n"); - break; - default: - g_string_append (buffer, "/>\n"); - break; - } - - for (child = node->children; child != NULL; child = child->next) - print_node (manager, child, indent_level + 2, buffer); - - switch (mnode->type) - { - case NODE_TYPE_UNDECIDED: - g_string_append_printf (buffer, "%*s</UNDECIDED>\n", indent_level, ""); - break; - case NODE_TYPE_ROOT: - g_string_append_printf (buffer, "%*s</ui>\n", indent_level, ""); - break; - case NODE_TYPE_MENUBAR: - g_string_append_printf (buffer, "%*s</menubar>\n", indent_level, ""); - break; - case NODE_TYPE_MENU: - g_string_append_printf (buffer, "%*s</menu>\n", indent_level, ""); - break; - case NODE_TYPE_TOOLBAR: - g_string_append_printf (buffer, "%*s</toolbar>\n", indent_level, ""); - break; - case NODE_TYPE_MENU_PLACEHOLDER: - case NODE_TYPE_TOOLBAR_PLACEHOLDER: - g_string_append_printf (buffer, "%*s</placeholder>\n", indent_level, ""); - break; - case NODE_TYPE_POPUP: - g_string_append_printf (buffer, "%*s</popup>\n", indent_level, ""); - break; - default: - ;; /* Nothing */ - } -} - -static gboolean -gtk_ui_manager_buildable_custom_tag_start (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - GMarkupParser *parser, - gpointer *data) -{ - if (child) - return FALSE; - - if (strcmp (tagname, "ui") == 0) - { - ParseContext *ctx; - - ctx = g_new0 (ParseContext, 1); - ctx->state = STATE_START; - ctx->manager = GTK_UI_MANAGER (buildable); - ctx->current = NULL; - ctx->merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (buildable)); - - *data = ctx; - *parser = ui_parser; - - return TRUE; - } - - return FALSE; - -} - -static void -gtk_ui_manager_buildable_custom_tag_end (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer *data) -{ - queue_update (GTK_UI_MANAGER (buildable)); - g_object_notify (G_OBJECT (buildable), "ui"); - g_free (data); -} - -/** - * gtk_ui_manager_get_ui: - * @manager: a #GtkUIManager - * - * Creates a [UI definition][XML-UI] of the merged UI. - * - * Returns: A newly allocated string containing an XML representation of - * the merged UI. - * - * Since: 2.4 - * - * Deprecated: 3.10 - **/ -gchar * -gtk_ui_manager_get_ui (GtkUIManager *manager) -{ - GString *buffer; - - buffer = g_string_new (NULL); - - gtk_ui_manager_ensure_update (manager); - - print_node (manager, manager->private_data->root_node, 0, buffer); - - return g_string_free (buffer, FALSE); -} diff --git a/gtk/deprecated/gtkuimanager.h b/gtk/deprecated/gtkuimanager.h deleted file mode 100644 index 371d7cce53..0000000000 --- a/gtk/deprecated/gtkuimanager.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * GTK - The GIMP Toolkit - * Copyright (C) 1998, 1999 Red Hat, Inc. - * All rights reserved. - * - * This Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Author: James Henstridge <james@daa.com.au> - * - * Modified by the GTK+ Team and others 2003. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_UI_MANAGER_H__ -#define __GTK_UI_MANAGER_H__ - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only <gtk/gtk.h> can be included directly." -#endif - -#include <gtk/gtkaccelgroup.h> -#include <gtk/gtkwidget.h> -#include <gtk/deprecated/gtkaction.h> -#include <gtk/deprecated/gtkactiongroup.h> - -G_BEGIN_DECLS - -#define GTK_TYPE_UI_MANAGER (gtk_ui_manager_get_type ()) -#define GTK_UI_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_UI_MANAGER, GtkUIManager)) -#define GTK_UI_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_UI_MANAGER, GtkUIManagerClass)) -#define GTK_IS_UI_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_UI_MANAGER)) -#define GTK_IS_UI_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_UI_MANAGER)) -#define GTK_UI_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_UI_MANAGER, GtkUIManagerClass)) - -typedef struct _GtkUIManager GtkUIManager; -typedef struct _GtkUIManagerClass GtkUIManagerClass; -typedef struct _GtkUIManagerPrivate GtkUIManagerPrivate; - - -struct _GtkUIManager { - GObject parent; - - /*< private >*/ - GtkUIManagerPrivate *private_data; -}; - -struct _GtkUIManagerClass { - GObjectClass parent_class; - - /* Signals */ - void (* add_widget) (GtkUIManager *manager, - GtkWidget *widget); - void (* actions_changed) (GtkUIManager *manager); - void (* connect_proxy) (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy); - void (* disconnect_proxy) (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy); - void (* pre_activate) (GtkUIManager *manager, - GtkAction *action); - void (* post_activate) (GtkUIManager *manager, - GtkAction *action); - - /* Virtual functions */ - GtkWidget * (* get_widget) (GtkUIManager *manager, - const gchar *path); - GtkAction * (* get_action) (GtkUIManager *manager, - const gchar *path); - - /* Padding for future expansion */ - void (*_gtk_reserved1) (void); - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); -}; - -/** - * GtkUIManagerItemType: - * @GTK_UI_MANAGER_AUTO: Pick the type of the UI element according to context. - * @GTK_UI_MANAGER_MENUBAR: Create a menubar. - * @GTK_UI_MANAGER_MENU: Create a menu. - * @GTK_UI_MANAGER_TOOLBAR: Create a toolbar. - * @GTK_UI_MANAGER_PLACEHOLDER: Insert a placeholder. - * @GTK_UI_MANAGER_POPUP: Create a popup menu. - * @GTK_UI_MANAGER_MENUITEM: Create a menuitem. - * @GTK_UI_MANAGER_TOOLITEM: Create a toolitem. - * @GTK_UI_MANAGER_SEPARATOR: Create a separator. - * @GTK_UI_MANAGER_ACCELERATOR: Install an accelerator. - * @GTK_UI_MANAGER_POPUP_WITH_ACCELS: Same as %GTK_UI_MANAGER_POPUP, but the - * actions’ accelerators are shown. - * - * These enumeration values are used by gtk_ui_manager_add_ui() to determine - * what UI element to create. - * - * Deprecated: 3.10 - */ -typedef enum { - GTK_UI_MANAGER_AUTO = 0, - GTK_UI_MANAGER_MENUBAR = 1 << 0, - GTK_UI_MANAGER_MENU = 1 << 1, - GTK_UI_MANAGER_TOOLBAR = 1 << 2, - GTK_UI_MANAGER_PLACEHOLDER = 1 << 3, - GTK_UI_MANAGER_POPUP = 1 << 4, - GTK_UI_MANAGER_MENUITEM = 1 << 5, - GTK_UI_MANAGER_TOOLITEM = 1 << 6, - GTK_UI_MANAGER_SEPARATOR = 1 << 7, - GTK_UI_MANAGER_ACCELERATOR = 1 << 8, - GTK_UI_MANAGER_POPUP_WITH_ACCELS = 1 << 9 -} GtkUIManagerItemType; - -GDK_DEPRECATED_IN_3_10 -GType gtk_ui_manager_get_type (void) G_GNUC_CONST; -GDK_DEPRECATED_IN_3_10 -GtkUIManager *gtk_ui_manager_new (void); - -GDK_DEPRECATED_IN_3_10 -void gtk_ui_manager_insert_action_group (GtkUIManager *manager, - GtkActionGroup *action_group, - gint pos); -GDK_DEPRECATED_IN_3_10 -void gtk_ui_manager_remove_action_group (GtkUIManager *manager, - GtkActionGroup *action_group); -GDK_DEPRECATED_IN_3_10 -GList *gtk_ui_manager_get_action_groups (GtkUIManager *manager); -GDK_DEPRECATED_IN_3_10 -GtkAccelGroup *gtk_ui_manager_get_accel_group (GtkUIManager *manager); -GDK_DEPRECATED_IN_3_10 -GtkWidget *gtk_ui_manager_get_widget (GtkUIManager *manager, - const gchar *path); -GDK_DEPRECATED_IN_3_10 -GSList *gtk_ui_manager_get_toplevels (GtkUIManager *manager, - GtkUIManagerItemType types); -GDK_DEPRECATED_IN_3_10 -GtkAction *gtk_ui_manager_get_action (GtkUIManager *manager, - const gchar *path); -GDK_DEPRECATED_IN_3_10 -guint gtk_ui_manager_add_ui_from_string (GtkUIManager *manager, - const gchar *buffer, - gssize length, - GError **error); -GDK_DEPRECATED_IN_3_10 -guint gtk_ui_manager_add_ui_from_file (GtkUIManager *manager, - const gchar *filename, - GError **error); -GDK_DEPRECATED_IN_3_10 -guint gtk_ui_manager_add_ui_from_resource(GtkUIManager *manager, - const gchar *resource_path, - GError **error); -GDK_DEPRECATED_IN_3_10 -void gtk_ui_manager_add_ui (GtkUIManager *manager, - guint merge_id, - const gchar *path, - const gchar *name, - const gchar *action, - GtkUIManagerItemType type, - gboolean top); -GDK_DEPRECATED_IN_3_10 -void gtk_ui_manager_remove_ui (GtkUIManager *manager, - guint merge_id); -GDK_DEPRECATED_IN_3_10 -gchar *gtk_ui_manager_get_ui (GtkUIManager *manager); -GDK_DEPRECATED_IN_3_10 -void gtk_ui_manager_ensure_update (GtkUIManager *manager); -GDK_DEPRECATED_IN_3_10 -guint gtk_ui_manager_new_merge_id (GtkUIManager *manager); - -G_END_DECLS - -#endif /* __GTK_UI_MANAGER_H__ */ @@ -249,7 +249,6 @@ #include <gtk/deprecated/gtkgradient.h> #include <gtk/deprecated/gtkrecentaction.h> #include <gtk/deprecated/gtksymboliccolor.h> -#include <gtk/deprecated/gtkuimanager.h> #endif /* GTK_DISABLE_DEPRECATED */ #include <gtk/gtk-autocleanups.h> diff --git a/gtk/gtkaccelgroup.c b/gtk/gtkaccelgroup.c index 74fa51fa77..399302d4d8 100644 --- a/gtk/gtkaccelgroup.c +++ b/gtk/gtkaccelgroup.c @@ -44,10 +44,7 @@ * * A #GtkAccelGroup represents a group of keyboard accelerators, * typically attached to a toplevel #GtkWindow (with - * gtk_window_add_accel_group()). Usually you won’t need to create a - * #GtkAccelGroup directly; instead, when using #GtkUIManager, GTK+ - * automatically sets up the accelerators for your menus in the ui - * manager’s #GtkAccelGroup. + * gtk_window_add_accel_group()). * * Note that “accelerators” are different from * “mnemonics”. Accelerators are shortcuts for diff --git a/gtk/gtkaccelmap.c b/gtk/gtkaccelmap.c index 70e3c7dc29..c63586dcec 100644 --- a/gtk/gtkaccelmap.c +++ b/gtk/gtkaccelmap.c @@ -41,11 +41,11 @@ * SECTION:gtkaccelmap * @Short_description: Loadable keyboard accelerator specifications * @Title: Accelerator Maps - * @See_also: #GtkAccelGroup, #GtkAccelKey, #GtkUIManager, gtk_widget_set_accel_path(), gtk_menu_item_set_accel_path() + * @See_also: #GtkAccelGroup, #GtkAccelKey, gtk_widget_set_accel_path(), gtk_menu_item_set_accel_path() * * Accelerator maps are used to define runtime configurable accelerators. * Functions for manipulating them are are usually used by higher level - * convenience mechanisms like #GtkUIManager and are thus considered + * convenience mechanisms and are thus considered * “low-level”. You’ll want to use them if you’re manually creating menus that * should have user-configurable accelerators. * diff --git a/gtk/gtkbuildable.h b/gtk/gtkbuildable.h index 9652a5edf4..911dfe32c7 100644 --- a/gtk/gtkbuildable.h +++ b/gtk/gtkbuildable.h @@ -57,8 +57,8 @@ typedef struct _GtkBuildableIface GtkBuildableIface; * (i.e. setting the #GtkWidget:visible property) until the whole interface * is created. * @construct_child: Constructs a child of a buildable that has been - * specified as “constructor” in the UI definition. #GtkUIManager implements - * this to reference to a widget created in a <ui> tag which is outside + * specified as “constructor” in the UI definition. This can be used to + * reference a widget created in a <ui> tag which is outside * of the normal GtkBuilder UI definition hierarchy. A reference to the * constructed object is returned and becomes owned by the caller. * @custom_tag_start: Implement this if the buildable needs to parse diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index eb4dc8d7f4..55c656940f 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -6229,11 +6229,9 @@ destroy_accel_path (gpointer data) * to be saved for future use. (See gtk_accel_map_save().) * * This function is a low level function that would most likely - * be used by a menu creation system like #GtkUIManager. If you - * use #GtkUIManager, setting up accelerator paths will be done - * automatically. + * be used by a menu creation system. * - * Even when you you aren’t using #GtkUIManager, if you only want to + * If you only want to * set up accelerators on menu items gtk_menu_item_set_accel_path() * provides a somewhat more convenient interface. * @@ -13578,7 +13576,7 @@ gtk_widget_get_no_show_all (GtkWidget *widget) * calls to gtk_widget_show_all() will affect this widget. * * This is mostly for use in constructing widget hierarchies with externally - * controlled visibility, see #GtkUIManager. + * controlled visibility. * * Since: 2.4 **/ diff --git a/tests/Makefile.am b/tests/Makefile.am index 0b4b71f9e7..15a6f0f27d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -124,7 +124,6 @@ noinst_PROGRAMS = $(TEST_PROGS) \ testverticalcells \ treestoretest \ testxinerama \ - testmerge \ testactions \ testgrouping \ testtooltips \ @@ -250,7 +249,6 @@ testtreesort_DEPENDENCIES = $(DEPS) testverticalcells_DEPENDENCIES = $(DEPS) treestoretest_DEPENDENCIES = $(TEST_DEPS) testxinerama_DEPENDENCIES = $(TEST_DEPS) -testmerge_DEPENDENCIES = $(TEST_DEPS) testactions_DEPENDENCIES = $(TEST_DEPS) testgrouping_DEPENDENCIES = $(TEST_DEPS) testtooltips_DEPENDENCIES = $(TEST_DEPS) @@ -374,9 +372,6 @@ testprint_SOURCES = \ testspinbutton_SOURCES = \ testspinbutton.c -testmerge_SOURCES = \ - testmerge.c - testactions_SOURCES = \ testactions.c @@ -510,9 +505,6 @@ EXTRA_DIST += \ check-y.xpm \ check-n.xpm \ test.xpm \ - merge-1.ui \ - merge-2.ui \ - merge-3.ui \ gnome-textfile.png \ testsplitheaders.ui \ makefile.msc \ diff --git a/tests/testactions.c b/tests/testactions.c index e1065bcd08..02f65fd729 100644 --- a/tests/testactions.c +++ b/tests/testactions.c @@ -181,156 +181,13 @@ static const gchar *ui_info = " <menuitem name=\"poppaste\" action=\"paste\" />\n" " </popup>\n"; -static void -add_widget (GtkUIManager *merge, - GtkWidget *widget, - GtkContainer *container) -{ - - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE); - gtk_widget_show (widget); - - if (GTK_IS_TOOLBAR (widget)) - { - toolbar = GTK_TOOLBAR (widget); - gtk_toolbar_set_show_arrow (toolbar, TRUE); - } -} - static guint ui_id = 0; static GtkActionGroup *dag = NULL; static void -ensure_update (GtkUIManager *manager) -{ - GTimer *timer; - double seconds; - gulong microsecs; - - timer = g_timer_new (); - g_timer_start (timer); - - gtk_ui_manager_ensure_update (manager); - - g_timer_stop (timer); - seconds = g_timer_elapsed (timer, µsecs); - g_timer_destroy (timer); - - g_print ("Time: %fs\n", seconds); -} - -static void -add_cb (GtkWidget *button, - GtkUIManager *manager) -{ - GtkWidget *spinbutton; - GtkAction *action; - int i, num; - char *name, *label; - - if (ui_id != 0 || dag != NULL) - return; - - spinbutton = g_object_get_data (G_OBJECT (button), "spinbutton"); - num = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton)); - - dag = gtk_action_group_new ("DynamicActions"); - gtk_ui_manager_insert_action_group (manager, dag, 0); - - ui_id = gtk_ui_manager_new_merge_id (manager); - - for (i = 0; i < num; i++) - { - name = g_strdup_printf ("DynAction%u", i); - label = g_strdup_printf ("Dynamic Item %d", i); - - action = g_object_new (GTK_TYPE_ACTION, - "name", name, - "label", label, - NULL); - gtk_action_group_add_action (dag, action); - g_object_unref (action); - - gtk_ui_manager_add_ui (manager, ui_id, "/menubar/DynamicMenu", - name, name, - GTK_UI_MANAGER_MENUITEM, FALSE); - } - - ensure_update (manager); -} - -static void -remove_cb (GtkWidget *button, - GtkUIManager *manager) -{ - if (ui_id == 0 || dag == NULL) - return; - - gtk_ui_manager_remove_ui (manager, ui_id); - ensure_update (manager); - ui_id = 0; - - gtk_ui_manager_remove_action_group (manager, dag); - g_object_unref (dag); - dag = NULL; -} - -static void create_window (GtkActionGroup *action_group) { - GtkUIManager *merge; - GtkWidget *window; - GtkWidget *box; - GtkWidget *hbox, *spinbutton, *button; - GError *error = NULL; - - merge = gtk_ui_manager_new (); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), -1, -1); - gtk_window_set_title (GTK_WINDOW (window), "Action Test"); - g_signal_connect_swapped (window, "destroy", G_CALLBACK (g_object_unref), merge); - g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); - - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER (window), box); - gtk_widget_show (box); - - gtk_ui_manager_insert_action_group (merge, action_group, 0); - g_signal_connect (merge, "add_widget", G_CALLBACK (add_widget), box); - - gtk_window_add_accel_group (GTK_WINDOW (window), - gtk_ui_manager_get_accel_group (merge)); - - if (!gtk_ui_manager_add_ui_from_string (merge, ui_info, -1, &error)) - { - g_message ("building menus failed: %s", error->message); - g_error_free (error); - } - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_end (GTK_BOX (box), hbox, FALSE, FALSE); - gtk_widget_show (hbox); - - spinbutton = gtk_spin_button_new_with_range (100, 10000, 100); - gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE); - gtk_widget_show (spinbutton); - - button = gtk_button_new_with_label ("Add"); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE); - gtk_widget_show (button); - - g_object_set_data (G_OBJECT (button), "spinbutton", spinbutton); - g_signal_connect (button, "clicked", G_CALLBACK (add_cb), merge); - - button = gtk_button_new_with_label ("Remove"); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE); - gtk_widget_show (button); - - g_signal_connect (button, "clicked", G_CALLBACK (remove_cb), merge); - - gtk_widget_show (window); -} + } int main (int argc, char **argv) @@ -362,21 +219,6 @@ main (int argc, char **argv) gtk_main (); -#ifdef DEBUG_UI_MANAGER - { - GList *action; - - for (action = gtk_action_group_list_actions (action_group); - action; - action = action->next) - { - GtkAction *a = action->data; - g_print ("action %s ref count %d\n", - gtk_action_get_name (a), G_OBJECT (a)->ref_count); - } - } -#endif - g_object_unref (action); g_object_unref (action_group); diff --git a/tests/testmerge.c b/tests/testmerge.c deleted file mode 100644 index 041afc121f..0000000000 --- a/tests/testmerge.c +++ /dev/null @@ -1,678 +0,0 @@ -/* testmerge.c - * Copyright (C) 2003 James Henstridge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#define GDK_DISABLE_DEPRECATION_WARNINGS - -#include <gtk/gtk.h> - -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif - -struct { const gchar *filename; guint merge_id; } merge_ids[] = { - { "merge-1.ui", 0 }, - { "merge-2.ui", 0 }, - { "merge-3.ui", 0 } -}; - -static void -dump_tree (GtkWidget *button, - GtkUIManager *merge) -{ - gchar *dump; - - dump = gtk_ui_manager_get_ui (merge); - g_message ("%s", dump); - g_free (dump); -} - -static void -dump_accels (void) -{ - gtk_accel_map_save_fd (STDOUT_FILENO); -} - -static void -print_toplevel (GtkWidget *widget, gpointer user_data) -{ - g_print ("%s\n", G_OBJECT_TYPE_NAME (widget)); -} - -static void -dump_toplevels (GtkWidget *button, - GtkUIManager *merge) -{ - GSList *toplevels; - - toplevels = gtk_ui_manager_get_toplevels (merge, - GTK_UI_MANAGER_MENUBAR | - GTK_UI_MANAGER_TOOLBAR | - GTK_UI_MANAGER_POPUP); - - g_slist_foreach (toplevels, (GFunc) print_toplevel, NULL); - g_slist_free (toplevels); -} - -static gint -delayed_toggle_dynamic (GtkUIManager *merge) -{ - GtkAction *dyn; - static GtkActionGroup *dynamic = NULL; - static guint merge_id = 0; - - if (!dynamic) - { - dynamic = gtk_action_group_new ("dynamic"); - gtk_ui_manager_insert_action_group (merge, dynamic, 0); - dyn = g_object_new (GTK_TYPE_ACTION, - "name", "dyn1", - "label", "Dynamic action 1", - "stock_id", NULL, - NULL); - gtk_action_group_add_action (dynamic, dyn); - dyn = g_object_new (GTK_TYPE_ACTION, - "name", "dyn2", - "label", "Dynamic action 2", - "stock_id", NULL, - NULL); - gtk_action_group_add_action (dynamic, dyn); - } - - if (merge_id == 0) - { - merge_id = gtk_ui_manager_new_merge_id (merge); - gtk_ui_manager_add_ui (merge, merge_id, "/toolbar1/ToolbarPlaceholder", - "dyn1", "dyn1", 0, 0); - gtk_ui_manager_add_ui (merge, merge_id, "/toolbar1/ToolbarPlaceholder", - "dynsep", NULL, GTK_UI_MANAGER_SEPARATOR, 0); - gtk_ui_manager_add_ui (merge, merge_id, "/toolbar1/ToolbarPlaceholder", - "dyn2", "dyn2", 0, 0); - - gtk_ui_manager_add_ui (merge, merge_id, "/menubar/EditMenu", - "dyn1menu", "dyn1", GTK_UI_MANAGER_MENU, 0); - gtk_ui_manager_add_ui (merge, merge_id, "/menubar/EditMenu/dyn1menu", - "dyn1", "dyn1", GTK_UI_MANAGER_MENUITEM, 0); - gtk_ui_manager_add_ui (merge, merge_id, "/menubar/EditMenu/dyn1menu/dyn1", - "dyn2", "dyn2", GTK_UI_MANAGER_AUTO, FALSE); - } - else - { - gtk_ui_manager_remove_ui (merge, merge_id); - merge_id = 0; - } - - return FALSE; -} - -static void -toggle_dynamic (GtkWidget *button, - GtkUIManager *merge) -{ - gdk_threads_add_timeout (2000, (GSourceFunc)delayed_toggle_dynamic, merge); -} - -static void -activate_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", name, typename); -} - -static GtkActionEntry entries[] = { - { "FileMenuAction", NULL, "_File" }, - { "EditMenuAction", NULL, "_Edit" }, - { "HelpMenuAction", NULL, "_Help" }, - { "JustifyMenuAction", NULL, "_Justify" }, - { "EmptyMenu1Action", NULL, "Empty 1" }, - { "EmptyMenu2Action", NULL, "Empty 2" }, - { "Test", NULL, "Test" }, - - { "QuitAction", NULL, NULL, "<control>q", "Quit", G_CALLBACK (gtk_main_quit) }, - { "NewAction", NULL, NULL, "<control>n", "Create something", G_CALLBACK (activate_action) }, - { "New2Action", NULL, NULL, "<control>m", "Create something else", G_CALLBACK (activate_action) }, - { "OpenAction", NULL, NULL, NULL, "Open it", G_CALLBACK (activate_action) }, - { "CutAction", NULL, NULL, "<control>x", "Knive", G_CALLBACK (activate_action) }, - { "CopyAction", NULL, NULL, "<control>c", "Copy", G_CALLBACK (activate_action) }, - { "PasteAction", NULL, NULL, "<control>v", "Paste", G_CALLBACK (activate_action) }, - { "AboutAction", NULL, "_About", NULL, "About", G_CALLBACK (activate_action) }, -}; -static guint n_entries = G_N_ELEMENTS (entries); - -enum { - JUSTIFY_LEFT, - JUSTIFY_CENTER, - JUSTIFY_RIGHT, - JUSTIFY_FILL -}; - -static void -add_widget (GtkUIManager *merge, - GtkWidget *widget, - GtkBox *box) -{ - gtk_box_pack_start (box, widget, FALSE, FALSE); - gtk_widget_show (widget); -} - -static void -toggle_merge (GtkWidget *button, - GtkUIManager *merge) -{ - gint mergenum; - - mergenum = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "mergenum")); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) - { - GError *err = NULL; - - g_message ("merging %s", merge_ids[mergenum].filename); - merge_ids[mergenum].merge_id = - gtk_ui_manager_add_ui_from_file (merge, merge_ids[mergenum].filename, &err); - if (err != NULL) - { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)), - 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - "could not merge %s: %s", merge_ids[mergenum].filename, - err->message); - - g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show (dialog); - - g_clear_error (&err); - } - } - else - { - g_message ("unmerging %s (merge_id=%u)", merge_ids[mergenum].filename, - merge_ids[mergenum].merge_id); - gtk_ui_manager_remove_ui (merge, merge_ids[mergenum].merge_id); - } -} - -static void -set_name_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkAction *action; - char *name; - - gtk_tree_model_get (tree_model, iter, 0, &action, -1); - g_object_get (action, "name", &name, NULL); - g_object_set (cell, "text", name, NULL); - g_free (name); - g_object_unref (action); -} - -static void -set_sensitive_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkAction *action; - gboolean sensitive; - - gtk_tree_model_get (tree_model, iter, 0, &action, -1); - g_object_get (action, "sensitive", &sensitive, NULL); - g_object_set (cell, "active", sensitive, NULL); - g_object_unref (action); -} - - -static void -set_visible_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkAction *action; - gboolean visible; - - gtk_tree_model_get (tree_model, iter, 0, &action, -1); - g_object_get (action, "visible", &visible, NULL); - g_object_set (cell, "active", visible, NULL); - g_object_unref (action); -} - -static void -sensitivity_toggled (GtkCellRendererToggle *cell, - const gchar *path_str, - GtkTreeModel *model) -{ - GtkTreePath *path; - GtkTreeIter iter; - GtkAction *action; - gboolean sensitive; - - path = gtk_tree_path_new_from_string (path_str); - gtk_tree_model_get_iter (model, &iter, path); - - gtk_tree_model_get (model, &iter, 0, &action, -1); - g_object_get (action, "sensitive", &sensitive, NULL); - g_object_set (action, "sensitive", !sensitive, NULL); - gtk_tree_model_row_changed (model, path, &iter); - gtk_tree_path_free (path); -} - -static void -visibility_toggled (GtkCellRendererToggle *cell, - const gchar *path_str, - GtkTreeModel *model) -{ - GtkTreePath *path; - GtkTreeIter iter; - GtkAction *action; - gboolean visible; - - path = gtk_tree_path_new_from_string (path_str); - gtk_tree_model_get_iter (model, &iter, path); - - gtk_tree_model_get (model, &iter, 0, &action, -1); - g_object_get (action, "visible", &visible, NULL); - g_object_set (action, "visible", !visible, NULL); - gtk_tree_model_row_changed (model, path, &iter); - gtk_tree_path_free (path); -} - -static gint -iter_compare_func (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - GValue a_value = G_VALUE_INIT, b_value = G_VALUE_INIT; - GtkAction *a_action, *b_action; - const gchar *a_name, *b_name; - gint retval = 0; - - gtk_tree_model_get_value (model, a, 0, &a_value); - gtk_tree_model_get_value (model, b, 0, &b_value); - a_action = GTK_ACTION (g_value_get_object (&a_value)); - b_action = GTK_ACTION (g_value_get_object (&b_value)); - - a_name = gtk_action_get_name (a_action); - b_name = gtk_action_get_name (b_action); - if (a_name == NULL && b_name == NULL) - retval = 0; - else if (a_name == NULL) - retval = -1; - else if (b_name == NULL) - retval = 1; - else - retval = strcmp (a_name, b_name); - - g_value_unset (&b_value); - g_value_unset (&a_value); - - return retval; -} - -static GtkWidget * -create_tree_view (GtkUIManager *merge) -{ - GtkWidget *tree_view, *sw; - GtkListStore *store; - GList *p; - GtkCellRenderer *cell; - - store = gtk_list_store_new (1, GTK_TYPE_ACTION); - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), 0, - iter_compare_func, NULL, NULL); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), 0, - GTK_SORT_ASCENDING); - - for (p = gtk_ui_manager_get_action_groups (merge); p; p = p->next) - { - GList *actions, *l; - - actions = gtk_action_group_list_actions (p->data); - - for (l = actions; l; l = l->next) - { - GtkTreeIter iter; - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, l->data, -1); - } - - g_list_free (actions); - } - - tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); - g_object_unref (store); - - gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view), - -1, "Action", - gtk_cell_renderer_text_new (), - set_name_func, NULL, NULL); - - gtk_tree_view_column_set_sort_column_id (gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 0), 0); - - cell = gtk_cell_renderer_toggle_new (); - g_signal_connect (cell, "toggled", G_CALLBACK (sensitivity_toggled), store); - gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view), - -1, "Sensitive", - cell, - set_sensitive_func, NULL, NULL); - - cell = gtk_cell_renderer_toggle_new (); - g_signal_connect (cell, "toggled", G_CALLBACK (visibility_toggled), store); - gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view), - -1, "Visible", - cell, - set_visible_func, NULL, NULL); - - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (sw), tree_view); - - return sw; -} - -static gboolean -area_press (GtkWidget *drawing_area, - GdkEventButton *event, - GtkUIManager *merge) -{ - gtk_widget_grab_focus (drawing_area); - - if (gdk_event_triggers_context_menu ((GdkEvent *) event) && - event->type == GDK_BUTTON_PRESS) - { - GtkWidget *menu = gtk_ui_manager_get_widget (merge, "/FileMenu"); - - if (GTK_IS_MENU (menu)) - { - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, - NULL, drawing_area, - 3, event->time); - return TRUE; - } - } - - return FALSE; - -} - -static void -activate_path (GtkWidget *button, - GtkUIManager *merge) -{ - GtkAction *action = gtk_ui_manager_get_action (merge, - "/menubar/HelpMenu/About"); - if (action) - gtk_action_activate (action); - else - g_message ("no action found"); -} - -typedef struct _ActionStatus ActionStatus; - -struct _ActionStatus { - GtkAction *action; - GtkWidget *statusbar; -}; - -static void -action_status_destroy (gpointer data) -{ - ActionStatus *action_status = data; - - g_object_unref (action_status->action); - g_object_unref (action_status->statusbar); - - g_free (action_status); -} - -static void -set_tip (GtkWidget *widget) -{ - ActionStatus *data; - gchar *tooltip; - - data = g_object_get_data (G_OBJECT (widget), "action-status"); - - if (data) - { - g_object_get (data->action, "tooltip", &tooltip, NULL); - - gtk_statusbar_push (GTK_STATUSBAR (data->statusbar), 0, - tooltip ? tooltip : ""); - - g_free (tooltip); - } -} - -static void -unset_tip (GtkWidget *widget) -{ - ActionStatus *data; - - data = g_object_get_data (G_OBJECT (widget), "action-status"); - - if (data) - gtk_statusbar_pop (GTK_STATUSBAR (data->statusbar), 0); -} - -static void -connect_proxy (GtkUIManager *merge, - GtkAction *action, - GtkWidget *proxy, - GtkWidget *statusbar) -{ - if (GTK_IS_MENU_ITEM (proxy)) - { - ActionStatus *data; - - data = g_object_get_data (G_OBJECT (proxy), "action-status"); - if (data) - { - g_object_unref (data->action); - g_object_unref (data->statusbar); - - data->action = g_object_ref (action); - data->statusbar = g_object_ref (statusbar); - } - else - { - data = g_new0 (ActionStatus, 1); - - data->action = g_object_ref (action); - data->statusbar = g_object_ref (statusbar); - - g_object_set_data_full (G_OBJECT (proxy), "action-status", - data, action_status_destroy); - - g_signal_connect (proxy, "select", G_CALLBACK (set_tip), NULL); - g_signal_connect (proxy, "deselect", G_CALLBACK (unset_tip), NULL); - } - } -} - -int -main (int argc, char **argv) -{ - GtkActionGroup *action_group; - GtkAction *action; - GtkUIManager *merge; - GtkWidget *window, *grid, *frame, *menu_box, *vbox, *view; - GtkWidget *button, *area, *statusbar; - GtkWidget *box; - gint i; - - gtk_init (&argc, &argv); - - action_group = gtk_action_group_new ("TestActions"); - gtk_action_group_add_actions (action_group, - entries, n_entries, - NULL); - action = gtk_action_group_get_action (action_group, "EmptyMenu1Action"); - g_object_set (action, "hide_if_empty", FALSE, NULL); - action = gtk_action_group_get_action (action_group, "EmptyMenu2Action"); - g_object_set (action, "hide_if_empty", TRUE, NULL); - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), -1, 400); - g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); - - grid = gtk_grid_new (); - gtk_grid_set_row_spacing (GTK_GRID (grid), 2); - gtk_grid_set_column_spacing (GTK_GRID (grid), 2); - gtk_container_add (GTK_CONTAINER (window), grid); - - frame = gtk_frame_new ("Menus and Toolbars"); - gtk_grid_attach (GTK_GRID (grid), frame, 0, 1, 2, 1); - - menu_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER (frame), menu_box); - - statusbar = gtk_statusbar_new (); - gtk_box_pack_end (GTK_BOX (menu_box), statusbar, FALSE, FALSE); - - area = gtk_drawing_area_new (); - gtk_widget_set_events (area, GDK_BUTTON_PRESS_MASK); - gtk_widget_set_size_request (area, -1, 40); - gtk_box_pack_end (GTK_BOX (menu_box), area, FALSE, FALSE); - gtk_widget_show (area); - - button = gtk_button_new (); - gtk_box_pack_end (GTK_BOX (menu_box), button, FALSE, FALSE); - - gtk_widget_show (button); - - button = gtk_check_button_new (); - gtk_box_pack_end (GTK_BOX (menu_box), button, FALSE, FALSE); - gtk_widget_show (button); - - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_end (GTK_BOX (menu_box), box, FALSE, FALSE); - gtk_container_add (GTK_CONTAINER (box), gtk_label_new ("Bold:")); - button = gtk_switch_new (); - gtk_container_add (GTK_CONTAINER (box), button); - gtk_widget_show_all (box); - - merge = gtk_ui_manager_new (); - - g_signal_connect (merge, "connect-proxy", G_CALLBACK (connect_proxy), statusbar); - g_signal_connect (area, "button_press_event", G_CALLBACK (area_press), merge); - - gtk_ui_manager_insert_action_group (merge, action_group, 0); - g_signal_connect (merge, "add_widget", G_CALLBACK (add_widget), menu_box); - - gtk_window_add_accel_group (GTK_WINDOW (window), - gtk_ui_manager_get_accel_group (merge)); - - frame = gtk_frame_new ("UI Files"); - gtk_widget_set_vexpand (frame, TRUE); - gtk_grid_attach (GTK_GRID (grid), frame, 0, 0, 1, 1); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); - gtk_container_add (GTK_CONTAINER (frame), vbox); - - for (i = 0; i < G_N_ELEMENTS (merge_ids); i++) - { - button = gtk_check_button_new_with_label (merge_ids[i].filename); - g_object_set_data (G_OBJECT (button), "mergenum", GINT_TO_POINTER (i)); - g_signal_connect (button, "toggled", G_CALLBACK (toggle_merge), merge); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); - } - - button = gtk_check_button_new_with_label ("Dynamic"); - g_signal_connect (button, "clicked", G_CALLBACK (toggle_dynamic), merge); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE); - - button = gtk_button_new_with_label ("Activate path"); - g_signal_connect (button, "clicked", G_CALLBACK (activate_path), merge); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE); - - button = gtk_button_new_with_label ("Dump Tree"); - g_signal_connect (button, "clicked", G_CALLBACK (dump_tree), merge); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE); - - button = gtk_button_new_with_label ("Dump Toplevels"); - g_signal_connect (button, "clicked", G_CALLBACK (dump_toplevels), merge); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE); - - button = gtk_button_new_with_label ("Dump Accels"); - g_signal_connect (button, "clicked", G_CALLBACK (dump_accels), NULL); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE); - - view = create_tree_view (merge); - gtk_widget_set_hexpand (view, TRUE); - gtk_widget_set_vexpand (view, TRUE); - gtk_grid_attach (GTK_GRID (grid), view, 1, 0, 1, 1); - - gtk_widget_show_all (window); - gtk_main (); - -#ifdef DEBUG_UI_MANAGER - { - GList *action; - - g_print ("\n> before unreffing the ui manager <\n"); - for (action = gtk_action_group_list_actions (action_group); - action; - action = action->next) - { - GtkAction *a = action->data; - g_print (" action %s ref count %d\n", - gtk_action_get_name (a), G_OBJECT (a)->ref_count); - } - } -#endif - - g_object_unref (merge); - -#ifdef DEBUG_UI_MANAGER - { - GList *action; - - g_print ("\n> after unreffing the ui manager <\n"); - for (action = gtk_action_group_list_actions (action_group); - action; - action = action->next) - { - GtkAction *a = action->data; - g_print (" action %s ref count %d\n", - gtk_action_get_name (a), G_OBJECT (a)->ref_count); - } - } -#endif - - g_object_unref (action_group); - - return 0; -} diff --git a/testsuite/gtk/action.c b/testsuite/gtk/action.c index a727b0a0b6..61631d9efb 100644 --- a/testsuite/gtk/action.c +++ b/testsuite/gtk/action.c @@ -60,12 +60,6 @@ menu_item_label_notify_count (ActionTest *fixture, g_signal_connect (item, "notify::label", G_CALLBACK (notify_count_emmisions), &emmisions); - g_assert_cmpuint (emmisions, ==, 1); - - gtk_action_set_label (fixture->action, "new label"); - - g_assert_cmpuint (emmisions, ==, 2); - g_object_unref (item); } diff --git a/testsuite/gtk/builder.c b/testsuite/gtk/builder.c index 12db440460..36f0e0e5fd 100644 --- a/testsuite/gtk/builder.c +++ b/testsuite/gtk/builder.c @@ -302,73 +302,6 @@ test_connect_signals (void) } static void -test_uimanager_simple (void) -{ - GtkBuilder *builder; - GObject *window, *uimgr, *menubar; - GObject *menu, *label; - GList *children; - const gchar buffer[] = - "<interface>" - " <object class=\"GtkUIManager\" id=\"uimgr1\"/>" - "</interface>"; - - const gchar buffer2[] = - "<interface>" - " <object class=\"GtkUIManager\" id=\"uimgr1\">" - " <child>" - " <object class=\"GtkActionGroup\" id=\"ag1\">" - " <child>" - " <object class=\"GtkAction\" id=\"file\">" - " <property name=\"label\">_File</property>" - " </object>" - " <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>" - " </child>" - " </object>" - " </child>" - " <ui>" - " <menubar name=\"menubar1\">" - " <menu action=\"file\">" - " </menu>" - " </menubar>" - " </ui>" - " </object>" - " <object class=\"GtkWindow\" id=\"window1\">" - " <child>" - " <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>" - " </child>" - " </object>" - "</interface>"; - - builder = builder_new_from_string (buffer, -1, NULL); - - uimgr = gtk_builder_get_object (builder, "uimgr1"); - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - g_assert (GTK_IS_UI_MANAGER (uimgr)); - G_GNUC_END_IGNORE_DEPRECATIONS; - g_object_unref (builder); - - builder = builder_new_from_string (buffer2, -1, NULL); - - menubar = gtk_builder_get_object (builder, "menubar1"); - g_assert (GTK_IS_MENU_BAR (menubar)); - - children = gtk_container_get_children (GTK_CONTAINER (menubar)); - menu = children->data; - g_assert (GTK_IS_MENU_ITEM (menu)); - g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0); - g_list_free (children); - - label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu))); - g_assert (GTK_IS_LABEL (label)); - g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0); - - window = gtk_builder_get_object (builder, "window1"); - gtk_widget_destroy (GTK_WIDGET (window)); - g_object_unref (builder); -} - -static void test_domain (void) { GtkBuilder *builder; @@ -741,7 +674,6 @@ test_types (void) " <object class=\"GtkTreeView\" id=\"treeview\"/>" " <object class=\"GtkViewport\" id=\"viewport\"/>" " <object class=\"GtkWindow\" id=\"window\"/>" - " <object class=\"GtkUIManager\" id=\"uimanager\"/>" "</interface>"; const gchar buffer2[] = "<interface>" @@ -1991,7 +1923,6 @@ test_add_objects (void) GError *error; gint ret; GObject *obj; - GtkUIManager *manager; GtkWidget *menubar; GObject *menu, *label; GList *children; @@ -2034,7 +1965,7 @@ test_add_objects (void) "<interface/>"; const gchar buffer2[] = "<interface>" - " <object class=\"GtkUIManager\" id=\"uimgr1\">" + " <object class=\"GtkLabel\" id=\"uimgr1\">" " <child>" " <object class=\"GtkActionGroup\" id=\"ag1\">" " <child>" @@ -2092,7 +2023,7 @@ test_add_objects (void) ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects3, &error); g_assert (ret); obj = gtk_builder_get_object (builder, "uimgr1"); - g_assert (GTK_IS_UI_MANAGER (obj)); + g_assert (GTK_IS_LABEL (obj)); obj = gtk_builder_get_object (builder, "file"); g_assert (GTK_IS_ACTION (obj)); obj = gtk_builder_get_object (builder, "menubar1"); @@ -2119,12 +2050,6 @@ test_add_objects (void) ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects4, &error); g_assert (ret); obj = gtk_builder_get_object (builder, "uimgr1"); - g_assert (GTK_IS_UI_MANAGER (obj)); - manager = GTK_UI_MANAGER (obj); - obj = gtk_builder_get_object (builder, "file"); - g_assert (GTK_IS_ACTION (obj)); - menubar = gtk_ui_manager_get_widget (manager, "/menubar1"); - g_assert (GTK_IS_MENU_BAR (menubar)); children = gtk_container_get_children (GTK_CONTAINER (menubar)); menu = children->data; @@ -2844,7 +2769,6 @@ main (int argc, char **argv) g_test_add_func ("/Builder/Notebook", test_notebook); g_test_add_func ("/Builder/Domain", test_domain); g_test_add_func ("/Builder/Signal Autoconnect", test_connect_signals); - g_test_add_func ("/Builder/UIManager Simple", test_uimanager_simple); g_test_add_func ("/Builder/Spin Button", test_spin_button); g_test_add_func ("/Builder/SizeGroup", test_sizegroup); g_test_add_func ("/Builder/ListStore", test_list_store); diff --git a/testsuite/gtk/notify.c b/testsuite/gtk/notify.c index b0b0be072e..c8eb0a9fb6 100644 --- a/testsuite/gtk/notify.c +++ b/testsuite/gtk/notify.c @@ -362,8 +362,7 @@ test_type (gconstpointer data) /* Deprecated, not getting fixed */ if (g_str_equal (g_type_name (type), "GtkColorSelection") || - g_str_equal (g_type_name (type), "GtkNumerableIcon") || - g_str_equal (g_type_name (type), "GtkUIManager")) + g_str_equal (g_type_name (type), "GtkNumerableIcon")) return; /* These can't be freely constructed/destroyed */ |