static void
gtk_application_window_update_shell_shows_menubar (GtkApplicationWindow *window,
                                                   GtkSettings          *settings)
{
  gboolean shown_by_shell;

  g_object_get (settings, "gtk-shell-shows-menubar", &shown_by_shell, NULL);

  if (shown_by_shell)
    {
      /* the shell shows it, so don't show it locally */
      if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)) != 0)
        g_menu_remove (window->priv->menubar_section, 0);
    }
  else
    {
      /* the shell does not show it, so make sure we show it */
      if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)) == 0)
        {
          GMenuModel *menubar;

          menubar = gtk_application_get_menubar (gtk_window_get_application (GTK_WINDOW (window)));

          if (menubar != NULL)
            g_menu_append_section (window->priv->menubar_section, NULL, menubar);
        }
    }
}
예제 #2
0
void
gw_application_set_win_menubar (GwApplication *application, GMenuModel *menumodel)
{
    //Sanity checks
    g_return_if_fail (application != NULL);
    g_return_if_fail (menumodel != NULL);
    if (g_menu_model_get_n_items (menumodel) == 0) return;

    //Declarations
    GMenuModel *menubar;
    gint length;

    //Initializations
    menubar = gtk_application_get_menubar (GTK_APPLICATION (application));
    g_return_if_fail (menubar != NULL);
    length = g_menu_model_get_n_items (menubar);

    //Clear the menubar
    while (length-- > 0) g_menu_remove (G_MENU (menubar), 0);

    //Add the menuitem linking the menus 
    {
      GMenuItem *menuitem = g_menu_item_new_section (NULL, menumodel);
      if (menuitem != NULL)
      {
        g_menu_append_item (G_MENU (menubar), menuitem);
        g_object_unref (menuitem); menuitem = NULL;
      }
      gw_application_add_accelerators (application, menubar);
    }
}
예제 #3
0
static void
gtk_application_window_update_shell_shows_app_menu (GtkApplicationWindow *window,
                                                    GtkSettings          *settings)
{
  gboolean shown_by_shell;
  gboolean shown_by_titlebar;

  g_object_get (settings, "gtk-shell-shows-app-menu", &shown_by_shell, NULL);

  shown_by_titlebar = _gtk_window_titlebar_shows_app_menu (GTK_WINDOW (window));

  if (shown_by_shell || shown_by_titlebar)
    {
      /* the shell shows it, so don't show it locally */
      if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) != 0)
        g_menu_remove (window->priv->app_menu_section, 0);
    }
  else
    {
      /* the shell does not show it, so make sure we show it */
      if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) == 0)
        {
          GMenuModel *app_menu = NULL;

          if (gtk_window_get_application (GTK_WINDOW (window)) != NULL)
            app_menu = gtk_application_get_app_menu (gtk_window_get_application (GTK_WINDOW (window)));

          if (app_menu != NULL)
            {
              const gchar *app_name;
              gchar *name;

              app_name = g_get_application_name ();
              if (app_name != g_get_prgname ())
                {
                  /* the app has set its application name, use it */
                  name = g_strdup (app_name);
                }
              else
                {
                  /* get the name from .desktop file */
                  name = gtk_application_window_get_app_desktop_name ();
                  if (name == NULL)
                    name = g_strdup (_("Application"));
                }

              g_menu_append_submenu (window->priv->app_menu_section, name, app_menu);
              g_free (name);
            }
        }
    }
}
static GMenuModel *
find_gmenu_model (GMenuModel  *model,
		  const gchar *model_id)
{
	gint i, n_items;
	GMenuModel *insertion_model = NULL;

	n_items = g_menu_model_get_n_items (model);

	for (i = 0; i < n_items && !insertion_model; i++) {
		gchar *id = NULL;
		if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) &&
		    g_strcmp0 (id, model_id) == 0) {
			insertion_model = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
			if (!insertion_model)
				insertion_model = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
		} else {
			GMenuModel *submodel;
			GMenuModel *submenu;
			gint j, j_items;

			submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);

			if (!submodel)
			        submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);

			if (!submodel)
				continue;

			j_items = g_menu_model_get_n_items (submodel);
			for (j = 0; j < j_items; j++) {
				submenu = g_menu_model_get_item_link (submodel, j, G_MENU_LINK_SUBMENU);
				if (submenu) {
					insertion_model = find_gmenu_model (submenu, model_id);
					g_object_unref (submenu);
				}

				if (insertion_model)
					break;
			}

			g_object_unref (submodel);
		}

		g_free (id);
	}

	return insertion_model;
}
예제 #5
0
파일: testgmenu.c 프로젝트: 3v1n0/gtk
static void
connect_to_items_changed (GMenuModel *model,
                          GCallback   callback,
                          gpointer    data)
{
  gint i;
  GMenuModel *m;
  GMenuLinkIter *iter;

  if (!g_object_get_data (G_OBJECT (model), "handler-connected"))
    {
      g_signal_connect (model, "items-changed", callback, data);
      g_object_set_data (G_OBJECT (model), "handler-connected", GINT_TO_POINTER (1));
    }
  for (i = 0; i < g_menu_model_get_n_items (model); i++)
    {
      iter = g_menu_model_iterate_item_links (model, i);
      while (g_menu_link_iter_next (iter))
        {
          m = g_menu_link_iter_get_value (iter);
          connect_to_items_changed (m, callback, data);
          g_object_unref (m);
        }
      g_object_unref (iter);
    }
}
예제 #6
0
static void
impl_deactivate	(EogWindowActivatable *activatable)
{
	EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (activatable);
	GMenu *menu;
	GMenuModel *model;
	gint i;

	eog_debug (DEBUG_PLUGINS);

	menu = eog_window_get_gear_menu_section (plugin->window,
						 "plugins-section");

	g_return_if_fail (G_IS_MENU (menu));

	/* Remove menu entry */
	model = G_MENU_MODEL (menu);
	for (i = 0; i < g_menu_model_get_n_items (model); i++) {
		gchar *id;
		if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) {
			const gboolean found =
				(g_strcmp0 (id, EOG_POSTR_PLUGIN_MENU_ID) == 0);
			g_free (id);

			if (found) {
				g_menu_remove (menu, i);
				break;
			}
		}
	}

	/* Finally remove action */
	g_action_map_remove_action (G_ACTION_MAP (plugin->window),
				    EOG_POSTR_PLUGIN_ACTION);
}
예제 #7
0
파일: testgmenu.c 프로젝트: 3v1n0/gtk
static void
toggle_italic (GtkToggleButton *button, gpointer data)
{
  GMenuModel *model;
  GActionGroup *group;
  GSimpleAction *action;
  gboolean adding;
  GMenuModel *m;
  GtkTreeView *tv = data;
  GtkTreeModel *store;

  model = g_object_get_data (G_OBJECT (button), "model");
  group = g_object_get_data (G_OBJECT (button), "group");

  store = gtk_tree_view_get_model (tv);

  adding = gtk_toggle_button_get_active (button);

  m = g_menu_model_get_item_link (model, g_menu_model_get_n_items (model) - 1, G_MENU_LINK_SECTION);
  if (adding)
    {
      action = g_simple_action_new_stateful ("italic", NULL, g_variant_new_boolean (FALSE));
      g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
      g_signal_connect (action, "activate", G_CALLBACK (activate_toggle), NULL);
      g_object_unref (action);
      action_list_add (store, "italic");
      g_menu_insert (G_MENU (m), 1, "Italic", "italic");
    }
  else
    {
      g_action_map_remove_action (G_ACTION_MAP (group), "italic");
      action_list_remove (store, "italic");
      g_menu_remove (G_MENU (m), 1);
    }
}
예제 #8
0
/*
 * The original GMenu is modified adding to the section @submodel_name
 * the items in @gmenu_to_merge.
 * @gmenu_to_merge should be a list of menu items.
 */
