gimp/app/core/gimpdata.c

1245 lines
34 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
cleanup. 2001-04-22 Michael Natterer <mitch@gimp.org> * app/Makefile.am: cleanup. * app/interface.c: #include "gimpui.h" * app/gui/dialogs-constructors.[ch] * app/gui/dialogs.c * app/gui/menus.c * app/gui/test-commands.[ch]: changes for the image menu below. * app/apptypes.h * app/widgets/Makefile.am * app/widgets/gimpcontainermenu.[ch] * app/widgets/gimpcontainermenuimpl.[ch]: new widgets. The actual implemtation lives in a separate file because gimpcontainermenu.c's code is identical to gimpcontainerview.c's except for the base class. This will become an interface with Gtk 2.0. * app/widgets/gimpimagedock.[ch]: a dock with an image menu. The pages still don't follow the context correctly. * app/widgets/gimpmenuitem.[ch]: a menu item with a preview. * app/widgets/gimpdialogfactory.[ch]: pass a dock constructor to the constructor and provide a method to create a new dock within this factory's context. * app/widgets/gimpdock.[ch]: removed the constructor because we create only image docks now. Put the vbox into a main_vbox (which also contains the image menu). * app/widgets/gimpdockbook.[ch]: create new docks with the dialog factory. * app/gimpcontainer.[ch] * app/gimpdata.[ch] * app/gimpdatafactory.[ch] * app/gimpdatalist.[ch] * app/gimplist.[ch] * app/gimpviewable.[ch] * app/widgets/gimpbrushpreview.[ch] * app/widgets/gimpcontainergridview.[ch] * app/widgets/gimpcontainerlistview.[ch] * app/widgets/gimpcontainerview.[ch] * app/widgets/gimpdatafactoryview.[ch] * app/widgets/gimpdockable.[ch] * app/widgets/gimpdrawablelistitem.[ch] * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimpdrawablepreview.[ch] * app/widgets/gimplayerlistitem.[ch] * app/widgets/gimplayerlistview.[ch] * app/widgets/gimplistitem.[ch] * app/widgets/gimppalettepreview.[ch] * app/widgets/gimppatternpreview.[ch] * app/widgets/gimppreview.[ch]: ass-sign some copyrights.
2001-04-22 08:38:56 +08:00
* gimpdata.c
* Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "gimp-memsize.h"
#include "gimpdata.h"
#include "gimptag.h"
#include "gimptagged.h"
#include "gimp-intl.h"
enum
{
DIRTY,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_FILE,
PROP_WRITABLE,
PROP_DELETABLE,
PROP_MIME_TYPE
};
struct _GimpDataPrivate
{
GFile *file;
GQuark mime_type;
guint writable : 1;
guint deletable : 1;
guint dirty : 1;
guint internal : 1;
gint freeze_count;
gint64 mtime;
/* Identifies the GimpData object across sessions. Used when there
* is not a filename associated with the object.
*/
gchar *identifier;
GList *tags;
};
#define GIMP_DATA_GET_PRIVATE(obj) (((GimpData *) (obj))->priv)
static void gimp_data_tagged_iface_init (GimpTaggedInterface *iface);
static void gimp_data_constructed (GObject *object);
static void gimp_data_finalize (GObject *object);
static void gimp_data_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_data_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_data_name_changed (GimpObject *object);
static gint64 gimp_data_get_memsize (GimpObject *object,
gint64 *gui_size);
static gboolean gimp_data_is_name_editable (GimpViewable *viewable);
static void gimp_data_real_dirty (GimpData *data);
static GimpData * gimp_data_real_duplicate (GimpData *data);
static gint gimp_data_real_compare (GimpData *data1,
GimpData *data2);
static gboolean gimp_data_add_tag (GimpTagged *tagged,
GimpTag *tag);
static gboolean gimp_data_remove_tag (GimpTagged *tagged,
GimpTag *tag);
static GList * gimp_data_get_tags (GimpTagged *tagged);
static gchar * gimp_data_get_identifier (GimpTagged *tagged);
static gchar * gimp_data_get_checksum (GimpTagged *tagged);
G_DEFINE_TYPE_WITH_CODE (GimpData, gimp_data, GIMP_TYPE_VIEWABLE,
G_ADD_PRIVATE (GimpData)
G_IMPLEMENT_INTERFACE (GIMP_TYPE_TAGGED,
gimp_data_tagged_iface_init))
#define parent_class gimp_data_parent_class
static guint data_signals[LAST_SIGNAL] = { 0 };
static void
gimp_data_class_init (GimpDataClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning) 2001-07-24 Michael Natterer <mitch@gimp.org> Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning) * configure.in: require glib/gtk+ >= 1.3.7, commented out the gtkxmhtml stuff. From now on, you will need glib, pango, atk and gtk+ HEAD from CVS to hack or use GIMP HEAD. Beware, it crashes randomly :) * app/core/Makefile.am * app/core/gimpmarshal.list: new file plus rules to generate gimpmarshal.[ch] from it. * app/core/* * app/tools/* * app/widgets/* * libgimpwidgets/*: started to use the glib object system. All core/ objects are still gtk objects however. All signals are created using g_signal_new(). There are many gtk+ artefacts left. Finally, we will _not_ use the gtk_signal_foo() wrappers and friends any more. * app/colormaps.c * app/devices.[ch] * app/disp_callbacks.c * app/errorconsole.c * app/file-save.[ch] * app/interface.c * app/module_db.c * app/nav_window.c * app/ops_buttons.c * app/scroll.c * app/user_install.c * app/gui/about-dialog.c * app/gui/brush-editor.c * app/gui/brushes-commands.c * app/gui/color-notebook.c * app/gui/colormap-dialog.c * app/gui/dialogs-commands.c * app/gui/dialogs-constructors.c * app/gui/file-commands.c * app/gui/file-dialog-utils.c * app/gui/file-new-dialog.c * app/gui/file-open-dialog.[ch] * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/gradients-commands.c * app/gui/image-commands.c * app/gui/info-dialog.[ch] * app/gui/layer-select.c * app/gui/layers-commands.c * app/gui/menus.c * app/gui/offset-dialog.c * app/gui/palette-editor.c * app/gui/palettes-commands.c * app/gui/patterns-commands.c * app/gui/preferences-dialog.c * app/gui/resize-dialog.[ch] * app/gui/splash.c * app/gui/tips-dialog.c * app/gui/tool-options-dialog.c * app/gui/toolbox.c * app/gui/tools-commands.c * libgimp/gimpbrushmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * libgimp/gimpui.c * libgimpbase/gimpenv.c: tons and tons of changes like "const gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete and currently disables), lots of s/gtk_signal/g_signal/, removal/replacement of deprecated stuff, s/GtkSignalFunc/GCallback/ and lots of small changes and fixes while I was on it, zillions of warnings left... * modules/Makefile.am: disabled the water color selector temporarily (XInput issues). * plug-ins/Makefile.am * plug-ins/common/.cvsignore * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl: simply excluded all plug-ins which did not build (including Script-Fu). They are trivial to fix.
2001-07-25 05:27:11 +08:00
parent_class = g_type_class_peek_parent (klass);
changed GimpObject::get_memsize() to return a second value named 2003-08-25 Michael Natterer <mitch@gimp.org> * app/core/gimpobject.[ch]: changed GimpObject::get_memsize() to return a second value named "gui_size", where the primary return value is the "constant" actual size (as long as no operation is performed on the object), and the second "gui_size" return value is the size of temporary stuff like preview caches or boundary segments (which may change asynchronously, even if the object is on the undo stack). * app/core/gimp.c * app/core/gimpbrush.c * app/core/gimpbrushpipe.c * app/core/gimpbuffer.c * app/core/gimpchannel.c * app/core/gimpcontainer.c * app/core/gimpcontext.c * app/core/gimpdata.c * app/core/gimpdatafactory.c * app/core/gimpdrawable.c * app/core/gimpgradient.c * app/core/gimpimage-undo.c * app/core/gimpimage.c * app/core/gimpitem.c * app/core/gimplayer.c * app/core/gimplist.c * app/core/gimppalette.c * app/core/gimpparasitelist.c * app/core/gimppattern.c * app/core/gimpundo.c * app/core/gimpundostack.c * app/core/gimpviewable.c * app/text/gimptextlayer.c * app/vectors/gimpstroke.c * app/vectors/gimpvectors.c: changed get_memsize() implementations accordingly. * app/display/gimpdisplayshell-title.c * app/gui/debug-commands.c * app/widgets/gimppreview.c: changed callers accordingly. * app/core/gimpimage-undo-push.c: changed layer, channel, vectors and layer_mask undo steps to add/subtract the size of the resp. objects whenever they take/drop ownership of them. Ignore the objects' "gui_size" to get identical sizes on adding/subtracting. Fixes bug #120429.
2003-08-25 18:49:33 +08:00
data_signals[DIRTY] =
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning) 2001-07-24 Michael Natterer <mitch@gimp.org> Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning) * configure.in: require glib/gtk+ >= 1.3.7, commented out the gtkxmhtml stuff. From now on, you will need glib, pango, atk and gtk+ HEAD from CVS to hack or use GIMP HEAD. Beware, it crashes randomly :) * app/core/Makefile.am * app/core/gimpmarshal.list: new file plus rules to generate gimpmarshal.[ch] from it. * app/core/* * app/tools/* * app/widgets/* * libgimpwidgets/*: started to use the glib object system. All core/ objects are still gtk objects however. All signals are created using g_signal_new(). There are many gtk+ artefacts left. Finally, we will _not_ use the gtk_signal_foo() wrappers and friends any more. * app/colormaps.c * app/devices.[ch] * app/disp_callbacks.c * app/errorconsole.c * app/file-save.[ch] * app/interface.c * app/module_db.c * app/nav_window.c * app/ops_buttons.c * app/scroll.c * app/user_install.c * app/gui/about-dialog.c * app/gui/brush-editor.c * app/gui/brushes-commands.c * app/gui/color-notebook.c * app/gui/colormap-dialog.c * app/gui/dialogs-commands.c * app/gui/dialogs-constructors.c * app/gui/file-commands.c * app/gui/file-dialog-utils.c * app/gui/file-new-dialog.c * app/gui/file-open-dialog.[ch] * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/gradients-commands.c * app/gui/image-commands.c * app/gui/info-dialog.[ch] * app/gui/layer-select.c * app/gui/layers-commands.c * app/gui/menus.c * app/gui/offset-dialog.c * app/gui/palette-editor.c * app/gui/palettes-commands.c * app/gui/patterns-commands.c * app/gui/preferences-dialog.c * app/gui/resize-dialog.[ch] * app/gui/splash.c * app/gui/tips-dialog.c * app/gui/tool-options-dialog.c * app/gui/toolbox.c * app/gui/tools-commands.c * libgimp/gimpbrushmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * libgimp/gimpui.c * libgimpbase/gimpenv.c: tons and tons of changes like "const gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete and currently disables), lots of s/gtk_signal/g_signal/, removal/replacement of deprecated stuff, s/GtkSignalFunc/GCallback/ and lots of small changes and fixes while I was on it, zillions of warnings left... * modules/Makefile.am: disabled the water color selector temporarily (XInput issues). * plug-ins/Makefile.am * plug-ins/common/.cvsignore * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl: simply excluded all plug-ins which did not build (including Script-Fu). They are trivial to fix.
2001-07-25 05:27:11 +08:00
g_signal_new ("dirty",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpDataClass, dirty),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
object_class->constructed = gimp_data_constructed;
object_class->finalize = gimp_data_finalize;
object_class->set_property = gimp_data_set_property;
object_class->get_property = gimp_data_get_property;
gimp_object_class->name_changed = gimp_data_name_changed;
gimp_object_class->get_memsize = gimp_data_get_memsize;
viewable_class->name_editable = TRUE;
viewable_class->is_name_editable = gimp_data_is_name_editable;
took gimpcontextpreview.[ch] out of the build but still left the sources 2001-02-12 Michael Natterer <mitch@gimp.org> * app/Makefile.am: took gimpcontextpreview.[ch] out of the build but still left the sources there as reference. * app/app_procs.c: initialize the render stuff before creating the toolbox (needed for the previews). * app/devices.c * app/indicator_area.c: use GimpPreviews instead of GimpContextPreviews. * app/context_manager.[ch]: create the global data lists here because they now must exist before any context is created. * app/brushes.[ch] * app/gradients.[ch] * app/palettes.[ch] * app/patterns.[ch]: removed them here. * app/gimpcontainer.[ch]: added a "freeze_count" and emit the "freeze" and "thaw" signals accordingly. * app/gimpcontext.[ch]: greatly simplified the way how the contexts connect to the data lists (simply keep them connected all the time). Also removed all those ugly explicit update functions because "thaw" callbacks do this job now. * app/gimpdata.c: a GimpData object now becomes dirty on "name_changed"; "dirty" now triggers "invalidate_preview" because the context does not dispatch these signals any more soon. * app/brush_select.c * app/convert.c * app/gimpdnd.c * app/gradient_editor.c * app/gradient_select.c * app/pattern_select.c * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-12 11:27:28 +08:00
klass->dirty = gimp_data_real_dirty;
klass->save = NULL;
klass->get_extension = NULL;
klass->copy = NULL;
klass->duplicate = gimp_data_real_duplicate;
klass->compare = gimp_data_real_compare;
g_object_class_install_property (object_class, PROP_FILE,
g_param_spec_object ("file", NULL, NULL,
G_TYPE_FILE,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_WRITABLE,
g_param_spec_boolean ("writable", NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_DELETABLE,
g_param_spec_boolean ("deletable", NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_MIME_TYPE,
g_param_spec_string ("mime-type", NULL, NULL,
NULL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_data_tagged_iface_init (GimpTaggedInterface *iface)
{
iface->add_tag = gimp_data_add_tag;
iface->remove_tag = gimp_data_remove_tag;
iface->get_tags = gimp_data_get_tags;
iface->get_identifier = gimp_data_get_identifier;
iface->get_checksum = gimp_data_get_checksum;
}
static void
gimp_data_init (GimpData *data)
{
GimpDataPrivate *private = gimp_data_get_instance_private (data);
data->priv = private;
private->writable = TRUE;
private->deletable = TRUE;
private->dirty = TRUE;
/* freeze the data object during construction */
gimp_data_freeze (data);
}
static void
gimp_data_constructed (GObject *object)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (object);
G_OBJECT_CLASS (parent_class)->constructed (object);
if (! GIMP_DATA_GET_CLASS (object)->save)
private->writable = FALSE;
gimp_data_thaw (GIMP_DATA (object));
}
static void
gimp_data_finalize (GObject *object)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (object);
g_clear_object (&private->file);
if (private->tags)
{
g_list_free_full (private->tags, (GDestroyNotify) g_object_unref);
private->tags = NULL;
}
g_clear_pointer (&private->identifier, g_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_data_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpData *data = GIMP_DATA (object);
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (data);
switch (property_id)
{
case PROP_FILE:
gimp_data_set_file (data,
g_value_get_object (value),
private->writable,
private->deletable);
break;
case PROP_WRITABLE:
private->writable = g_value_get_boolean (value);
break;
case PROP_DELETABLE:
private->deletable = g_value_get_boolean (value);
break;
case PROP_MIME_TYPE:
if (g_value_get_string (value))
private->mime_type = g_quark_from_string (g_value_get_string (value));
else
private->mime_type = 0;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_data_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (object);
switch (property_id)
{
case PROP_FILE:
g_value_set_object (value, private->file);
break;
case PROP_WRITABLE:
g_value_set_boolean (value, private->writable);
break;
case PROP_DELETABLE:
g_value_set_boolean (value, private->deletable);
break;
case PROP_MIME_TYPE:
g_value_set_string (value, g_quark_to_string (private->mime_type));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_data_name_changed (GimpObject *object)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (object);
private->dirty = TRUE;
if (GIMP_OBJECT_CLASS (parent_class)->name_changed)
GIMP_OBJECT_CLASS (parent_class)->name_changed (object);
}
static gint64
changed GimpObject::get_memsize() to return a second value named 2003-08-25 Michael Natterer <mitch@gimp.org> * app/core/gimpobject.[ch]: changed GimpObject::get_memsize() to return a second value named "gui_size", where the primary return value is the "constant" actual size (as long as no operation is performed on the object), and the second "gui_size" return value is the size of temporary stuff like preview caches or boundary segments (which may change asynchronously, even if the object is on the undo stack). * app/core/gimp.c * app/core/gimpbrush.c * app/core/gimpbrushpipe.c * app/core/gimpbuffer.c * app/core/gimpchannel.c * app/core/gimpcontainer.c * app/core/gimpcontext.c * app/core/gimpdata.c * app/core/gimpdatafactory.c * app/core/gimpdrawable.c * app/core/gimpgradient.c * app/core/gimpimage-undo.c * app/core/gimpimage.c * app/core/gimpitem.c * app/core/gimplayer.c * app/core/gimplist.c * app/core/gimppalette.c * app/core/gimpparasitelist.c * app/core/gimppattern.c * app/core/gimpundo.c * app/core/gimpundostack.c * app/core/gimpviewable.c * app/text/gimptextlayer.c * app/vectors/gimpstroke.c * app/vectors/gimpvectors.c: changed get_memsize() implementations accordingly. * app/display/gimpdisplayshell-title.c * app/gui/debug-commands.c * app/widgets/gimppreview.c: changed callers accordingly. * app/core/gimpimage-undo-push.c: changed layer, channel, vectors and layer_mask undo steps to add/subtract the size of the resp. objects whenever they take/drop ownership of them. Ignore the objects' "gui_size" to get identical sizes on adding/subtracting. Fixes bug #120429.
2003-08-25 18:49:33 +08:00
gimp_data_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (object);
gint64 memsize = 0;
memsize += gimp_g_object_get_memsize (G_OBJECT (private->file));
changed GimpObject::get_memsize() to return a second value named 2003-08-25 Michael Natterer <mitch@gimp.org> * app/core/gimpobject.[ch]: changed GimpObject::get_memsize() to return a second value named "gui_size", where the primary return value is the "constant" actual size (as long as no operation is performed on the object), and the second "gui_size" return value is the size of temporary stuff like preview caches or boundary segments (which may change asynchronously, even if the object is on the undo stack). * app/core/gimp.c * app/core/gimpbrush.c * app/core/gimpbrushpipe.c * app/core/gimpbuffer.c * app/core/gimpchannel.c * app/core/gimpcontainer.c * app/core/gimpcontext.c * app/core/gimpdata.c * app/core/gimpdatafactory.c * app/core/gimpdrawable.c * app/core/gimpgradient.c * app/core/gimpimage-undo.c * app/core/gimpimage.c * app/core/gimpitem.c * app/core/gimplayer.c * app/core/gimplist.c * app/core/gimppalette.c * app/core/gimpparasitelist.c * app/core/gimppattern.c * app/core/gimpundo.c * app/core/gimpundostack.c * app/core/gimpviewable.c * app/text/gimptextlayer.c * app/vectors/gimpstroke.c * app/vectors/gimpvectors.c: changed get_memsize() implementations accordingly. * app/display/gimpdisplayshell-title.c * app/gui/debug-commands.c * app/widgets/gimppreview.c: changed callers accordingly. * app/core/gimpimage-undo-push.c: changed layer, channel, vectors and layer_mask undo steps to add/subtract the size of the resp. objects whenever they take/drop ownership of them. Ignore the objects' "gui_size" to get identical sizes on adding/subtracting. Fixes bug #120429.
2003-08-25 18:49:33 +08:00
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static gboolean
gimp_data_is_name_editable (GimpViewable *viewable)
{
return gimp_data_is_writable (GIMP_DATA (viewable)) &&
! gimp_data_is_internal (GIMP_DATA (viewable));
}
static void
gimp_data_real_dirty (GimpData *data)
{
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (data));
/* Emit the "name-changed" to signal general dirtiness, our name
* changed implementation will also set the "dirty" flag to TRUE.
*/
gimp_object_name_changed (GIMP_OBJECT (data));
}
static GimpData *
gimp_data_real_duplicate (GimpData *data)
{
if (GIMP_DATA_GET_CLASS (data)->copy)
{
GimpData *new = g_object_new (G_OBJECT_TYPE (data), NULL);
gimp_data_copy (new, data);
return new;
}
return NULL;
}
static gint
gimp_data_real_compare (GimpData *data1,
GimpData *data2)
{
GimpDataPrivate *private1 = GIMP_DATA_GET_PRIVATE (data1);
GimpDataPrivate *private2 = GIMP_DATA_GET_PRIVATE (data2);
/* move the internal objects (like the FG -> BG) gradient) to the top */
if (private1->internal != private2->internal)
return private1->internal ? -1 : 1;
/* keep user-deletable objects above system resource files */
if (private1->deletable != private2->deletable)
return private1->deletable ? -1 : 1;
return gimp_object_name_collate ((GimpObject *) data1,
(GimpObject *) data2);
}
static gboolean
gimp_data_add_tag (GimpTagged *tagged,
GimpTag *tag)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (tagged);
GList *list;
for (list = private->tags; list; list = g_list_next (list))
{
GimpTag *this = GIMP_TAG (list->data);
if (gimp_tag_equals (tag, this))
return FALSE;
}
private->tags = g_list_prepend (private->tags, g_object_ref (tag));
return TRUE;
}
static gboolean
gimp_data_remove_tag (GimpTagged *tagged,
GimpTag *tag)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (tagged);
GList *list;
for (list = private->tags; list; list = g_list_next (list))
{
GimpTag *this = GIMP_TAG (list->data);
if (gimp_tag_equals (tag, this))
{
private->tags = g_list_delete_link (private->tags, list);
g_object_unref (this);
return TRUE;
}
}
return FALSE;
}
static GList *
gimp_data_get_tags (GimpTagged *tagged)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (tagged);
return private->tags;
}
static gchar *
gimp_data_get_identifier (GimpTagged *tagged)
{
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (tagged);
gchar *identifier = NULL;
if (private->file)
{
const gchar *data_dir = gimp_data_directory ();
const gchar *gimp_dir = gimp_directory ();
gchar *path = g_file_get_path (private->file);
gchar *tmp;
if (g_str_has_prefix (path, data_dir))
{
tmp = g_strconcat ("${gimp_data_dir}",
path + strlen (data_dir),
NULL);
identifier = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
g_free (tmp);
}
else if (g_str_has_prefix (path, gimp_dir))
{
tmp = g_strconcat ("${gimp_dir}",
path + strlen (gimp_dir),
NULL);
identifier = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
g_free (tmp);
}
else if (g_str_has_prefix (path, MYPAINT_BRUSHES_DIR))
{
tmp = g_strconcat ("${mypaint_brushes_dir}",
path + strlen (MYPAINT_BRUSHES_DIR),
NULL);
identifier = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
g_free (tmp);
}
else
{
identifier = g_filename_to_utf8 (path, -1,
NULL, NULL, NULL);
}
if (! identifier)
{
g_printerr ("%s: failed to convert '%s' to utf8.\n",
G_STRFUNC, path);
identifier = g_strdup (path);
}
g_free (path);
}
else if (private->internal)
{
identifier = g_strdup (private->identifier);
}
return identifier;
}
static gchar *
gimp_data_get_checksum (GimpTagged *tagged)
{
return NULL;
}
/**
* gimp_data_save:
* @data: object whose contents are to be saved.
* @error: return location for errors or %NULL
*
* Save the object. If the object is marked as "internal", nothing
* happens. Otherwise, it is saved to disk, using the file name set
* by gimp_data_set_file(). If the save is successful, the object is
* marked as not dirty. If not, an error message is returned using
* the @error argument.
*
* Returns: %TRUE if the object is internal or the save is successful.
**/
gboolean
gimp_data_save (GimpData *data,
GError **error)
{
GimpDataPrivate *private;
gboolean success = FALSE;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
g_return_val_if_fail (private->writable == TRUE, FALSE);
if (private->internal)
added a boolean "internal" which indicates that the data object is an 2002-06-12 Michael Natterer <mitch@gimp.org> * app/core/gimpdata.[ch]: added a boolean "internal" which indicates that the data object is an automatically created internal object. Changed the code to refuse saving to deleting internal objects. * app/core/Makefile.am * app/core/gimp-gradients.[ch]: new files implementing internal gradients (FG -> BG in RGB and HSV and FG -> transparent). * app/core/gimp.c: call gimp_gradients_init(). * app/core/gimpdatafactory.c (gimp_data_factory_data_free): don't free internal objects so they stay there on "Refresh". * app/core/gimpdatalist.c: sort internal objects to the beginning of the list. * app/widgets/gimpdataeditor.c: refuse to change the name of internal objects. * app/widgets/gimpdatafactoryview.c: set the "Delete" button insensitive for internal objects. * app/widgets/gimpgradienteditor.c: refuse to edit internal gradients, just display them so color picking works. * app/gui/brushes-commands.c * app/gui/gradients-commands.c * app/gui/palettes-commands.c * app/gui/patterns-commands.c: set the "Delete" menu item insensitive for internal objects. * app/gui/gui.c: need to call render_setup() earlier because of you-dont-want-to-know-why. Will change it back once the previews have their own render buffers. * app/tools/gimpblendtool.c: Replaced the "Type" menu by a preview showing the active gradient. Clicking the preview pops up the gradient selection. Renamed the "Gradient" menu to "Shape". Removed "blend_mode" from the BlendOptions struct because we always use "custom" mode now.
2002-06-12 21:48:47 +08:00
{
private->dirty = FALSE;
added a boolean "internal" which indicates that the data object is an 2002-06-12 Michael Natterer <mitch@gimp.org> * app/core/gimpdata.[ch]: added a boolean "internal" which indicates that the data object is an automatically created internal object. Changed the code to refuse saving to deleting internal objects. * app/core/Makefile.am * app/core/gimp-gradients.[ch]: new files implementing internal gradients (FG -> BG in RGB and HSV and FG -> transparent). * app/core/gimp.c: call gimp_gradients_init(). * app/core/gimpdatafactory.c (gimp_data_factory_data_free): don't free internal objects so they stay there on "Refresh". * app/core/gimpdatalist.c: sort internal objects to the beginning of the list. * app/widgets/gimpdataeditor.c: refuse to change the name of internal objects. * app/widgets/gimpdatafactoryview.c: set the "Delete" button insensitive for internal objects. * app/widgets/gimpgradienteditor.c: refuse to edit internal gradients, just display them so color picking works. * app/gui/brushes-commands.c * app/gui/gradients-commands.c * app/gui/palettes-commands.c * app/gui/patterns-commands.c: set the "Delete" menu item insensitive for internal objects. * app/gui/gui.c: need to call render_setup() earlier because of you-dont-want-to-know-why. Will change it back once the previews have their own render buffers. * app/tools/gimpblendtool.c: Replaced the "Type" menu by a preview showing the active gradient. Clicking the preview pops up the gradient selection. Renamed the "Gradient" menu to "Shape". Removed "blend_mode" from the BlendOptions struct because we always use "custom" mode now.
2002-06-12 21:48:47 +08:00
return TRUE;
}
g_return_val_if_fail (G_IS_FILE (private->file), FALSE);
if (GIMP_DATA_GET_CLASS (data)->save)
{
GOutputStream *output;
output = G_OUTPUT_STREAM (g_file_replace (private->file,
NULL, FALSE, G_FILE_CREATE_NONE,
NULL, error));
if (output)
{
success = GIMP_DATA_GET_CLASS (data)->save (data, output, error);
if (success)
{
if (! g_output_stream_close (output, NULL, error))
{
g_prefix_error (error,
_("Error saving '%s': "),
gimp_file_get_utf8_name (private->file));
success = FALSE;
}
}
else
{
GCancellable *cancellable = g_cancellable_new ();
g_cancellable_cancel (cancellable);
if (error && *error)
{
g_prefix_error (error,
_("Error saving '%s': "),
gimp_file_get_utf8_name (private->file));
}
else
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE,
_("Error saving '%s'"),
gimp_file_get_utf8_name (private->file));
}
g_output_stream_close (output, cancellable, NULL);
g_object_unref (cancellable);
}
g_object_unref (output);
}
}
if (success)
{
GFileInfo *info = g_file_query_info (private->file,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
if (info)
{
private->mtime =
g_file_info_get_attribute_uint64 (info,
G_FILE_ATTRIBUTE_TIME_MODIFIED);
g_object_unref (info);
}
private->dirty = FALSE;
}
return success;
}
/**
* gimp_data_dirty:
* @data: a #GimpData object.
*
* Marks @data as dirty. Unless the object is frozen, this causes
* its preview to be invalidated, and emits a "dirty" signal. If the
* object is frozen, the function has no effect.
**/
void
gimp_data_dirty (GimpData *data)
{
GimpDataPrivate *private;
g_return_if_fail (GIMP_IS_DATA (data));
private = GIMP_DATA_GET_PRIVATE (data);
if (private->freeze_count == 0)
g_signal_emit (data, data_signals[DIRTY], 0);
}
void
gimp_data_clean (GimpData *data)
{
GimpDataPrivate *private;
g_return_if_fail (GIMP_IS_DATA (data));
private = GIMP_DATA_GET_PRIVATE (data);
private->dirty = FALSE;
}
gboolean
gimp_data_is_dirty (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
return private->dirty;
}
/**
* gimp_data_freeze:
* @data: a #GimpData object.
*
* Increments the freeze count for the object. A positive freeze count
* prevents the object from being treated as dirty. Any call to this
* function must be followed eventually by a call to gimp_data_thaw().
**/
void
gimp_data_freeze (GimpData *data)
{
GimpDataPrivate *private;
g_return_if_fail (GIMP_IS_DATA (data));
took gimpcontextpreview.[ch] out of the build but still left the sources 2001-02-12 Michael Natterer <mitch@gimp.org> * app/Makefile.am: took gimpcontextpreview.[ch] out of the build but still left the sources there as reference. * app/app_procs.c: initialize the render stuff before creating the toolbox (needed for the previews). * app/devices.c * app/indicator_area.c: use GimpPreviews instead of GimpContextPreviews. * app/context_manager.[ch]: create the global data lists here because they now must exist before any context is created. * app/brushes.[ch] * app/gradients.[ch] * app/palettes.[ch] * app/patterns.[ch]: removed them here. * app/gimpcontainer.[ch]: added a "freeze_count" and emit the "freeze" and "thaw" signals accordingly. * app/gimpcontext.[ch]: greatly simplified the way how the contexts connect to the data lists (simply keep them connected all the time). Also removed all those ugly explicit update functions because "thaw" callbacks do this job now. * app/gimpdata.c: a GimpData object now becomes dirty on "name_changed"; "dirty" now triggers "invalidate_preview" because the context does not dispatch these signals any more soon. * app/brush_select.c * app/convert.c * app/gimpdnd.c * app/gradient_editor.c * app/gradient_select.c * app/pattern_select.c * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-12 11:27:28 +08:00
private = GIMP_DATA_GET_PRIVATE (data);
private->freeze_count++;
}
/**
* gimp_data_thaw:
* @data: a #GimpData object.
*
* Decrements the freeze count for the object. If the freeze count
* drops to zero, the object is marked as dirty, and the "dirty"
* signal is emitted. It is an error to call this function without
* having previously called gimp_data_freeze().
**/
void
gimp_data_thaw (GimpData *data)
{
GimpDataPrivate *private;
g_return_if_fail (GIMP_IS_DATA (data));
private = GIMP_DATA_GET_PRIVATE (data);
g_return_if_fail (private->freeze_count > 0);
private->freeze_count--;
if (private->freeze_count == 0)
gimp_data_dirty (data);
}
gboolean
gimp_data_is_frozen (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
return private->freeze_count > 0;
}
/**
* gimp_data_delete_from_disk:
* @data: a #GimpData object.
* @error: return location for errors or %NULL
*
* Deletes the object from disk. If the object is marked as "internal",
* nothing happens. Otherwise, if the file exists whose name has been
* set by gimp_data_set_file(), it is deleted. Obviously this is
* a potentially dangerous function, which should be used with care.
*
* Returns: %TRUE if the object is internal to Gimp, or the deletion is
* successful.
**/
gboolean
gimp_data_delete_from_disk (GimpData *data,
GError **error)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
g_return_val_if_fail (private->file != NULL, FALSE);
g_return_val_if_fail (private->deletable == TRUE, FALSE);
if (private->internal)
added a boolean "internal" which indicates that the data object is an 2002-06-12 Michael Natterer <mitch@gimp.org> * app/core/gimpdata.[ch]: added a boolean "internal" which indicates that the data object is an automatically created internal object. Changed the code to refuse saving to deleting internal objects. * app/core/Makefile.am * app/core/gimp-gradients.[ch]: new files implementing internal gradients (FG -> BG in RGB and HSV and FG -> transparent). * app/core/gimp.c: call gimp_gradients_init(). * app/core/gimpdatafactory.c (gimp_data_factory_data_free): don't free internal objects so they stay there on "Refresh". * app/core/gimpdatalist.c: sort internal objects to the beginning of the list. * app/widgets/gimpdataeditor.c: refuse to change the name of internal objects. * app/widgets/gimpdatafactoryview.c: set the "Delete" button insensitive for internal objects. * app/widgets/gimpgradienteditor.c: refuse to edit internal gradients, just display them so color picking works. * app/gui/brushes-commands.c * app/gui/gradients-commands.c * app/gui/palettes-commands.c * app/gui/patterns-commands.c: set the "Delete" menu item insensitive for internal objects. * app/gui/gui.c: need to call render_setup() earlier because of you-dont-want-to-know-why. Will change it back once the previews have their own render buffers. * app/tools/gimpblendtool.c: Replaced the "Type" menu by a preview showing the active gradient. Clicking the preview pops up the gradient selection. Renamed the "Gradient" menu to "Shape". Removed "blend_mode" from the BlendOptions struct because we always use "custom" mode now.
2002-06-12 21:48:47 +08:00
return TRUE;
return g_file_delete (private->file, NULL, error);
}
gimprc.in user_install user_install.bat app/gimprc.[ch] removed the 2001-02-13 Michael Natterer <mitch@gimp.org> * gimprc.in * user_install * user_install.bat * app/gimprc.[ch] * app/preferences_dialog.c: removed the "brush_vbr_path" variable, because all data types will be editable and saveable soon. * app/Makefile.am * app/apptypes.h * app/gimpdatafactory.[ch]: new object which holds a data list and knows how to create, edit, duplicate etc. the items in it. Will completely replace the brushes.[ch], patterns.[ch], ... files soon. * po/POTFILES.in * app/gimpdatacontainerview.[ch]: removed. * app/gimpdatafactoryview.[ch]: added. A view on the GimpDataFactory with a GUI for creating, editing, deleting etc. items (mostly unimplemented). * app/context_manager.[ch]: replaced the global data lists by global data factories. * app/brush_select.c * app/brushes.[ch] * app/commands.c * app/convert.c * app/devices.c * app/gimpbrush.[ch] * app/gimpbrushgenerated.c * app/gimpcontext.c * app/gimpdata.[ch] * app/gimpdatalist.[ch] * app/gimpdnd.c * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch] * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/indicator_area.c * app/palette.c * app/palette_import.c * app/palette_select.c * app/palettes.[ch] * app/pattern_select.c * app/patterns.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-14 03:53:07 +08:00
const gchar *
gimp_data_get_extension (GimpData *data)
{
g_return_val_if_fail (GIMP_IS_DATA (data), NULL);
if (GIMP_DATA_GET_CLASS (data)->get_extension)
return GIMP_DATA_GET_CLASS (data)->get_extension (data);
gimprc.in user_install user_install.bat app/gimprc.[ch] removed the 2001-02-13 Michael Natterer <mitch@gimp.org> * gimprc.in * user_install * user_install.bat * app/gimprc.[ch] * app/preferences_dialog.c: removed the "brush_vbr_path" variable, because all data types will be editable and saveable soon. * app/Makefile.am * app/apptypes.h * app/gimpdatafactory.[ch]: new object which holds a data list and knows how to create, edit, duplicate etc. the items in it. Will completely replace the brushes.[ch], patterns.[ch], ... files soon. * po/POTFILES.in * app/gimpdatacontainerview.[ch]: removed. * app/gimpdatafactoryview.[ch]: added. A view on the GimpDataFactory with a GUI for creating, editing, deleting etc. items (mostly unimplemented). * app/context_manager.[ch]: replaced the global data lists by global data factories. * app/brush_select.c * app/brushes.[ch] * app/commands.c * app/convert.c * app/devices.c * app/gimpbrush.[ch] * app/gimpbrushgenerated.c * app/gimpcontext.c * app/gimpdata.[ch] * app/gimpdatalist.[ch] * app/gimpdnd.c * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch] * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/indicator_area.c * app/palette.c * app/palette_import.c * app/palette_select.c * app/palettes.[ch] * app/pattern_select.c * app/patterns.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-14 03:53:07 +08:00
return NULL;
gimprc.in user_install user_install.bat app/gimprc.[ch] removed the 2001-02-13 Michael Natterer <mitch@gimp.org> * gimprc.in * user_install * user_install.bat * app/gimprc.[ch] * app/preferences_dialog.c: removed the "brush_vbr_path" variable, because all data types will be editable and saveable soon. * app/Makefile.am * app/apptypes.h * app/gimpdatafactory.[ch]: new object which holds a data list and knows how to create, edit, duplicate etc. the items in it. Will completely replace the brushes.[ch], patterns.[ch], ... files soon. * po/POTFILES.in * app/gimpdatacontainerview.[ch]: removed. * app/gimpdatafactoryview.[ch]: added. A view on the GimpDataFactory with a GUI for creating, editing, deleting etc. items (mostly unimplemented). * app/context_manager.[ch]: replaced the global data lists by global data factories. * app/brush_select.c * app/brushes.[ch] * app/commands.c * app/convert.c * app/devices.c * app/gimpbrush.[ch] * app/gimpbrushgenerated.c * app/gimpcontext.c * app/gimpdata.[ch] * app/gimpdatalist.[ch] * app/gimpdnd.c * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch] * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/indicator_area.c * app/palette.c * app/palette_import.c * app/palette_select.c * app/palettes.[ch] * app/pattern_select.c * app/patterns.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-14 03:53:07 +08:00
}
/**
* gimp_data_set_file:
* @data: A #GimpData object
* @file: File to assign to @data.
* @writable: %TRUE if we want to be able to write to this file.
* @deletable: %TRUE if we want to be able to delete this file.
*
* This function assigns a file to @data, and sets some flags
* according to the properties of the file. If @writable is %TRUE,
* and the user has permission to write or overwrite the requested
* file name, and a "save" method exists for @data's object type, then
* @data is marked as writable.
**/
void
gimp_data_set_file (GimpData *data,
GFile *file,
gboolean writable,
gboolean deletable)
{
GimpDataPrivate *private;
gchar *path;
g_return_if_fail (GIMP_IS_DATA (data));
g_return_if_fail (G_IS_FILE (file));
path = g_file_get_path (file);
g_return_if_fail (path != NULL);
g_return_if_fail (g_path_is_absolute (path));
g_free (path);
private = GIMP_DATA_GET_PRIVATE (data);
if (private->internal)
added a boolean "internal" which indicates that the data object is an 2002-06-12 Michael Natterer <mitch@gimp.org> * app/core/gimpdata.[ch]: added a boolean "internal" which indicates that the data object is an automatically created internal object. Changed the code to refuse saving to deleting internal objects. * app/core/Makefile.am * app/core/gimp-gradients.[ch]: new files implementing internal gradients (FG -> BG in RGB and HSV and FG -> transparent). * app/core/gimp.c: call gimp_gradients_init(). * app/core/gimpdatafactory.c (gimp_data_factory_data_free): don't free internal objects so they stay there on "Refresh". * app/core/gimpdatalist.c: sort internal objects to the beginning of the list. * app/widgets/gimpdataeditor.c: refuse to change the name of internal objects. * app/widgets/gimpdatafactoryview.c: set the "Delete" button insensitive for internal objects. * app/widgets/gimpgradienteditor.c: refuse to edit internal gradients, just display them so color picking works. * app/gui/brushes-commands.c * app/gui/gradients-commands.c * app/gui/palettes-commands.c * app/gui/patterns-commands.c: set the "Delete" menu item insensitive for internal objects. * app/gui/gui.c: need to call render_setup() earlier because of you-dont-want-to-know-why. Will change it back once the previews have their own render buffers. * app/tools/gimpblendtool.c: Replaced the "Type" menu by a preview showing the active gradient. Clicking the preview pops up the gradient selection. Renamed the "Gradient" menu to "Shape". Removed "blend_mode" from the BlendOptions struct because we always use "custom" mode now.
2002-06-12 21:48:47 +08:00
return;
g_set_object (&private->file, file);
private->writable = FALSE;
private->deletable = FALSE;
/* if the data is supposed to be writable or deletable,
* still check if it really is
*/
if (writable || deletable)
{
GFileInfo *info;
if (g_file_query_exists (private->file, NULL)) /* check if it exists */
{
info = g_file_query_info (private->file,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
/* and we can write it */
if (info)
{
if (g_file_info_get_attribute_boolean (info,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
{
private->writable = writable ? TRUE : FALSE;
private->deletable = deletable ? TRUE : FALSE;
}
g_object_unref (info);
}
}
else /* OR it doesn't exist */
{
GFile *parent = g_file_get_parent (private->file);
info = g_file_query_info (parent,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
/* and we can write to its parent directory */
if (info)
{
if (g_file_info_get_attribute_boolean (info,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
{
private->writable = writable ? TRUE : FALSE;
private->deletable = deletable ? TRUE : FALSE;
}
g_object_unref (info);
}
g_object_unref (parent);
}
/* if we can't save, we are not writable */
if (! GIMP_DATA_GET_CLASS (data)->save)
private->writable = FALSE;
}
}
GFile *
gimp_data_get_file (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), NULL);
private = GIMP_DATA_GET_PRIVATE (data);
return private->file;
}
/**
* gimp_data_create_filename:
* @data: a #Gimpdata object.
* @dest_dir: directory in which to create a file name.
*
* This function creates a unique file name to be used for saving
* a representation of @data in the directory @dest_dir. If the
* user does not have write permission in @dest_dir, then @data
* is marked as "not writable", so you should check on this before
* assuming that @data can be saved.
**/
void
gimp_data_create_filename (GimpData *data,
GFile *dest_dir)
{
GimpDataPrivate *private;
gchar *safename;
gchar *basename;
GFile *file;
gint i;
gint unum = 1;
GError *error = NULL;
g_return_if_fail (GIMP_IS_DATA (data));
g_return_if_fail (G_IS_FILE (dest_dir));
private = GIMP_DATA_GET_PRIVATE (data);
if (private->internal)
return;
safename = g_strstrip (g_strdup (gimp_object_get_name (data)));
if (safename[0] == '.')
safename[0] = '-';
for (i = 0; safename[i]; i++)
if (strchr ("\\/*?\"`'<>{}|\n\t ;:$^&", safename[i]))
safename[i] = '-';
basename = g_strconcat (safename, gimp_data_get_extension (data), NULL);
file = g_file_get_child_for_display_name (dest_dir, basename, &error);
g_free (basename);
if (! file)
{
g_warning ("gimp_data_create_filename:\n"
"g_file_get_child_for_display_name() failed for '%s': %s",
gimp_object_get_name (data), error->message);
g_clear_error (&error);
g_free (safename);
return;
}
while (g_file_query_exists (file, NULL))
{
g_object_unref (file);
basename = g_strdup_printf ("%s-%d%s",
safename,
unum++,
gimp_data_get_extension (data));
file = g_file_get_child_for_display_name (dest_dir, basename, NULL);
g_free (basename);
}
g_free (safename);
gimp_data_set_file (data, file, TRUE, TRUE);
g_object_unref (file);
}
static const gchar *tag_blacklist[] = { "brushes",
"dynamics",
"patterns",
"palettes",
"gradients",
"tool-presets" };
/**
* gimp_data_set_folder_tags:
* @data: a #Gimpdata object.
* @top_directory: the top directory of the currently processed data
* hierarchy.
*
* Sets tags based on all folder names below top_directory. So if the
* data's filename is e.g.
* /home/foo/.config/GIMP/X.Y/brushes/Flowers/Roses/rose.gbr, it will
* add "Flowers" and "Roses" tags.
*
* if the top directory (as passed, or as derived from the data's
* filename) does not end with one of the default data directory names
* (brushes, patterns etc), its name will be added as tag too.
**/
void
gimp_data_set_folder_tags (GimpData *data,
GFile *top_directory)
{
GimpDataPrivate *private;
gchar *tmp;
gchar *dirname;
gchar *top_path;
g_return_if_fail (GIMP_IS_DATA (data));
g_return_if_fail (G_IS_FILE (top_directory));
private = GIMP_DATA_GET_PRIVATE (data);
if (private->internal)
return;
g_return_if_fail (private->file != NULL);
tmp = g_file_get_path (private->file);
dirname = g_path_get_dirname (tmp);
g_free (tmp);
top_path = g_file_get_path (top_directory);
g_return_if_fail (g_str_has_prefix (dirname, top_path));
/* walk up the hierarchy and set each folder on the way as tag,
* except the top_directory
*/
while (strcmp (dirname, top_path))
{
gchar *basename = g_path_get_basename (dirname);
GimpTag *tag = gimp_tag_new (basename);
gimp_tag_set_internal (tag, TRUE);
gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
g_object_unref (tag);
g_free (basename);
tmp = g_path_get_dirname (dirname);
g_free (dirname);
dirname = tmp;
}
g_free (top_path);
if (dirname)
{
gchar *basename = g_path_get_basename (dirname);
gint i;
for (i = 0; i < G_N_ELEMENTS (tag_blacklist); i++)
{
if (! strcmp (basename, tag_blacklist[i]))
break;
}
if (i == G_N_ELEMENTS (tag_blacklist))
{
GimpTag *tag = gimp_tag_new (basename);
gimp_tag_set_internal (tag, TRUE);
gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
g_object_unref (tag);
}
g_free (basename);
g_free (dirname);
}
}
const gchar *
gimp_data_get_mime_type (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), NULL);
private = GIMP_DATA_GET_PRIVATE (data);
return g_quark_to_string (private->mime_type);
}
gboolean
gimp_data_is_writable (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
return private->writable;
}
gboolean
gimp_data_is_deletable (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
return private->deletable;
}
void
gimp_data_set_mtime (GimpData *data,
gint64 mtime)
{
GimpDataPrivate *private;
g_return_if_fail (GIMP_IS_DATA (data));
private = GIMP_DATA_GET_PRIVATE (data);
private->mtime = mtime;
}
gint64
gimp_data_get_mtime (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), 0);
private = GIMP_DATA_GET_PRIVATE (data);
return private->mtime;
}
gboolean
gimp_data_is_copyable (GimpData *data)
{
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
return GIMP_DATA_GET_CLASS (data)->copy != NULL;
}
/**
* gimp_data_copy:
* @data: a #GimpData object
* @src_data: the #GimpData object to copy from
*
* Copies @src_data to @data. Only the object data is copied: the
* name, file name, preview, etc. are not copied.
**/
void
gimp_data_copy (GimpData *data,
GimpData *src_data)
{
g_return_if_fail (GIMP_IS_DATA (data));
g_return_if_fail (GIMP_IS_DATA (src_data));
g_return_if_fail (GIMP_DATA_GET_CLASS (data)->copy != NULL);
g_return_if_fail (GIMP_DATA_GET_CLASS (data)->copy ==
GIMP_DATA_GET_CLASS (src_data)->copy);
if (data != src_data)
GIMP_DATA_GET_CLASS (data)->copy (data, src_data);
}
gboolean
gimp_data_is_duplicatable (GimpData *data)
{
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
if (GIMP_DATA_GET_CLASS (data)->duplicate == gimp_data_real_duplicate)
return gimp_data_is_copyable (data);
else
return GIMP_DATA_GET_CLASS (data)->duplicate != NULL;
}
/**
* gimp_data_duplicate:
* @data: a #GimpData object
*
* Creates a copy of @data, if possible. Only the object data is
* copied: the newly created object is not automatically given an
* object name, file name, preview, etc.
*
* Returns: (nullable) (transfer full): the newly created copy, or %NULL if
* @data cannot be copied.
**/
added a note about apptype.h and about not including headers in headers. 2001-02-14 Michael Natterer <mitch@gimp.org> * HACKING: added a note about apptype.h and about not including headers in headers. * app/apptypes.h: added GimpTool and BitmapCursor. * app/cursorutil.h * app/devices.h * app/draw_core.h * app/tools/color_picker.h * app/tools/tool.h * app/tools/tool_options.h * app/gimpcontext.h: removed includes of "tools/tool.h" * app/gimprc.[ch]: indentadion cleanup, added "module_db_load_inhibit". * app/module_db.c: removed the above variable here. * app/gimpdata.[ch]: added a vitrual "duplicate" method. * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushpipe.[ch] * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch]: all "load", "new" and "get_standard" functions return a GimpData pointer now. * app/gimpdatafactory.[ch]: made some stuff const. * app/gimpdatafactoryview.c: activate the "duplicate" button and set the initial button sensitivity correctly. * app/brush_select.c * app/gradient_select.c * app/pattern_select.c: use the new GimpDataFactoryView. * libgimp/Makefile.am: grouped the file to sort out what _may_ go to subdirs or separate libs. * libgimp/gimpenv.[ch]: added many "const". * app/app_procs.c * app/brush_edit.c * app/gimpcontext.c * app/gimpdnd.c * app/gradient_editor.c * app/palette.c * app/palette_import.c * app/user_install.c: many related changes. * libgimpmath/gimpmathtypes.h * libgimpmath/gimpvector.[ch]: minor cleanups. * plug-ins/script-fu/script-fu.c: gimp_data_directory() is const now.
2001-02-14 22:57:14 +08:00
GimpData *
gimp_data_duplicate (GimpData *data)
added a note about apptype.h and about not including headers in headers. 2001-02-14 Michael Natterer <mitch@gimp.org> * HACKING: added a note about apptype.h and about not including headers in headers. * app/apptypes.h: added GimpTool and BitmapCursor. * app/cursorutil.h * app/devices.h * app/draw_core.h * app/tools/color_picker.h * app/tools/tool.h * app/tools/tool_options.h * app/gimpcontext.h: removed includes of "tools/tool.h" * app/gimprc.[ch]: indentadion cleanup, added "module_db_load_inhibit". * app/module_db.c: removed the above variable here. * app/gimpdata.[ch]: added a vitrual "duplicate" method. * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushpipe.[ch] * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch]: all "load", "new" and "get_standard" functions return a GimpData pointer now. * app/gimpdatafactory.[ch]: made some stuff const. * app/gimpdatafactoryview.c: activate the "duplicate" button and set the initial button sensitivity correctly. * app/brush_select.c * app/gradient_select.c * app/pattern_select.c: use the new GimpDataFactoryView. * libgimp/Makefile.am: grouped the file to sort out what _may_ go to subdirs or separate libs. * libgimp/gimpenv.[ch]: added many "const". * app/app_procs.c * app/brush_edit.c * app/gimpcontext.c * app/gimpdnd.c * app/gradient_editor.c * app/palette.c * app/palette_import.c * app/user_install.c: many related changes. * libgimpmath/gimpmathtypes.h * libgimpmath/gimpvector.[ch]: minor cleanups. * plug-ins/script-fu/script-fu.c: gimp_data_directory() is const now.
2001-02-14 22:57:14 +08:00
{
g_return_val_if_fail (GIMP_IS_DATA (data), NULL);
if (gimp_data_is_duplicatable (data))
{
GimpData *new = GIMP_DATA_GET_CLASS (data)->duplicate (data);
GimpDataPrivate *private = GIMP_DATA_GET_PRIVATE (new);
g_object_set (new,
"name", NULL,
"writable", GIMP_DATA_GET_CLASS (new)->save != NULL,
"deletable", TRUE,
NULL);
g_clear_object (&private->file);
return new;
}
return NULL;
}
added a note about apptype.h and about not including headers in headers. 2001-02-14 Michael Natterer <mitch@gimp.org> * HACKING: added a note about apptype.h and about not including headers in headers. * app/apptypes.h: added GimpTool and BitmapCursor. * app/cursorutil.h * app/devices.h * app/draw_core.h * app/tools/color_picker.h * app/tools/tool.h * app/tools/tool_options.h * app/gimpcontext.h: removed includes of "tools/tool.h" * app/gimprc.[ch]: indentadion cleanup, added "module_db_load_inhibit". * app/module_db.c: removed the above variable here. * app/gimpdata.[ch]: added a vitrual "duplicate" method. * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushpipe.[ch] * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch]: all "load", "new" and "get_standard" functions return a GimpData pointer now. * app/gimpdatafactory.[ch]: made some stuff const. * app/gimpdatafactoryview.c: activate the "duplicate" button and set the initial button sensitivity correctly. * app/brush_select.c * app/gradient_select.c * app/pattern_select.c: use the new GimpDataFactoryView. * libgimp/Makefile.am: grouped the file to sort out what _may_ go to subdirs or separate libs. * libgimp/gimpenv.[ch]: added many "const". * app/app_procs.c * app/brush_edit.c * app/gimpcontext.c * app/gimpdnd.c * app/gradient_editor.c * app/palette.c * app/palette_import.c * app/user_install.c: many related changes. * libgimpmath/gimpmathtypes.h * libgimpmath/gimpvector.[ch]: minor cleanups. * plug-ins/script-fu/script-fu.c: gimp_data_directory() is const now.
2001-02-14 22:57:14 +08:00
/**
* gimp_data_make_internal:
* @data: a #GimpData object.
*
* Mark @data as "internal" to Gimp, which means that it will not be
* saved to disk. Note that if you do this, later calls to
* gimp_data_save() and gimp_data_delete_from_disk() will
* automatically return successfully without giving any warning.
*
* The identifier name shall be an untranslated globally unique string
* that identifies the internal object across sessions.
**/
void
gimp_data_make_internal (GimpData *data,
const gchar *identifier)
{
GimpDataPrivate *private;
g_return_if_fail (GIMP_IS_DATA (data));
private = GIMP_DATA_GET_PRIVATE (data);
g_clear_object (&private->file);
Added infrastructure to make sure we don't write to the global brush, 2004-01-28 Michael Natterer <mitch@gimp.org> Added infrastructure to make sure we don't write to the global brush, pattern etc. directories. Needed to make this configurable because we can't rely on the global directories being read-only, having certain names or being otherwise detectable at runtime in a sane way. Fixes bug #132214. * libgimpbase/gimpdatafiles.[ch]: added "const gchar *dirname" to the GimpDataFileData struct so callbacks don't need to call g_path_get_dirname() for each file. * libgimpwidgets/gimpfileentry.c: made it work with non UTF-8 encoded filenames. * libgimpwidgets/gimppatheditor.[ch]: ditto. Added GUI and API for setting/getting a second "writable_path". The widget makes sure that the writable_path is always a subset of the path. * app/config/gimpconfig-utils.[ch]: added new function gimp_config_build_writable_path(). * app/config/gimpcoreconfig.[ch]: added separate properties for the writable brush, pattern, gradient, palette and font paths. * app/config/gimprc-blurbs.h: added (still empty) blurbs for the new properties. * app/core/gimpdata.[ch] (gimp_data_set_filename): added parameter "gboolean writable". Set data->writable to FALSE by default. If "writable" is passed as TRUE, still check if we can write to the file before setting data->writable to TRUE. (gimp_data_create_filename): changed "data_path" parameter to "dest_dir" and assume dest_dir is writable. (gimp_data_duplicate): set data->dirty to TRUE to make sure duplicated things will be saved. * app/core/gimpbrush.c * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c * app/core/gimpgradient.c * app/core/gimppalette.c * app/core/gimppattern.c: don't set the data's filename and don't touch data->dirty in the _load() functions because that's done by the data factory now. Don't touch data->dirty in the _duplicate() functions because that's done by gimp_data_duplicate() itself now. * app/core/gimpdatafactory.[ch] (gimp_data_factory_new): added "writable_property_name" and remember it. Added utility function gimp_data_factory_get_save_dir() which determines the directory to save new datas to. Added public function gimp_data_factory_data_save_single() which saves a single data object. Make sure new things get saved to the first writable directory as specified in preferences. * app/core/gimp.c (gimp_real_initialize): pass the writable_paths' property names to gimp_data_factory_new(). * app/widgets/gimpdataeditor.c (gimp_data_editor_save_dirty): use gimp_data_factory_data_save_single() instead of implementing saving here. * app/widgets/gimppropwidgets.[ch] (gimp_prop_path_editor_new): added "const gchar *writable_property_name" parameter (can be NULL). Added the needed callbacks to handle the writable_path and made the path_editor and file_entry code aware of non UTF-8 filename encodings. Some general cleanup. * app/gui/preferences-dialog.c: changed accordingly.
2004-01-29 05:53:50 +08:00
g_free (private->identifier);
private->identifier = g_strdup (identifier);
private->writable = FALSE;
private->deletable = FALSE;
private->internal = TRUE;
}
gboolean
gimp_data_is_internal (GimpData *data)
{
GimpDataPrivate *private;
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
private = GIMP_DATA_GET_PRIVATE (data);
return private->internal;
}
/**
* gimp_data_compare:
* @data1: a #GimpData object.
* @data2: another #GimpData object.
*
* Compares two data objects for use in sorting. Objects marked as
* "internal" come first, then user-writable objects, then system data
* files. In these three groups, the objects are sorted alphabetically
* by name, using gimp_object_name_collate().
*
* Returns: -1 if @data1 compares before @data2,
* 0 if they compare equal,
* 1 if @data1 compares after @data2.
**/
Long overdue core container cleanup: 2004-05-24 Michael Natterer <mitch@gimp.org> Long overdue core container cleanup: * app/core/gimplist.[ch]: added "unique-names" and "sort-func" properties and merged the resp. code from GimpDataList into GimpList. Removed "policy" parameters from gimp_list_new() and added "unique_names". Added new constructor gimp_list_new_weak(). Made public function gimp_list_uniquefy_name() private. * app/core/Makefile.am * app/core/core-types.h * app/core/gimpdatalist.[ch]: removed. Its functionality is entirely in GimpList now. * app/core/gimpdata.[ch]: added gimp_data_name_compare() which used to live in GimpDataList. * app/core/gimp.c * app/core/gimpdatafactory.c * app/core/gimpimage.c * app/core/gimptoolinfo.c * app/core/gimpundostack.c * app/paint/gimp-paint.c * app/tools/gimp-tools.c * app/widgets/gimpdevices.c * app/widgets/gimptemplateeditor.c * app/widgets/gimpundoeditor.c: changed list creation accordingly. Made gimp->templates, gimp->named_buffers, tool_info->presets and the image's lists of layers, channels and vectors automatically ensure unique names. * app/widgets/gimptemplateview.c * app/actions/file-commands.c * app/actions/templates-commands.c * app/actions/tool-options-commands.c: removed calls to gimp_list_uniquefy_name(). * app/core/gimpitem.c: removed major insanity where the items themselves where ensuring their unique names. Bah! * app/core/gimplayer.c (gimp_layer_name_changed): chain up conditionally. * app/core/gimplayermask.c (gimp_layer_mask_name_changed): removed because there is no need any more to keep the parent implementation from being invoked.
2004-05-24 18:49:34 +08:00
gint
gimp_data_compare (GimpData *data1,
GimpData *data2)
Long overdue core container cleanup: 2004-05-24 Michael Natterer <mitch@gimp.org> Long overdue core container cleanup: * app/core/gimplist.[ch]: added "unique-names" and "sort-func" properties and merged the resp. code from GimpDataList into GimpList. Removed "policy" parameters from gimp_list_new() and added "unique_names". Added new constructor gimp_list_new_weak(). Made public function gimp_list_uniquefy_name() private. * app/core/Makefile.am * app/core/core-types.h * app/core/gimpdatalist.[ch]: removed. Its functionality is entirely in GimpList now. * app/core/gimpdata.[ch]: added gimp_data_name_compare() which used to live in GimpDataList. * app/core/gimp.c * app/core/gimpdatafactory.c * app/core/gimpimage.c * app/core/gimptoolinfo.c * app/core/gimpundostack.c * app/paint/gimp-paint.c * app/tools/gimp-tools.c * app/widgets/gimpdevices.c * app/widgets/gimptemplateeditor.c * app/widgets/gimpundoeditor.c: changed list creation accordingly. Made gimp->templates, gimp->named_buffers, tool_info->presets and the image's lists of layers, channels and vectors automatically ensure unique names. * app/widgets/gimptemplateview.c * app/actions/file-commands.c * app/actions/templates-commands.c * app/actions/tool-options-commands.c: removed calls to gimp_list_uniquefy_name(). * app/core/gimpitem.c: removed major insanity where the items themselves where ensuring their unique names. Bah! * app/core/gimplayer.c (gimp_layer_name_changed): chain up conditionally. * app/core/gimplayermask.c (gimp_layer_mask_name_changed): removed because there is no need any more to keep the parent implementation from being invoked.
2004-05-24 18:49:34 +08:00
{
g_return_val_if_fail (GIMP_IS_DATA (data1), 0);
g_return_val_if_fail (GIMP_IS_DATA (data2), 0);
g_return_val_if_fail (GIMP_DATA_GET_CLASS (data1)->compare ==
GIMP_DATA_GET_CLASS (data2)->compare, 0);
Long overdue core container cleanup: 2004-05-24 Michael Natterer <mitch@gimp.org> Long overdue core container cleanup: * app/core/gimplist.[ch]: added "unique-names" and "sort-func" properties and merged the resp. code from GimpDataList into GimpList. Removed "policy" parameters from gimp_list_new() and added "unique_names". Added new constructor gimp_list_new_weak(). Made public function gimp_list_uniquefy_name() private. * app/core/Makefile.am * app/core/core-types.h * app/core/gimpdatalist.[ch]: removed. Its functionality is entirely in GimpList now. * app/core/gimpdata.[ch]: added gimp_data_name_compare() which used to live in GimpDataList. * app/core/gimp.c * app/core/gimpdatafactory.c * app/core/gimpimage.c * app/core/gimptoolinfo.c * app/core/gimpundostack.c * app/paint/gimp-paint.c * app/tools/gimp-tools.c * app/widgets/gimpdevices.c * app/widgets/gimptemplateeditor.c * app/widgets/gimpundoeditor.c: changed list creation accordingly. Made gimp->templates, gimp->named_buffers, tool_info->presets and the image's lists of layers, channels and vectors automatically ensure unique names. * app/widgets/gimptemplateview.c * app/actions/file-commands.c * app/actions/templates-commands.c * app/actions/tool-options-commands.c: removed calls to gimp_list_uniquefy_name(). * app/core/gimpitem.c: removed major insanity where the items themselves where ensuring their unique names. Bah! * app/core/gimplayer.c (gimp_layer_name_changed): chain up conditionally. * app/core/gimplayermask.c (gimp_layer_mask_name_changed): removed because there is no need any more to keep the parent implementation from being invoked.
2004-05-24 18:49:34 +08:00
return GIMP_DATA_GET_CLASS (data1)->compare (data1, data2);
Long overdue core container cleanup: 2004-05-24 Michael Natterer <mitch@gimp.org> Long overdue core container cleanup: * app/core/gimplist.[ch]: added "unique-names" and "sort-func" properties and merged the resp. code from GimpDataList into GimpList. Removed "policy" parameters from gimp_list_new() and added "unique_names". Added new constructor gimp_list_new_weak(). Made public function gimp_list_uniquefy_name() private. * app/core/Makefile.am * app/core/core-types.h * app/core/gimpdatalist.[ch]: removed. Its functionality is entirely in GimpList now. * app/core/gimpdata.[ch]: added gimp_data_name_compare() which used to live in GimpDataList. * app/core/gimp.c * app/core/gimpdatafactory.c * app/core/gimpimage.c * app/core/gimptoolinfo.c * app/core/gimpundostack.c * app/paint/gimp-paint.c * app/tools/gimp-tools.c * app/widgets/gimpdevices.c * app/widgets/gimptemplateeditor.c * app/widgets/gimpundoeditor.c: changed list creation accordingly. Made gimp->templates, gimp->named_buffers, tool_info->presets and the image's lists of layers, channels and vectors automatically ensure unique names. * app/widgets/gimptemplateview.c * app/actions/file-commands.c * app/actions/templates-commands.c * app/actions/tool-options-commands.c: removed calls to gimp_list_uniquefy_name(). * app/core/gimpitem.c: removed major insanity where the items themselves where ensuring their unique names. Bah! * app/core/gimplayer.c (gimp_layer_name_changed): chain up conditionally. * app/core/gimplayermask.c (gimp_layer_mask_name_changed): removed because there is no need any more to keep the parent implementation from being invoked.
2004-05-24 18:49:34 +08:00
}
/**
* gimp_data_error_quark:
*
* This function is used to implement the GIMP_DATA_ERROR macro. It
* shouldn't be called directly.
*
* Returns: the #GQuark to identify error in the GimpData error domain.
**/
GQuark
gimp_data_error_quark (void)
{
return g_quark_from_static_string ("gimp-data-error-quark");
added a note about apptype.h and about not including headers in headers. 2001-02-14 Michael Natterer <mitch@gimp.org> * HACKING: added a note about apptype.h and about not including headers in headers. * app/apptypes.h: added GimpTool and BitmapCursor. * app/cursorutil.h * app/devices.h * app/draw_core.h * app/tools/color_picker.h * app/tools/tool.h * app/tools/tool_options.h * app/gimpcontext.h: removed includes of "tools/tool.h" * app/gimprc.[ch]: indentadion cleanup, added "module_db_load_inhibit". * app/module_db.c: removed the above variable here. * app/gimpdata.[ch]: added a vitrual "duplicate" method. * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushpipe.[ch] * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch]: all "load", "new" and "get_standard" functions return a GimpData pointer now. * app/gimpdatafactory.[ch]: made some stuff const. * app/gimpdatafactoryview.c: activate the "duplicate" button and set the initial button sensitivity correctly. * app/brush_select.c * app/gradient_select.c * app/pattern_select.c: use the new GimpDataFactoryView. * libgimp/Makefile.am: grouped the file to sort out what _may_ go to subdirs or separate libs. * libgimp/gimpenv.[ch]: added many "const". * app/app_procs.c * app/brush_edit.c * app/gimpcontext.c * app/gimpdnd.c * app/gradient_editor.c * app/palette.c * app/palette_import.c * app/user_install.c: many related changes. * libgimpmath/gimpmathtypes.h * libgimpmath/gimpvector.[ch]: minor cleanups. * plug-ins/script-fu/script-fu.c: gimp_data_directory() is const now.
2001-02-14 22:57:14 +08:00
}