summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <jdahlin@lozenge>2007-07-09 13:40:10 +0000
committerJohan Dahlin <johan@src.gnome.org>2007-07-09 13:40:10 +0000
commit83b5d32aef1156246478250c0773d3fcf1853e13 (patch)
tree5328eee3b32dcaae1c8f8710aa52b145ef3c7cbc
parent8ba20f3ebe233f2987837fbd770516365e9b4566 (diff)
downloadgdk-pixbuf-83b5d32aef1156246478250c0773d3fcf1853e13.tar.gz
|___* demos/gtk-demo/demo.ui: |___* gtk/gtk-builder-convert: |___*
2007-07-09 Johan Dahlin,,, <jdahlin@lozenge> |___* demos/gtk-demo/demo.ui: |___* gtk/gtk-builder-convert: |___* gtk/gtkactiongroup.c: (gtk_action_group_buildable_init), |___(gtk_action_group_buildable_add_child), |___(accelerator_start_element), |___(gtk_action_group_buildable_custom_tag_start), |___(gtk_action_group_buildable_custom_tag_end): |___* gtk/gtkuimanager.c: (child_hierarchy_changed_cb), |___(gtk_ui_manager_buildable_construct_child): |___* tests/buildertest.c: (test_uimanager_simple): |___Add actiongroup/action accelerator support for builder. #454654 svn path=/trunk/; revision=18408
-rw-r--r--ChangeLog15
-rw-r--r--demos/gtk-demo/demo.ui1
-rwxr-xr-xgtk/gtk-builder-convert19
-rw-r--r--gtk/gtkactiongroup.c126
-rw-r--r--gtk/gtkuimanager.c33
-rw-r--r--tests/buildertest.c1
6 files changed, 191 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index cc66a6bb8..d98a416d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2007-07-09 Johan Dahlin,,, <jdahlin@lozenge>
+
+ * demos/gtk-demo/demo.ui:
+ * gtk/gtk-builder-convert:
+ * gtk/gtkactiongroup.c: (gtk_action_group_buildable_init),
+ (gtk_action_group_buildable_add_child),
+ (accelerator_start_element),
+ (gtk_action_group_buildable_custom_tag_start),
+ (gtk_action_group_buildable_custom_tag_end):
+ * gtk/gtkuimanager.c: (child_hierarchy_changed_cb),
+ (gtk_ui_manager_buildable_construct_child):
+ * tests/buildertest.c: (test_uimanager_simple):
+
+ Add actiongroup/action accelerator support for builder. #454654
+
2007-07-08 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkbuilderparser.c (pgettext): Support old-style
diff --git a/demos/gtk-demo/demo.ui b/demos/gtk-demo/demo.ui
index 26d668997..1c84db2b5 100644
--- a/demos/gtk-demo/demo.ui
+++ b/demos/gtk-demo/demo.ui
@@ -104,6 +104,7 @@
<property name="stock_id">gtk-about</property>
<signal handler="about_activate" name="activate"/>
</object>
+ <accelerator key="F1"/>
</child>
</object>
</child>
diff --git a/gtk/gtk-builder-convert b/gtk/gtk-builder-convert
index d77f8c3d1..59218d555 100755
--- a/gtk/gtk-builder-convert
+++ b/gtk/gtk-builder-convert
@@ -92,6 +92,16 @@ def get_signal_nodes(node):
signals.append(child)
return signals
+def get_accelerator_nodes(node):
+ assert node.tagName == 'object'
+ accelerators = []
+ for child in node.childNodes:
+ if child.nodeType == Node.TEXT_NODE:
+ continue
+ if child.tagName == 'accelerator':
+ accelerators.append(child)
+ return accelerators
+
def get_object_node(child_node):
assert child_node.tagName == 'child'
nodes = []
@@ -418,6 +428,15 @@ class GtkBuilderConverter(object):
group.appendChild(child)
child.appendChild(action)
+ for accelerator in get_accelerator_nodes(node):
+ signal = accelerator.getAttribute('signal')
+ if signal_name != 'activate':
+ print 'Unhandled accelerator signal for %s::%s' % (
+ node.getAttribute('class'), signal_name)
+ continue
+ accelerator.removeAttribute('signal')
+ child.appendChild(accelerator)
+
def _convert_sizegroup(self, node, prop):
# This is Gazpacho only
node.removeChild(prop)
diff --git a/gtk/gtkactiongroup.c b/gtk/gtkactiongroup.c
index 34ca057bb..b9d6ee083 100644
--- a/gtk/gtkactiongroup.c
+++ b/gtk/gtkactiongroup.c
@@ -29,6 +29,7 @@
*/
#include <config.h>
+#include <string.h>
#include "gtkactiongroup.h"
#include "gtkbuildable.h"
@@ -39,6 +40,7 @@
#include "gtkradioaction.h"
#include "gtkaccelmap.h"
#include "gtkmarshalers.h"
+#include "gtkbuilderprivate.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtkalias.h"
@@ -97,6 +99,17 @@ static void gtk_action_group_buildable_add_child (GtkBuildable *buildable,
static void gtk_action_group_buildable_set_name (GtkBuildable *buildable,
const gchar *name);
static const gchar* gtk_action_group_buildable_get_name (GtkBuildable *buildable);
+static gboolean gtk_action_group_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_action_group_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *user_data);
GType
gtk_action_group_get_type (void)
@@ -298,6 +311,8 @@ gtk_action_group_buildable_init (GtkBuildableIface *iface)
iface->add_child = gtk_action_group_buildable_add_child;
iface->set_name = gtk_action_group_buildable_set_name;
iface->get_name = gtk_action_group_buildable_get_name;
+ iface->custom_tag_start = gtk_action_group_buildable_custom_tag_start;
+ iface->custom_tag_end = gtk_action_group_buildable_custom_tag_end;
}
static void
@@ -306,8 +321,8 @@ gtk_action_group_buildable_add_child (GtkBuildable *buildable,
GObject *child,
const gchar *type)
{
- gtk_action_group_add_action (GTK_ACTION_GROUP (buildable),
- GTK_ACTION (child));
+ gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (buildable),
+ GTK_ACTION (child), NULL);
}
static void
@@ -325,6 +340,113 @@ gtk_action_group_buildable_get_name (GtkBuildable *buildable)
return self->private_data->name;
}
+typedef struct {
+ GObject *child;
+ guint key;
+ guint modifiers;
+} AcceleratorParserData;
+
+static void
+accelerator_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ gint i;
+ guint key = 0;
+ gint modifiers = 0;
+ AcceleratorParserData *parser_data = (AcceleratorParserData*)user_data;
+
+ if (strcmp (element_name, "accelerator") != 0)
+ g_warning ("Unknown <accelerator> tag: %s", element_name);
+
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "key") == 0)
+ key = gdk_keyval_from_name (values[i]);
+ else if (strcmp (names[i], "modifiers") == 0)
+ {
+ if (!_gtk_builder_flags_from_string (GDK_TYPE_MODIFIER_TYPE,
+ values[i],
+ &modifiers,
+ error))
+ return;
+ }
+ }
+
+ if (key == 0)
+ {
+ g_warning ("<accelerator> requires a key attribute");
+ return;
+ }
+ parser_data->key = key;
+ parser_data->modifiers = (guint)modifiers;
+}
+
+static const GMarkupParser accelerator_parser =
+ {
+ accelerator_start_element
+ };
+
+static gboolean
+gtk_action_group_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *user_data)
+{
+ AcceleratorParserData *parser_data;
+
+ if (child && strcmp (tagname, "accelerator") == 0)
+ {
+ parser_data = g_slice_new0 (AcceleratorParserData);
+ parser_data->child = child;
+ *user_data = parser_data;
+ *parser = accelerator_parser;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+gtk_action_group_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *user_data)
+{
+ AcceleratorParserData *data;
+
+ if (strcmp (tagname, "accelerator") == 0)
+ {
+ GtkActionGroup *action_group;
+ GtkAction *action;
+ gchar *accel_path;
+
+ data = (AcceleratorParserData*)user_data;
+ action_group = GTK_ACTION_GROUP (buildable);
+ action = GTK_ACTION (child);
+
+ accel_path = g_strconcat ("<Actions>/",
+ action_group->private_data->name, "/",
+ gtk_action_get_name (action), NULL);
+
+ if (gtk_accel_map_lookup_entry (accel_path, NULL))
+ gtk_accel_map_change_entry (accel_path, data->key, data->modifiers, TRUE);
+ else
+ gtk_accel_map_add_entry (accel_path, data->key, data->modifiers);
+
+ gtk_action_set_accel_path (action, accel_path);
+
+ g_free (accel_path);
+ g_slice_free (AcceleratorParserData, data);
+ }
+}
+
/**
* gtk_action_group_new:
* @name: the name of the action group.
diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c
index 3e0ac69be..687567d3d 100644
--- a/gtk/gtkuimanager.c
+++ b/gtk/gtkuimanager.c
@@ -453,6 +453,29 @@ gtk_ui_manager_buildable_add_child (GtkBuildable *buildable,
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 (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,
@@ -464,10 +487,16 @@ gtk_ui_manager_buildable_construct_child (GtkBuildable *buildable,
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\n", name);
-
+ {
+ g_error ("Unknown ui manager child: %s\n", 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 (widget);
}
diff --git a/tests/buildertest.c b/tests/buildertest.c
index a6577d73f..f495f8833 100644
--- a/tests/buildertest.c
+++ b/tests/buildertest.c
@@ -259,6 +259,7 @@ gboolean test_uimanager_simple (void)
" <object class=\"GtkAction\" id=\"file\">"
" <property name=\"label\">_File</property>"
" </object>"
+ " <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
" </child>"
" </object>"
" </child>"