/*
 * Copyright © 2011 Canonical Ltd.
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * licence, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 * USA.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include "gmenumodel.h"

/**
 * SECTION:gmenumodel
 * @title: GMenuModel
 * @short_description: An abstract class representing the contents of a menu
 * @see_also: #GActionGroup
 *
 * #GMenuModel represents the contents of a menu -- an ordered list of
 * menu items. The items are associated with actions, which can be
 * activated through them. Items can be grouped in sections, and may
 * have submenus associated with them. Both items and sections usually
 * have some representation data, such as labels or icons. The type of
 * the associated action (ie whether it is stateful, and what kind of
 * state it has) can influence the representation of the item.
 *
 * The conceptual model of menus in #GMenuModel is hierarchical:
 * sections and submenus are again represented by #GMenuModels.
 * Menus themselves do not define their own roles. Rather, the role
 * of a particular #GMenuModel is defined by the item that references
 * it (or, in the case of the 'root' menu, is defined by the context
 * in which it is used).
 *
 * As an example, consider the visible portions of the menu in
 * <xref linkend="menu-example"/>.
 *
 * <figure id="menu-example">
 *   <title>An example menu</title>
 *   <graphic fileref="menu-example.png" format="PNG"></graphic>
 * </figure>
 *
 * There are 8 "menus" visible in the screenshot: one menubar, two
 * submenus and 5 sections:
 * <itemizedlist>
 * <listitem>the toplevel menubar (containing 4 items)</listitem>
 * <listitem>the View submenu (containing 3 sections)</listitem>
 * <listitem>the first section of the View submenu (containing 2 items)</listitem>
 * <listitem>the second section of the View submenu (containing 1 item)</listitem>
 * <listitem>the final section of the View submenu (containing 1 item)</listitem>
 * <listitem>the Highlight Mode submenu (containing 2 sections)</listitem>
 * <listitem>the Sources section (containing 2 items)</listitem>
 * <listitem>the Markup section (containing 2 items)</listitem>
 * </itemizedlist>
 *
 * <xref linkend="menu-model"/> illustrates the conceptual connection between
 * these 8 menus. Each large block in the figure represents a menu and the
 * smaller blocks within the large block represent items in that menu. Some
 * items contain references to other menus.
 *
 * <figure id="menu-model">
 *   <title>A menu model</title>
 *   <graphic fileref="menu-model.png" format="PNG"></graphic>
 * </figure>
 *
 * Notice that the separators visible in <xref linkend="menu-example"/>
 * appear nowhere in <xref linkend="menu-model"/>. This is because
 * separators are not explicitly represented in the menu model. Instead,
 * a separator is inserted between any two non-empty sections of a menu.
 * Section items can have labels just like any other item. In that case,
 * a display system may show a section header instead of a separator.
 *
 * The motivation for this abstract model of application controls is
 * that modern user interfaces tend to make these controls available
 * outside the application. Examples include global menus, jumplists,
 * dash boards, etc. To support such uses, it is necessary to 'export'
 * information about actions and their representation in menus, which
 * is exactly what the
 * <link linkend="gio-GActionGroup-exporter">GActionGroup exporter</link>
 * and the
 * <link linkend="gio-GMenuModel-exporter">GMenuModel exporter</link>
 * do for #GActionGroup and #GMenuModel. The client-side counterparts
 * to make use of the exported information are #GDBusActionGroup and
 * #GDBusMenuModel.
 *
 * The API of #GMenuModel is very generic, with iterators for the
 * attributes and links of an item, see g_menu_model_iterate_item_attributes()
 * and g_menu_model_iterate_item_links(). The 'standard' attributes and
 * link types have predefined names: %G_MENU_ATTRIBUTE_LABEL,
 * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, %G_MENU_LINK_SECTION
 * and %G_MENU_LINK_SUBMENU.
 *
 * Items in a #GMenuModel represent active controls if they refer to
 * an action that can get activated when the user interacts with the
 * menu item. The reference to the action is encoded by the string id
 * in the %G_MENU_ATTRIBUTE_ACTION attribute. An action id uniquely
 * identifies an action in an action group. Which action group(s) provide
 * actions depends on the context in which the menu model is used.
 * E.g. when the model is exported as the application menu of a
 * #GtkApplication, actions can be application-wide or window-specific
 * (and thus come from two different action groups). By convention, the
 * application-wide actions have names that start with "app.", while the
 * names of window-specific actions start with "win.".
 *
 * While a wide variety of stateful actions is possible, the following
 * is the minimum that is expected to be supported by all users of exported
 * menu information:
 * <itemizedlist>
 * <listitem>an action with no parameter type and no state</listitem>
 * <listitem>an action with no parameter type and boolean state</listitem>
 * <listitem>an action with string parameter type and string state</listitem>
 * </itemizedlist>
 *
 * <formalpara><title>Stateless</title>
 * <para>
 * A stateless action typically corresponds to an ordinary menu item.
 * </para>
 * <para>
 * Selecting such a menu item will activate the action (with no parameter).
 * </para>
 * </formalpara>
 *
 * <formalpara><title>Boolean State</title>
 * <para>
 * An action with a boolean state will most typically be used with a "toggle"
 * or "switch" menu item. The state can be set directly, but activating the
 * action (with no parameter) results in the state being toggled.
 * </para>
 * <para>
 * Selecting a toggle menu item will activate the action. The menu item should
 * be rendered as "checked" when the state is true.
 * </para>
 * </formalpara>
 *
 * <formalpara><title>String Parameter and State</title>
 * <para>
 * Actions with string parameters and state will most typically be used to
 * represent an enumerated choice over the items available for a group of
 * radio menu items. Activating the action with a string parameter is
 * equivalent to setting that parameter as the state.
 * </para>
 * <para>
 * Radio menu items, in addition to being associated with the action, will
 * have a target value. Selecting that menu item will result in activation
 * of the action with the target value as the parameter. The menu item should
 * be rendered as "selected" when the state of the action is equal to the
 * target value of the menu item.
 * </para>
 * </formalpara>
 */

