gimp/app/gui/image-commands.c

442 lines
10 KiB
C
Raw Normal View History

app/Makefile.am removed. 2001-06-26 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/color_transfer.[ch]: removed. * app/tools/Makefile.am * app/tools/gimpcolorbalancetool-transfer.[ch]: added. * app/tools/gimpcolorbalancetool.c: changed accordingly. * app/base/Makefile.am * app/base/tile-manager-crop.[ch]: formerly known as crop_buffer(). * app/tools/gimptexttool.c: changed accordingly. * app/context_manager.[ch]: added the global clipboard and the named buffer list here. * app/app_procs.c: don't call color_transfer_init() and don't free the buffer stuff (done by the context manager now). * app/errorconsole.c: don't #include "gui/commands.h" * app/global_edit.[ch]: removed lots of stuff which is now done by gui/edit-commands.* or the new GimpBuffer object. The "paste named" dialog will go away and this file will be moved to core/ soon. * app/image_new.c: no need to declare the global_buffer extern any more. * app/qmask.c: don't #include "global_edit.h" * app/core/Makefile.am * app/core/core-types.h * app/core/gimpbuffer.[ch]: new object (aka named buffer) * app/core/gimpcontext.[ch]: added a GimpBuffer attribute. * app/core/gimpimage.[ch]: one s/int/gboolean/. * app/core/gimppattern.c: hmm... * app/gui/commands.[ch]: split up in small files: * app/gui/Makefile.am * app/gui/edit-commands.[ch] * app/gui/file-commands.[ch] * app/gui/image-commands.[ch] * app/gui/select-commands.[ch] * app/gui/view-commands.[ch]: new files. * app/gui/dialogs-constructors.[ch] * app/gui/dialogs.c: added the named buffer list & grid. * app/gui/file-new-dialog.[ch] * app/gui/menus.c * app/gui/palette-editor.c * app/gui/test-commands.c: changed accordingly. * app/pdb/edit_cmds.c * tools/pdbgen/pdb/edit.pdb: changed for the global_edit stuff. * app/widgets/Makefile.am * app/widgets/gimpbufferpreview.[ch] * app/widgets/gimpbufferview.[ch] * app/widgets/gimpcontainereditor.[ch]: new widgets. * app/widgets/gimpcontainerview-utils.c * app/widgets/gimpdatafactoryview.[ch] * app/widgets/gimpdnd.[ch] * app/widgets/gimpdrawablepreview.c * app/widgets/gimplayerlistview.c * app/widgets/gimppreview.c * app/widgets/widgets-types.h: changed accordingly for the new GimpBuffer object and it's views, misc. cleanups. * pixmaps/Makefile.am * pixmaps/paste-as-new.xpm * pixmaps/paste-into.xpm * pixmaps/paste.xpm: new pixmaps (they all look the same... Tigert? ;-) * po/POTFILES.in: added the new files.
2001-06-26 20:09:43 +08:00
/* 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 <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "core/core-types.h"
#include "core/gimpdrawable.h"
#include "core/gimpdrawable-desaturate.h"
#include "core/gimpdrawable-equalize.h"
#include "core/gimpimage.h"
#include "core/gimpimage-duplicate.h"
#include "pdb/procedural_db.h"
#include "convert-dialog.h"
#include "offset-dialog.h"
#include "resize-dialog.h"
#include "gdisplay.h"
#include "undo.h"
#include "libgimp/gimpintl.h"
#define return_if_no_display(gdisp) \
gdisp = gdisplay_active (); \
if (!gdisp) return
/* local functions */
static void image_resize_callback (GtkWidget *widget,
gpointer data);
static void image_scale_callback (GtkWidget *widget,
gpointer data);
static void image_scale_warn_callback (GtkWidget *widget,
gboolean do_scale,
gpointer data);
static void image_scale_implement (ImageResize *image_scale);
/* public functions */
void
image_convert_rgb_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
convert_to_rgb (gdisp->gimage);
}
void
image_convert_grayscale_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
convert_to_grayscale (gdisp->gimage);
}
void
image_convert_indexed_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
convert_to_indexed (gdisp->gimage);
}
void
image_desaturate_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
GimpDrawable *drawable;
return_if_no_display (gdisp);
drawable = gimp_image_active_drawable (gdisp->gimage);
if (! gimp_drawable_is_rgb (drawable))
{
g_message (_("Desaturate operates only on RGB color drawables."));
return;
}
gimp_drawable_desaturate (drawable);
gdisplays_flush ();
}
void
image_invert_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
GimpDrawable *drawable;
Argument *return_vals;
gint nreturn_vals;
return_if_no_display (gdisp);
drawable = gimp_image_active_drawable (gdisp->gimage);
if (gimp_drawable_is_indexed (drawable))
{
g_message (_("Invert does not operate on indexed drawables."));
return;
}
return_vals =
app/core/Makefile.am app/core/core-types.h added an "application object" 2001-07-04 Michael Natterer <mitch@gimp.org> * app/core/Makefile.am * app/core/core-types.h * app/core/gimp.[ch]: added an "application object" called Gimp. Currently, it contains the image list, the clipboard, the data factories, the procedural hashtable and the tool info list. It's the toplevel object of the core object system. Finally, creating a Gimp object will return a standalone gimp core engine instance with no other global states/variables involved. * app/app_procs.[ch]: allocate a "Gimp" instance called "the_gimp" :) Removed stuff which is now done by the "Gimp" object. Merged gimp_init() into app_init() because gimp_init() is taken now. * app/context_manager.[ch]: removed stuff done by "Gimp". * app/batch.[ch] * app/gimage.[ch] * app/xcf/xcf-load.[ch] * app/xcf/xcf.[ch] * app/core/gimpedit.[ch] * app/tools/tool_manager.[ch]: pass around an additional "Gimp" argument. * app/pdb/procedural_db.[ch]: pass a "Gimp" pointer as first parameter to all internal procedures and to all procedural_db_* functions. * app/core/gimpcontext.[ch] * app/core/gimpimage.[ch]: added a "Gimp" pointer to the structs. * app/devices.c * app/errors.c * app/file-open.c * app/file-save.c * app/gimphelp.c * app/gimpunit.c * app/image_new.c * app/main.c * app/nav_window.c * app/plug_in.c * app/base/base.c * app/core/gimpdatafactory.c * app/core/gimpimage-duplicate.c * app/core/gimpimage-mask.c * app/core/gimptoolinfo.[ch] * app/gui/brush-select.c * app/gui/convert-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/file-open-dialog.c * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/gradient-select.c * app/gui/gui.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/menus.c * app/gui/palette-editor.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/paths-dialog.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/test-commands.c * app/gui/toolbox.c * app/gui/tools-commands.c * app/tools/gimpbezierselecttool.c * app/tools/gimpbucketfilltool.c * app/tools/gimppainttool.h * app/tools/gimptexttool.c * app/tools/gimptransformtool.h * app/widgets/gimpbufferview.c * app/widgets/gimpcontainerview-utils.c * app/widgets/gimpcursor.c * app/widgets/gimpdnd.c * app/widgets/gimpimagedock.c: changed accordingly. Cleaned up lots of includes. Many files still access the global "the_gimp" variable exported by app_procs.h. * tools/pdbgen/app.pl * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/edit.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/palette.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/procedural_db.pdb: changed accordingly. Don't use "the_gimp" here because all procedures get passed a "Gimp" pointer now. * app/pdb/*: regenerated.
2001-07-05 03:31:35 +08:00
procedural_db_run_proc (gdisp->gimage->gimp,
"gimp_invert",
app/Makefile.am removed. 2001-06-26 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/color_transfer.[ch]: removed. * app/tools/Makefile.am * app/tools/gimpcolorbalancetool-transfer.[ch]: added. * app/tools/gimpcolorbalancetool.c: changed accordingly. * app/base/Makefile.am * app/base/tile-manager-crop.[ch]: formerly known as crop_buffer(). * app/tools/gimptexttool.c: changed accordingly. * app/context_manager.[ch]: added the global clipboard and the named buffer list here. * app/app_procs.c: don't call color_transfer_init() and don't free the buffer stuff (done by the context manager now). * app/errorconsole.c: don't #include "gui/commands.h" * app/global_edit.[ch]: removed lots of stuff which is now done by gui/edit-commands.* or the new GimpBuffer object. The "paste named" dialog will go away and this file will be moved to core/ soon. * app/image_new.c: no need to declare the global_buffer extern any more. * app/qmask.c: don't #include "global_edit.h" * app/core/Makefile.am * app/core/core-types.h * app/core/gimpbuffer.[ch]: new object (aka named buffer) * app/core/gimpcontext.[ch]: added a GimpBuffer attribute. * app/core/gimpimage.[ch]: one s/int/gboolean/. * app/core/gimppattern.c: hmm... * app/gui/commands.[ch]: split up in small files: * app/gui/Makefile.am * app/gui/edit-commands.[ch] * app/gui/file-commands.[ch] * app/gui/image-commands.[ch] * app/gui/select-commands.[ch] * app/gui/view-commands.[ch]: new files. * app/gui/dialogs-constructors.[ch] * app/gui/dialogs.c: added the named buffer list & grid. * app/gui/file-new-dialog.[ch] * app/gui/menus.c * app/gui/palette-editor.c * app/gui/test-commands.c: changed accordingly. * app/pdb/edit_cmds.c * tools/pdbgen/pdb/edit.pdb: changed for the global_edit stuff. * app/widgets/Makefile.am * app/widgets/gimpbufferpreview.[ch] * app/widgets/gimpbufferview.[ch] * app/widgets/gimpcontainereditor.[ch]: new widgets. * app/widgets/gimpcontainerview-utils.c * app/widgets/gimpdatafactoryview.[ch] * app/widgets/gimpdnd.[ch] * app/widgets/gimpdrawablepreview.c * app/widgets/gimplayerlistview.c * app/widgets/gimppreview.c * app/widgets/widgets-types.h: changed accordingly for the new GimpBuffer object and it's views, misc. cleanups. * pixmaps/Makefile.am * pixmaps/paste-as-new.xpm * pixmaps/paste-into.xpm * pixmaps/paste.xpm: new pixmaps (they all look the same... Tigert? ;-) * po/POTFILES.in: added the new files.
2001-06-26 20:09:43 +08:00
&nreturn_vals,
GIMP_PDB_DRAWABLE, gimp_drawable_get_ID (drawable),
GIMP_PDB_END);
if (!return_vals || return_vals[0].value.pdb_int != GIMP_PDB_SUCCESS)
g_message (_("Invert operation failed."));
procedural_db_destroy_args (return_vals, nreturn_vals);
gdisplays_flush ();
}
void
image_equalize_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
GimpDrawable *drawable;
return_if_no_display (gdisp);
drawable = gimp_image_active_drawable (gdisp->gimage);
if (gimp_drawable_is_indexed (drawable))
{
g_message (_("Equalize does not operate on indexed drawables."));
return;
}
gimp_drawable_equalize (drawable, TRUE);
gdisplays_flush ();
}
void
image_offset_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
offset_dialog_create (gdisp->gimage);
}
void
image_resize_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
GimpImage *gimage;
ImageResize *image_resize;
return_if_no_display (gdisp);
gimage = gdisp->gimage;
image_resize = g_new0 (ImageResize, 1);
image_resize->gimage = gimage;
image_resize->resize = resize_widget_new (ResizeWidget,
ResizeImage,
GTK_OBJECT (gimage),
"destroy",
gimage->width,
gimage->height,
gimage->xresolution,
gimage->yresolution,
gimage->unit,
gdisp->dot_for_dot,
image_resize_callback,
NULL,
image_resize);
gtk_signal_connect_object (GTK_OBJECT (image_resize->resize->resize_shell),
"destroy",
GTK_SIGNAL_FUNC (g_free),
(GtkObject *) image_resize);
gtk_widget_show (image_resize->resize->resize_shell);
}
void
image_scale_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
GimpImage *gimage;
ImageResize *image_scale;
return_if_no_display (gdisp);
gimage = gdisp->gimage;
image_scale = g_new0 (ImageResize, 1);
image_scale->gimage = gimage;
image_scale->resize = resize_widget_new (ScaleWidget,
ResizeImage,
GTK_OBJECT (gimage),
"destroy",
gimage->width,
gimage->height,
gimage->xresolution,
gimage->yresolution,
gimage->unit,
gdisp->dot_for_dot,
image_scale_callback,
NULL,
image_scale);
gtk_signal_connect_object (GTK_OBJECT (image_scale->resize->resize_shell),
"destroy",
GTK_SIGNAL_FUNC (g_free),
(GtkObject *) image_scale);
gtk_widget_show (image_scale->resize->resize_shell);
}
void
image_duplicate_cmd_callback (GtkWidget *widget,
gpointer data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
gdisplay_new (gimp_image_duplicate (gdisp->gimage), 0x0101);
}
/* private functions */
static void
image_resize_callback (GtkWidget *widget,
gpointer data)
{
ImageResize *image_resize;
image_resize = (ImageResize *) data;
g_assert (image_resize != NULL);
g_assert (image_resize->gimage != NULL);
gtk_widget_set_sensitive (image_resize->resize->resize_shell, FALSE);
if (image_resize->resize->width > 0 &&
image_resize->resize->height > 0)
{
gimp_image_resize (image_resize->gimage,
image_resize->resize->width,
image_resize->resize->height,
image_resize->resize->offset_x,
image_resize->resize->offset_y);
gdisplays_flush ();
}
else
{
g_message (_("Resize Error: Both width and height must be "
"greater than zero."));
}
gtk_widget_destroy (image_resize->resize->resize_shell);
}
static void
image_scale_callback (GtkWidget *widget,
gpointer data)
{
ImageResize *image_scale;
image_scale = (ImageResize *) data;
g_assert (image_scale != NULL);
g_assert (image_scale->gimage != NULL);
gtk_widget_set_sensitive (image_scale->resize->resize_shell, FALSE);
if (gimp_image_check_scaling (image_scale->gimage,
image_scale->resize->width,
image_scale->resize->height))
{
image_scale_implement (image_scale);
gtk_widget_destroy (image_scale->resize->resize_shell);
}
else
{
GtkWidget *dialog;
dialog =
gimp_query_boolean_box (_("Layer Too Small"),
gimp_standard_help_func,
"dialogs/scale_layer_warn.html",
FALSE,
_("The chosen image size will shrink\n"
"some layers completely away.\n"
"Is this what you want?"),
_("OK"), _("Cancel"),
GTK_OBJECT (image_scale->resize->resize_shell),
"destroy",
image_scale_warn_callback,
image_scale);
gtk_widget_show (dialog);
}
}
static void
image_scale_warn_callback (GtkWidget *widget,
gboolean do_scale,
gpointer data)
{
ImageResize *image_scale;
GimpImage *gimage;
image_scale = (ImageResize *) data;
gimage = image_scale->gimage;
if (do_scale) /* User doesn't mind losing layers... */
{
image_scale_implement (image_scale);
gtk_widget_destroy (image_scale->resize->resize_shell);
}
else
{
gtk_widget_set_sensitive (image_scale->resize->resize_shell, TRUE);
}
}
static void
image_scale_implement (ImageResize *image_scale)
{
GimpImage *gimage = NULL;
gboolean rulers_flush = FALSE;
gboolean display_flush = FALSE; /* this is a bit ugly:
we hijack the flush variable
to check if an undo_group was
already started */
g_assert (image_scale != NULL);
g_assert (image_scale->gimage != NULL);
gimage = image_scale->gimage;
if (image_scale->resize->resolution_x != gimage->xresolution ||
image_scale->resize->resolution_y != gimage->yresolution)
{
undo_push_group_start (gimage, IMAGE_SCALE_UNDO);
gimp_image_set_resolution (gimage,
image_scale->resize->resolution_x,
image_scale->resize->resolution_y);
rulers_flush = TRUE;
display_flush = TRUE;
}
if (image_scale->resize->unit != gimage->unit)
{
if (!display_flush)
undo_push_group_start (gimage, IMAGE_SCALE_UNDO);
gimp_image_set_unit (gimage, image_scale->resize->unit);
gdisplays_setup_scale (gimage);
gdisplays_resize_cursor_label (gimage);
rulers_flush = TRUE;
display_flush = TRUE;
}
if (image_scale->resize->width != gimage->width ||
image_scale->resize->height != gimage->height)
{
if (image_scale->resize->width > 0 &&
image_scale->resize->height > 0)
{
if (!display_flush)
undo_push_group_start (gimage, IMAGE_SCALE_UNDO);
gimp_image_scale (gimage,
image_scale->resize->width,
image_scale->resize->height);
display_flush = TRUE;
}
else
{
g_message (_("Scale Error: Both width and height must be "
"greater than zero."));
return;
}
}
if (rulers_flush)
{
gdisplays_setup_scale (gimage);
gdisplays_resize_cursor_label (gimage);
}
if (display_flush)
{
undo_push_group_end (gimage);
gdisplays_flush ();
}
}