void
nautilus_gmenu_merge (GMenu       *original,
                      GMenu       *gmenu_to_merge,
                      const gchar *submodel_name,
                      gboolean     prepend)
{
    gint i, n_items;
    GMenuModel *submodel;
    GMenuItem *item;

    g_return_if_fail (G_IS_MENU (original));
    g_return_if_fail (G_IS_MENU (gmenu_to_merge));

    submodel = find_gmenu_model (G_MENU_MODEL (original), submodel_name);

    g_return_if_fail (submodel != NULL);

    n_items = g_menu_model_get_n_items (G_MENU_MODEL (gmenu_to_merge));

    for (i = 0; i < n_items; i++)
    {
        item = g_menu_item_new_from_model (G_MENU_MODEL (gmenu_to_merge), i);
        if (prepend)
        {
            g_menu_prepend_item (G_MENU (submodel), item);
        }
        else
        {
            g_menu_append_item (G_MENU (submodel), item);
        }
        g_object_unref (item);
    }

    g_object_unref (submodel);
}
예제 #9
0
파일: plugman.c 프로젝트: Davletvm/gtk
static void
disable_plugin (const gchar *name)
{
  GMenuModel *plugin_menu;

  g_print ("Disabling '%s' plugin\n", name);

  plugin_menu = find_plugin_menu ();
  if (plugin_menu)
    {
      const gchar *id;
      gint i;

      for (i = 0; i < g_menu_model_get_n_items (plugin_menu); i++)
        {
           if (g_menu_model_get_item_attribute (plugin_menu, i, "id", "s", &id) &&
               g_strcmp0 (id, name) == 0)
             {
               g_menu_remove (G_MENU (plugin_menu), i);
               g_print ("Menus of '%s' plugin removed\n", name);
             }
        }
    }
  else
    g_warning ("Plugin menu not found\n");

  g_action_map_remove_action (G_ACTION_MAP (g_application_get_default ()), name);
  g_print ("Actions of '%s' plugin removed\n", name);

  if (g_strcmp0 (name, "red") == 0)
    is_red_plugin_enabled = FALSE;
  else
    is_black_plugin_enabled = FALSE;
}
예제 #10
0
파일: testgmenu.c 프로젝트: 3v1n0/gtk
static void
toggle_sumerian (GtkToggleButton *button, gpointer data)
{
  GMenuModel *model;
  gboolean adding;
  GMenuModel *m;

  model = g_object_get_data (G_OBJECT (button), "model");

  adding = gtk_toggle_button_get_active (button);

  m = g_menu_model_get_item_link (model, g_menu_model_get_n_items (model) - 1, G_MENU_LINK_SECTION);
  m = g_menu_model_get_item_link (m, g_menu_model_get_n_items (m) - 1, G_MENU_LINK_SUBMENU);
  if (adding)
    g_menu_append (G_MENU (m), "Sumerian", "lang::sumerian");
  else
    g_menu_remove (G_MENU (m), g_menu_model_get_n_items (m) - 1);
}
예제 #11
0
static GMenuModel *
find_extension_point_section (GMenuModel  *model,
                              const gchar *extension_point)
{
	gint i, n_items;
	GMenuModel *section = NULL;

	n_items = g_menu_model_get_n_items (model);

	for (i = 0; i < n_items && !section; i++)
	{
		gchar *id = NULL;

		if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) &&
		    strcmp (id, extension_point) == 0)
		{
			section = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
		}
		else
		{
			GMenuModel *subsection;
			GMenuModel *submenu;
			gint j, j_items;

			subsection = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);

			j_items = g_menu_model_get_n_items (subsection);

			for (j = 0; j < j_items && !section; j++)
			{
				submenu = g_menu_model_get_item_link (subsection, j, G_MENU_LINK_SUBMENU);
				if (submenu)
				{
					section = find_extension_point_section (submenu, extension_point);
				}
			}
		}

		g_free (id);
	}

	return section;
}
예제 #12
0
파일: testgmenu.c 프로젝트: 3v1n0/gtk
static void
toggle_speed (GtkToggleButton *button, gpointer data)
{
  GMenuModel *model;
  GActionGroup *group;
  GSimpleAction *action;
  gboolean adding;
  GMenuModel *m;
  GMenu *submenu;
  GtkTreeView *tv = data;
  GtkTreeModel *store;

  model = g_object_get_data (G_OBJECT (button), "model");
  group = g_object_get_data (G_OBJECT (button), "group");

  store = gtk_tree_view_get_model (tv);

  adding = gtk_toggle_button_get_active (button);

  m = g_menu_model_get_item_link (model, 1, G_MENU_LINK_SECTION);
  if (adding)
    {
      action = g_simple_action_new ("faster", NULL);
      g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
      g_signal_connect (action, "activate", G_CALLBACK (activate_action), NULL);
      g_object_unref (action);

      action = g_simple_action_new ("slower", NULL);
      g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
      g_signal_connect (action, "activate", G_CALLBACK (activate_action), NULL);
      g_object_unref (action);

      action_list_add (store, "faster");
      action_list_add (store, "slower");

      submenu = g_menu_new ();
      g_menu_append (submenu, "Faster", "faster");
      g_menu_append (submenu, "Slower", "slower");
      g_menu_append_submenu (G_MENU (m), "Speed", G_MENU_MODEL (submenu));
    }
  else
    {
      g_action_map_remove_action (G_ACTION_MAP (group), "faster");
      g_action_map_remove_action (G_ACTION_MAP (group), "slower");

      action_list_remove (store, "faster");
      action_list_remove (store, "slower");

      g_menu_remove (G_MENU (m), g_menu_model_get_n_items (m) - 1);
    }
}
예제 #13
0
static void
gtk_application_window_update_menubar (GtkApplicationWindow *window)
{
  gboolean should_have_menubar;
  gboolean have_menubar;

  have_menubar = window->priv->menubar != NULL;

  should_have_menubar = window->priv->show_menubar &&
                        (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) ||
                         g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)));

  if (have_menubar && !should_have_menubar)
    {
      gtk_widget_unparent (window->priv->menubar);
      window->priv->menubar = NULL;

      gtk_widget_queue_resize (GTK_WIDGET (window));
    }

  if (!have_menubar && should_have_menubar)
    {
      GMenu *combined;

      combined = g_menu_new ();
      g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
      g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));

      window->priv->menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (combined));
      gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
      gtk_widget_show_all (window->priv->menubar);
      g_object_unref (combined);

      gtk_widget_queue_resize (GTK_WIDGET (window));
    }
}
예제 #14
0
static void
g_menu_exporter_menu_prepare (GMenuExporterMenu *menu)
{
  gint n_items;

  g_assert (menu->item_links == NULL);

  if (g_menu_model_is_mutable (menu->model))
    menu->handler_id = g_signal_connect (menu->model, "items-changed",
                                         G_CALLBACK (g_menu_exporter_menu_items_changed), menu);

  menu->item_links = g_sequence_new (g_menu_exporter_link_free);

  n_items = g_menu_model_get_n_items (menu->model);
  if (n_items)
    g_menu_exporter_menu_items_changed (menu->model, 0, 0, n_items, menu);
}
예제 #15
0
static void
eog_reload_plugin_deactivate (EogWindowActivatable *activatable)
{
	const gchar * const empty_accels[1] = { NULL };
	EogReloadPlugin *plugin = EOG_RELOAD_PLUGIN (activatable);
	GMenu *menu;
	GMenuModel *model;
	gint i;

	eog_debug (DEBUG_PLUGINS);

	menu = eog_window_get_gear_menu_section (plugin->window,
						 "plugins-section");

	g_return_if_fail (G_IS_MENU (menu));

	/* Remove menu entry */
	model = G_MENU_MODEL (menu);
	for (i = 0; i < g_menu_model_get_n_items (model); i++) {
		gchar *id;
		if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) {
			const gboolean found =
				(g_strcmp0 (id, EOG_RELOAD_PLUGIN_MENU_ID) == 0);
			g_free (id);

			if (found) {
				g_menu_remove (menu, i);
				break;
			}
		}
	}

	/* Unset accelerator */
	gtk_application_set_accels_for_action(GTK_APPLICATION (EOG_APP),
					      "win." EOG_RELOAD_PLUGIN_ACTION,
					      empty_accels);

	/* Disconnect selection-changed handler as the thumbview would
	 * otherwise still cause callbacks during its own disposal */
	g_signal_handlers_disconnect_by_func (eog_window_get_thumb_view (plugin->window),
					      _selection_changed_cb, plugin);

	/* Finally remove action */
	g_action_map_remove_action (G_ACTION_MAP (plugin->window),
				    EOG_RELOAD_PLUGIN_ACTION);
}
예제 #16
0
void
gw_menumodel_set_links (GMenuModel *menumodel, const gchar *LABEL, const gchar *NEW_LABEL, const gchar *LINK_TYPE, GMenuModel *link)
{
    //Sanity checks
    g_return_if_fail (menumodel != NULL);
    g_return_if_fail (LABEL != NULL);
    g_return_if_fail (LINK_TYPE != NULL);

    //Declarations
    gint total_items;
    gint index;
    gchar *label;
    gboolean valid;
    GMenuItem *menuitem;
    GMenuModel *sublink;

    //Initializations
    total_items = g_menu_model_get_n_items (menumodel);

    for (index = 0; index < total_items; index++)
    {
      valid = g_menu_model_get_item_attribute (menumodel, index, G_MENU_ATTRIBUTE_LABEL, "s", &label, NULL);
      if (valid == TRUE && label != NULL)
      {
        if (label != NULL && strcmp (label, LABEL) == 0)
        {
          menuitem = g_menu_item_new (NEW_LABEL, NULL);
          g_menu_item_set_link (menuitem, LINK_TYPE, link);
          g_menu_remove (G_MENU (menumodel), index);
          g_menu_insert_item (G_MENU (menumodel), index, menuitem);
          g_object_unref (menuitem); menuitem = NULL;
        }
        g_free (label); label = NULL;
      }

      //Recursive work
      sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SUBMENU);
      if (sublink != NULL) gw_menumodel_set_links (sublink, LABEL, NEW_LABEL, LINK_TYPE, link);
      sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SECTION);
      if (sublink != NULL) gw_menumodel_set_links (sublink, LABEL, NEW_LABEL, LINK_TYPE, link);
    }
}
예제 #17
0
void
gw_application_remove_accelerators (GwApplication *application, GMenuModel *menumodel)
{
    //Sanity checks
    g_return_if_fail (application != NULL);
    g_return_if_fail (menumodel != NULL);

    //Declarations
    gint total_items;
    gint index;
    gchar *accel = NULL;
    gchar *action = NULL;
    gchar *detail = NULL;
    GMenuModel *sublink = NULL;

    //Initializations
    total_items = g_menu_model_get_n_items (menumodel);

    for (index = 0; index < total_items; index++)
    {
      g_menu_model_get_item_attribute (menumodel, index, "accel", "s", &accel, NULL);
      g_menu_model_get_item_attribute (menumodel, index, G_MENU_ATTRIBUTE_ACTION, "s", &action, NULL);
      g_menu_model_get_item_attribute (menumodel, index, G_MENU_ATTRIBUTE_TARGET, "s", &detail, NULL);
      if (accel != NULL && action != NULL)
      {
        if (detail != NULL)
          gtk_application_remove_accelerator (GTK_APPLICATION (application), action, g_variant_new_string (detail));
        else
          gtk_application_remove_accelerator (GTK_APPLICATION (application), action, NULL);
      }

      if (accel != NULL) g_free (accel); accel = NULL;
      if (action != NULL) g_free (action); action = NULL;
      if (detail != NULL) g_free (detail); detail = NULL;

      //Recursive work
      sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SUBMENU);
      if (sublink != NULL) gw_application_remove_accelerators (application, sublink);
      sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SECTION);
      if (sublink != NULL) gw_application_remove_accelerators (application, sublink);
    }
}
예제 #18
0
static void
extract_accels_from_menu(GMenuModel    * model,
                         GActionMap    * action_map,
                         GtkAccelGroup * accel_group)
{
    gint i, n = g_menu_model_get_n_items(model);
    GMenuLinkIter *iter;
    const gchar *key;
    GMenuModel *m;

    for (i = 0; i < n; i++) {
        extract_accel_from_menu_item(model, i, action_map, accel_group);

        iter = g_menu_model_iterate_item_links(model, i);
        while (g_menu_link_iter_get_next(iter, &key, &m)) {
            extract_accels_from_menu(m, action_map, accel_group);
            g_object_unref(m);
        }
        g_object_unref(iter);
    }
}
예제 #19
0
static void
add_accelerators_from_menu (GtkWindow      *window,
			    GtkAccelGroup  *accel_group,
			    GMenuModel     *model)
{
	int		 i;
	GMenuLinkIter	*iter;
	const char	*key;
	GMenuModel	*m;

	for (i = 0; i < g_menu_model_get_n_items (model); i++) {
		add_accelerators_from_menu_item (window, accel_group, model, i);

		iter = g_menu_model_iterate_item_links (model, i);
		while (g_menu_link_iter_get_next (iter, &key, &m)) {
			add_accelerators_from_menu (window, accel_group, m);
			g_object_unref (m);
		}
		g_object_unref (iter);
	}
}
예제 #20
0
static void
impl_deactivate	(EogWindowActivatable *activatable)
{
	const gchar * const empty_accels[1] = { NULL };
	EogFitToWidthPlugin *plugin = EOG_FIT_TO_WIDTH_PLUGIN (activatable);
	GMenu *menu;
	GMenuModel *model;
	gint i;

	menu = eog_window_get_gear_menu_section (plugin->window,
						 "plugins-section");

	g_return_if_fail (G_IS_MENU (menu));

	/* Remove menu entry */
	model = G_MENU_MODEL (menu);
	for (i = 0; i < g_menu_model_get_n_items (model); i++) {
		gchar *id;
		if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) {
			const gboolean found =
				(g_strcmp0 (id, EOG_FIT_TO_WIDTH_PLUGIN_MENU_ID) == 0);
			g_free (id);

			if (found) {
				g_menu_remove (menu, i);
				break;
			}
		}
	}

	/* Unset accelerator */
	gtk_application_set_accels_for_action(GTK_APPLICATION (EOG_APP),
					      "win." EOG_FIT_TO_WIDTH_PLUGIN_ACTION,
					      empty_accels);

	/* Finally remove action */
	g_action_map_remove_action (G_ACTION_MAP (plugin->window),
				    EOG_FIT_TO_WIDTH_PLUGIN_ACTION);
}
void
nautilus_gmenu_replace_section (GMenu       *menu,
				const gchar *section_id,
				GMenuModel  *section)
{
	GMenuModel *orig_section;
	GMenuItem *item;
	gint idx;

	orig_section = find_gmenu_model (G_MENU_MODEL (menu), section_id);
	g_return_if_fail (orig_section != NULL);

	g_menu_remove_all (G_MENU (orig_section));

	for (idx = 0; idx < g_menu_model_get_n_items (section); idx++) {
		item = g_menu_item_new_from_model (section, idx);
		g_menu_append_item (G_MENU (orig_section), item);
		g_object_unref (item);
	}

	g_object_unref (orig_section);
}
예제 #22
0
GeditMenuExtension *
gedit_window_activatable_extend_gear_menu (GeditWindowActivatable *activatable,
                                           const gchar            *extension_point)
{
	GeditMenuExtension *menu = NULL;
	GeditWindow *window;
	GMenuModel *model;
	gint i, n_items;

	g_return_val_if_fail (GEDIT_IS_WINDOW_ACTIVATABLE (activatable), NULL);
	g_return_val_if_fail (extension_point != NULL, NULL);

	g_object_get (G_OBJECT (activatable), "window", &window, NULL);
	model = _gedit_window_get_gear_menu (window);
	g_object_unref (window);

	n_items = g_menu_model_get_n_items (model);

	for (i = 0; i < n_items; i++)
	{
		gchar *id = NULL;

		if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) &&
		    strcmp (id, extension_point) == 0)
		{
			GMenuModel *section;

			section = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
			menu = _gedit_menu_extension_new (G_MENU (section));
		}

		g_free (id);
	}

	return menu;
}
예제 #23
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;
}
예제 #24
0
파일: gtkmodelmenu.c 프로젝트: Pfiver/gtk
static void
gtk_model_menu_binding_append_model (GtkModelMenuBinding *binding,
                                     GMenuModel          *model,
                                     gboolean             with_separators)
{
  gint n, i;

  g_signal_connect (model, "items-changed", G_CALLBACK (gtk_model_menu_binding_items_changed), binding);
  binding->connected = g_slist_prepend (binding->connected, g_object_ref (model));

  /* Deciding if we should show a separator is a bit difficult.  There
   * are two types of separators:
   *
   *  - section headings (when sections have 'label' property)
   *
   *  - normal separators automatically put between sections
   *
   * The easiest way to think about it is that a section usually has a
   * separator (or heading) immediately before it.
   *
   * There are three exceptions to this general rule:
   *
   *  - empty sections don't get separators or headings
   *
   *  - sections only get separators and headings at the toplevel of a
   *    menu (ie: no separators on nested sections or in menubars)
   *
   *  - the first section in the menu doesn't get a normal separator,
   *    but it can get a header (if it's not empty)
   *
   * Unfortunately, we cannot simply check the size of the section in
   * order to determine if we should place a header: the section may
   * contain other sections that are themselves empty.  Instead, we need
   * to append the section, and check if we ended up with any actual
   * content.  If we did, then we need to insert before that content.
   * We use 'our_position' to keep track of this.
   */

  n = g_menu_model_get_n_items (model);

  for (i = 0; i < n; i++)
    {
      gint our_position = binding->n_items;
      gchar *heading = NULL;

      gtk_model_menu_binding_append_item (binding, model, i, &heading);

      if (with_separators && our_position < binding->n_items)
        {
          GtkWidget *separator = NULL;

          if (heading)
            {
              separator = gtk_menu_item_new_with_label (heading);
              gtk_widget_set_sensitive (separator, FALSE);
            }
          else if (our_position > 0)
            separator = gtk_separator_menu_item_new ();

          if (separator)
            {
              gtk_menu_shell_insert (binding->shell, separator, our_position);
              gtk_widget_show (separator);
              binding->n_items++;
            }
        }

      g_free (heading);
    }
}
예제 #25
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;
}
예제 #26
0
파일: testgmenu.c 프로젝트: 3v1n0/gtk
static void
append_items_from_model (GtkWidget    *menu,
                         GMenuModel   *model,
                         GActionGroup *group,
                         gboolean     *need_separator,
                         const gchar  *heading)
{
  gint n;
  gint i;
  GtkWidget *w;
  GtkWidget *menuitem;
  GtkWidget *submenu;
  GMenuModel *m;
  gchar *label;

  n = g_menu_model_get_n_items (model);

  if (*need_separator && n > 0)
    {
      w = gtk_separator_menu_item_new ();
      gtk_widget_show (w);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), w);
      *need_separator = FALSE;
    }

  if (heading != NULL)
    {
      w = gtk_menu_item_new_with_label (heading);
      gtk_widget_show (w);
      gtk_widget_set_sensitive (w, FALSE);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), w);
    }

  for (i = 0; i < n; i++)
    {
      if ((m = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION)))
        {
          label = NULL;
          g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label);
          append_items_from_model (menu, m, group, need_separator, label);
          g_object_unref (m);
          g_free (label);

          if (*need_separator)
            {
              w = gtk_separator_menu_item_new ();
              gtk_widget_show (w);
              gtk_menu_shell_append (GTK_MENU_SHELL (menu), w);
              *need_separator = FALSE;
            }

          continue;
        }

      menuitem = create_menuitem_from_model (model, i, group);

      if ((m = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU)))
        {
          submenu = create_menu_from_model (m, group);
          gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
          g_object_unref (m);
        }

      gtk_widget_show (menuitem);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);

      *need_separator = TRUE;
    }
}