Commit 21f26743 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

made gimp_config_sync() and gimp_config_connect() also work on objects of

2004-03-11  Sven Neumann  <sven@gimp.org>

	* app/config/gimpconfig-utils.c: made gimp_config_sync() and
	gimp_config_connect() also work on objects of different types.
	Properties with the same name and the same type are synced /
	connected.

	* app/core/gimpcontext.[ch]: added convenience functions to get/set
	the font by name.

	* app/tools/gimptextoptions.[ch]: don't hold a GimpText object
	that duplicates properties like font and color which are in
	GimpContext already. Instead added all text properties that are
	controlled from the text tool options.  Handling of the foreground
	color is somewhat broken and needs a GimpContext wizard (Mitch!).

	* app/text/gimptext.c: blurbs are not any longer needed now that
	the property widgets are created from the GimpTextOptions.

	* app/tools/gimptexttool.c: changed accordingly.

	* app/widgets/gimptexteditor.[ch]: use an internal GtkTextBuffer
	and emit "text-changed" when it changes.
parent af78bf37
2004-03-11 Sven Neumann <sven@gimp.org>
* app/config/gimpconfig-utils.c: made gimp_config_sync() and
gimp_config_connect() also work on objects of different types.
Properties with the same name and the same type are synced /
connected.
* app/core/gimpcontext.[ch]: added convenience functions to get/set
the font by name.
* app/tools/gimptextoptions.[ch]: don't hold a GimpText object
that duplicates properties like font and color which are in
GimpContext already. Instead added all text properties that are
controlled from the text tool options. Handling of the foreground
color is somewhat broken and needs a GimpContext wizard (Mitch!).
* app/text/gimptext.c: blurbs are not any longer needed now that
the property widgets are created from the GimpTextOptions.
* app/tools/gimptexttool.c: changed accordingly.
* app/widgets/gimptexteditor.[ch]: use an internal GtkTextBuffer
and emit "text-changed" when it changes.
2004-03-11 Sven Neumann <sven@gimp.org>
* plug-ins/common/colortoalpha.c: when running in interactive
......@@ -43,25 +43,35 @@ gimp_config_connect_notify (GObject *src,
GParamSpec *param_spec,
GObject *dest)
{
if ((param_spec->flags & G_PARAM_READABLE) &&
(param_spec->flags & G_PARAM_WRITABLE) &&
! (param_spec->flags & G_PARAM_CONSTRUCT_ONLY))
if (param_spec->flags & G_PARAM_READABLE)
{
GValue value = { 0, };
GParamSpec *dest_spec;
g_value_init (&value, param_spec->value_type);
dest_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (dest),
param_spec->name);
g_object_get_property (src, param_spec->name, &value);
if (dest_spec &&
(dest_spec->value_type == param_spec->value_type) &&
(dest_spec->flags & G_PARAM_WRITABLE) &&
(dest_spec->flags & G_PARAM_CONSTRUCT_ONLY) == 0)
{
GValue value = { 0, };
g_value_init (&value, param_spec->value_type);
g_object_get_property (src, param_spec->name, &value);
g_signal_handlers_block_by_func (dest, gimp_config_connect_notify, src);
g_object_set_property (dest, param_spec->name, &value);
g_signal_handlers_unblock_by_func (dest, gimp_config_connect_notify, src);
g_signal_handlers_block_by_func (dest,
gimp_config_connect_notify, src);
g_object_set_property (dest, param_spec->name, &value);
g_signal_handlers_unblock_by_func (dest,
gimp_config_connect_notify, src);
g_value_unset (&value);
g_value_unset (&value);
}
}
}
/**
* gimp_config_connect:
* @a: a #GObject
......@@ -72,11 +82,9 @@ gimp_config_connect_notify (GObject *src,
* one are propagated to the other. This is a two-way connection.
*
* If @property_name is %NULL the connection is setup for all
* properties. It is then required that @a and @b are of the same
* type. If a name is given, only this property is connected. In this
* case, the two objects don't need to be of the same type but they
* should both have a property of the same type that has the given
* @property_name.
* properties. It is not required that @a and @b are of the same type.
* Only changes on properties that exist in both object classes and
* are of the same value_type are propagated.
**/
void
gimp_config_connect (GObject *a,
......@@ -86,10 +94,7 @@ gimp_config_connect (GObject *a,
gchar *signal_name;
g_return_if_fail (a != b);
g_return_if_fail (G_IS_OBJECT (a));
g_return_if_fail (G_IS_OBJECT (b));
g_return_if_fail (property_name != NULL ||
G_TYPE_FROM_INSTANCE (a) == G_TYPE_FROM_INSTANCE (b));
g_return_if_fail (G_IS_OBJECT (a) && G_IS_OBJECT (b));
if (property_name)
signal_name = g_strconcat ("notify::", property_name, NULL);
......@@ -119,8 +124,7 @@ void
gimp_config_disconnect (GObject *a,
GObject *b)
{
g_return_if_fail (G_IS_OBJECT (a));
g_return_if_fail (G_IS_OBJECT (b));
g_return_if_fail (G_IS_OBJECT (a) && G_IS_OBJECT (b));
g_signal_handlers_disconnect_by_func (b,
G_CALLBACK (gimp_config_connect_notify),
......@@ -130,11 +134,50 @@ gimp_config_disconnect (GObject *a,
b);
}
static gboolean
gimp_config_diff_property (GObject *a,
GObject *b,
GParamSpec *prop_spec)
{
GValue a_value = { 0, };
GValue b_value = { 0, };
gboolean retval = FALSE;
g_value_init (&a_value, prop_spec->value_type);
g_value_init (&b_value, prop_spec->value_type);
g_object_get_property (a, prop_spec->name, &a_value);
g_object_get_property (b, prop_spec->name, &b_value);
if (g_param_values_cmp (prop_spec, &a_value, &b_value))
{
if ((prop_spec->flags & GIMP_PARAM_AGGREGATE) &&
G_IS_PARAM_SPEC_OBJECT (prop_spec) &&
g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
GIMP_TYPE_CONFIG))
{
if (! gimp_config_is_equal_to (g_value_get_object (&a_value),
g_value_get_object (&b_value)))
{
retval = TRUE;
}
}
else
{
retval = TRUE;
}
}
g_value_unset (&a_value);
g_value_unset (&b_value);
return retval;
}
static GList *
gimp_config_diff_internal (GimpConfig *a,
GimpConfig *b,
GParamFlags flags)
gimp_config_diff_same (GimpConfig *a,
GimpConfig *b,
GParamFlags flags)
{
GParamSpec **param_specs;
guint n_param_specs;
......@@ -150,36 +193,42 @@ gimp_config_diff_internal (GimpConfig *a,
if (! flags || ((prop_spec->flags & flags) == flags))
{
GValue a_value = { 0, };
GValue b_value = { 0, };
if (gimp_config_diff_property (G_OBJECT (a),
G_OBJECT (b), prop_spec))
list = g_list_prepend (list, prop_spec);
}
}
g_value_init (&a_value, prop_spec->value_type);
g_value_init (&b_value, prop_spec->value_type);
g_free (param_specs);
g_object_get_property (G_OBJECT (a), prop_spec->name, &a_value);
g_object_get_property (G_OBJECT (b), prop_spec->name, &b_value);
return list;
}
if (g_param_values_cmp (param_specs[i], &a_value, &b_value))
{
if ((prop_spec->flags & GIMP_PARAM_AGGREGATE) &&
G_IS_PARAM_SPEC_OBJECT (prop_spec) &&
g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
GIMP_TYPE_CONFIG))
{
if (! gimp_config_is_equal_to (g_value_get_object (&a_value),
g_value_get_object (&b_value)))
{
list = g_list_prepend (list, prop_spec);
}
}
else
{
list = g_list_prepend (list, prop_spec);
}
}
static GList *
gimp_config_diff_other (GimpConfig *a,
GimpConfig *b,
GParamFlags flags)
{
GParamSpec **param_specs;
guint n_param_specs;
gint i;
GList *list = NULL;
param_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a),
&n_param_specs);
for (i = 0; i < n_param_specs; i++)
{
GParamSpec *a_spec = param_specs[i];
GParamSpec *b_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (b),
a_spec->name);
g_value_unset (&a_value);
g_value_unset (&b_value);
if (b_spec &&
(a_spec->value_type == b_spec->value_type) &&
(! flags || (a_spec->flags & b_spec->flags & flags) == flags))
{
if (gimp_config_diff_property (G_OBJECT (a), G_OBJECT (b), b_spec))
list = g_list_prepend (list, b_spec);
}
}
......@@ -188,15 +237,20 @@ gimp_config_diff_internal (GimpConfig *a,
return list;
}
/**
* gimp_config_diff:
* @a: a #GimpConfig
* @b: another #GimpConfig of the same type as @a
* @a: a #GimpConfig object
* @b: another #GimpConfig object
* @flags: a mask of GParamFlags
*
* Compares all properties of @a and @b that have all @flags set. If
* @flags is 0, all properties are compared.
*
* If the two objects are not of the same type, only properties that
* exist in both object classes and are of the same value_type are
* compared.
*
* Return value: a GList of differing GParamSpecs.
**/
GList *
......@@ -204,24 +258,34 @@ gimp_config_diff (GimpConfig *a,
GimpConfig *b,
GParamFlags flags)
{
GList *diff;
g_return_val_if_fail (GIMP_IS_CONFIG (a), FALSE);
g_return_val_if_fail (GIMP_IS_CONFIG (b), FALSE);
g_return_val_if_fail (G_TYPE_FROM_INSTANCE (a) == G_TYPE_FROM_INSTANCE (b),
FALSE);
return g_list_reverse (gimp_config_diff_internal (a, b, flags));
if (G_TYPE_FROM_INSTANCE (a) == G_TYPE_FROM_INSTANCE (b))
diff = gimp_config_diff_same (a, b, flags);
else
diff = gimp_config_diff_other (a, b, flags);
return g_list_reverse (diff);
}
/**
* gimp_config_sync:
* @src: a #GimpConfig
* @dest: another #GimpConfig of the same type as @src
* @src: a #GimpConfig object
* @dest: another #GimpConfig object
* @flags: a mask of GParamFlags
*
* Compares all read- and write-able properties from @src and @dest
* that have all @flags set. Differing values are then copied from
* @src to @dest. If @flags is 0, all differing read/write properties
* are synced.
* @src to @dest. If @flags is 0, all differing read/write properties.
*
* Properties marked as "construct-only" are not touched.
*
* If the two objects are not of the same type, only
* properties that exist in both object classes and are of the same
* value_type are synchronized
*
* Return value: %TRUE if @dest was modified, %FALSE otherwise
**/
......@@ -235,15 +299,16 @@ gimp_config_sync (GimpConfig *src,
g_return_val_if_fail (GIMP_IS_CONFIG (src), FALSE);
g_return_val_if_fail (GIMP_IS_CONFIG (dest), FALSE);
g_return_val_if_fail (G_TYPE_FROM_INSTANCE (src) == G_TYPE_FROM_INSTANCE (dest),
FALSE);
/* we use the internal version here for a number of reasons:
/* we use the internal versions here for a number of reasons:
* - it saves a g_list_reverse()
* - it avoids duplicated parameter checks
* - it makes GimpTemplateEditor work (resolution is set before size)
*/
diff = gimp_config_diff_internal (src, dest, (flags | G_PARAM_READWRITE));
if (G_TYPE_FROM_INSTANCE (src) == G_TYPE_FROM_INSTANCE (dest))
diff = gimp_config_diff_same (src, dest, (flags | G_PARAM_READWRITE));
else
diff = gimp_config_diff_other (src, dest, flags);
if (!diff)
return FALSE;
......@@ -275,7 +340,8 @@ gimp_config_sync (GimpConfig *src,
* @config: a #GimpConfig
*
* Resets all writable properties of @object to the default values as
* defined in their #GParamSpec.
* defined in their #GParamSpec. Properties marked as "construct-only"
* are not touched.
**/
void
gimp_config_reset_properties (GimpConfig *config)
......
......@@ -87,8 +87,8 @@ static void gimp_context_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_context_get_memsize (GimpObject *object,
gint64 *gui_size);
static gint64 gimp_context_get_memsize (GimpObject *object,
gint64 *gui_size);
static gboolean gimp_context_serialize (GimpConfig *config,
GimpConfigWriter *writer,
......@@ -1124,11 +1124,11 @@ gimp_context_serialize_property (GimpConfig *config,
context = GIMP_CONTEXT (config);
#if 0
//#if 0
/* serialize nothing if the property is not defined */
if (! ((1 << property_id) & context->defined_props))
return TRUE;
#endif
//#endif
switch (property_id)
{
......@@ -2694,6 +2694,28 @@ gimp_context_set_font (GimpContext *context,
gimp_context_real_set_font (context, font);
}
const gchar *
gimp_context_get_font_name (GimpContext *context)
{
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return (context->font ?
gimp_object_get_name (GIMP_OBJECT (context->font)) : NULL);
}
void
gimp_context_set_font_name (GimpContext *context,
const gchar *name)
{
GimpObject *font;
g_return_if_fail (GIMP_IS_CONTEXT (context));
font = gimp_container_get_child_by_name (context->gimp->fonts, name);
gimp_context_set_font (context, GIMP_FONT (font));
}
void
gimp_context_font_changed (GimpContext *context)
{
......@@ -2704,7 +2726,7 @@ gimp_context_font_changed (GimpContext *context)
context->font);
}
/* the active palette was modified */
/* the active font was modified */
static void
gimp_context_font_dirty (GimpFont *font,
GimpContext *context)
......
......@@ -265,6 +265,9 @@ void gimp_context_palette_changed (GimpContext *context);
GimpFont * gimp_context_get_font (GimpContext *context);
void gimp_context_set_font (GimpContext *context,
GimpFont *font);
const gchar * gimp_context_get_font_name (GimpContext *context);
void gimp_context_set_font_name (GimpContext *context,
const gchar *name);
void gimp_context_font_changed (GimpContext *context);
......
......@@ -41,8 +41,6 @@
#include "gimptext.h"
#include "gimp-intl.h"
enum
{
......@@ -174,17 +172,11 @@ gimp_text_class_init (GimpTextClass *klass)
TRUE, FALSE, GIMP_UNIT_PIXEL,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HINTING,
"hinting",
N_("Hinting alters the font outline to "
"produce a crisp bitmap at small "
"sizes"),
"hinting", NULL,
TRUE,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_AUTOHINT,
"autohint",
N_("If available, hints from the font are "
"used but you may prefer to always use "
"the automatic hinter"),
"autohint", NULL,
FALSE,
GIMP_PARAM_DEFAULTS);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ANTIALIAS,
......@@ -200,8 +192,7 @@ gimp_text_class_init (GimpTextClass *klass)
language,
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_BASE_DIR,
"base-direction",
NULL,
"base-direction", NULL,
GIMP_TYPE_TEXT_DIRECTION,
GIMP_TEXT_DIRECTION_LTR,
0);
......@@ -215,24 +206,20 @@ gimp_text_class_init (GimpTextClass *klass)
GIMP_TEXT_OUTLINE_NONE,
GIMP_PARAM_DEFAULTS);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_JUSTIFICATION,
"justify",
NULL,
"justify", NULL,
GIMP_TYPE_TEXT_JUSTIFICATION,
GIMP_TEXT_JUSTIFY_LEFT,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_INDENTATION,
"indent",
N_("Indentation of the first line"),
"indent", NULL,
-8192.0, 8192.0, 0.0,
GIMP_PARAM_DEFAULTS);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_LINE_SPACING,
"line-spacing",
N_("Modify line spacing"),
"line-spacing", NULL,
-8192.0, 8192.0, 0.0,
GIMP_PARAM_DEFAULTS);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_LETTER_SPACING,
"letter-spacing",
N_("Modify letter spacing"),
"letter-spacing", NULL,
-8192.0, 8192.0, 0.0,
GIMP_PARAM_DEFAULTS);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_BOX_MODE,
......
......@@ -21,6 +21,7 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
......@@ -52,31 +53,37 @@
enum
{
PROP_0,
PROP_TEXT
PROP_FONT_SIZE,
PROP_UNIT,
PROP_HINTING,
PROP_AUTOHINT,
PROP_ANTIALIAS,
PROP_LANGUAGE,
PROP_BASE_DIR,
PROP_JUSTIFICATION,
PROP_INDENTATION,
PROP_LINE_SPACING,
PROP_COLOR
};
static void gimp_text_options_init (GimpTextOptions *options);
static void gimp_text_options_class_init (GimpTextOptionsClass *options_class);
static void gimp_text_options_class_init (GimpTextOptionsClass *options_class);
static void gimp_text_options_init (GimpTextOptions *options);
static void gimp_text_options_finalize (GObject *object);
static void gimp_text_options_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_text_options_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_text_options_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_text_options_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_text_options_reset (GimpToolOptions *options);
static void gimp_text_options_notify_font (GimpContext *context,
GParamSpec *pspec,
GimpText *text);
static void gimp_text_options_notify_text_font (GimpText *text,
GParamSpec *pspec,
GimpContext *context);
static void gimp_text_options_notify_color (GObject *object,
GParamSpec *pspec);
static void gimp_text_options_notify_font (GimpContext *context,
GParamSpec *pspec,
GimpText *text);
static GimpToolOptionsClass *parent_class = NULL;
......@@ -99,7 +106,7 @@ gimp_text_options_get_type (void)
NULL, /* class_data */
sizeof (GimpTextOptions),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_text_options_init,
(GInstanceInitFunc) gimp_text_options_init
};
type = g_type_register_static (GIMP_TYPE_TOOL_OPTIONS,
......@@ -113,59 +120,130 @@ gimp_text_options_get_type (void)
static void
gimp_text_options_class_init (GimpTextOptionsClass *klass)
{
GObjectClass *object_class;
GimpToolOptionsClass *options_class;
object_class = G_OBJECT_CLASS (klass);
options_class = GIMP_TOOL_OPTIONS_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpRGB black;
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_text_options_finalize;
object_class->set_property = gimp_text_options_set_property;
object_class->get_property = gimp_text_options_get_property;
options_class->reset = gimp_text_options_reset;
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_TEXT,
"text", NULL,
GIMP_TYPE_TEXT,
GIMP_PARAM_AGGREGATE);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_UNIT,
"font-size-unit", NULL,
TRUE, FALSE, GIMP_UNIT_PIXEL,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_FONT_SIZE,
"font-size", NULL,
0.0, 8192.0, 18.0,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HINTING,
"hinting",
N_("Hinting alters the font outline to "
"produce a crisp bitmap at small "
"sizes"),
TRUE,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_AUTOHINT,
"autohint",
N_("If available, hints from the font are "
"used but you may prefer to always use "
"the automatic hinter"),
FALSE,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ANTIALIAS,
"antialias", NULL,
TRUE,
0);
GIMP_CONFIG_INSTALL_PROP_STRING (object_class, PROP_LANGUAGE,
"language", NULL,
(const gchar *) gtk_get_default_language (),
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_BASE_DIR,
"base-direction", NULL,
GIMP_TYPE_TEXT_DIRECTION,
GIMP_TEXT_DIRECTION_LTR,
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_JUSTIFICATION,
"justify", NULL,
GIMP_TYPE_TEXT_JUSTIFICATION,
GIMP_TEXT_JUSTIFY_LEFT,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_INDENTATION,
"indent",
N_("Indentation of the first line"),
-8192.0, 8192.0, 0.0,
GIMP_PARAM_DEFAULTS);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_LINE_SPACING,
"line-spacing",
N_("Modify line spacing"),
-8192.0, 8192.0, 0.0,
GIMP_PARAM_DEFAULTS);
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
g_object_class_install_property (object_class, PROP_COLOR,
gimp_param_spec_color ("color", NULL, NULL,
&black,
G_PARAM_READWRITE));
}
static void
gimp_text_options_init (GimpTextOptions *options)
{
options->text = g_object_new (GIMP_TYPE_TEXT, NULL);
options->buffer = gimp_prop_text_buffer_new (G_OBJECT (options->text),
"text", -1);
gimp_context_get_foreground (GIMP_CONTEXT (options), &options->color);
g_signal_connect_object (options, "notify::font",
G_CALLBACK (gimp_text_options_notify_font),
options->text, 0);
g_signal_connect_object (options->text, "notify::font",
G_CALLBACK (gimp_text_options_notify_text_font),
options, 0);
g_signal_connect (options, "notify::foreground",
G_CALLBACK (gimp_text_options_notify_color),
NULL);
}
static void
gimp_text_options_finalize (GObject *object)