Beispiel #1
0
static GVariant *
g_menu_exporter_menu_describe_item (GMenuExporterMenu *menu,
                                    gint               position)
{
  GMenuAttributeIter *attr_iter;
  GVariantBuilder builder;
  GSequenceIter *iter;
  GMenuExporterLink *link;
  const char *name;
  GVariant *value;

  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);

  attr_iter = g_menu_model_iterate_item_attributes (menu->model, position);
  while (g_menu_attribute_iter_get_next (attr_iter, &name, &value))
    {
      g_variant_builder_add (&builder, "{sv}", name, value);
      g_variant_unref (value);
    }
  g_object_unref (attr_iter);

  iter = g_sequence_get_iter_at_pos (menu->item_links, position);
  for (link = g_sequence_get (iter); link; link = link->next)
    g_variant_builder_add (&builder, "{sv}", link->name,
                           g_variant_new ("(uu)", g_menu_exporter_group_get_id (link->menu->group), link->menu->id));

  return g_variant_builder_end (&builder);
}
Beispiel #2
0
static void
add_accelerators_from_menu_item (GtkWindow      *window,
				 GtkAccelGroup  *accel_group,
				 GMenuModel     *model,
				 int             item)
{
	GMenuAttributeIter	*iter;
	const char		*key;
	GVariant		*value;
	const char		*accel = NULL;
	const char		*action = NULL;
	GVariant		*target = NULL;

	iter = g_menu_model_iterate_item_attributes (model, item);
	while (g_menu_attribute_iter_get_next (iter, &key, &value)) {
		if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
			action = g_variant_get_string (value, NULL);
		else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
			accel = g_variant_get_string (value, NULL);
		else if (g_str_equal (key, "target"))
			target = g_variant_ref (value);
		g_variant_unref (value);
	}
	g_object_unref (iter);

	_gtk_window_add_accelerator_for_action (window,
						accel_group,
						action,
						accel,
						target);

	if (target != NULL)
		g_variant_unref (target);
}
Beispiel #3
0
static void
extract_accel_from_menu_item(GMenuModel    * model,
                             gint            item,
                             GActionMap    * action_map,
                             GtkAccelGroup * accel_group)
{
    GMenuAttributeIter *iter;
    const gchar *key;
    GVariant *value;
    const gchar *accel = NULL;
    const gchar *action = NULL;
    GVariant *target = NULL;

    iter = g_menu_model_iterate_item_attributes(model, item);
    while (g_menu_attribute_iter_get_next(iter, &key, &value)) {
        if (g_str_equal(key, "action")
            && g_variant_is_of_type(value, G_VARIANT_TYPE_STRING))
            action = g_variant_get_string(value, NULL);
        else if (g_str_equal(key, "accel")
                 && g_variant_is_of_type(value, G_VARIANT_TYPE_STRING))
            accel = g_variant_get_string(value, NULL);
        else if (g_str_equal(key, "target"))
            target = g_variant_ref(value);
        g_variant_unref(value);
    }
    g_object_unref(iter);

    if (accel && action) {
        guint accel_key;
        GdkModifierType accel_mods;
        AccelInfo *info;
        const gchar *basename;
        GClosure *closure;

        gtk_accelerator_parse(accel, &accel_key, &accel_mods);
        basename = strchr(action, '.');
        basename = basename ? basename + 1 : action;
        info = g_new(AccelInfo, 1);
        info->action = g_action_map_lookup_action(action_map, basename);
        info->parameter = target ? g_variant_ref(target) : NULL;
        closure = g_cclosure_new(G_CALLBACK(accel_activate), info,
                                 (GClosureNotify) accel_info_free);
        gtk_accel_group_connect(accel_group, accel_key, accel_mods, 0,
                                closure);
    }

    if (target)
        g_variant_unref(target);
}
Beispiel #4
0
static gboolean
append_menu (RBButtonBar *bar, GMenuModel *menu, gboolean need_separator)
{
	int i;
	gulong id;

	id = g_signal_connect (menu, "items-changed", G_CALLBACK (items_changed_cb), bar);
	g_hash_table_insert (bar->priv->handlers, (gpointer)id, g_object_ref (menu));

	for (i = 0; i < g_menu_model_get_n_items (menu); i++) {
		char *label_text;
		char *accel;
		GtkWidget *button;
		GtkWidget *label;
		GMenuModel *submenu;

		/* recurse into sections */
		submenu = g_menu_model_get_item_link (menu, i, G_MENU_LINK_SECTION);
		if (submenu != NULL) {
			need_separator = append_menu (bar, submenu, TRUE);
			continue;
		}

		/* if this item and the previous item are in different sections, add
		 * a separator between them.  this may not be a good idea.
		 */
		if (need_separator) {
			GtkWidget *sep;

			if (bar->priv->position > 0) {
				sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
				gtk_widget_show (sep);
				g_object_set (sep, "margin-start", 6, "margin-end", 6, NULL);
				gtk_grid_attach (GTK_GRID (bar), sep, bar->priv->position++, 0, 1, 1);
			}

			need_separator = FALSE;
		}

		button = NULL;

		/* submenus become menu buttons, normal items become buttons */
		submenu = g_menu_model_get_item_link (menu, i, G_MENU_LINK_SUBMENU);

		if (submenu != NULL) {
			button = gtk_menu_button_new ();
			gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), submenu);

			g_object_set_data_full (G_OBJECT (button), "rb-menu-model", g_object_ref (submenu), (GDestroyNotify)g_object_unref);
		} else {
			GMenuAttributeIter *iter;
			const char *name;
			GVariant *value;
			char *str;
			guint signal_id;
		
			/* we can't do more than one of action and rb-property-bind
			 * and rb-signal-bind, so just do whichever turns up first
			 * in the iterator
			 */
			iter = g_menu_model_iterate_item_attributes (menu, i);
			while (g_menu_attribute_iter_get_next (iter, &name, &value)) {
				if (g_str_equal (name, "action")) {
					button = gtk_button_new ();
					g_variant_get (value, "s", &str, NULL);
					gtk_actionable_set_action_name (GTK_ACTIONABLE (button), str);
					/* action target too somehow? */
					g_free (str);
					break;
				} else if (g_str_equal (name, "rb-property-bind")) {
					/* property has to be a boolean, can't do inverts, etc. etc. */
					button = gtk_toggle_button_new ();
					g_variant_get (value, "s", &str, NULL);
					g_object_bind_property (bar->priv->target, str,
								button, "active",
								G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
					g_free (str);
					break;
				} else if (g_str_equal (name, "rb-signal-bind")) {
					button = gtk_button_new ();
					g_variant_get (value, "s", &str, NULL);
					signal_id = g_signal_lookup (str, G_OBJECT_TYPE (bar->priv->target));
					if (signal_id != 0) {
						g_object_set_data (G_OBJECT (button), "rb-signal-bind-id", GUINT_TO_POINTER (signal_id));
						g_signal_connect (button, "clicked", G_CALLBACK (signal_button_clicked_cb), bar);
					}
					g_free (str);
					break;
				}
			}

			g_object_unref (iter);
		}

		if (button == NULL) {
			g_warning ("no idea what's going on here");
			continue;
		}

		gtk_widget_set_hexpand (button, FALSE);
		gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);

		label_text = NULL;
		g_menu_model_get_item_attribute (menu, i, "label", "s", &label_text);
		label = gtk_label_new (g_dgettext (NULL, label_text));
		g_object_set (label, "margin-left", 6, "margin-right", 6, NULL);
		gtk_container_add (GTK_CONTAINER (button), label);

		if (g_menu_model_get_item_attribute (menu, i, "accel", "s", &accel)) {
			g_object_set_data_full (G_OBJECT (button), "rb-accel", accel, (GDestroyNotify) g_free);
		}

		gtk_widget_show_all (button);
		gtk_size_group_add_widget (bar->priv->size_group, button);
		gtk_grid_attach (GTK_GRID (bar), button, bar->priv->position++, 0, 1, 1);

		g_free (label_text);
	}

	return need_separator;
}
Beispiel #5
0
static GString *
g_menu_markup_print_string (GString    *string,
                            GMenuModel *model,
                            gint        indent,
                            gint        tabstop)
{
  gboolean need_nl = FALSE;
  gint i, n;

  if G_UNLIKELY (string == NULL)
    string = g_string_new (NULL);

  n = g_menu_model_get_n_items (model);

  for (i = 0; i < n; i++)
    {
      GMenuAttributeIter *attr_iter;
      GMenuLinkIter *link_iter;
      GString *contents;
      GString *attrs;

      attr_iter = g_menu_model_iterate_item_attributes (model, i);
      link_iter = g_menu_model_iterate_item_links (model, i);
      contents = g_string_new (NULL);
      attrs = g_string_new (NULL);

      while (g_menu_attribute_iter_next (attr_iter))
        {
          const char *name = g_menu_attribute_iter_get_name (attr_iter);
          GVariant *value = g_menu_attribute_iter_get_value (attr_iter);

          if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
            {
              gchar *str;
              str = g_markup_printf_escaped (" %s='%s'", name, g_variant_get_string (value, NULL));
              g_string_append (attrs, str);
              g_free (str);
            }

          else
            {
              gchar *printed;
              gchar *str;
              const gchar *type;

              printed = g_variant_print (value, TRUE);
              type = g_variant_type_peek_string (g_variant_get_type (value));
              str = g_markup_printf_escaped ("<attribute name='%s' type='%s'>%s</attribute>\n", name, type, printed);
              indent_string (contents, indent + tabstop);
              g_string_append (contents, str);
              g_free (printed);
              g_free (str);
            }

          g_variant_unref (value);
        }
      g_object_unref (attr_iter);

      while (g_menu_link_iter_next (link_iter))
        {
          const gchar *name = g_menu_link_iter_get_name (link_iter);
          GMenuModel *menu = g_menu_link_iter_get_value (link_iter);
          gchar *str;

          if (contents->str[0])
            g_string_append_c (contents, '\n');

          str = g_markup_printf_escaped ("<link name='%s'>\n", name);
          indent_string (contents, indent + tabstop);
          g_string_append (contents, str);
          g_free (str);

          g_menu_markup_print_string (contents, menu, indent + 2 * tabstop, tabstop);

          indent_string (contents, indent + tabstop);
          g_string_append (contents, "</link>\n");
          g_object_unref (menu);
        }
      g_object_unref (link_iter);

      if (contents->str[0])
        {
          indent_string (string, indent);
          g_string_append_printf (string, "<item%s>\n", attrs->str);
          g_string_append (string, contents->str);
          indent_string (string, indent);
          g_string_append (string, "</item>\n");
          need_nl = TRUE;
        }

      else
        {
          if (need_nl)
            g_string_append_c (string, '\n');

          indent_string (string, indent);
          g_string_append_printf (string, "<item%s/>\n", attrs->str);
          need_nl = FALSE;
        }

      g_string_free (contents, TRUE);
      g_string_free (attrs, TRUE);
    }

  return string;
}