2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2000-09-29 20:00:00 +08:00
|
|
|
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
|
1998-07-12 19:40:43 +08:00
|
|
|
*
|
2001-04-22 08:38:56 +08:00
|
|
|
* gimplist.c
|
|
|
|
* Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
|
|
|
|
*
|
1998-07-12 19:40:43 +08:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
2000-09-29 20:00:00 +08:00
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2003-04-06 19:21:56 +08:00
|
|
|
#include <stdlib.h>
|
2001-03-17 03:14:04 +08:00
|
|
|
#include <string.h> /* strcmp */
|
|
|
|
|
2001-08-14 22:53:55 +08:00
|
|
|
#include <glib-object.h>
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-05-10 06:34:59 +08:00
|
|
|
#include "core-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
Jens Lautenbacher <jtl@gimp.org>
2000-12-18 Sven Neumann <sven@gimp.org>
Jens Lautenbacher <jtl@gimp.org>
* app/Makefile.am
* app/gimpbrushlistP.h
* app/gimpbrushpipeP.h
* app/gimpobjectP.h: removed these three files
* app/parasitelistP.h
* app/channels_dialog.c
* app/docindex.c
* app/gimpdrawable.c
* app/gimpdrawableP.h
* app/gimpimage.c
* app/gimpimageP.h
* app/gimplist.[ch]
* app/gimpobject.c
* app/gimpobject.h
* app/gimpsetP.h: changed according to header removal
* app/airbrush.c
* app/brush_select.[ch]
* app/brushes_cmds.c
* app/gimpbrush.[ch]
* app/gimpbrushgenerated.[ch]
* app/gimpbrushlist.[ch]
* app/gimpbrushpipe.[ch]
* app/gimpcontextpreview.c
* app/paint_core.c
* app/paintbrush.c
* app/pencil.c
* tools/pdbgen/pdb/brushes.pdb: Big Brushes Cleanup.
The GimpBrush* object hierarchy and the file formats were broken by
"design". This made it overly difficult to read and write pixmap
brushes and brush pipes, leading to the situation that The GIMP was
not able to read it's very own file formats. Since the GimpBrush
format did support arbitrary color depths, the introduction of a
file format for pixmap brushes was unnecessary.
The GimpBrushPixmap object is dead. GimpBrush has an additional
pixmap temp_buf and handles pixmap brushes transparently. The file
format of pixmap brushes is not any longer a grayscale brush plus
a pattern, but a simple brush with RGBA data. The old brushes can
still be loaded, but the .gpb format is deprecated.
GimpBrushPipe derives from GimpBrush. The fileformat is still a text
header, followed by a number of brushes, but those brushes are stored
in the new GimpBrush format (no pattern anymore). The pipe does not
care about the depth of the contained GimpBrushes, so we get
grayscale BrushPipes for free. Since the brush loader still loads the
old format, old .gih files can also still be loaded.
Since the brushes in the GimpBrushPipe do not any longer contain a
pointer to the pipe object, we do only temporarily switch brushes
in the paint_core routines. This is not very elegant, but the best
we can do without a major redesign.
* app/patterns.[ch]: changed the loader to work with a filedescriptor
instead of a filehandle to make it work with the new brush loading
code.
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl
* plug-ins/common/gih.c: new plug-in that saves GIH files in the
new format (loader will follow soon)
* plug-ins/common/gpb.c: removed since Pixmap Brushes are no longer
supported as a special file format.
* plug-ins/common/gbr.c: load and save brushes in the new brush format
which allows RGBA brushes too.
* plug-ins/common/pat.c: load and save grayscale patterns too
2000-12-18 23:14:08 +08:00
|
|
|
#include "gimplist.h"
|
1998-07-12 19:40:43 +08:00
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
PROP_UNIQUE_NAMES,
|
2008-05-11 02:42:41 +08:00
|
|
|
PROP_SORT_FUNC,
|
|
|
|
PROP_APPEND
|
2004-05-24 18:49:34 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void gimp_list_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec);
|
|
|
|
static void gimp_list_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec);
|
|
|
|
|
2003-11-17 01:51:36 +08:00
|
|
|
static gint64 gimp_list_get_memsize (GimpObject *object,
|
|
|
|
gint64 *gui_size);
|
2002-01-31 00:14:26 +08:00
|
|
|
|
2001-08-11 22:39:19 +08:00
|
|
|
static void gimp_list_add (GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpObject *object);
|
2001-08-11 22:39:19 +08:00
|
|
|
static void gimp_list_remove (GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpObject *object);
|
2001-08-11 22:39:19 +08:00
|
|
|
static void gimp_list_reorder (GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpObject *object,
|
|
|
|
gint new_index);
|
2003-08-26 05:25:13 +08:00
|
|
|
static void gimp_list_clear (GimpContainer *container);
|
2001-08-11 22:39:19 +08:00
|
|
|
static gboolean gimp_list_have (const GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
const GimpObject *object);
|
2001-08-11 22:39:19 +08:00
|
|
|
static void gimp_list_foreach (const GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
GFunc func,
|
|
|
|
gpointer user_data);
|
2001-08-11 22:39:19 +08:00
|
|
|
static GimpObject * gimp_list_get_child_by_name (const GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
const gchar *name);
|
2001-08-11 22:39:19 +08:00
|
|
|
static GimpObject * gimp_list_get_child_by_index (const GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
gint index);
|
2001-08-11 22:39:19 +08:00
|
|
|
static gint gimp_list_get_child_index (const GimpContainer *container,
|
2004-03-16 21:03:24 +08:00
|
|
|
const GimpObject *object);
|
1998-07-12 19:40:43 +08:00
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
static void gimp_list_uniquefy_name (GimpList *gimp_list,
|
|
|
|
GimpObject *object);
|
|
|
|
static void gimp_list_object_renamed (GimpObject *object,
|
|
|
|
GimpList *list);
|
|
|
|
|
2000-09-29 20:00:00 +08:00
|
|
|
|
2006-05-15 17:46:31 +08:00
|
|
|
G_DEFINE_TYPE (GimpList, gimp_list, GIMP_TYPE_CONTAINER)
|
1998-07-12 19:40:43 +08:00
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
#define parent_class gimp_list_parent_class
|
1998-07-12 19:40:43 +08:00
|
|
|
|
|
|
|
|
2001-02-04 22:10:03 +08:00
|
|
|
static void
|
|
|
|
gimp_list_class_init (GimpListClass *klass)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
2004-05-24 18:49:34 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
|
|
|
GimpContainerClass *container_class = GIMP_CONTAINER_CLASS (klass);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
object_class->set_property = gimp_list_set_property;
|
|
|
|
object_class->get_property = gimp_list_get_property;
|
|
|
|
|
2002-01-31 00:14:26 +08:00
|
|
|
gimp_object_class->get_memsize = gimp_list_get_memsize;
|
|
|
|
|
2001-02-06 01:48:50 +08:00
|
|
|
container_class->add = gimp_list_add;
|
|
|
|
container_class->remove = gimp_list_remove;
|
2001-02-18 05:20:10 +08:00
|
|
|
container_class->reorder = gimp_list_reorder;
|
2003-08-26 05:25:13 +08:00
|
|
|
container_class->clear = gimp_list_clear;
|
2001-02-06 01:48:50 +08:00
|
|
|
container_class->have = gimp_list_have;
|
|
|
|
container_class->foreach = gimp_list_foreach;
|
|
|
|
container_class->get_child_by_name = gimp_list_get_child_by_name;
|
|
|
|
container_class->get_child_by_index = gimp_list_get_child_by_index;
|
|
|
|
container_class->get_child_index = gimp_list_get_child_index;
|
2004-05-24 18:49:34 +08:00
|
|
|
|
|
|
|
g_object_class_install_property (object_class, PROP_UNIQUE_NAMES,
|
2006-04-12 20:49:29 +08:00
|
|
|
g_param_spec_boolean ("unique-names",
|
2004-05-24 18:49:34 +08:00
|
|
|
NULL, NULL,
|
|
|
|
FALSE,
|
2006-01-19 04:29:40 +08:00
|
|
|
GIMP_PARAM_READWRITE |
|
2004-05-24 18:49:34 +08:00
|
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
|
|
|
|
g_object_class_install_property (object_class, PROP_SORT_FUNC,
|
2006-04-12 20:49:29 +08:00
|
|
|
g_param_spec_pointer ("sort-func",
|
2004-05-24 18:49:34 +08:00
|
|
|
NULL, NULL,
|
2006-01-19 04:29:40 +08:00
|
|
|
GIMP_PARAM_READWRITE |
|
2004-05-24 18:49:34 +08:00
|
|
|
G_PARAM_CONSTRUCT));
|
2008-05-11 02:42:41 +08:00
|
|
|
|
|
|
|
g_object_class_install_property (object_class, PROP_APPEND,
|
|
|
|
g_param_spec_boolean ("append",
|
|
|
|
NULL, NULL,
|
|
|
|
FALSE,
|
|
|
|
GIMP_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT));
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-02-04 22:10:03 +08:00
|
|
|
gimp_list_init (GimpList *list)
|
|
|
|
{
|
2004-05-24 18:49:34 +08:00
|
|
|
list->list = NULL;
|
|
|
|
list->unique_names = FALSE;
|
|
|
|
list->sort_func = NULL;
|
2008-05-11 02:42:41 +08:00
|
|
|
list->append = FALSE;
|
2004-05-24 18:49:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_list_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GimpList *list = GIMP_LIST (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_UNIQUE_NAMES:
|
|
|
|
list->unique_names = g_value_get_boolean (value);
|
|
|
|
break;
|
|
|
|
case PROP_SORT_FUNC:
|
|
|
|
gimp_list_set_sort_func (list, g_value_get_pointer (value));
|
|
|
|
break;
|
2008-05-11 02:42:41 +08:00
|
|
|
case PROP_APPEND:
|
|
|
|
list->append = g_value_get_boolean (value);
|
|
|
|
break;
|
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_list_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GimpList *list = GIMP_LIST (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_UNIQUE_NAMES:
|
|
|
|
g_value_set_boolean (value, list->unique_names);
|
|
|
|
break;
|
|
|
|
case PROP_SORT_FUNC:
|
|
|
|
g_value_set_pointer (value, list->sort_func);
|
|
|
|
break;
|
2008-05-11 02:42:41 +08:00
|
|
|
case PROP_APPEND:
|
|
|
|
g_value_set_boolean (value, list->append);
|
|
|
|
break;
|
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
2001-02-04 22:10:03 +08:00
|
|
|
}
|
|
|
|
|
2003-11-17 01:51:36 +08:00
|
|
|
static gint64
|
2003-08-25 18:49:33 +08:00
|
|
|
gimp_list_get_memsize (GimpObject *object,
|
2003-11-17 01:51:36 +08:00
|
|
|
gint64 *gui_size)
|
2002-01-31 00:14:26 +08:00
|
|
|
{
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpList *list = GIMP_LIST (object);
|
2003-11-17 01:51:36 +08:00
|
|
|
gint64 memsize = 0;
|
2002-01-31 00:14:26 +08:00
|
|
|
|
2008-11-21 06:45:19 +08:00
|
|
|
memsize += (gimp_container_get_n_children (GIMP_CONTAINER (list)) *
|
2002-01-31 00:14:26 +08:00
|
|
|
sizeof (GList));
|
|
|
|
|
2008-11-21 06:45:19 +08:00
|
|
|
if (gimp_container_get_policy (GIMP_CONTAINER (list)) ==
|
2002-01-31 00:14:26 +08:00
|
|
|
GIMP_CONTAINER_POLICY_STRONG)
|
|
|
|
{
|
2004-03-16 21:03:24 +08:00
|
|
|
GList *glist;
|
2002-01-31 00:14:26 +08:00
|
|
|
|
2004-03-16 21:03:24 +08:00
|
|
|
for (glist = list->list; glist; glist = g_list_next (glist))
|
|
|
|
memsize += gimp_object_get_memsize (GIMP_OBJECT (glist->data), gui_size);
|
2002-01-31 00:14:26 +08:00
|
|
|
}
|
|
|
|
|
2003-08-25 18:49:33 +08:00
|
|
|
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
|
|
|
|
gui_size);
|
2002-01-31 00:14:26 +08:00
|
|
|
}
|
|
|
|
|
1998-07-12 19:40:43 +08:00
|
|
|
static void
|
2001-02-04 22:10:03 +08:00
|
|
|
gimp_list_add (GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
GimpObject *object)
|
1998-07-12 19:40:43 +08:00
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
2001-02-04 22:10:03 +08:00
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
if (list->unique_names)
|
|
|
|
gimp_list_uniquefy_name (list, object);
|
|
|
|
|
|
|
|
if (list->unique_names || list->sort_func)
|
|
|
|
g_signal_connect (object, "name-changed",
|
|
|
|
G_CALLBACK (gimp_list_object_renamed),
|
|
|
|
list);
|
|
|
|
|
|
|
|
if (list->sort_func)
|
|
|
|
list->list = g_list_insert_sorted (list->list, object, list->sort_func);
|
2008-05-11 02:42:41 +08:00
|
|
|
else if (list->append)
|
|
|
|
list->list = g_list_append (list->list, object);
|
2004-05-24 18:49:34 +08:00
|
|
|
else
|
|
|
|
list->list = g_list_prepend (list->list, object);
|
2008-10-11 18:14:21 +08:00
|
|
|
|
|
|
|
GIMP_CONTAINER_CLASS (parent_class)->add (container, object);
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-02-04 22:10:03 +08:00
|
|
|
gimp_list_remove (GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
GimpObject *object)
|
1998-07-12 19:40:43 +08:00
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
2001-02-04 22:10:03 +08:00
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
if (list->unique_names || list->sort_func)
|
|
|
|
g_signal_handlers_disconnect_by_func (object,
|
|
|
|
gimp_list_object_renamed,
|
|
|
|
list);
|
|
|
|
|
2001-02-04 22:10:03 +08:00
|
|
|
list->list = g_list_remove (list->list, object);
|
2008-10-11 18:14:21 +08:00
|
|
|
|
|
|
|
GIMP_CONTAINER_CLASS (parent_class)->remove (container, object);
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
|
|
|
|
2001-02-18 05:20:10 +08:00
|
|
|
static void
|
|
|
|
gimp_list_reorder (GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
GimpObject *object,
|
|
|
|
gint new_index)
|
2001-02-18 05:20:10 +08:00
|
|
|
{
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
2001-02-18 05:20:10 +08:00
|
|
|
|
|
|
|
list->list = g_list_remove (list->list, object);
|
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (new_index == -1 ||
|
|
|
|
new_index == gimp_container_get_n_children (container) - 1)
|
2001-02-18 05:20:10 +08:00
|
|
|
list->list = g_list_append (list->list, object);
|
|
|
|
else
|
|
|
|
list->list = g_list_insert (list->list, object, new_index);
|
|
|
|
}
|
|
|
|
|
2003-08-26 05:25:13 +08:00
|
|
|
static void
|
|
|
|
gimp_list_clear (GimpContainer *container)
|
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
2003-08-26 05:25:13 +08:00
|
|
|
|
|
|
|
while (list->list)
|
|
|
|
gimp_container_remove (container, list->list->data);
|
|
|
|
}
|
|
|
|
|
2001-02-04 22:10:03 +08:00
|
|
|
static gboolean
|
2001-08-11 22:39:19 +08:00
|
|
|
gimp_list_have (const GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
const GimpObject *object)
|
1998-07-12 19:40:43 +08:00
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
2001-02-04 22:10:03 +08:00
|
|
|
return g_list_find (list->list, object) ? TRUE : FALSE;
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
|
|
|
|
2001-02-04 22:10:03 +08:00
|
|
|
static void
|
2001-08-11 22:39:19 +08:00
|
|
|
gimp_list_foreach (const GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
GFunc func,
|
|
|
|
gpointer user_data)
|
1998-07-12 19:40:43 +08:00
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
2001-02-04 22:10:03 +08:00
|
|
|
g_list_foreach (list->list, func, user_data);
|
|
|
|
}
|
1999-10-27 02:27:27 +08:00
|
|
|
|
2001-02-06 01:48:50 +08:00
|
|
|
static GimpObject *
|
2001-08-11 22:39:19 +08:00
|
|
|
gimp_list_get_child_by_name (const GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
const gchar *name)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
|
|
|
GList *glist;
|
2001-02-04 22:10:03 +08:00
|
|
|
|
|
|
|
for (glist = list->list; glist; glist = g_list_next (glist))
|
|
|
|
{
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpObject *object = glist->data;
|
2001-02-04 22:10:03 +08:00
|
|
|
|
|
|
|
if (! strcmp (object->name, name))
|
2006-04-12 20:49:29 +08:00
|
|
|
return object;
|
2001-02-04 22:10:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
|
|
|
|
2001-02-06 01:48:50 +08:00
|
|
|
static GimpObject *
|
2001-08-11 22:39:19 +08:00
|
|
|
gimp_list_get_child_by_index (const GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
gint index)
|
1998-07-12 19:40:43 +08:00
|
|
|
{
|
2004-03-16 21:03:24 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
2001-02-06 01:48:50 +08:00
|
|
|
GList *glist;
|
2001-02-04 22:10:03 +08:00
|
|
|
|
|
|
|
glist = g_list_nth (list->list, index);
|
|
|
|
|
|
|
|
if (glist)
|
|
|
|
return (GimpObject *) glist->data;
|
|
|
|
|
|
|
|
return NULL;
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
|
|
|
|
2001-02-06 01:48:50 +08:00
|
|
|
static gint
|
2001-08-11 22:39:19 +08:00
|
|
|
gimp_list_get_child_index (const GimpContainer *container,
|
2006-04-12 20:49:29 +08:00
|
|
|
const GimpObject *object)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpList *list = GIMP_LIST (container);
|
2001-02-04 22:10:03 +08:00
|
|
|
|
|
|
|
return g_list_index (list->list, (gpointer) object);
|
1998-07-12 19:40:43 +08:00
|
|
|
}
|
2002-06-08 04:23:33 +08:00
|
|
|
|
2003-10-09 21:35:15 +08:00
|
|
|
/**
|
|
|
|
* gimp_list_new:
|
|
|
|
* @children_type: the #GType of objects the list is going to hold
|
2004-05-24 18:49:34 +08:00
|
|
|
* @unique_names: if the list should ensure that all its children
|
|
|
|
* have unique names.
|
2003-10-09 21:35:15 +08:00
|
|
|
*
|
|
|
|
* Creates a new #GimpList object. Since #GimpList is a #GimpContainer
|
|
|
|
* implementation, it holds GimpObjects. Thus @children_type must be
|
|
|
|
* GIMP_TYPE_OBJECT or a type derived from it.
|
|
|
|
*
|
2004-05-24 18:49:34 +08:00
|
|
|
* The returned list has the #GIMP_CONTAINER_POLICY_STRONG.
|
|
|
|
*
|
2003-10-09 21:35:15 +08:00
|
|
|
* Return value: a new #GimpList object
|
|
|
|
**/
|
2002-06-08 04:23:33 +08:00
|
|
|
GimpContainer *
|
2004-05-24 18:49:34 +08:00
|
|
|
gimp_list_new (GType children_type,
|
|
|
|
gboolean unique_names)
|
2002-06-08 04:23:33 +08:00
|
|
|
{
|
|
|
|
GimpList *list;
|
|
|
|
|
2002-10-23 22:55:07 +08:00
|
|
|
g_return_val_if_fail (g_type_is_a (children_type, GIMP_TYPE_OBJECT), NULL);
|
2002-06-08 04:23:33 +08:00
|
|
|
|
|
|
|
list = g_object_new (GIMP_TYPE_LIST,
|
2006-12-11 03:13:58 +08:00
|
|
|
"children-type", children_type,
|
2004-05-24 18:49:34 +08:00
|
|
|
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
|
|
|
"unique-names", unique_names ? TRUE : FALSE,
|
|
|
|
NULL);
|
|
|
|
|
2006-06-16 17:42:13 +08:00
|
|
|
/* for debugging purposes only */
|
|
|
|
gimp_object_set_static_name (GIMP_OBJECT (list), g_type_name (children_type));
|
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
return GIMP_CONTAINER (list);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_list_new_weak:
|
|
|
|
* @children_type: the #GType of objects the list is going to hold
|
|
|
|
* @unique_names: if the list should ensure that all its children
|
|
|
|
* have unique names.
|
|
|
|
*
|
|
|
|
* Creates a new #GimpList object. Since #GimpList is a #GimpContainer
|
|
|
|
* implementation, it holds GimpObjects. Thus @children_type must be
|
|
|
|
* GIMP_TYPE_OBJECT or a type derived from it.
|
|
|
|
*
|
|
|
|
* The returned list has the #GIMP_CONTAINER_POLICY_WEAK.
|
|
|
|
*
|
|
|
|
* Return value: a new #GimpList object
|
|
|
|
**/
|
|
|
|
GimpContainer *
|
|
|
|
gimp_list_new_weak (GType children_type,
|
|
|
|
gboolean unique_names)
|
|
|
|
{
|
|
|
|
GimpList *list;
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_type_is_a (children_type, GIMP_TYPE_OBJECT), NULL);
|
|
|
|
|
|
|
|
list = g_object_new (GIMP_TYPE_LIST,
|
2006-12-11 03:13:58 +08:00
|
|
|
"children-type", children_type,
|
2004-05-24 18:49:34 +08:00
|
|
|
"policy", GIMP_CONTAINER_POLICY_WEAK,
|
|
|
|
"unique-names", unique_names ? TRUE : FALSE,
|
2002-06-08 04:23:33 +08:00
|
|
|
NULL);
|
|
|
|
|
2006-06-16 17:42:13 +08:00
|
|
|
/* for debugging purposes only */
|
|
|
|
gimp_object_set_static_name (GIMP_OBJECT (list), g_type_name (children_type));
|
|
|
|
|
2002-06-08 04:23:33 +08:00
|
|
|
return GIMP_CONTAINER (list);
|
|
|
|
}
|
|
|
|
|
2003-10-09 21:35:15 +08:00
|
|
|
/**
|
|
|
|
* gimp_list_reverse:
|
|
|
|
* @list: a #GimpList
|
|
|
|
*
|
|
|
|
* Reverses the order of elements in a #GimpList.
|
|
|
|
**/
|
2002-06-08 04:23:33 +08:00
|
|
|
void
|
|
|
|
gimp_list_reverse (GimpList *list)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_LIST (list));
|
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (gimp_container_get_n_children (GIMP_CONTAINER (list)) > 1)
|
2002-06-08 04:23:33 +08:00
|
|
|
{
|
|
|
|
gimp_container_freeze (GIMP_CONTAINER (list));
|
|
|
|
list->list = g_list_reverse (list->list);
|
|
|
|
gimp_container_thaw (GIMP_CONTAINER (list));
|
|
|
|
}
|
|
|
|
}
|
2003-03-27 22:11:05 +08:00
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
/**
|
|
|
|
* gimp_list_set_sort_func:
|
|
|
|
* @list: a #GimpList
|
|
|
|
* @sort_func: a #GCompareFunc
|
|
|
|
*
|
|
|
|
* Sorts the elements of @list using gimp_list_sort() and remembers the
|
|
|
|
* passed @sort_func in order to keep the list ordered across inserting
|
|
|
|
* or renaming children.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_list_set_sort_func (GimpList *list,
|
|
|
|
GCompareFunc sort_func)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_LIST (list));
|
|
|
|
|
|
|
|
if (sort_func != list->sort_func)
|
|
|
|
{
|
|
|
|
if (sort_func)
|
|
|
|
gimp_list_sort (list, sort_func);
|
|
|
|
|
|
|
|
list->sort_func = sort_func;
|
|
|
|
g_object_notify (G_OBJECT (list), "sort-func");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-09 21:35:15 +08:00
|
|
|
/**
|
|
|
|
* gimp_list_sort:
|
|
|
|
* @list: a #GimpList
|
2004-05-24 18:49:34 +08:00
|
|
|
* @sort_func: a #GCompareFunc
|
2003-10-09 21:35:15 +08:00
|
|
|
*
|
2004-05-24 18:49:34 +08:00
|
|
|
* Sorts the elements of a #GimpList according to the given @sort_func.
|
2003-10-09 21:35:15 +08:00
|
|
|
* See g_list_sort() for a detailed description of this function.
|
|
|
|
**/
|
2003-03-27 22:11:05 +08:00
|
|
|
void
|
|
|
|
gimp_list_sort (GimpList *list,
|
2004-05-24 18:49:34 +08:00
|
|
|
GCompareFunc sort_func)
|
2003-03-27 22:11:05 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_LIST (list));
|
2004-05-24 18:49:34 +08:00
|
|
|
g_return_if_fail (sort_func != NULL);
|
2003-03-27 22:11:05 +08:00
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (gimp_container_get_n_children (GIMP_CONTAINER (list)) > 1)
|
2003-03-27 22:11:05 +08:00
|
|
|
{
|
|
|
|
gimp_container_freeze (GIMP_CONTAINER (list));
|
2004-05-24 18:49:34 +08:00
|
|
|
list->list = g_list_sort (list->list, sort_func);
|
2003-03-27 22:11:05 +08:00
|
|
|
gimp_container_thaw (GIMP_CONTAINER (list));
|
|
|
|
}
|
|
|
|
}
|
2003-04-06 19:21:56 +08:00
|
|
|
|
2003-10-09 21:35:15 +08:00
|
|
|
/**
|
|
|
|
* gimp_list_sort_by_name:
|
|
|
|
* @list: a #GimpList
|
|
|
|
*
|
|
|
|
* Sorts the #GimpObject elements of a #GimpList by their names.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_list_sort_by_name (GimpList *list)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_LIST (list));
|
|
|
|
|
|
|
|
gimp_list_sort (list, (GCompareFunc) gimp_object_name_collate);
|
|
|
|
}
|
|
|
|
|
2004-05-24 18:49:34 +08:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
|
|
|
static void
|
2003-04-06 19:21:56 +08:00
|
|
|
gimp_list_uniquefy_name (GimpList *gimp_list,
|
2004-05-24 18:49:34 +08:00
|
|
|
GimpObject *object)
|
2003-04-06 19:21:56 +08:00
|
|
|
{
|
2008-05-21 05:30:40 +08:00
|
|
|
GList *list;
|
|
|
|
const gchar *name = gimp_object_get_name (object);
|
2003-04-06 19:21:56 +08:00
|
|
|
|
2008-05-21 05:30:40 +08:00
|
|
|
if (! name)
|
|
|
|
return;
|
2003-04-06 19:21:56 +08:00
|
|
|
|
|
|
|
for (list = gimp_list->list; list; list = g_list_next (list))
|
|
|
|
{
|
2008-05-21 05:30:40 +08:00
|
|
|
GimpObject *object2 = list->data;
|
|
|
|
const gchar *name2 = gimp_object_get_name (object2);
|
2003-04-06 19:21:56 +08:00
|
|
|
|
|
|
|
if (object != object2 &&
|
2008-05-21 05:30:40 +08:00
|
|
|
name2 &&
|
|
|
|
! strcmp (name, name2))
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
2008-05-21 05:30:40 +08:00
|
|
|
GList *list2;
|
|
|
|
gchar *ext = strrchr (name, '#');
|
|
|
|
gchar *new_name = NULL;
|
|
|
|
gint unique_ext = 0;
|
2003-04-06 19:21:56 +08:00
|
|
|
|
|
|
|
if (ext)
|
|
|
|
{
|
|
|
|
gchar *ext_str;
|
|
|
|
|
|
|
|
unique_ext = atoi (ext + 1);
|
|
|
|
|
|
|
|
ext_str = g_strdup_printf ("%d", unique_ext);
|
|
|
|
|
|
|
|
/* check if the extension really is of the form "#<n>" */
|
|
|
|
if (! strcmp (ext_str, ext + 1))
|
|
|
|
{
|
|
|
|
*ext = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unique_ext = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (ext_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
unique_ext++;
|
|
|
|
|
|
|
|
g_free (new_name);
|
|
|
|
|
2008-05-21 05:30:40 +08:00
|
|
|
new_name = g_strdup_printf ("%s#%d", name, unique_ext);
|
2003-04-06 19:21:56 +08:00
|
|
|
|
|
|
|
for (list2 = gimp_list->list; list2; list2 = g_list_next (list2))
|
|
|
|
{
|
2008-05-21 05:30:40 +08:00
|
|
|
object2 = list2->data;
|
|
|
|
name2 = gimp_object_get_name (object2);
|
2003-04-06 19:21:56 +08:00
|
|
|
|
2008-05-21 05:30:40 +08:00
|
|
|
if (object != object2 &&
|
|
|
|
name2 &&
|
|
|
|
! strcmp (new_name, name2))
|
2006-04-12 20:49:29 +08:00
|
|
|
break;
|
2003-04-06 19:21:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while (list2);
|
|
|
|
|
2006-04-07 18:51:22 +08:00
|
|
|
gimp_object_take_name (object, new_name);
|
2006-04-12 20:49:29 +08:00
|
|
|
break;
|
|
|
|
}
|
2003-04-06 19:21:56 +08:00
|
|
|
}
|
|
|
|
}
|
2004-05-24 18:49:34 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_list_object_renamed (GimpObject *object,
|
|
|
|
GimpList *list)
|
|
|
|
{
|
|
|
|
if (list->unique_names)
|
|
|
|
{
|
|
|
|
g_signal_handlers_block_by_func (object,
|
|
|
|
gimp_list_object_renamed,
|
|
|
|
list);
|
|
|
|
|
|
|
|
gimp_list_uniquefy_name (list, object);
|
|
|
|
|
|
|
|
g_signal_handlers_unblock_by_func (object,
|
|
|
|
gimp_list_object_renamed,
|
|
|
|
list);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (list->sort_func)
|
|
|
|
{
|
|
|
|
GList *glist;
|
|
|
|
gint old_index;
|
|
|
|
gint new_index = 0;
|
|
|
|
|
|
|
|
old_index = g_list_index (list->list, object);
|
|
|
|
|
|
|
|
for (glist = list->list; glist; glist = g_list_next (glist))
|
|
|
|
{
|
|
|
|
GimpObject *object2 = GIMP_OBJECT (glist->data);
|
|
|
|
|
|
|
|
if (object == object2)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (list->sort_func (object, object2) > 0)
|
|
|
|
new_index++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_index != old_index)
|
|
|
|
gimp_container_reorder (GIMP_CONTAINER (list), object, new_index);
|
|
|
|
}
|
|
|
|
}
|