mirror of https://github.com/GNOME/gimp.git
367 lines
12 KiB
C
367 lines
12 KiB
C
/* gimpxmpmodelwidget.c - interface definition for XMPModel bound
|
|
* GTKWidgets
|
|
*
|
|
* Copyright (C) 2010, Róman Joost <romanofski@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 <string.h>
|
|
|
|
#include <libgimp/gimp.h>
|
|
#include <libgimp/gimpui.h>
|
|
|
|
#include "xmp-schemas.h"
|
|
#include "xmp-model.h"
|
|
|
|
#include "gimpxmpmodelwidget.h"
|
|
|
|
|
|
#define GIMP_XMP_MODEL_WIDGET_GET_PRIVATE(obj) \
|
|
(gimp_xmp_model_widget_get_private (GIMP_XMP_MODEL_WIDGET (obj)))
|
|
|
|
|
|
typedef struct _GimpXmpModelWidgetPrivate GimpXmpModelWidgetPrivate;
|
|
|
|
struct _GimpXmpModelWidgetPrivate
|
|
{
|
|
const gchar *schema_uri;
|
|
const gchar *property_name;
|
|
XMPModel *xmp_model;
|
|
};
|
|
|
|
|
|
static void gimp_xmp_model_widget_iface_base_init (GimpXmpModelWidgetInterface *iface);
|
|
|
|
static GimpXmpModelWidgetPrivate *
|
|
gimp_xmp_model_widget_get_private (GimpXmpModelWidget *widget);
|
|
|
|
static void gimp_xmp_model_widget_xmpmodel_changed (XMPModel *xmp_model,
|
|
GtkTreeIter *iter,
|
|
gpointer *user_data);
|
|
|
|
const gchar * find_schema_prefix (const gchar *schema_uri);
|
|
|
|
void set_property_edit_icon (GtkWidget *widget,
|
|
XMPModel *xmp_model,
|
|
GtkTreeIter *iter);
|
|
|
|
|
|
GType
|
|
gimp_xmp_model_widget_interface_get_type (void)
|
|
{
|
|
static GType iface_type = 0;
|
|
|
|
if (! iface_type)
|
|
{
|
|
const GTypeInfo iface_info =
|
|
{
|
|
sizeof (GimpXmpModelWidgetInterface),
|
|
(GBaseInitFunc) gimp_xmp_model_widget_iface_base_init,
|
|
(GBaseFinalizeFunc) NULL,
|
|
};
|
|
|
|
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
|
"GimpXmpModelWidgetInterface",
|
|
&iface_info, 0);
|
|
}
|
|
|
|
return iface_type;
|
|
}
|
|
|
|
static void
|
|
gimp_xmp_model_widget_iface_base_init (GimpXmpModelWidgetInterface *iface)
|
|
{
|
|
static gboolean initialized = FALSE;
|
|
|
|
if (! initialized)
|
|
{
|
|
g_object_interface_install_property (iface,
|
|
g_param_spec_string ("schema-uri",
|
|
NULL, NULL, NULL,
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_interface_install_property (iface,
|
|
g_param_spec_string ("property-name",
|
|
NULL, NULL, NULL,
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_interface_install_property (iface,
|
|
g_param_spec_object ("xmp-model",
|
|
NULL, NULL,
|
|
GIMP_TYPE_XMP_MODEL,
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
GIMP_PARAM_READWRITE));
|
|
iface->widget_set_text = NULL;
|
|
initialized = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* gimp_xmp_model_widget_install_properties:
|
|
* @klass: the class structure for a type deriving from #GObject
|
|
*
|
|
* Installs the necessary properties for a class implementing
|
|
* #GimpXmpModelWidgetInterface. A #GimpXmpModelWidgetProp property is
|
|
* installed for each property, using the values from the
|
|
* #GimpXmpModelWidgetProp enumeration.
|
|
**/
|
|
void
|
|
gimp_xmp_model_widget_install_properties (GObjectClass *klass)
|
|
{
|
|
g_object_class_override_property (klass,
|
|
GIMP_XMP_MODEL_WIDGET_PROP_SCHEMA_URI,
|
|
"schema-uri");
|
|
|
|
g_object_class_override_property (klass,
|
|
GIMP_XMP_MODEL_WIDGET_PROP_XMPMODEL,
|
|
"xmp-model");
|
|
|
|
g_object_class_override_property (klass,
|
|
GIMP_XMP_MODEL_WIDGET_PROP_PROPERTY_NAME,
|
|
"property-name");
|
|
}
|
|
|
|
void
|
|
gimp_xmp_model_widget_constructor (GObject *object)
|
|
{
|
|
GimpXmpModelWidget *widget = GIMP_XMP_MODEL_WIDGET (object);
|
|
GimpXmpModelWidgetPrivate *priv;
|
|
gchar *signal;
|
|
|
|
priv = GIMP_XMP_MODEL_WIDGET_GET_PRIVATE (object);
|
|
|
|
signal = g_strdup_printf ("property-changed::%s:%s",
|
|
find_schema_prefix (priv->schema_uri),
|
|
priv->property_name);
|
|
|
|
g_signal_connect (priv->xmp_model, signal,
|
|
G_CALLBACK (gimp_xmp_model_widget_xmpmodel_changed),
|
|
widget);
|
|
|
|
g_free (signal);
|
|
}
|
|
|
|
void
|
|
gimp_xmp_model_widget_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GimpXmpModelWidgetPrivate *priv = GIMP_XMP_MODEL_WIDGET_GET_PRIVATE (object);
|
|
|
|
switch (property_id)
|
|
{
|
|
case GIMP_XMP_MODEL_WIDGET_PROP_SCHEMA_URI:
|
|
priv->schema_uri = g_value_dup_string (value);
|
|
break;
|
|
|
|
case GIMP_XMP_MODEL_WIDGET_PROP_PROPERTY_NAME:
|
|
priv->property_name = g_value_dup_string (value);
|
|
break;
|
|
|
|
case GIMP_XMP_MODEL_WIDGET_PROP_XMPMODEL:
|
|
priv->xmp_model = g_value_dup_object (value);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
gimp_xmp_model_widget_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GimpXmpModelWidgetPrivate *priv = GIMP_XMP_MODEL_WIDGET_GET_PRIVATE (object);
|
|
|
|
switch (property_id)
|
|
{
|
|
case GIMP_XMP_MODEL_WIDGET_PROP_SCHEMA_URI:
|
|
g_value_set_string (value, priv->schema_uri);
|
|
break;
|
|
|
|
case GIMP_XMP_MODEL_WIDGET_PROP_PROPERTY_NAME:
|
|
g_value_set_string (value, priv->property_name);
|
|
break;
|
|
|
|
case GIMP_XMP_MODEL_WIDGET_PROP_XMPMODEL:
|
|
g_value_set_object (value, priv->xmp_model);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_xmp_model_widget_private_finalize (GimpXmpModelWidgetPrivate *private)
|
|
{
|
|
g_slice_free (GimpXmpModelWidgetPrivate, private);
|
|
}
|
|
|
|
static GimpXmpModelWidgetPrivate *
|
|
gimp_xmp_model_widget_get_private (GimpXmpModelWidget *widget)
|
|
{
|
|
const gchar *private_key = "gimp-xmp-model-widget-private";
|
|
|
|
GimpXmpModelWidgetPrivate *private;
|
|
|
|
private = g_object_get_data (G_OBJECT (widget), private_key);
|
|
|
|
if (! private)
|
|
{
|
|
private = g_slice_new0 (GimpXmpModelWidgetPrivate);
|
|
|
|
g_object_set_data_full (G_OBJECT (widget), private_key, private,
|
|
(GDestroyNotify) gimp_xmp_model_widget_private_finalize);
|
|
}
|
|
|
|
return private;
|
|
}
|
|
|
|
/**
|
|
* gimp_xmp_model_widget_xmpmodel_changed:
|
|
* @xmp_model: XMPModel this widget is bound to.
|
|
* @iter: The iter which points to the last change in the XMPModel
|
|
* @user_data: which should be the GtkWidget displaying the value.
|
|
*
|
|
* If the XMPModel has been changed, the GtkWidget needs to be updated.
|
|
* This method updates the corresponding GtkWidget with the new value
|
|
* from the XMPModel.
|
|
**/
|
|
static void
|
|
gimp_xmp_model_widget_xmpmodel_changed (XMPModel *xmp_model,
|
|
GtkTreeIter *iter,
|
|
gpointer *user_data)
|
|
{
|
|
GimpXmpModelWidget *widget = GIMP_XMP_MODEL_WIDGET (user_data);
|
|
GimpXmpModelWidgetPrivate *priv = GIMP_XMP_MODEL_WIDGET_GET_PRIVATE (widget);
|
|
const gchar *tree_value;
|
|
const gchar *property_name;
|
|
GdkPixbuf *icon;
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (xmp_model), iter,
|
|
COL_XMP_NAME, &property_name,
|
|
COL_XMP_VALUE, &tree_value,
|
|
COL_XMP_EDIT_ICON, &icon,
|
|
-1);
|
|
|
|
if (! strcmp (priv->property_name, property_name))
|
|
gimp_xmp_model_widget_set_text (widget, tree_value);
|
|
|
|
if (icon == NULL)
|
|
set_property_edit_icon (GTK_WIDGET (widget), priv->xmp_model, iter);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* gimp_xmp_model_widget_set_text:
|
|
* @widget: The GtkWidget where the new value is set.
|
|
* @tree_value: The new string which will be set on the widget.
|
|
*
|
|
* This method sets the new value on the GtkWidget implementing the
|
|
* #GimpXmpModelWidgetInterface.
|
|
**/
|
|
void
|
|
gimp_xmp_model_widget_set_text (GimpXmpModelWidget *widget,
|
|
const gchar *tree_value)
|
|
{
|
|
GimpXmpModelWidgetInterface *iface;
|
|
|
|
iface = GIMP_XMP_MODEL_WIDGET_GET_INTERFACE (widget);
|
|
|
|
if (iface->widget_set_text)
|
|
iface->widget_set_text (widget, tree_value);
|
|
}
|
|
|
|
/**
|
|
* gimp_xmp_model_widget_changed:
|
|
* @widget: The GtkWidget which was changed.
|
|
* @value: The new string from the GtkWidget.
|
|
*
|
|
* If the GtkWidget was changed, a new value is set in the #XMPModel.
|
|
**/
|
|
void
|
|
gimp_xmp_model_widget_changed (GimpXmpModelWidget *widget,
|
|
const gchar *value)
|
|
{
|
|
GimpXmpModelWidgetPrivate *priv = GIMP_XMP_MODEL_WIDGET_GET_PRIVATE (widget);
|
|
|
|
xmp_model_set_scalar_property (priv->xmp_model,
|
|
priv->schema_uri,
|
|
priv->property_name,
|
|
value);
|
|
}
|
|
|
|
/**
|
|
* utility methods
|
|
**/
|
|
|
|
/* find the schema prefix for the given URI */
|
|
const gchar*
|
|
find_schema_prefix (const gchar *schema_uri)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; xmp_schemas[i].uri != NULL; ++i)
|
|
{
|
|
if (! strcmp (xmp_schemas[i].uri, schema_uri))
|
|
return xmp_schemas[i].prefix;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
set_property_edit_icon (GtkWidget *widget,
|
|
XMPModel *xmp_model,
|
|
GtkTreeIter *iter)
|
|
{
|
|
GdkPixbuf *icon;
|
|
gboolean editable;
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (xmp_model), iter,
|
|
COL_XMP_EDITABLE, &editable,
|
|
COL_XMP_EDIT_ICON, &icon,
|
|
-1);
|
|
|
|
if (editable == XMP_AUTO_UPDATE)
|
|
{
|
|
icon = gtk_widget_render_icon (GTK_WIDGET (widget), GIMP_STOCK_WILBER,
|
|
GTK_ICON_SIZE_MENU, NULL);
|
|
gtk_tree_store_set (GTK_TREE_STORE (xmp_model), iter,
|
|
COL_XMP_EDIT_ICON, icon,
|
|
-1);
|
|
}
|
|
else if (editable == TRUE)
|
|
{
|
|
icon = gtk_widget_render_icon (GTK_WIDGET (widget), GTK_STOCK_EDIT,
|
|
GTK_ICON_SIZE_MENU, NULL);
|
|
gtk_tree_store_set (GTK_TREE_STORE (xmp_model), iter,
|
|
COL_XMP_EDIT_ICON, icon,
|
|
-1);
|
|
}
|
|
|
|
return;
|
|
}
|