/**
 * GMenuModel:
 *
 * #GMenuModel is an opaque structure type.  You must access it using the
 * functions below.
 *
 * Since: 2.32
 */

/**
 * GMenuAttributeIter:
 *
 * #GMenuAttributeIter is an opaque structure type.  You must access it
 * using the functions below.
 *
 * Since: 2.32
 */

/**
 * GMenuLinkIter:
 *
 * #GMenuLinkIter is an opaque structure type.  You must access it using
 * the functions below.
 *
 * Since: 2.32
 */

typedef struct
{
  GMenuLinkIter parent_instance;
  GHashTableIter iter;
  GHashTable *table;
} GMenuLinkHashIter;

typedef GMenuLinkIterClass GMenuLinkHashIterClass;

static GType g_menu_link_hash_iter_get_type (void);

G_DEFINE_TYPE (GMenuLinkHashIter, g_menu_link_hash_iter, G_TYPE_MENU_LINK_ITER)

static gboolean
g_menu_link_hash_iter_get_next (GMenuLinkIter  *link_iter,
                                const gchar   **out_name,
                                GMenuModel    **value)
{
  GMenuLinkHashIter *iter = (GMenuLinkHashIter *) link_iter;
  gpointer keyptr, valueptr;

  if (!g_hash_table_iter_next (&iter->iter, &keyptr, &valueptr))
    return FALSE;

  *out_name = keyptr;
  *value = g_object_ref (valueptr);

  return TRUE;
}

static void
g_menu_link_hash_iter_finalize (GObject *object)
{
  GMenuLinkHashIter *iter = (GMenuLinkHashIter *) object;

  g_hash_table_unref (iter->table);

  G_OBJECT_CLASS (g_menu_link_hash_iter_parent_class)
    ->finalize (object);
}

