Commit 8d9e3622 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

app/gui/Makefile.am app/gui/brush-select.[ch] app/gui/font-select.[ch]

2004-07-09  Michael Natterer  <mitch@gimp.org>

	* app/gui/Makefile.am
	* app/gui/brush-select.[ch]
	* app/gui/font-select.[ch]
	* app/gui/gradient-select.[ch]
	* app/gui/palette-select.[ch]
	* app/gui/pattern-select.[ch]: removed...

	* app/widgets/Makefile.am
	* app/widgets/widgets-types.h
	* app/widgets/gimppdbdialog.[ch]
	* app/widgets/gimpdataselect.[ch]
	* app/widgets/gimpbrushselect.[ch]
	* app/widgets/gimpgradientselect.[ch]
	* app/widgets/gimppaletteselect.[ch]
	* app/widgets/gimppatternselect.[ch]
	* app/widgets/gimpfontselect.[ch]: ...and added here as a
	hierarchy of widgets.

	* app/widgets/gimpdatafactoryview.h: removed typdef
	GimpDataEditFunc, it's in widgets-types.h now.

	* app/gui/convert-dialog.c: changed accordingly.

	* app/core/gimp.[ch]: added vtable entries for creating, closing
	and setting PDB dialogs.

	* app/gui/gui-vtable.c: implement the vtable entries using the new
	widgets.

	* tools/pdbgen/pdb/brush_select.pdb
	* tools/pdbgen/pdb/font_select.pdb
	* tools/pdbgen/pdb/gradient_select.pdb
	* tools/pdbgen/pdb/palette_select.pdb
	* tools/pdbgen/pdb/pattern_select.pdb: use the new functions of
	the Gimp object to create / manage the selection dialogs. The
	generated files don't depend on GUI stuff any longer.

	* app/pdb/brush_select_cmds.c
	* app/pdb/font_select_cmds.c
	* app/pdb/gradient_select_cmds.c
	* app/pdb/palette_select_cmds.c
	* app/pdb/pattern_select_cmds.c: regenerated.
