|___* 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
This commit is contained in:
Johan Dahlin 2007-07-09 13:40:10 +00:00 committed by Johan Dahlin
parent 8ba20f3ebe
commit 83b5d32aef
6 changed files with 191 additions and 4 deletions

View File

@ -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

View File

@ -104,6 +104,7 @@
<property name="stock_id">gtk-about</property>
<signal handler="about_activate" name="activate"/>
</object>
<accelerator key="F1"/>
</child>
</object>
</child>

View File

@ -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)

View File

@ -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.

View File

@ -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);
}

View File

@ -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>"