Beispiel #1
0
Datei: menus.c Projekt: GNOME/dia
GtkAction *
menus_get_action (const gchar *name)
{
  GtkAction *action;

  action = gtk_action_group_get_action (toolbox_actions, name);
  if (!action)
    action = gtk_action_group_get_action (display_actions, name);
  if (!action)
    action = gtk_action_group_get_action (tool_actions, name);
  if (!action) {
    GList *groups, *list;

    /* search everything there is, could probably replace the above */
    if (display_ui_manager) /* classic mode */
      groups = gtk_ui_manager_get_action_groups (display_ui_manager);
    else
      groups = gtk_ui_manager_get_action_groups (_ui_manager);
    for (list = groups; list != NULL; list = list->next) {
      action = gtk_action_group_get_action (GTK_ACTION_GROUP (list->data), name);
      if (action)
	break;
    }
  }

  return action;
}
Beispiel #2
0
static GtkActionGroup *get_named_group (GtkUIManager *uim,
					const char *name, 
					int *newgroup)
{
    GList *list = gtk_ui_manager_get_action_groups(uim); 
    GtkActionGroup *actions = NULL;

    while (list != NULL) {
	GtkActionGroup *group = list->data;

	if (!strcmp(gtk_action_group_get_name(group), name)) {
	    actions = group;
	    break;
	}
	list = list->next;
    } 

    if (actions == NULL) {
	actions = gtk_action_group_new(name);
	gtk_action_group_set_translation_domain(actions, "gretl");
	*newgroup = 1;
    } else {
	*newgroup = 0;
    }

    return actions;
}
Beispiel #3
0
int vwin_menu_add_item_unique (windata_t *vwin, 
			       const gchar *aname, 
			       const gchar *path, 
			       GtkActionEntry *entry)
{
    GList *list = gtk_ui_manager_get_action_groups(vwin->ui);
    GtkActionGroup *actions;
    guint id;

    while (list != NULL) {
	GtkActionGroup *group = list->data;

	if (!strcmp(aname, gtk_action_group_get_name(group))) {
	    gtk_ui_manager_remove_action_group(vwin->ui, group);
	    break;
	}
	list = list->next;
    }

    id = gtk_ui_manager_new_merge_id(vwin->ui);
    actions = gtk_action_group_new(aname);
    gtk_action_group_set_translation_domain(actions, "gretl");

    gtk_action_group_add_actions(actions, entry, 1, vwin);
    gtk_ui_manager_add_ui(vwin->ui, id, path, entry->name, entry->name,
			  GTK_UI_MANAGER_MENUITEM, FALSE);

    gtk_ui_manager_insert_action_group(vwin->ui, actions, 0);
    g_object_unref(actions);
	
    return id;
}
static gboolean
gimp_color_panel_button_press (GtkWidget      *widget,
                               GdkEventButton *bevent)
{
  if (gdk_event_triggers_context_menu ((GdkEvent *) bevent))
    {
      GimpColorButton *color_button;
      GimpColorPanel  *color_panel;
      GtkUIManager    *ui_manager;
      GtkActionGroup  *group;
      GtkAction       *action;
      GimpRGB          color;

      color_button = GIMP_COLOR_BUTTON (widget);
      color_panel  = GIMP_COLOR_PANEL (widget);
      ui_manager   = GTK_UI_MANAGER (color_button->popup_menu);

      group = gtk_ui_manager_get_action_groups (ui_manager)->data;

      action = gtk_action_group_get_action (group,
                                            "color-button-use-foreground");
      gtk_action_set_visible (action, color_panel->context != NULL);

      action = gtk_action_group_get_action (group,
                                            "color-button-use-background");
      gtk_action_set_visible (action, color_panel->context != NULL);

      if (color_panel->context)
        {
          action = gtk_action_group_get_action (group,
                                                "color-button-use-foreground");
          gimp_context_get_foreground (color_panel->context, &color);
          g_object_set (action, "color", &color, NULL);

          action = gtk_action_group_get_action (group,
                                                "color-button-use-background");
          gimp_context_get_background (color_panel->context, &color);
          g_object_set (action, "color", &color, NULL);
        }

      action = gtk_action_group_get_action (group, "color-button-use-black");
      gimp_rgba_set (&color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
      g_object_set (action, "color", &color, NULL);

      action = gtk_action_group_get_action (group, "color-button-use-white");
      gimp_rgba_set (&color, 1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
      g_object_set (action, "color", &color, NULL);
    }

  if (GTK_WIDGET_CLASS (parent_class)->button_press_event)
    return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, bevent);

  return FALSE;
}
Beispiel #5
0
static GtkActionGroup *
find_action_group (GtkUIManager *manager,
		   const char *name)
{
	GList *list, *element;

	list = gtk_ui_manager_get_action_groups (manager);
	element = g_list_find_custom (list, name, (GCompareFunc) find_name);
	g_return_val_if_fail (element != NULL, NULL);

	return GTK_ACTION_GROUP (element->data);
}
Beispiel #6
0
static void
gimp_ui_manager_real_update (GimpUIManager *manager,
                             gpointer       update_data)
{
  GList *list;

  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
       list;
       list = g_list_next (list))
    {
      gimp_action_group_update (list->data, update_data);
    }
}
Beispiel #7
0
static gboolean
gimp_controllers_event_mapped (GimpControllerInfo        *info,
                               GimpController            *controller,
                               const GimpControllerEvent *event,
                               const gchar               *action_name,
                               GimpControllerManager     *manager)
{
  GtkUIManager *ui_manager = GTK_UI_MANAGER (manager->ui_manager);
  GList        *list;

  for (list = gtk_ui_manager_get_action_groups (ui_manager);
       list;
       list = g_list_next (list))
    {
      GtkActionGroup *group = list->data;
      GtkAction      *action;

      action = gtk_action_group_get_action (group, action_name);

      if (action)
        {
          switch (event->type)
            {
            case GIMP_CONTROLLER_EVENT_VALUE:
              if (G_VALUE_HOLDS_DOUBLE (&event->value.value) &&
                  GIMP_IS_ENUM_ACTION (action)               &&
                  GIMP_ENUM_ACTION (action)->value_variable)
                {
                  gdouble value = g_value_get_double (&event->value.value);

                  gimp_enum_action_selected (GIMP_ENUM_ACTION (action),
                                             value * 1000);

                  break;
                }
              /* else fallthru */

            case GIMP_CONTROLLER_EVENT_TRIGGER:
            default:
              gtk_action_activate (action);
              break;
            }

          return TRUE;
        }
    }

  return FALSE;
}
Beispiel #8
0
static void
rbuimanager_mark(void *p)
{
    GtkUIManager *manager;
    GList *node;

    manager = GTK_UI_MANAGER(p);
    for (node = gtk_ui_manager_get_action_groups(manager);
         node;
         node = g_list_next(node)) {
        GtkWidget *action_group = node->data;
        rbgobj_gc_mark_instance(action_group);
    }

    rbgobj_gc_mark_instance(gtk_ui_manager_get_accel_group(manager));
}
GtkActionGroup *
giggle_ui_manager_get_action_group (GtkUIManager *manager,
				    const char   *group_name)
{
	GList *groups;

	groups = gtk_ui_manager_get_action_groups (manager);

	while (groups) {
		if (!g_strcmp0 (group_name,
				gtk_action_group_get_name (groups->data)))
			return groups->data;

		groups = groups->next;
	}

	return NULL;
}
/**
 * _rb_source_register_action_group:
 * @source: a #RBSource
 * @group_name: action group name
 * @actions: array of GtkActionEntry structures for the action group
 * @num_actions: number of actions in the @actions array
 * @user_data: user data to use for action signal handlers
 *
 * Creates and registers a GtkActionGroup for the source.
 *
 * Return value: the created action group
 */