static void
g_menu_link_hash_iter_init (GMenuLinkHashIter *iter)
{
}

static void
g_menu_link_hash_iter_class_init (GMenuLinkHashIterClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_menu_link_hash_iter_finalize;
  class->get_next = g_menu_link_hash_iter_get_next;
}


typedef struct
{
  GMenuAttributeIter parent_instance;
  GHashTableIter iter;
  GHashTable *table;
} GMenuAttributeHashIter;

typedef GMenuAttributeIterClass GMenuAttributeHashIterClass;

static GType g_menu_attribute_hash_iter_get_type (void);

G_DEFINE_TYPE (GMenuAttributeHashIter, g_menu_attribute_hash_iter, G_TYPE_MENU_ATTRIBUTE_ITER)

static gboolean
g_menu_attribute_hash_iter_get_next (GMenuAttributeIter  *attr_iter,
                                     const gchar        **name,
                                     GVariant           **value)
{
  GMenuAttributeHashIter *iter = (GMenuAttributeHashIter *) attr_iter;
  gpointer keyptr, valueptr;

  if (!g_hash_table_iter_next (&iter->iter, &keyptr, &valueptr))
    return FALSE;

  *name = keyptr;

  *value = g_variant_ref (valueptr);

  return TRUE;
}

static void
g_menu_attribute_hash_iter_finalize (GObject *object)
{
  GMenuAttributeHashIter *iter = (GMenuAttributeHashIter *) object;

  g_hash_table_unref (iter->table);

  G_OBJECT_CLASS (g_menu_attribute_hash_iter_parent_class)
    ->finalize (object);
}

static void
g_menu_attribute_hash_iter_init (GMenuAttributeHashIter *iter)
{
}

static void
g_menu_attribute_hash_iter_class_init (GMenuAttributeHashIterClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_menu_attribute_hash_iter_finalize;
  class->get_next = g_menu_attribute_hash_iter_get_next;
}

G_DEFINE_ABSTRACT_TYPE (GMenuModel, g_menu_model, G_TYPE_OBJECT)


guint g_menu_model_items_changed_signal;

static GMenuAttributeIter *
g_menu_model_real_iterate_item_attributes (GMenuModel *model,
                                           gint        item_index)
{
  GHashTable *table = NULL;
  GMenuAttributeIter *result;

  G_MENU_MODEL_GET_CLASS (model)->get_item_attributes (model, item_index, &table);

  if (table)
    {
      GMenuAttributeHashIter *iter = g_object_new (g_menu_attribute_hash_iter_get_type (), NULL);
      g_hash_table_iter_init (&iter->iter, table);
      iter->table = g_hash_table_ref (table);
      result = G_MENU_ATTRIBUTE_ITER (iter);
    }
  else
    {
      g_critical ("GMenuModel implementation '%s' doesn't override iterate_item_attributes() "
                  "and fails to return sane values from get_item_attributes()",
                  G_OBJECT_TYPE_NAME (model));
      result = NULL;
    }

  if (table != NULL)
    g_hash_table_unref (table);

  return result;
}

static GVariant *
g_menu_model_real_get_item_attribute_value (GMenuModel         *model,
                                            gint                item_index,
                                            const gchar        *attribute,
                                            const GVariantType *expected_type)
{
  GHashTable *table = NULL;
  GVariant *value = NULL;

  G_MENU_MODEL_GET_CLASS (model)
    ->get_item_attributes (model, item_index, &table);

  if (table != NULL)
    {
      value = g_hash_table_lookup (table, attribute);

      if (value != NULL)
        {
          if (expected_type == NULL || g_variant_is_of_type (value, expected_type))
            value = g_variant_ref (value);
          else
            value = NULL;
        }
    }
  else
    g_assert_not_reached ();

  if (table != NULL)
    g_hash_table_unref (table);

  return value;
}

