Files
gimp/libgimpwidgets/gimpintstore.c
Michael Natterer 8005eea835 Remove the "GIMP" from all "Since: GIMP 2.x" API doc comments
because it confuses gtk-doc and breaks some links. Also change the
"Index of new symbols in GIMP 2.x" sections to be what seems to be the
modern standard (looked at the GLib and GTK+ docs), and update some
other stuff.
2015-05-31 21:18:09 +02:00

312 lines
9.2 KiB
C

/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpintstore.c
* Copyright (C) 2004-2007 Sven Neumann <sven@gimp.org>
*
* 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 3 of the License, 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, see
* <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "gimpwidgetstypes.h"
#include "gimpintstore.h"
#include "libgimp/libgimp-intl.h"
/**
* SECTION: gimpintstore
* @title: GimpIntStore
* @short_description: A model for integer based name-value pairs
* (e.g. enums)
*
* A model for integer based name-value pairs (e.g. enums)
**/
enum
{
PROP_0,
PROP_USER_DATA_TYPE
};
typedef struct
{
GType user_data_type;
} GimpIntStorePrivate;
static void gimp_int_store_tree_model_init (GtkTreeModelIface *iface);
static void gimp_int_store_constructed (GObject *object);
static void gimp_int_store_finalize (GObject *object);
static void gimp_int_store_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_int_store_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_int_store_row_inserted (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter);
static void gimp_int_store_row_deleted (GtkTreeModel *model,
GtkTreePath *path);
static void gimp_int_store_add_empty (GimpIntStore *store);
G_DEFINE_TYPE_WITH_CODE (GimpIntStore, gimp_int_store, GTK_TYPE_LIST_STORE,
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
gimp_int_store_tree_model_init))
#define GIMP_INT_STORE_GET_PRIVATE(obj) \
G_TYPE_INSTANCE_GET_PRIVATE (obj, GIMP_TYPE_INT_STORE, GimpIntStorePrivate)
#define parent_class gimp_int_store_parent_class
static GtkTreeModelIface *parent_iface = NULL;
static void
gimp_int_store_class_init (GimpIntStoreClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_int_store_constructed;
object_class->finalize = gimp_int_store_finalize;
object_class->set_property = gimp_int_store_set_property;
object_class->get_property = gimp_int_store_get_property;
/**
* GimpIntStore:user-data-type:
*
* Sets the #GType for the GIMP_INT_STORE_USER_DATA column.
*
* You need to set this property when constructing the store if you want
* to use the GIMP_INT_STORE_USER_DATA column and want to have the store
* handle ref-counting of your user data.
*
* Since: 2.4
*/
g_object_class_install_property (object_class,
PROP_USER_DATA_TYPE,
g_param_spec_gtype ("user-data-type",
NULL, NULL,
G_TYPE_NONE,
G_PARAM_CONSTRUCT_ONLY |
GIMP_PARAM_READWRITE));
g_type_class_add_private (object_class, sizeof (GimpIntStorePrivate));
}
static void
gimp_int_store_tree_model_init (GtkTreeModelIface *iface)
{
parent_iface = g_type_interface_peek_parent (iface);
iface->row_inserted = gimp_int_store_row_inserted;
iface->row_deleted = gimp_int_store_row_deleted;
}
static void
gimp_int_store_init (GimpIntStore *store)
{
store->empty_iter = NULL;
}
static void
gimp_int_store_constructed (GObject *object)
{
GimpIntStore *store = GIMP_INT_STORE (object);
GimpIntStorePrivate *priv = GIMP_INT_STORE_GET_PRIVATE (store);
GType types[GIMP_INT_STORE_NUM_COLUMNS];
G_OBJECT_CLASS (parent_class)->constructed (object);
types[GIMP_INT_STORE_VALUE] = G_TYPE_INT;
types[GIMP_INT_STORE_LABEL] = G_TYPE_STRING;
types[GIMP_INT_STORE_ICON_NAME] = G_TYPE_STRING;
types[GIMP_INT_STORE_PIXBUF] = GDK_TYPE_PIXBUF;
types[GIMP_INT_STORE_USER_DATA] = (priv->user_data_type != G_TYPE_NONE ?
priv->user_data_type : G_TYPE_POINTER);
gtk_list_store_set_column_types (GTK_LIST_STORE (store),
GIMP_INT_STORE_NUM_COLUMNS, types);
gimp_int_store_add_empty (store);
}
static void
gimp_int_store_finalize (GObject *object)
{
GimpIntStore *store = GIMP_INT_STORE (object);
if (store->empty_iter)
{
gtk_tree_iter_free (store->empty_iter);
store->empty_iter = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_int_store_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpIntStorePrivate *priv = GIMP_INT_STORE_GET_PRIVATE (object);
switch (property_id)
{
case PROP_USER_DATA_TYPE:
priv->user_data_type = g_value_get_gtype (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_int_store_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpIntStorePrivate *priv = GIMP_INT_STORE_GET_PRIVATE (object);
switch (property_id)
{
case PROP_USER_DATA_TYPE:
g_value_set_gtype (value, priv->user_data_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_int_store_row_inserted (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter)
{
GimpIntStore *store = GIMP_INT_STORE (model);
if (parent_iface->row_inserted)
parent_iface->row_inserted (model, path, iter);
if (store->empty_iter &&
memcmp (iter, store->empty_iter, sizeof (GtkTreeIter)))
{
gtk_list_store_remove (GTK_LIST_STORE (store), store->empty_iter);
gtk_tree_iter_free (store->empty_iter);
store->empty_iter = NULL;
}
}
static void
gimp_int_store_row_deleted (GtkTreeModel *model,
GtkTreePath *path)
{
if (parent_iface->row_deleted)
parent_iface->row_deleted (model, path);
}
static void
gimp_int_store_add_empty (GimpIntStore *store)
{
GtkTreeIter iter = { 0, };
g_return_if_fail (store->empty_iter == NULL);
gtk_list_store_prepend (GTK_LIST_STORE (store), &iter);
gtk_list_store_set (GTK_LIST_STORE (store), &iter,
GIMP_INT_STORE_VALUE, -1,
/* This string appears in an empty menu as in
* "nothing selected and nothing to select"
*/
GIMP_INT_STORE_LABEL, (_("(Empty)")),
-1);
store->empty_iter = gtk_tree_iter_copy (&iter);
}
/**
* gimp_int_store_new:
*
* Creates a #GtkListStore with a number of useful columns.
* #GimpIntStore is especially useful if the items you want to store
* are identified using an integer value.
*
* Return value: a new #GimpIntStore.
*
* Since: 2.2
**/
GtkListStore *
gimp_int_store_new (void)
{
return g_object_new (GIMP_TYPE_INT_STORE, NULL);
}
/**
* gimp_int_store_lookup_by_value:
* @model: a #GimpIntStore
* @value: an integer value to lookup in the @model
* @iter: return location for the iter of the given @value
*
* Iterate over the @model looking for @value.
*
* Return value: %TRUE if the value has been located and @iter is
* valid, %FALSE otherwise.
*
* Since: 2.2
**/
gboolean
gimp_int_store_lookup_by_value (GtkTreeModel *model,
gint value,
GtkTreeIter *iter)
{
gboolean iter_valid;
g_return_val_if_fail (GTK_IS_TREE_MODEL (model), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
for (iter_valid = gtk_tree_model_get_iter_first (model, iter);
iter_valid;
iter_valid = gtk_tree_model_iter_next (model, iter))
{
gint this;
gtk_tree_model_get (model, iter,
GIMP_INT_STORE_VALUE, &this,
-1);
if (this == value)
break;
}
return iter_valid;
}