parent ac9e95bb
2004-07-09 Michael Natterer <mitch@gimp.org>
* app/gui/Makefile.am
* app/gui/brush-select.[ch]
* app/gui/font-select.[ch]
* app/gui/gradient-select.[ch]
* app/gui/palette-select.[ch]
* app/gui/pattern-select.[ch]: removed...
* app/widgets/Makefile.am
* app/widgets/widgets-types.h
* app/widgets/gimppdbdialog.[ch]
* app/widgets/gimpdataselect.[ch]
* app/widgets/gimpbrushselect.[ch]
* app/widgets/gimpgradientselect.[ch]
* app/widgets/gimppaletteselect.[ch]
* app/widgets/gimppatternselect.[ch]
* app/widgets/gimpfontselect.[ch]: ...and added here as a
hierarchy of widgets.
* app/widgets/gimpdatafactoryview.h: removed typdef
GimpDataEditFunc, it's in widgets-types.h now.
* app/gui/convert-dialog.c: changed accordingly.
* app/core/gimp.[ch]: added vtable entries for creating, closing
and setting PDB dialogs.
* app/gui/gui-vtable.c: implement the vtable entries using the new
widgets.
* tools/pdbgen/pdb/brush_select.pdb
* tools/pdbgen/pdb/font_select.pdb
* tools/pdbgen/pdb/gradient_select.pdb
* tools/pdbgen/pdb/palette_select.pdb
* tools/pdbgen/pdb/pattern_select.pdb: use the new functions of
the Gimp object to create / manage the selection dialogs. The
generated files don't depend on GUI stuff any longer.
* app/pdb/brush_select_cmds.c
* app/pdb/font_select_cmds.c
* app/pdb/gradient_select_cmds.c
* app/pdb/palette_select_cmds.c
* app/pdb/pattern_select_cmds.c: regenerated.
2004-07-09 Sven Neumann <sven@gimp.org>
* app/gui/file-save-dialog.c (file_save_overwrite): improved text
......
......@@ -223,6 +223,11 @@ gimp_init (Gimp *gimp)
gimp->gui_progress_restart_func = NULL;
gimp->gui_progress_update_func = NULL;
gimp->gui_progress_end_func = NULL;
gimp->gui_get_program_class_func = NULL;
gimp->gui_get_display_name_func = NULL;
gimp->gui_get_theme_dir_func = NULL;
gimp->gui_pdb_dialog_set_func = NULL;
gimp->gui_pdb_dialog_close_func = NULL;
gimp->gui_pdb_dialogs_check_func = NULL;
gimp->busy = 0;
......@@ -1128,15 +1133,6 @@ gimp_end_progress (Gimp *gimp,
gimp->gui_progress_end_func (gimp, progress);
}
void
gimp_pdb_dialogs_check (Gimp *gimp)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
if (gimp->gui_pdb_dialogs_check_func)
gimp->gui_pdb_dialogs_check_func (gimp);
}
const gchar *
gimp_get_program_class (Gimp *gimp)
{
......@@ -1175,6 +1171,92 @@ gimp_get_theme_dir (Gimp *gimp)
return NULL;
}
gboolean
gimp_pdb_dialog_new (Gimp *gimp,
GimpContext *context,
GimpContainer *container,
const gchar *title,
const gchar *callback_name,
const gchar *object_name,
...)
{
gboolean retval = FALSE;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE);
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
g_return_val_if_fail (title != NULL, FALSE);
g_return_val_if_fail (callback_name != NULL, FALSE);
if (gimp->gui_pdb_dialog_new_func)
{
va_list args;
va_start (args, object_name);
retval = gimp->gui_pdb_dialog_new_func (gimp, context, container, title,
callback_name, object_name,
args);
va_end (args);
}
return retval;
}
gboolean
gimp_pdb_dialog_set (Gimp *gimp,
GimpContainer *container,
const gchar *callback_name,
const gchar *object_name,
...)
{
gboolean retval = FALSE;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
g_return_val_if_fail (callback_name != NULL, FALSE);
g_return_val_if_fail (object_name != NULL, FALSE);
if (gimp->gui_pdb_dialog_set_func)
{
va_list args;
va_start (args, object_name);
retval = gimp->gui_pdb_dialog_set_func (gimp, container, callback_name,
object_name, args);
va_end (args);
}
return retval;
}
gboolean
gimp_pdb_dialog_close (Gimp *gimp,
GimpContainer *container,
const gchar *callback_name)
{
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
g_return_val_if_fail (callback_name != NULL, FALSE);
if (gimp->gui_pdb_dialog_close_func)
return gimp->gui_pdb_dialog_close_func (gimp, container, callback_name);
return FALSE;
}
void
gimp_pdb_dialogs_check (Gimp *gimp)
{
g_return_if_fail (GIMP_IS_GIMP (gimp));
if (gimp->gui_pdb_dialogs_check_func)
gimp->gui_pdb_dialogs_check_func (gimp);
}
GimpImage *
gimp_create_image (Gimp *gimp,
gint width,
......
......@@ -55,12 +55,27 @@ typedef void (* GimpProgressUpdateFunc) (Gimp *gimp,
gdouble percentage);
typedef void (* GimpProgressEndFunc) (Gimp *gimp,
GimpProgress *progress);
typedef void (* GimpPDBDialogsCheckFunc) (Gimp *gimp);
typedef const gchar * (* GimpGetProgramClassFunc) (Gimp *gimp);
typedef gchar * (* GimpGetDisplayNameFunc) (Gimp *gimp,
gint gdisp_ID,
gint *monitor_number);
typedef const gchar * (* GimpGetThemeDirFunc) (Gimp *);
typedef const gchar * (* GimpGetThemeDirFunc) (Gimp *gimp);
typedef gboolean (* GimpPDBDialogNewFunc) (Gimp *gimp,
GimpContext *context,
GimpContainer *container,
const gchar *title,
const gchar *callback_name,
const gchar *object_name,
va_list args);
typedef gboolean (* GimpPDBDialogSetFunc) (Gimp *gimp,
GimpContainer *container,
const gchar *callback_name,
const gchar *object_name,
va_list args);
typedef gboolean (* GimpPDBDialogCloseFunc) (Gimp *gimp,
GimpContainer *container,
const gchar *callback_name);
typedef void (* GimpPDBDialogsCheckFunc) (Gimp *gimp);
#define GIMP_TYPE_GIMP (gimp_get_type ())
......@@ -105,10 +120,13 @@ struct _Gimp
GimpProgressRestartFunc gui_progress_restart_func;
GimpProgressUpdateFunc gui_progress_update_func;
GimpProgressEndFunc gui_progress_end_func;
GimpPDBDialogsCheckFunc gui_pdb_dialogs_check_func;
GimpGetProgramClassFunc gui_get_program_class_func;
GimpGetDisplayNameFunc gui_get_display_name_func;
GimpGetThemeDirFunc gui_get_theme_dir_func;
GimpPDBDialogNewFunc gui_pdb_dialog_new_func;
GimpPDBDialogSetFunc gui_pdb_dialog_set_func;
GimpPDBDialogCloseFunc gui_pdb_dialog_close_func;
GimpPDBDialogsCheckFunc gui_pdb_dialogs_check_func;
gint busy;
guint busy_idle_id;
......@@ -262,12 +280,27 @@ void gimp_update_progress (Gimp *gimp,
gdouble percentage);
void gimp_end_progress (Gimp *gimp,
GimpProgress *progress);
void gimp_pdb_dialogs_check (Gimp *gimp);
const gchar * gimp_get_program_class (Gimp *gimp);
gchar * gimp_get_display_name (Gimp *gimp,
gint gdisp_ID,
gint *monitor_number);
const gchar * gimp_get_theme_dir (Gimp *gimp);
gboolean gimp_pdb_dialog_new (Gimp *gimp,
GimpContext *context,
GimpContainer *container,
const gchar *title,
const gchar *callback_name,
const gchar *object_name,
...);
gboolean gimp_pdb_dialog_set (Gimp *gimp,
GimpContainer *container,
const gchar *callback_name,
const gchar *object_name,
...);
gboolean gimp_pdb_dialog_close (Gimp *gimp,
GimpContainer *container,
const gchar *callback_name);
void gimp_pdb_dialogs_check (Gimp *gimp);
GimpImage * gimp_create_image (Gimp *gimp,
gint width,
......
......@@ -33,9 +33,10 @@
#include "widgets/gimpenumwidgets.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimppaletteselect.h"
#include "widgets/gimpviewabledialog.h"
#include "palette-select.h"
#include "menus/menus.h"
#include "gimp-intl.h"
......@@ -45,7 +46,7 @@ typedef struct
GtkWidget *shell;
GtkWidget *custom_palette_button;
GimpImage *gimage;
PaletteSelect *palette_select;
GimpPdbDialog *palette_select;
GimpConvertDitherType dither_type;
gboolean alpha_dither;
gboolean remove_dups;
......@@ -55,18 +56,21 @@ typedef struct
} IndexedDialog;
static void indexed_response (GtkWidget *widget,
gint response_id,
IndexedDialog *dialog);
static void indexed_destroy_callback (GtkWidget *widget,
IndexedDialog *dialog);
static void indexed_response (GtkWidget *widget,
gint response_id,
IndexedDialog *dialog);
static void indexed_destroy (GtkWidget *widget,
IndexedDialog *dialog);
static void indexed_custom_palette_button_callback (GtkWidget *widget,
IndexedDialog *dialog);
static void indexed_palette_select_destroy_callback (GtkWidget *widget,
IndexedDialog *dialog);
static void indexed_custom_palette_button_callback (GtkWidget *widget,
IndexedDialog *dialog);
static void indexed_palette_select_destroy (GtkWidget *widget,
IndexedDialog *dialog);
static void indexed_palette_select_changed (GimpContext *context,
GimpPalette *palette,
IndexedDialog *dialog);
static GtkWidget * build_palette_button (Gimp *gimp);
static GtkWidget * build_palette_button (Gimp *gimp);
static gboolean UserHasWebPal = FALSE;
......@@ -129,7 +133,7 @@ convert_dialog_new (GimpImage *gimage,
dialog);
g_signal_connect (dialog->shell, "destroy",
G_CALLBACK (indexed_destroy_callback),
G_CALLBACK (indexed_destroy),
dialog);
main_vbox = gtk_vbox_new (FALSE, 12);
......@@ -433,24 +437,53 @@ indexed_response (GtkWidget *widget,
}
static void
indexed_destroy_callback (GtkWidget *widget,
IndexedDialog *dialog)
indexed_destroy (GtkWidget *widget,
IndexedDialog *dialog)
{
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (GTK_WIDGET (dialog->palette_select));
g_free (dialog);
}
static void
indexed_palette_select_destroy_callback (GtkWidget *widget,
IndexedDialog *dialog)
indexed_custom_palette_button_callback (GtkWidget *widget,
IndexedDialog *dialog)
{
if (! dialog->palette_select)
{
dialog->palette_select =
g_object_new (GIMP_TYPE_PALETTE_SELECT,
"title", _("Select Custom Palette"),
"role", "gimp-pelette-selection",
"help-func", gimp_standard_help_func,
"help_id", GIMP_HELP_PALETTE_DIALOG,
"context", gimp_get_user_context (dialog->gimage->gimp),
"select-type", GIMP_TYPE_PALETTE,
"initial-object", theCustomPalette,
"menu-factory", global_menu_factory,
NULL);
g_signal_connect (dialog->palette_select, "destroy",
G_CALLBACK (indexed_palette_select_destroy),
dialog);
g_signal_connect (dialog->palette_select->context, "palette_changed",
G_CALLBACK (indexed_palette_select_changed),
dialog);
}
gtk_window_present (GTK_WINDOW (dialog->palette_select));
}
static void
indexed_palette_select_destroy (GtkWidget *widget,
IndexedDialog *dialog)
{
dialog->palette_select = NULL;
}
static void
indexed_palette_select_palette (GimpContext *context,
indexed_palette_select_changed (GimpContext *context,
GimpPalette *palette,
IndexedDialog *dialog)
{
......@@ -469,30 +502,3 @@ indexed_palette_select_palette (GimpContext *context,
gimp_object_get_name (GIMP_OBJECT (palette)));
}
}
static void
indexed_custom_palette_button_callback (GtkWidget *widget,
IndexedDialog *dialog)
{
if (dialog->palette_select == NULL)
{
dialog->palette_select =
palette_select_new (dialog->gimage->gimp,
gimp_get_user_context (dialog->gimage->gimp),
_("Select Custom Palette"),
GIMP_OBJECT (theCustomPalette)->name,
NULL);
g_signal_connect (dialog->palette_select->shell, "destroy",
G_CALLBACK (indexed_palette_select_destroy_callback),
dialog);
g_signal_connect (dialog->palette_select->context,
"palette_changed",
G_CALLBACK (indexed_palette_select_palette),
dialog);
}
else
{
gtk_window_present (GTK_WINDOW (dialog->palette_select->shell));
}
}
......@@ -5,8 +5,6 @@ noinst_LIBRARIES = libappgui.a
dialogs_sources = \
about-dialog.c \
about-dialog.h \
brush-select.c \
brush-select.h \
color-notebook.c \
color-notebook.h \
convert-dialog.c \
......@@ -25,10 +23,6 @@ dialogs_sources = \
file-open-location-dialog.h \
file-save-dialog.c \
file-save-dialog.h \
font-select.c \
font-select.h \
gradient-select.c \
gradient-select.h \
grid-dialog.h \
grid-dialog.c \
info-dialog.c \
......@@ -41,10 +35,6 @@ dialogs_sources = \
offset-dialog.h \
palette-import-dialog.c \
palette-import-dialog.h \
palette-select.c \
palette-select.h \
pattern-select.c \
pattern-select.h \
preferences-dialog.c \
preferences-dialog.h \
resize-dialog.c \
......
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gui-types.h"
#include "base/temp-buf.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimpdatafactory.h"
#include "pdb/procedural_db.h"
#include "widgets/gimpbrushfactoryview.h"
#include "widgets/gimpcontainerbox.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpwidgets-constructors.h"
#include "menus/menus.h"
#include "brush-select.h"
#include "dialogs-constructors.h"
#include "gimp-intl.h"
/* local function prototypes */
static void brush_select_change_callbacks (BrushSelect *bsp,
gboolean closing);
static void brush_select_brush_changed (GimpContext *context,
GimpBrush *brush,
BrushSelect *bsp);
static void brush_select_opacity_changed (GimpContext *context,
gdouble opacity,
BrushSelect *bsp);
static void brush_select_paint_mode_changed (GimpContext *context,
GimpLayerModeEffects paint_mode,
BrushSelect *bsp);
static void opacity_scale_update (GtkAdjustment *adj,
BrushSelect *bsp);
static void paint_mode_menu_callback (GtkWidget *widget,
BrushSelect *bsp);
static void spacing_scale_update (GtkAdjustment *adj,
BrushSelect *bsp);
static void brush_select_response (GtkWidget *widget,
gint response_id,
BrushSelect *bsp);
/* list of active dialogs */
static GSList *brush_active_dialogs = NULL;
/* public functions */
BrushSelect *
brush_select_new (Gimp *gimp,
GimpContext *context,
const gchar *title,
const gchar *initial_brush,
const gchar *callback_name,
gdouble initial_opacity,
GimpLayerModeEffects initial_mode,
gint initial_spacing)
{
BrushSelect *bsp;
GtkWidget *table;
GtkAdjustment *spacing_adj;
GimpBrush *active = NULL;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (title != NULL, NULL);
if (gimp->no_data)
{
static gboolean first_call = TRUE;
if (first_call)
gimp_data_factory_data_init (gimp->brush_factory, FALSE);
first_call = FALSE;
}
if (initial_brush && strlen (initial_brush))
{
active = (GimpBrush *)
gimp_container_get_child_by_name (gimp->brush_factory->container,
initial_brush);
}
if (! active)
active = gimp_context_get_brush (context);
if (! active)
return NULL;
bsp = g_new0 (BrushSelect, 1);
/* Add to active brush dialogs list */
brush_active_dialogs = g_slist_append (brush_active_dialogs, bsp);
bsp->context = gimp_context_new (gimp, title, NULL);
bsp->callback_name = g_strdup (callback_name);
gimp_context_set_brush (bsp->context, active);
gimp_context_set_paint_mode (bsp->context, initial_mode);
gimp_context_set_opacity (bsp->context, initial_opacity);
bsp->spacing_value = initial_spacing;
g_signal_connect (bsp->context, "brush_changed",
G_CALLBACK (brush_select_brush_changed),
bsp);
g_signal_connect (bsp->context, "opacity_changed",
G_CALLBACK (brush_select_opacity_changed),
bsp);
g_signal_connect (bsp->context, "paint_mode_changed",
G_CALLBACK (brush_select_paint_mode_changed),
bsp);
/* The shell */
bsp->shell = gimp_dialog_new (title, "brush_selection",
NULL, 0,
gimp_standard_help_func,
GIMP_HELP_BRUSH_DIALOG,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
NULL);
g_signal_connect (bsp->shell, "response",
G_CALLBACK (brush_select_response),
bsp);
/* The Brush Grid */
bsp->view = gimp_brush_factory_view_new (GIMP_VIEW_TYPE_GRID,
gimp->brush_factory,
dialogs_edit_brush_func,
bsp->context,
FALSE,
GIMP_PREVIEW_SIZE_MEDIUM, 1,
global_menu_factory);
gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (GIMP_CONTAINER_EDITOR (bsp->view)->view),
5 * (GIMP_PREVIEW_SIZE_MEDIUM + 2),
5 * (GIMP_PREVIEW_SIZE_MEDIUM + 2));
gtk_container_set_border_width (GTK_CONTAINER (bsp->view), 12);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bsp->shell)->vbox), bsp->view);
gtk_widget_show (bsp->view);
/* Create the frame and the table for the options */
table = GIMP_BRUSH_FACTORY_VIEW (bsp->view)->spacing_scale->parent;
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
/* Create the opacity scale widget */
bsp->opacity_data =
GTK_ADJUSTMENT (gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
_("Opacity:"), -1, 5,
gimp_context_get_opacity (bsp->context) * 100.0,
0.0, 100.0, 1.0, 10.0, 1,
TRUE, 0.0, 0.0,
NULL, NULL));
g_signal_connect (bsp->opacity_data, "value_changed",
G_CALLBACK (opacity_scale_update),
bsp);
/* Create the paint mode option menu */
bsp->paint_mode_menu =
gimp_paint_mode_menu_new (G_CALLBACK (paint_mode_menu_callback),
bsp,
TRUE,
gimp_context_get_paint_mode (bsp->context));
gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
_("Mode:"), 0.0, 0.5,
bsp->paint_mode_menu, 2, FALSE);
spacing_adj = GIMP_BRUSH_FACTORY_VIEW (bsp->view)->spacing_adjustment;
/* Use passed spacing instead of brushes default */
if (initial_spacing >= 0)
gtk_adjustment_set_value (spacing_adj, initial_spacing);
g_signal_connect (spacing_adj, "value_changed",
G_CALLBACK (spacing_scale_update),
bsp);
gtk_widget_show (table);
gtk_widget_show (bsp->shell);
return bsp;
}
void
brush_select_free (BrushSelect *bsp)
{
g_return_if_fail (bsp != NULL);
gtk_widget_destroy (bsp->shell);
/* remove from active list */
brush_active_dialogs = g_slist_remove (brush_active_dialogs, bsp);
if (bsp->callback_name)
g_free (bsp->callback_name);
if (bsp->context)
g_object_unref (bsp->context);
g_free (bsp);
}
BrushSelect *
brush_select_get_by_callback (const gchar *callback_name)
{
GSList *list;
for (list = brush_active_dialogs; list; list = g_slist_next (list))
{
BrushSelect *bsp = list->data;
if (bsp->callback_name && ! strcmp (callback_name, bsp->callback_name))
return bsp;
}
return NULL;
}
void
brush_select_dialogs_check (void)
{
GSList *list = brush_active_dialogs;
while (list)
{
BrushSelect *bsp = list->data;
list = g_slist_next (list);
if (bsp->callback_name)
{
if (! procedural_db_lookup (bsp->context->gimp, bsp->callback_name))
brush_select_response (NULL, GTK_RESPONSE_CLOSE, bsp);
}
}
}
/* private functions */
static void
brush_select_change_callbacks (BrushSelect *bsp,
gboolean closing)
{
ProcRecord *proc;
GimpBrush *brush;
static gboolean busy = FALSE;
if (! bsp->callback_name || busy)