static GMenuLinkIter *
g_menu_model_real_iterate_item_links (GMenuModel *model,
                                      gint        item_index)
{
  GHashTable *table = NULL;
  GMenuLinkIter *result;

  G_MENU_MODEL_GET_CLASS (model)
    ->get_item_links (model, item_index, &table);

  if (table)
    {
      GMenuLinkHashIter *iter = g_object_new (g_menu_link_hash_iter_get_type (), NULL);
      g_hash_table_iter_init (&iter->iter, table);
      iter->table = g_hash_table_ref (table);
      result = G_MENU_LINK_ITER (iter);
    }
  else
    {
      g_critical ("GMenuModel implementation '%s' doesn't override iterate_item_links() "
                  "and fails to return sane values from get_item_links()",
                  G_OBJECT_TYPE_NAME (model));
      result = NULL;
    }

  if (table != NULL)
    g_hash_table_unref (table);

  return result;
}

static GMenuModel *
g_menu_model_real_get_item_link (GMenuModel  *model,
                                 gint         item_index,
                                 const gchar *link)
{
  GHashTable *table = NULL;
  GMenuModel *value = NULL;

  G_MENU_MODEL_GET_CLASS (model)
    ->get_item_links (model, item_index, &table);

  if (table != NULL)
    value = g_hash_table_lookup (table, link);
  else
    g_assert_not_reached ();

  if (value != NULL)
    g_object_ref (value);

  if (table != NULL)
    g_hash_table_unref (table);

  return value;
}

static void
g_menu_model_init (GMenuModel *model)
{
}