GtkActionGroup *
_rb_source_register_action_group (RBSource *source,
				  const char *group_name,
				  GtkActionEntry *actions,
				  int num_actions,
				  gpointer user_data)
{
	GtkUIManager *uimanager;
	GList *actiongroups;
	GList *i;
	GtkActionGroup *group;

	g_return_val_if_fail (group_name != NULL, NULL);

	g_object_get (source, "ui-manager", &uimanager, NULL);
	actiongroups = gtk_ui_manager_get_action_groups (uimanager);

	/* Don't create the action group if it's already registered */
	for (i = actiongroups; i != NULL; i = i->next) {
		const char *name;

		name = gtk_action_group_get_name (GTK_ACTION_GROUP (i->data));
		if (name != NULL && strcmp (name, group_name) == 0) {
			group = GTK_ACTION_GROUP (i->data);
			/* Add a reference */
			g_object_ref (group);
			goto out;
		}
	}

	group = gtk_action_group_new (group_name);
	gtk_action_group_set_translation_domain (group,
						 GETTEXT_PACKAGE);
	gtk_action_group_add_actions (group,
				      actions, num_actions,
				      user_data);
	gtk_ui_manager_insert_action_group (uimanager, group, 0);

 out:
	g_object_unref (uimanager);

	return group;
}
Beispiel #11
0
static GtkActionGroup *
find_action_group (GtkUIManager *uimanager, const char *group_name)
{
	GList *actiongroups;
	GList *i;
	actiongroups = gtk_ui_manager_get_action_groups (uimanager);

	/* Don't create the action group if it's already registered */
	for (i = actiongroups; i != NULL; i = i->next) {
		const char *name;

		name = gtk_action_group_get_name (GTK_ACTION_GROUP (i->data));
		if (name != NULL && strcmp (name, group_name) == 0) {
			return GTK_ACTION_GROUP (i->data);
		}
	}

	return NULL;
}
Beispiel #12
0
GimpActionGroup *
gimp_ui_manager_get_action_group (GimpUIManager *manager,
                                  const gchar   *name)
{
  GList *list;

  g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
       list;
       list = g_list_next (list))
    {
      GimpActionGroup *group = list->data;

      if (! strcmp (name, gtk_action_group_get_name (GTK_ACTION_GROUP (group))))
        return group;
    }

  return NULL;
}
static GtkAction *
find_action (EggEditableToolbar *etoolbar,
	     const char         *name)
{
  GList *l;
  GtkAction *action = NULL;

  l = gtk_ui_manager_get_action_groups (etoolbar->priv->manager);

  g_return_val_if_fail (name != NULL, NULL);

  for (; l != NULL; l = l->next)
    {
      GtkAction *tmp;

      tmp = gtk_action_group_get_action (GTK_ACTION_GROUP (l->data), name);
      if (tmp)
	action = tmp;
    }

  return action;
}
Beispiel #14
0
GtkAction *
gimp_ui_manager_find_action (GimpUIManager *manager,
                             const gchar   *group_name,
                             const gchar   *action_name)
{
  GimpActionGroup *group;
  GtkAction       *action = NULL;

  g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL);
  g_return_val_if_fail (action_name != NULL, NULL);

  if (group_name)
    {
      group = gimp_ui_manager_get_action_group (manager, group_name);

      if (group)
        action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
                                              action_name);
    }
  else
    {
      GList *list;

      for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
           list;
           list = g_list_next (list))
        {
          group = list->data;

          action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
                                                action_name);

          if (action)
            break;
        }
    }

  return action;
}
static GtkAction *
find_action (EggToolbarEditor *t,
	     const char       *name)
{
  GList *l;
  GtkAction *action = NULL;

  l = gtk_ui_manager_get_action_groups (t->priv->manager);

  g_return_val_if_fail (EGG_IS_TOOLBAR_EDITOR (t), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  for (; l != NULL; l = l->next)
    {
      GtkAction *tmp;

      tmp = gtk_action_group_get_action (GTK_ACTION_GROUP (l->data), name);
      if (tmp)
	action = tmp;
    }

  return action;
}
Beispiel #16
0
int
clip_GTK_UIMANAGERGETACTIONGROUPS(ClipMachine * ClipMachineMemory)
{
   C_object *cmanager = _fetch_co_arg(ClipMachineMemory);

   GList    *list;

   CHECKARG2(1, MAP_type_of_ClipVarType, NUMERIC_type_of_ClipVarType);
   CHECKCOBJ(cmanager, GTK_IS_UI_MANAGER(cmanager->object));

   list = gtk_ui_manager_get_action_groups(GTK_UI_MANAGER(cmanager->object));

   if (list)
    {
       ClipVar  *cv = RETPTR(ClipMachineMemory);

       long      n = g_list_length(list);

       _clip_array(ClipMachineMemory, cv, 1, &n);
       for (n = 0; list; list = g_list_next(list))
	{
	   C_object *cgaction;

	   GtkActionGroup *gaction;

	   gaction = list->data;
	   cgaction = _list_get_cobject(ClipMachineMemory, gaction);
	   if (!cgaction)
	      cgaction = _register_object(ClipMachineMemory, gaction, GTK_TYPE_ACTION_GROUP, NULL, NULL);
	   if (cgaction)
	      _clip_aset(ClipMachineMemory, cv, &cgaction->obj, 1, &n);
	}
    }
   return 0;
 err:
   return 1;
}
Beispiel #17
0
GtkWidget *
gimp_action_view_new (GimpUIManager *manager,
                      const gchar   *select_action,
                      gboolean       show_shortcuts)
{
  GtkTreeView       *view;
  GtkTreeViewColumn *column;
  GtkCellRenderer   *cell;
  GtkTreeStore      *store;
  GtkTreeModel      *filter;
  GtkAccelGroup     *accel_group;
  GList             *list;
  GtkTreePath       *select_path = NULL;

  g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL);

  store = gtk_tree_store_new (GIMP_ACTION_VIEW_N_COLUMNS,
                              G_TYPE_BOOLEAN,         /* COLUMN_VISIBLE        */
                              GTK_TYPE_ACTION,        /* COLUMN_ACTION         */
                              G_TYPE_STRING,          /* COLUMN_STOCK_ID       */
                              G_TYPE_STRING,          /* COLUMN_LABEL          */
                              G_TYPE_STRING,          /* COLUMN_LABEL_CASEFOLD */
                              G_TYPE_STRING,          /* COLUMN_NAME           */
                              G_TYPE_UINT,            /* COLUMN_ACCEL_KEY      */
                              GDK_TYPE_MODIFIER_TYPE, /* COLUMN_ACCEL_MASK     */
                              G_TYPE_CLOSURE);        /* COLUMN_ACCEL_CLOSURE  */

  accel_group = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (manager));

  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
       list;
       list = g_list_next (list))
    {
      GimpActionGroup *group = list->data;
      GList           *actions;
      GList           *list2;
      GtkTreeIter      group_iter;

      gtk_tree_store_append (store, &group_iter, NULL);

      gtk_tree_store_set (store, &group_iter,
                          GIMP_ACTION_VIEW_COLUMN_STOCK_ID, group->stock_id,
                          GIMP_ACTION_VIEW_COLUMN_LABEL,    group->label,
                          -1);

      actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));

      actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare);

      for (list2 = actions; list2; list2 = g_list_next (list2))
        {
          GtkAction       *action        = list2->data;
          const gchar     *name          = gtk_action_get_name (action);
          const gchar     *stock_id      = gtk_action_get_stock_id (action);
          gchar           *label;
          gchar           *label_casefold;
          guint            accel_key     = 0;
          GdkModifierType  accel_mask    = 0;
          GClosure        *accel_closure = NULL;
          GtkTreeIter      action_iter;

          if (strstr (name, "-menu")  ||
              strstr (name, "-popup") ||
              name[0] == '<')
            continue;

          label = gimp_strip_uline (gtk_action_get_label (action));

          if (! (label && strlen (label)))
            {
              g_free (label);
              label = g_strdup (name);
            }

          label_casefold = g_utf8_casefold (label, -1);

          if (show_shortcuts)
            {
              accel_closure = gtk_action_get_accel_closure (action);

              if (accel_closure)
                {
                  GtkAccelKey *key;

                  key = gtk_accel_group_find (accel_group,
                                              gimp_action_view_accel_find_func,
                                              accel_closure);

                  if (key            &&
                      key->accel_key &&
                      key->accel_flags & GTK_ACCEL_VISIBLE)
                    {
                      accel_key  = key->accel_key;
                      accel_mask = key->accel_mods;
                    }
                }
            }

          gtk_tree_store_append (store, &action_iter, &group_iter);

          gtk_tree_store_set (store, &action_iter,
                              GIMP_ACTION_VIEW_COLUMN_VISIBLE,        TRUE,
                              GIMP_ACTION_VIEW_COLUMN_ACTION,         action,
                              GIMP_ACTION_VIEW_COLUMN_STOCK_ID,       stock_id,
                              GIMP_ACTION_VIEW_COLUMN_LABEL,          label,
                              GIMP_ACTION_VIEW_COLUMN_LABEL_CASEFOLD, label_casefold,
                              GIMP_ACTION_VIEW_COLUMN_NAME,           name,
                              GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY,      accel_key,
                              GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK,     accel_mask,
                              GIMP_ACTION_VIEW_COLUMN_ACCEL_CLOSURE,  accel_closure,
                              -1);

          g_free (label);
          g_free (label_casefold);

          if (select_action && ! strcmp (select_action, name))
            {
              select_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
                                                     &action_iter);
            }
        }

      g_list_free (actions);
    }

  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);

  g_object_unref (store);

  view = g_object_new (GIMP_TYPE_ACTION_VIEW,
                       "model",      filter,
                       "rules-hint", TRUE,
                       NULL);

  g_object_unref (filter);

  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
                                            GIMP_ACTION_VIEW_COLUMN_VISIBLE);

  GIMP_ACTION_VIEW (view)->manager        = g_object_ref (manager);
  GIMP_ACTION_VIEW (view)->show_shortcuts = show_shortcuts;

  gtk_tree_view_set_search_column (GTK_TREE_VIEW (view),
                                   GIMP_ACTION_VIEW_COLUMN_LABEL);

  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, _("Action"));

  cell = gtk_cell_renderer_pixbuf_new ();
  gtk_tree_view_column_pack_start (column, cell, FALSE);
  gtk_tree_view_column_set_attributes (column, cell,
                                       "stock-id",
                                       GIMP_ACTION_VIEW_COLUMN_STOCK_ID,
                                       NULL);

  cell = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell, TRUE);
  gtk_tree_view_column_set_attributes (column, cell,
                                       "text",
                                       GIMP_ACTION_VIEW_COLUMN_LABEL,
                                       NULL);

  gtk_tree_view_append_column (view, column);

  if (show_shortcuts)
    {
      g_signal_connect (view, "button-press-event",
                        G_CALLBACK (gimp_action_view_button_press),
                        NULL);

      g_signal_connect (accel_group, "accel-changed",
                        G_CALLBACK (gimp_action_view_accel_changed),
                        view);

      column = gtk_tree_view_column_new ();
      gtk_tree_view_column_set_title (column, _("Shortcut"));

      cell = gtk_cell_renderer_accel_new ();
      g_object_set (cell,
                    "mode",     GTK_CELL_RENDERER_MODE_EDITABLE,
                    "editable", TRUE,
                    NULL);
      gtk_tree_view_column_pack_start (column, cell, TRUE);
      gtk_tree_view_column_set_attributes (column, cell,
                                           "accel-key",
                                           GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY,
                                           "accel-mods",
                                           GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK,
                                           NULL);

      g_signal_connect (cell, "accel-edited",
                        G_CALLBACK (gimp_action_view_accel_edited),
                        view);
      g_signal_connect (cell, "accel-cleared",
                        G_CALLBACK (gimp_action_view_accel_cleared),
                        view);

      gtk_tree_view_append_column (view, column);
    }

  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, _("Name"));

  cell = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell, TRUE);
  gtk_tree_view_column_set_attributes (column, cell,
                                       "text",
                                       GIMP_ACTION_VIEW_COLUMN_NAME,
                                       NULL);

  gtk_tree_view_append_column (view, column);

  if (select_path)
    {
      gimp_action_view_select_path (GIMP_ACTION_VIEW (view), select_path);
      gtk_tree_path_free (select_path);
    }

  return GTK_WIDGET (view);
}
Beispiel #18
0
static VALUE
rg_action_groups(VALUE self)
{
    /* Owned by GTK+ */
    return GLIST2ARY(gtk_ui_manager_get_action_groups(_SELF(self)));
}
Beispiel #19
0
void
debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action,
                                            gpointer   data)
{
  GimpDisplay      *display;
  GimpImageWindow  *window;
  GtkUIManager     *manager;
  GtkAccelGroup    *accel_group;
  GList            *group_it;
  GList            *strings = NULL;
  return_if_no_display (display, data);

  window  = gimp_display_shell_get_window (gimp_display_get_shell (display));
  manager = GTK_UI_MANAGER (gimp_image_window_get_ui_manager (window));

  accel_group = gtk_ui_manager_get_accel_group (manager);

  /* Gather formated strings of keyboard shortcuts */
  for (group_it = gtk_ui_manager_get_action_groups (manager);
       group_it;
       group_it = g_list_next (group_it))
    {
      GimpActionGroup *group     = group_it->data;
      GList           *actions   = NULL;
      GList           *action_it = NULL;

      actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
      actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare);

      for (action_it = actions; action_it; action_it = g_list_next (action_it))
        {
          GtkAction   *action        = action_it->data;
          const gchar *name          = gtk_action_get_name (action);
          GClosure    *accel_closure = NULL;

          if (strstr (name, "-menu")  ||
              strstr (name, "-popup") ||
              name[0] == '<')
              continue;

          accel_closure = gtk_action_get_accel_closure (action);

          if (accel_closure)
            {
              GtkAccelKey *key = gtk_accel_group_find (accel_group,
                                                       debug_accel_find_func,
                                                       accel_closure);
              if (key            &&
                  key->accel_key &&
                  key->accel_flags & GTK_ACCEL_VISIBLE)
                {
                  const gchar *label_tmp;
                  gchar       *label;
                  gchar       *key_string;

                  label_tmp  = gtk_action_get_label (action);
                  label      = gimp_strip_uline (label_tmp);
                  key_string = gtk_accelerator_get_label (key->accel_key,
                                                          key->accel_mods);

                  strings = g_list_prepend (strings,
                                            g_strdup_printf ("%-20s %s",
                                                             key_string, label));

                  g_free (key_string);
                  g_free (label);
                }
            }
        }

      g_list_free (actions);
    }

  /* Sort and prints the strings */
  {
    GList *string_it = NULL;

    strings = g_list_sort (strings, (GCompareFunc) strcmp);

    for (string_it = strings; string_it; string_it = g_list_next (string_it))
      {
        g_print ("%s\n", (gchar *) string_it->data);
        g_free (string_it->data);
      }

    g_list_free (strings);
  }
}
Beispiel #20
0
gboolean
update(ParasiteActionList *actionlist)
{
    GSList *i;

    gtk_tree_store_clear(actionlist->priv->model);

    for (i = actionlist->priv->uimanagers; i != NULL; i = g_slist_next(i))
    {
        GtkUIManager *uimanager;
        GList *action_groups;
        GList *j;
        gchar *name;

        uimanager = GTK_UI_MANAGER(i->data);

        GtkTreeIter i_iter;
        gtk_tree_store_append(actionlist->priv->model, &i_iter, NULL);

        name = g_strdup_printf("UIManager at %p", uimanager);
        gtk_tree_store_set(actionlist->priv->model, &i_iter,
                           ACTION_LABEL, name,
                           SORT_NAME, name,
                           ADDRESS, uimanager,
                           -1);
        g_free(name);

        action_groups = gtk_ui_manager_get_action_groups(uimanager);
        for (j = action_groups; j != NULL; j = g_list_next(j))
        {
            GtkActionGroup *action_group;
            GtkTreeIter j_iter;
            GList *actions;
            GList *k;

            action_group = GTK_ACTION_GROUP(j->data);

            gtk_tree_store_append(actionlist->priv->model, &j_iter, &i_iter);

            name = (gchar*) gtk_action_group_get_name(action_group);
            gtk_tree_store_set(actionlist->priv->model, &j_iter,
                               ACTION_LABEL, name,
                               SORT_NAME, name,
                               ROW_COLOR, gtk_action_group_get_sensitive(action_group)
                                              ? "black" : "grey",
                               ADDRESS, action_group,
                               -1);

            actions = gtk_action_group_list_actions(action_group);
            for (k = actions; k != NULL; k = g_list_next(k))
            {
                GtkTreeIter k_iter;
                GtkAction *action;
                gchar *action_label;
                gchar *action_name;
                gchar *action_stock;
                gchar *sort_name;

                action = GTK_ACTION(k->data);
                g_object_get(action,
                             "label",    &action_label,
                             "name",     &action_name,
                             "stock-id", &action_stock,
                             NULL);

                sort_name = g_strdup_printf("%s%s", name, action_name);

                gtk_tree_store_append(actionlist->priv->model, &k_iter, &j_iter);
                // FIXME: format the mnemonic
                gtk_tree_store_set(actionlist->priv->model, &k_iter,
                                   ACTION_LABEL, action_label,
                                   ACTION_NAME, action_name,
                                   ACTION_ICON, action_stock,
                                   ROW_COLOR, gtk_action_is_sensitive(action)
                                                  ? "black" : "grey",
                                   SORT_NAME, sort_name,
                                   ADDRESS, action,
                                   -1);

                g_free(sort_name);
                g_free(action_stock);
                g_free(action_name);
                g_free(action_label);
            }
        }
    }

    // FIXME: I'm undecided about this, but I also don't really want to try to
    // preserve the exsting expansion state of the whole tree.
    gtk_tree_view_expand_all(GTK_TREE_VIEW(actionlist));

    actionlist->priv->update_timeout = 0;

    return FALSE;
}