gimp/app/widgets/gimptooleditor.c

854 lines
30 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimptooleditor.c
* Copyright (C) 2001-2009 Michael Natterer <mitch@gimp.org>
* Stephen Griffiths <scgmk5@gmail.com>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "core/gimp.h"
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimptoolgroup.h"
#include "core/gimptreehandler.h"
#include "tools/gimp-tools.h"
#include "gimpcontainertreestore.h"
#include "gimpcontainerview.h"
#include "gimpdnd.h"
#include "gimpviewrenderer.h"
#include "gimptooleditor.h"
#include "gimphelp-ids.h"
#include "gimpwidgets-utils.h"
#include "gimp-intl.h"
struct _GimpToolEditorPrivate
{
GimpContainer *container;
GimpContext *context;
GtkWidget *scrolled;
GtkWidget *new_group_button;
GtkWidget *raise_button;
GtkWidget *lower_button;
GtkWidget *delete_button;
GtkWidget *reset_button;
GimpTreeHandler *tool_item_notify_handler;
/* State of tools at creation of the editor, stored to support
* reverting changes
*/
gchar *initial_tool_state;
};
/* local function prototypes */
static void gimp_tool_editor_view_iface_init (GimpContainerViewInterface *iface);
static void gimp_tool_editor_constructed (GObject *object);
static gboolean gimp_tool_editor_select_items (GimpContainerView *view,
GList *items,
GList *paths);
static void gimp_tool_editor_set_container (GimpContainerView *container_view,
GimpContainer *container);
static void gimp_tool_editor_set_context (GimpContainerView *container_view,
GimpContext *context);
static gboolean gimp_tool_editor_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreePath *drop_path,
GtkTreeViewDropPosition drop_pos,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action);
static void gimp_tool_editor_drop_viewables (GimpContainerTreeView *tree_view,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
static void gimp_tool_editor_tool_item_notify (GimpToolItem *tool_item,
GParamSpec *pspec,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_eye_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data);
static void gimp_tool_editor_eye_clicked (GtkCellRendererToggle *toggle,
gchar *path_str,
GdkModifierType state,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_new_group_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_raise_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_raise_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_lower_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_lower_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_delete_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static void gimp_tool_editor_reset_clicked (GtkButton *button,
GimpToolEditor *tool_editor);
static GimpToolItem * gimp_tool_editor_get_selected_tool_item (GimpToolEditor *tool_editor);
static GimpContainer * gimp_tool_editor_get_tool_item_container (GimpToolEditor *tool_editor,
GimpToolItem *tool_item);
static void gimp_tool_editor_update_container (GimpToolEditor *tool_editor);
static void gimp_tool_editor_update_sensitivity (GimpToolEditor *tool_editor);
G_DEFINE_TYPE_WITH_CODE (GimpToolEditor, gimp_tool_editor,
GIMP_TYPE_CONTAINER_TREE_VIEW,
G_ADD_PRIVATE (GimpToolEditor)
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONTAINER_VIEW,
gimp_tool_editor_view_iface_init))
#define parent_class gimp_tool_editor_parent_class
static GimpContainerViewInterface *parent_view_iface = NULL;
/* private functions */
static void
gimp_tool_editor_class_init (GimpToolEditorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpContainerTreeViewClass *tree_view_class = GIMP_CONTAINER_TREE_VIEW_CLASS (klass);
object_class->constructed = gimp_tool_editor_constructed;
tree_view_class->drop_possible = gimp_tool_editor_drop_possible;
tree_view_class->drop_viewables = gimp_tool_editor_drop_viewables;
}
static void
gimp_tool_editor_view_iface_init (GimpContainerViewInterface *iface)
{
parent_view_iface = g_type_interface_peek_parent (iface);
if (! parent_view_iface)
parent_view_iface = g_type_default_interface_peek (GIMP_TYPE_CONTAINER_VIEW);
iface->select_items = gimp_tool_editor_select_items;
iface->set_container = gimp_tool_editor_set_container;
iface->set_context = gimp_tool_editor_set_context;
}
static void
gimp_tool_editor_init (GimpToolEditor *tool_editor)
{
tool_editor->priv = gimp_tool_editor_get_instance_private (tool_editor);
}
static void
gimp_tool_editor_constructed (GObject *object)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (object);
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (object);
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (object);
gint view_size;
gint border_width;
G_OBJECT_CLASS (parent_class)->constructed (object);
view_size = gimp_container_view_get_view_size (container_view,
&border_width);
gimp_editor_set_show_name (GIMP_EDITOR (tool_editor), FALSE);
gtk_tree_view_set_level_indentation (tree_view->view,
0.8 * (view_size + 2 * border_width));
gimp_dnd_viewable_dest_add (GTK_WIDGET (tree_view->view),
GIMP_TYPE_TOOL_ITEM,
NULL, NULL);
/* construct tree view */
{
GtkTreeViewColumn *column;
GtkCellRenderer *eye_cell;
GtkStyleContext *tree_style;
GtkBorder border;
gint icon_size;
tree_style = gtk_widget_get_style_context (GTK_WIDGET (tool_editor));
gtk_style_context_get_border (tree_style, 0, &border);
column = gtk_tree_view_column_new ();
gtk_tree_view_insert_column (tree_view->view, column, 0);
eye_cell = gimp_cell_renderer_toggle_new (GIMP_ICON_VISIBLE);
g_object_get (eye_cell, "icon-size", &icon_size, NULL);
icon_size = MIN (icon_size, MAX (view_size - (border.left + border.right),
view_size - (border.top + border.bottom)));
g_object_set (eye_cell, "icon-size", icon_size, NULL);
gtk_tree_view_column_pack_start (column, eye_cell, FALSE);
gtk_tree_view_column_set_cell_data_func (column, eye_cell,
gimp_tool_editor_eye_data_func,
tree_view, NULL);
gimp_container_tree_view_add_toggle_cell (tree_view, eye_cell);
g_signal_connect (eye_cell, "clicked",
G_CALLBACK (gimp_tool_editor_eye_clicked),
tool_editor);
}
/* buttons */
tool_editor->priv->new_group_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_FOLDER_NEW,
_("Create a new tool group"), NULL,
G_CALLBACK (gimp_tool_editor_new_group_clicked),
NULL,
tool_editor);
tool_editor->priv->raise_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_GO_UP,
_("Raise this item"),
_("Raise this item to the top"),
G_CALLBACK (gimp_tool_editor_raise_clicked),
G_CALLBACK (gimp_tool_editor_raise_extend_clicked),
tool_editor);
tool_editor->priv->lower_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_GO_DOWN,
_("Lower this item"),
_("Lower this item to the bottom"),
G_CALLBACK (gimp_tool_editor_lower_clicked),
G_CALLBACK (gimp_tool_editor_lower_extend_clicked),
tool_editor);
tool_editor->priv->delete_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_EDIT_DELETE,
_("Delete this tool group"), NULL,
G_CALLBACK (gimp_tool_editor_delete_clicked),
NULL,
tool_editor);
tool_editor->priv->reset_button =
gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_RESET,
_("Reset tool order and visibility"), NULL,
G_CALLBACK (gimp_tool_editor_reset_clicked),
NULL,
tool_editor);
gimp_tool_editor_update_sensitivity (tool_editor);
}
static gboolean
gimp_tool_editor_select_items (GimpContainerView *container_view,
GList *viewables,
GList *paths)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
gboolean result;
result = parent_view_iface->select_items (container_view,
viewables, paths);
gimp_tool_editor_update_sensitivity (tool_editor);
return result;
}
static void
gimp_tool_editor_set_container (GimpContainerView *container_view,
GimpContainer *container)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
parent_view_iface->set_container (container_view, container);
gimp_tool_editor_update_container (tool_editor);
}
static void
gimp_tool_editor_set_context (GimpContainerView *container_view,
GimpContext *context)
{
GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view);
parent_view_iface->set_context (container_view, context);
gimp_tool_editor_update_container (tool_editor);
}
static gboolean
gimp_tool_editor_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreePath *drop_path,
GtkTreeViewDropPosition drop_pos,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action)
{
if (GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (
tree_view,
src_type, src_viewables, dest_viewable, drop_path, drop_pos,
return_drop_pos, return_drag_action))
{
if (gimp_viewable_get_parent (dest_viewable) ||
(gimp_viewable_get_children (dest_viewable) &&
(drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER ||
drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)))
{
GList *iter;
for (iter = src_viewables; iter; iter = iter->next)
{
GimpViewable *src_viewable = iter->data;
if (gimp_viewable_get_children (src_viewable))
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
static void
gimp_tool_editor_drop_viewables (GimpContainerTreeView *tree_view,
GList *src_viewables,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tree_view);
GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_viewables (tree_view,
src_viewables,
dest_viewable,
drop_pos);
if (src_viewables)
gimp_container_view_select_items (container_view, src_viewables);
}
static void
gimp_tool_editor_new_group_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GimpContainer *container;
GimpToolItem *tool_item;
GimpToolGroup *group;
gint index = 0;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
if (gimp_viewable_get_parent (GIMP_VIEWABLE (tool_item)) != NULL)
return;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
}
else
{
container = tool_editor->priv->container;
}
if (container)
{
group = gimp_tool_group_new ();
gimp_container_insert (container, GIMP_OBJECT (group), index);
g_object_unref (group);
gimp_container_view_select_item (container_view, GIMP_VIEWABLE (group));
}
}
static void
gimp_tool_editor_raise_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
if (index > 0)
{
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), index - 1);
}
}
}
static void
gimp_tool_editor_raise_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item && (mask & GDK_SHIFT_MASK))
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
if (index > 0)
{
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), 0);
}
}
}
static void
gimp_tool_editor_lower_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
if (index + 1 < gimp_container_get_n_children (container))
{
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), index + 1);
}
}
}
static void
gimp_tool_editor_lower_extend_clicked (GtkButton *button,
GdkModifierType mask,
GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item && (mask & GDK_SHIFT_MASK))
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_n_children (container) - 1;
index = MAX (index, 0);
gimp_container_reorder (container,
GIMP_OBJECT (tool_item), index);
}
}
static void
gimp_tool_editor_delete_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *src_container;
GimpContainer *dest_container;
gint index;
gint dest_index;
src_container = gimp_viewable_get_children (GIMP_VIEWABLE (tool_item));
dest_container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
if (! src_container)
return;
index = gimp_container_get_child_index (dest_container,
GIMP_OBJECT (tool_item));
dest_index = index;
g_object_ref (tool_item);
gimp_container_freeze (src_container);
gimp_container_freeze (dest_container);
gimp_container_remove (dest_container, GIMP_OBJECT (tool_item));
while (! gimp_container_is_empty (src_container))
{
GimpObject *object = gimp_container_get_first_child (src_container);
g_object_ref (object);
gimp_container_remove (src_container, object);
gimp_container_insert (dest_container, object, dest_index++);
g_object_unref (object);
}
gimp_container_thaw (dest_container);
gimp_container_thaw (src_container);
gimp_container_view_select_item (
container_view,
GIMP_VIEWABLE (gimp_container_get_child_by_index (dest_container,
index)));
g_object_unref (tool_item);
}
}
static void
gimp_tool_editor_reset_clicked (GtkButton *button,
GimpToolEditor *tool_editor)
{
gimp_tools_reset (tool_editor->priv->context->gimp,
tool_editor->priv->container,
FALSE);
}
static void
gimp_tool_editor_tool_item_notify (GimpToolItem *tool_item,
GParamSpec *pspec,
GimpToolEditor *tool_editor)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (tool_editor);
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GtkTreeIter *iter;
iter = gimp_container_view_lookup (container_view,
GIMP_VIEWABLE (tool_item));
if (iter)
{
GtkTreePath *path;
path = gtk_tree_model_get_path (tree_view->model, iter);
gtk_tree_model_row_changed (tree_view->model, path, iter);
gtk_tree_path_free (path);
}
}
static void
gimp_tool_editor_eye_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data)
{
GimpViewRenderer *renderer;
GimpToolItem *tool_item;
gtk_tree_model_get (tree_model, iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
tool_item = GIMP_TOOL_ITEM (renderer->viewable);
g_object_set (cell,
"active", gimp_tool_item_get_visible (tool_item),
"inconsistent", gimp_tool_item_get_visible (tool_item) &&
! gimp_tool_item_get_shown (tool_item),
NULL);
g_object_unref (renderer);
}
static void
gimp_tool_editor_eye_clicked (GtkCellRendererToggle *toggle,
gchar *path_str,
GdkModifierType state,
GimpToolEditor *tool_editor)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (tool_editor);
GtkTreePath *path;
GtkTreeIter iter;
path = gtk_tree_path_new_from_string (path_str);
if (gtk_tree_model_get_iter (tree_view->model, &iter, path))
{
GimpViewRenderer *renderer;
GimpToolItem *tool_item;
gboolean active;
gtk_tree_model_get (tree_view->model, &iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
tool_item = GIMP_TOOL_ITEM (renderer->viewable);
g_object_get (toggle,
"active", &active,
NULL);
gimp_tool_item_set_visible (tool_item, ! active);
g_object_unref (renderer);
}
gtk_tree_path_free (path);
}
static GimpToolItem *
gimp_tool_editor_get_selected_tool_item (GimpToolEditor *tool_editor)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (tool_editor);
if (tool_editor->priv->container)
{
GimpViewRenderer *renderer;
GimpToolItem *tool_item;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
selection = gtk_tree_view_get_selection (tree_view->view);
if (! gtk_tree_selection_get_selected (selection, &model, &iter))
return NULL;
gtk_tree_model_get (model, &iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
tool_item = GIMP_TOOL_ITEM (renderer->viewable);
g_object_unref (renderer);
return tool_item;
}
return NULL;
}
static GimpContainer *
gimp_tool_editor_get_tool_item_container (GimpToolEditor *tool_editor,
GimpToolItem *tool_item)
{
GimpViewable *parent;
parent = gimp_viewable_get_parent (GIMP_VIEWABLE (tool_item));
if (parent)
{
return gimp_viewable_get_children (parent);
}
else
{
return tool_editor->priv->container;
}
}
static void
gimp_tool_editor_update_container (GimpToolEditor *tool_editor)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor);
GimpContainer *container;
GimpContext *context;
g_clear_pointer (&tool_editor->priv->tool_item_notify_handler,
gimp_tree_handler_disconnect);
g_clear_pointer (&tool_editor->priv->initial_tool_state, g_free);
container = gimp_container_view_get_container (container_view);
context = gimp_container_view_get_context (container_view);
if (container && context)
{
GString *string;
GimpConfigWriter *writer;
tool_editor->priv->container = container;
tool_editor->priv->context = context;
tool_editor->priv->tool_item_notify_handler = gimp_tree_handler_connect (
container, "notify",
G_CALLBACK (gimp_tool_editor_tool_item_notify),
tool_editor);
/* save initial tool order */
string = g_string_new (NULL);
writer = gimp_config_writer_new_from_string (string);
gimp_tools_serialize (context->gimp, container, writer);
gimp_config_writer_finish (writer, NULL, NULL);
tool_editor->priv->initial_tool_state = g_string_free (string, FALSE);
}
}
static void
gimp_tool_editor_update_sensitivity (GimpToolEditor *tool_editor)
{
GimpToolItem *tool_item;
tool_item = gimp_tool_editor_get_selected_tool_item (tool_editor);
if (tool_item)
{
GimpContainer *container;
gint index;
container = gimp_tool_editor_get_tool_item_container (tool_editor,
tool_item);
index = gimp_container_get_child_index (container,
GIMP_OBJECT (tool_item));
gtk_widget_set_sensitive (
tool_editor->priv->new_group_button,
gimp_viewable_get_parent (GIMP_VIEWABLE (tool_item)) == NULL);
gtk_widget_set_sensitive (
tool_editor->priv->raise_button,
index > 0);
gtk_widget_set_sensitive (
tool_editor->priv->lower_button,
index < gimp_container_get_n_children (container) - 1);
gtk_widget_set_sensitive (
tool_editor->priv->delete_button,
gimp_viewable_get_children (GIMP_VIEWABLE (tool_item)) != NULL);
}
else
{
gtk_widget_set_sensitive (tool_editor->priv->new_group_button, TRUE);
gtk_widget_set_sensitive (tool_editor->priv->raise_button, FALSE);
gtk_widget_set_sensitive (tool_editor->priv->lower_button, FALSE);
gtk_widget_set_sensitive (tool_editor->priv->delete_button, FALSE);
}
}
/* public functions */
GtkWidget *
gimp_tool_editor_new (GimpContainer *container,
GimpContext *context,
gint view_size,
gint view_border_width)
{
GimpContainerView *container_view;
g_return_val_if_fail (GIMP_IS_CONTAINER (container), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
container_view = g_object_new (GIMP_TYPE_TOOL_EDITOR,
"view-size", view_size,
"view-border-width", view_border_width,
NULL);
gimp_container_view_set_context (container_view, context);
gimp_container_view_set_container (container_view, container);
gimp_container_view_set_reorderable (container_view, TRUE);
return GTK_WIDGET (container_view);
}
/**
* gimp_tool_editor_revert_changes:
* @tool_editor:
*
* Reverts the tool order and visibility to the state at creation.
**/
void
gimp_tool_editor_revert_changes (GimpToolEditor *tool_editor)
{
GScanner *scanner;
g_return_if_fail (GIMP_IS_TOOL_EDITOR (tool_editor));
scanner = gimp_scanner_new_string (tool_editor->priv->initial_tool_state, -1,
NULL);
gimp_tools_deserialize (tool_editor->priv->context->gimp,
tool_editor->priv->container,
scanner);
gimp_scanner_unref (scanner);
}