static void
g_menu_model_class_init (GMenuModelClass *class)
{
  class->iterate_item_attributes = g_menu_model_real_iterate_item_attributes;
  class->get_item_attribute_value = g_menu_model_real_get_item_attribute_value;
  class->iterate_item_links = g_menu_model_real_iterate_item_links;
  class->get_item_link = g_menu_model_real_get_item_link;

  /**
   * GMenuModel::items-changed:
   * @model: the #GMenuModel that is changing
   * @position: the position of the change
   * @removed: the number of items removed
   * @added: the number of items added
   *
   * Emitted when a change has occured to the menu.
   *
   * The only changes that can occur to a menu is that items are removed
   * or added.  Items may not change (except by being removed and added
   * back in the same location).  This signal is capable of describing
   * both of those changes (at the same time).
   *
   * The signal means that starting at the index @position, @removed
   * items were removed and @added items were added in their place.  If
   * @removed is zero then only items were added.  If @added is zero
   * then only items were removed.
   *
   * As an example, if the menu contains items a, b, c, d (in that
   * order) and the signal (2, 1, 3) occurs then the new composition of
   * the menu will be a, b, _, _, _, d (with each _ representing some
   * new item).
   *
   * Signal handlers may query the model (particularly the added items)
   * and expect to see the results of the modification that is being
   * reported.  The signal is emitted after the modification.
   **/
  g_menu_model_items_changed_signal =
    g_signal_new ("items-changed", G_TYPE_MENU_MODEL,
                  G_SIGNAL_RUN_LAST, 0, NULL, NULL,
                  g_cclosure_marshal_generic, G_TYPE_NONE,
                  3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
}

/**
 * g_menu_model_is_mutable:
 * @model: a #GMenuModel
 *
 * Queries if @model is mutable.
 *
 * An immutable #GMenuModel will never emit the #GMenuModel::items-changed
 * signal. Consumers of the model may make optimisations accordingly.
 *
 * Returns: %TRUE if the model is mutable (ie: "items-changed" may be
 *     emitted).
 *
 * Since: 2.32
 */
gboolean
g_menu_model_is_mutable (GMenuModel *model)
{
  return G_MENU_MODEL_GET_CLASS (model)
    ->is_mutable (model);
}

/**
 * g_menu_model_get_n_items:
 * @model: a #GMenuModel
 *
 * Query the number of items in @model.
 *
 * Returns: the number of items
 *
 * Since: 2.32
 */
gint
g_menu_model_get_n_items (GMenuModel *model)
{
  return G_MENU_MODEL_GET_CLASS (model)
    ->get_n_items (model);
}

/**
 * g_menu_model_iterate_item_attributes:
 * @model: a #GMenuModel
 * @item_index: the index of the item
 *
 * Creates a #GMenuAttributeIter to iterate over the attributes of
 * the item at position @item_index in @model.
 *
 * You must free the iterator with g_object_unref() when you are done.
 *
 * Returns: (transfer full): a new #GMenuAttributeIter
 *
 * Since: 2.32
 */
GMenuAttributeIter *
g_menu_model_iterate_item_attributes (GMenuModel *model,
                                      gint        item_index)
{
  return G_MENU_MODEL_GET_CLASS (model)
    ->iterate_item_attributes (model, item_index);
}

/**
 * g_menu_model_get_item_attribute_value:
 * @model: a #GMenuModel
 * @item_index: the index of the item
 * @attribute: the attribute to query
 * @expected_type: (allow-none): the expected type of the attribute, or
 *     %NULL
 *
 * Queries the item at position @item_index in @model for the attribute
 * specified by @attribute.
 *
 * If @expected_type is non-%NULL then it specifies the expected type of
 * the attribute.  If it is %NULL then any type will be accepted.
 *
 * If the attribute exists and matches @expected_type (or if the
 * expected type is unspecified) then the value is returned.
 *
 * If the attribute does not exist, or does not match the expected type
 * then %NULL is returned.
 *
 * Returns: (transfer full): the value of the attribute
 *
 * Since: 2.32
 */
GVariant *
g_menu_model_get_item_attribute_value (GMenuModel         *model,
                                       gint                item_index,
                                       const gchar        *attribute,
                                       const GVariantType *expected_type)
{
  return G_MENU_MODEL_GET_CLASS (model)
    ->get_item_attribute_value (model, item_index, attribute, expected_type);
}

/**
 * g_menu_model_get_item_attribute:
 * @model: a #GMenuModel
 * @item_index: the index of the item
 * @attribute: the attribute to query
 * @format_string: a #GVariant format string
 * @...: positional parameters, as per @format_string
 *
 * Queries item at position @item_index in @model for the attribute
 * specified by @attribute.
 *
 * If the attribute exists and matches the #GVariantType corresponding
 * to @format_string then @format_string is used to deconstruct the
 * value into the positional parameters and %TRUE is returned.
 *
 * If the attribute does not exist, or it does exist but has the wrong
 * type, then the positional parameters are ignored and %FALSE is
 * returned.
 *
 * This function is a mix of g_menu_model_get_item_attribute_value() and
 * g_variant_get(), followed by a g_variant_unref().  As such,
 * @format_string must make a complete copy of the data (since the
 * #GVariant may go away after the call to g_variant_unref()).  In
 * particular, no '&amp;' characters are allowed in @format_string.
 *
 * Returns: %TRUE if the named attribute was found with the expected
 *     type
 *
 * Since: 2.32
 */
gboolean
g_menu_model_get_item_attribute (GMenuModel  *model,
                                 gint         item_index,
                                 const gchar *attribute,
                                 const gchar *format_string,
                                 ...)
{
  GVariant *value;
  va_list ap;

  value = g_menu_model_get_item_attribute_value (model, item_index, attribute, NULL);

  if (value == NULL)
    return FALSE;

  if (!g_variant_check_format_string (value, format_string, TRUE))
    {
      g_variant_unref (value);
      return FALSE;
    }

  va_start (ap, format_string);
  g_variant_get_va (value, format_string, NULL, &ap);
  g_variant_unref (value);
  va_end (ap);

  return TRUE;
}

/**
 * g_menu_model_iterate_item_links:
 * @model: a #GMenuModel
 * @item_index: the index of the item
 *
 * Creates a #GMenuLinkIter to iterate over the links of the item at
 * position @item_index in @model.
 *
 * You must free the iterator with g_object_unref() when you are done.
 *
 * Returns: (transfer full): a new #GMenuLinkIter
 *
 * Since: 2.32
 */
GMenuLinkIter *
g_menu_model_iterate_item_links (GMenuModel *model,
                                 gint        item_index)
{
  return G_MENU_MODEL_GET_CLASS (model)
    ->iterate_item_links (model, item_index);
}

/**
 * g_menu_model_get_item_link:
 * @model: a #GMenuModel
 * @item_index: the index of the item
 * @link: the link to query
 *
 * Queries the item at position @item_index in @model for the link
 * specified by @link.
 *
 * If the link exists, the linked #GMenuModel is returned.  If the link
 * does not exist, %NULL is returned.
 *
 * Returns: (transfer full): the linked #GMenuModel, or %NULL
 *
 * Since: 2.32
 */
GMenuModel *
g_menu_model_get_item_link (GMenuModel *model,
                            gint        item_index,
                            const gchar *link)
{
  return G_MENU_MODEL_GET_CLASS (model)
    ->get_item_link (model, item_index, link);
}

/**
 * g_menu_model_items_changed:
 * @model: a #GMenuModel
 * @position: the position of the change
 * @removed: the number of items removed
 * @added: the number of items added
 *
 * Requests emission of the #GMenuModel::items-changed signal on @model.
 *
 * This function should never be called except by #GMenuModel
 * subclasses.  Any other calls to this function will very likely lead
 * to a violation of the interface of the model.
 *
 * The implementation should update its internal representation of the
 * menu before emitting the signal.  The implementation should further
 * expect to receive queries about the new state of the menu (and
 * particularly added menu items) while signal handlers are running.
 *
 * The implementation must dispatch this call directly from a mainloop
 * entry and not in response to calls -- particularly those from the
 * #GMenuModel API.  Said another way: the menu must not change while
 * user code is running without returning to the mainloop.
 *
 * Since: 2.32
 */
void
g_menu_model_items_changed (GMenuModel *model,
                            gint        position,
                            gint        removed,
                            gint        added)
{
  g_signal_emit (model, g_menu_model_items_changed_signal, 0, position, removed, added);
}

G_DEFINE_ABSTRACT_TYPE (GMenuAttributeIter, g_menu_attribute_iter, G_TYPE_OBJECT)

struct _GMenuAttributeIterPrivate
{
  GQuark name;
  GVariant *value;
  gboolean valid;
};

/**
 * g_menu_attribute_iter_get_next:
 * @iter: a #GMenuAttributeIter
 * @out_name: (out) (allow-none) (transfer none): the type of the attribute
 * @value: (out) (allow-none) (transfer full): the attribute value
 *
 * This function combines g_menu_attribute_iter_next() with
 * g_menu_attribute_iter_get_name() and g_menu_attribute_iter_get_value().
 *
 * First the iterator is advanced to the next (possibly first) attribute.
 * If that fails, then %FALSE is returned and there are no other
 * effects.
 *
 * If successful, @name and @value are set to the name and value of the
 * attribute that has just been advanced to.  At this point,
 * g_menu_attribute_iter_get_name() and g_menu_attribute_iter_get_value() will
 * return the same values again.
 *
 * The value returned in @name remains valid for as long as the iterator
 * remains at the current position.  The value returned in @value must
 * be unreffed using g_variant_unref() when it is no longer in use.
 *
 * Returns: %TRUE on success, or %FALSE if there is no additional
 *     attribute
 *
 * Since: 2.32
 */
gboolean
g_menu_attribute_iter_get_next (GMenuAttributeIter  *iter,
                                const gchar        **out_name,
                                GVariant           **value)
{
  const gchar *name;

  if (iter->priv->value)
    {
      g_variant_unref (iter->priv->value);
      iter->priv->value = NULL;
    }

  iter->priv->valid = G_MENU_ATTRIBUTE_ITER_GET_CLASS (iter)
    ->get_next (iter, &name, &iter->priv->value);

  if (iter->priv->valid)
    {
      iter->priv->name = g_quark_from_string (name);
      if (out_name)
        *out_name = g_quark_to_string (iter->priv->name);

      if (value)
        *value = g_variant_ref (iter->priv->value);
    }

  return iter->priv->valid;
}

/**
 * g_menu_attribute_iter_next:
 * @iter: a #GMenuAttributeIter
 *
 * Attempts to advance the iterator to the next (possibly first)
 * attribute.
 *
 * %TRUE is returned on success, or %FALSE if there are no more
 * attributes.
 *
 * You must call this function when you first acquire the iterator
 * to advance it to the first attribute (and determine if the first
 * attribute exists at all).
 *
 * Returns: %TRUE on success, or %FALSE when there are no more attributes
 *
 * Since: 2.32
 */
gboolean
g_menu_attribute_iter_next (GMenuAttributeIter *iter)
{
  return g_menu_attribute_iter_get_next (iter, NULL, NULL);
}

/**
 * g_menu_attribute_iter_get_name:
 * @iter: a #GMenuAttributeIter
 *
 * Gets the name of the attribute at the current iterator position, as
 * a string.
 *
 * The iterator is not advanced.
 *
 * Returns: the name of the attribute
 *
 * Since: 2.32
 */
const gchar *
g_menu_attribute_iter_get_name (GMenuAttributeIter *iter)
{
  g_return_val_if_fail (iter->priv->valid, 0);

  return g_quark_to_string (iter->priv->name);
}

/**
 * g_menu_attribute_iter_get_value:
 * @iter: a #GMenuAttributeIter
 *
 * Gets the value of the attribute at the current iterator position.
 *
 * The iterator is not advanced.
 *
 * Returns: (transfer full): the value of the current attribute
 *
 * Since: 2.32
 */
GVariant *
g_menu_attribute_iter_get_value (GMenuAttributeIter *iter)
{
  g_return_val_if_fail (iter->priv->valid, NULL);

  return g_variant_ref (iter->priv->value);
}

static void
g_menu_attribute_iter_finalize (GObject *object)
{
  GMenuAttributeIter *iter = G_MENU_ATTRIBUTE_ITER (object);

  if (iter->priv->value)
    g_variant_unref (iter->priv->value);

  G_OBJECT_CLASS (g_menu_attribute_iter_parent_class)
    ->finalize (object);
}

static void
g_menu_attribute_iter_init (GMenuAttributeIter *iter)
{
  iter->priv = G_TYPE_INSTANCE_GET_PRIVATE (iter, G_TYPE_MENU_ATTRIBUTE_ITER, GMenuAttributeIterPrivate);
}

static void
g_menu_attribute_iter_class_init (GMenuAttributeIterClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_menu_attribute_iter_finalize;

  g_type_class_add_private (class, sizeof (GMenuAttributeIterPrivate));
}

G_DEFINE_ABSTRACT_TYPE (GMenuLinkIter, g_menu_link_iter, G_TYPE_OBJECT)

struct _GMenuLinkIterPrivate
{
  GQuark name;
  GMenuModel *value;
  gboolean valid;
};

/**
 * g_menu_link_iter_get_next:
 * @iter: a #GMenuLinkIter
 * @out_link: (out) (allow-none) (transfer none): the name of the link
 * @value: (out) (allow-none) (transfer full): the linked #GMenuModel
 *
 * This function combines g_menu_link_iter_next() with
 * g_menu_link_iter_get_name() and g_menu_link_iter_get_value().
 *
 * First the iterator is advanced to the next (possibly first) link.
 * If that fails, then %FALSE is returned and there are no other effects.
 *
 * If successful, @out_link and @value are set to the name and #GMenuModel
 * of the link that has just been advanced to.  At this point,
 * g_menu_link_iter_get_name() and g_menu_link_iter_get_value() will return the
 * same values again.
 *
 * The value returned in @out_link remains valid for as long as the iterator
 * remains at the current position.  The value returned in @value must
 * be unreffed using g_object_unref() when it is no longer in use.
 *
 * Returns: %TRUE on success, or %FALSE if there is no additional link
 *
 * Since: 2.32
 */
gboolean
g_menu_link_iter_get_next (GMenuLinkIter  *iter,
                           const gchar   **out_link,
                           GMenuModel    **value)
{
  const gchar *name;

  if (iter->priv->value)
    {
      g_object_unref (iter->priv->value);
      iter->priv->value = NULL;
    }

  iter->priv->valid = G_MENU_LINK_ITER_GET_CLASS (iter)
    ->get_next (iter, &name, &iter->priv->value);

  if (iter->priv->valid)
    {
      g_assert (name != NULL);

      iter->priv->name = g_quark_from_string (name);
      if (out_link)
        *out_link = g_quark_to_string (iter->priv->name);

      if (value)
        *value = g_object_ref (iter->priv->value);
    }

  return iter->priv->valid;
}

/**
 * g_menu_link_iter_next:
 * @iter: a #GMenuLinkIter
 *
 * Attempts to advance the iterator to the next (possibly first)
 * link.
 *
 * %TRUE is returned on success, or %FALSE if there are no more links.
 *
 * You must call this function when you first acquire the iterator to
 * advance it to the first link (and determine if the first link exists
 * at all).
 *
 * Returns: %TRUE on success, or %FALSE when there are no more links
 *
 * Since: 2.32
 */
gboolean
g_menu_link_iter_next (GMenuLinkIter *iter)
{
  return g_menu_link_iter_get_next (iter, NULL, NULL);
}

/**
 * g_menu_link_iter_get_name:
 * @iter: a #GMenuLinkIter
 *
 * Gets the name of the link at the current iterator position.
 *
 * The iterator is not advanced.
 *
 * Returns: the type of the link
 *
 * Since: 2.32
 */
const gchar *
g_menu_link_iter_get_name (GMenuLinkIter *iter)
{
  g_return_val_if_fail (iter->priv->valid, 0);

  return g_quark_to_string (iter->priv->name);
}

/**
 * g_menu_link_iter_get_value:
 * @iter: a #GMenuLinkIter
 *
 * Gets the linked #GMenuModel at the current iterator position.
 *
 * The iterator is not advanced.
 *
 * Returns: (transfer full): the #GMenuModel that is linked to
 *
 * Since: 2.32
 */
GMenuModel *
g_menu_link_iter_get_value (GMenuLinkIter *iter)
{
  g_return_val_if_fail (iter->priv->valid, NULL);

  return g_object_ref (iter->priv->value);
}

static void
g_menu_link_iter_finalize (GObject *object)
{
  GMenuLinkIter *iter = G_MENU_LINK_ITER (object);

  if (iter->priv->value)
    g_object_unref (iter->priv->value);

  G_OBJECT_CLASS (g_menu_link_iter_parent_class)
    ->finalize (object);
}

static void
g_menu_link_iter_init (GMenuLinkIter *iter)
{
  iter->priv = G_TYPE_INSTANCE_GET_PRIVATE (iter, G_TYPE_MENU_LINK_ITER, GMenuLinkIterPrivate);
}

static void
g_menu_link_iter_class_init (GMenuLinkIterClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_menu_link_iter_finalize;

  g_type_class_add_private (class, sizeof (GMenuLinkIterPrivate));
}
