edit-commands.c 11.9 KB
Newer Older
Michael Natterer's avatar
Michael Natterer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* 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"

Hans Breuer's avatar
Hans Breuer committed
21 22
#include <string.h>

Michael Natterer's avatar
Michael Natterer committed
23 24
#include <gtk/gtk.h>

25
#include "libgimpbase/gimpbase.h"
Michael Natterer's avatar
Michael Natterer committed
26 27
#include "libgimpwidgets/gimpwidgets.h"

Michael Natterer's avatar
Michael Natterer committed
28
#include "actions-types.h"
Michael Natterer's avatar
Michael Natterer committed
29

30
#include "core/gimp.h"
31
#include "core/gimp-edit.h"
Michael Natterer's avatar
Michael Natterer committed
32 33 34 35
#include "core/gimpbuffer.h"
#include "core/gimpcontainer.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
36
#include "core/gimpimage-undo.h"
Michael Natterer's avatar
Michael Natterer committed
37

38 39
#include "vectors/gimpvectors-import.h"

40
#include "display/gimpdisplay.h"
41 42
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-transform.h"
43

44
#include "widgets/gimpclipboard.h"
45
#include "widgets/gimphelp-ids.h"
Michael Natterer's avatar
Michael Natterer committed
46
#include "widgets/gimpdialogfactory.h"
47 48
#include "widgets/gimpmessagebox.h"
#include "widgets/gimpmessagedialog.h"
Michael Natterer's avatar
Michael Natterer committed
49

50
#include "dialogs/dialogs.h"
Michael Natterer's avatar
Michael Natterer committed
51

52
#include "actions.h"
Michael Natterer's avatar
Michael Natterer committed
53 54
#include "edit-commands.h"

55
#include "gimp-intl.h"
Michael Natterer's avatar
Michael Natterer committed
56 57 58 59


/*  local function prototypes  */

60 61
static void   edit_paste                 (GimpDisplay *gdisp,
                                          gboolean     paste_into);
62
static void   cut_named_buffer_callback  (GtkWidget   *widget,
Michael Natterer's avatar
Michael Natterer committed
63 64
                                          const gchar *name,
                                          gpointer     data);
65
static void   copy_named_buffer_callback (GtkWidget   *widget,
Michael Natterer's avatar
Michael Natterer committed
66 67
                                          const gchar *name,
                                          gpointer     data);
Michael Natterer's avatar
Michael Natterer committed
68 69 70 71 72


/*  public functions  */

void
73
edit_undo_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
74
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
75
{
Michael Natterer's avatar
Michael Natterer committed
76 77
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
78

79
  if (gimp_image_undo (gimage))
80
    gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
81 82 83
}

void
84
edit_redo_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
85
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
86
{
Michael Natterer's avatar
Michael Natterer committed
87 88
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
89

90
  if (gimp_image_redo (gimage))
91
    gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
92 93
}

94 95 96 97 98 99 100
void
edit_undo_clear_cmd_callback (GtkAction *action,
                              gpointer   data)
{
  GimpImage *gimage;
  GtkWidget *widget;
  GtkWidget *dialog;
101
  gchar     *size;
102 103
  gint64     memsize;
  gint64     guisize;
104 105 106
  return_if_no_image (gimage, data);
  return_if_no_widget (widget, data);

107
  dialog = gimp_message_dialog_new (_("Clear Undo History"), GIMP_STOCK_WARNING,
108 109 110
                                    widget,
                                    GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
111 112
                                    gimp_standard_help_func,
                                    GIMP_HELP_EDIT_UNDO_CLEAR,
113 114 115 116 117 118

                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    GTK_STOCK_CLEAR,  GTK_RESPONSE_OK,

                                    NULL);

119 120 121 122 123
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

124
  g_signal_connect_object (gtk_widget_get_toplevel (widget), "unmap",
125 126 127
                           G_CALLBACK (gtk_widget_destroy),
                           dialog, G_CONNECT_SWAPPED);

128 129 130
  g_signal_connect_object (gimage, "disconnect",
                           G_CALLBACK (gtk_widget_destroy),
                           dialog, G_CONNECT_SWAPPED);
131 132 133 134

  gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
                                     _("Really clear image's undo history?"));

135 136 137 138 139 140 141 142 143 144 145 146 147 148
  memsize = gimp_object_get_memsize (GIMP_OBJECT (gimage->undo_stack),
                                     &guisize);
  memsize += guisize;
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->redo_stack),
                                      &guisize);
  memsize += guisize;

  size = gimp_memsize_to_string (memsize);

  gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box,
                             _("Clearing the undo history of this "
                               "image will gain %s of memory."), size);
  g_free (size);

149 150 151 152 153 154 155 156
  if (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK)
    {
      gimp_image_undo_disable (gimage);
      gimp_image_undo_enable (gimage);
      gimp_image_flush (gimage);
    }

  gtk_widget_destroy (dialog);
157 158
}

Michael Natterer's avatar
Michael Natterer committed
159
void
160
edit_cut_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
161
                       gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
162
{
163 164 165
  GimpImage    *gimage;
  GimpDrawable *drawable;
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
166

167
  if (gimp_edit_cut (gimage, drawable, action_data_get_context (data)))
168
    gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
169 170 171
}

void
172
edit_copy_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
173
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
174
{
175 176 177
  GimpImage    *gimage;
  GimpDrawable *drawable;
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
178

179
  if (gimp_edit_copy (gimage, drawable, action_data_get_context (data)))
180
    gimp_image_flush (gimage);
181 182 183 184 185 186 187 188 189 190 191
}

void
edit_copy_visible_cmd_callback (GtkAction *action,
                                gpointer   data)
{
  GimpImage *gimage;
  return_if_no_image (gimage, data);

  if (gimp_edit_copy_visible (gimage, action_data_get_context (data)))
    gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
192 193
}

194
void
195
edit_paste_cmd_callback (GtkAction *action,
196 197
                         gpointer   data)
{
198
  GimpDisplay *gdisp = action_data_get_display (data);
199

200 201 202 203
  if (gdisp)
    edit_paste (gdisp, FALSE);
  else
    edit_paste_as_new_cmd_callback (action, data);
204 205 206
}

void
207
edit_paste_into_cmd_callback (GtkAction *action,
208 209 210 211 212 213 214 215
                              gpointer   data)
{
  GimpDisplay *gdisp;
  return_if_no_display (gdisp, data);

  edit_paste (gdisp, TRUE);
}

Michael Natterer's avatar
Michael Natterer committed
216
void
217
edit_paste_as_new_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
218
                                gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
219
{
220 221
  Gimp       *gimp;
  GimpBuffer *buffer;
222
  return_if_no_gimp (gimp, data);
Michael Natterer's avatar
Michael Natterer committed
223

224
  buffer = gimp_clipboard_get_buffer (gimp);
225 226 227 228 229 230 231

  if (buffer)
    {
      gimp_edit_paste_as_new (gimp, action_data_get_image (data), buffer);

      g_object_unref (buffer);
    }
Michael Natterer's avatar
Michael Natterer committed
232 233 234
}

void
235
edit_named_cut_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
236
                             gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
237
{
238 239
  GimpImage *gimage;
  GtkWidget *widget;
240
  GtkWidget *dialog;
241 242
  return_if_no_image (gimage, data);
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
243

244 245 246 247 248 249 250 251
  dialog = gimp_query_string_box (_("Cut Named"), widget,
                                  gimp_standard_help_func,
                                  GIMP_HELP_BUFFER_CUT,
                                  _("Enter a name for this buffer"),
                                  NULL,
                                  G_OBJECT (gimage), "disconnect",
                                  cut_named_buffer_callback, gimage);
  gtk_widget_show (dialog);
Michael Natterer's avatar
Michael Natterer committed
252 253 254
}

void
255
edit_named_copy_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
256
                              gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
257
{
258 259
  GimpImage *gimage;
  GtkWidget *widget;
260
  GtkWidget *dialog;
261 262
  return_if_no_image (gimage, data);
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
263

264 265 266 267 268 269 270 271
  dialog = gimp_query_string_box (_("Copy Named"), widget,
                                  gimp_standard_help_func,
                                  GIMP_HELP_BUFFER_COPY,
                                  _("Enter a name for this buffer"),
                                  NULL,
                                  G_OBJECT (gimage), "disconnect",
                                  copy_named_buffer_callback, gimage);
  gtk_widget_show (dialog);
Michael Natterer's avatar
Michael Natterer committed
272 273 274
}

void
275
edit_named_paste_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
276
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
277
{
278 279
  GtkWidget *widget;
  return_if_no_widget (widget, data);
280

281
  gimp_dialog_factory_dialog_raise (global_dock_factory,
282
                                    gtk_widget_get_screen (widget),
283
                                    "gimp-buffer-list|gimp-buffer-grid", -1);
Michael Natterer's avatar
Michael Natterer committed
284 285 286
}

void
287
edit_clear_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
288
                         gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
289
{
290 291 292
  GimpImage    *gimage;
  GimpDrawable *drawable;
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
293

294
  gimp_edit_clear (gimage, drawable, action_data_get_context (data));
295
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
296 297 298
}

void
299 300 301
edit_fill_cmd_callback (GtkAction *action,
                        gint       value,
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
302
{
303
  GimpImage    *gimage;
304
  GimpDrawable *drawable;
305
  GimpFillType  fill_type;
306
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
307

308
  fill_type = (GimpFillType) value;
Michael Natterer's avatar
Michael Natterer committed
309

310
  gimp_edit_fill (gimage, drawable, action_data_get_context (data),
311
                  fill_type);
312
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
313 314 315 316 317
}


/*  private functions  */

318 319 320 321
static void
edit_paste (GimpDisplay *gdisp,
            gboolean     paste_into)
{
322 323
  gchar *svg;
  gsize  svg_size;
324

325 326 327
  svg = gimp_clipboard_get_svg (gdisp->gimage->gimp, &svg_size);

  if (svg)
328
    {
329 330 331 332 333
      if (gimp_vectors_import_buffer (gdisp->gimage, svg, svg_size,
                                      TRUE, TRUE, -1, NULL))
        {
          gimp_image_flush (gdisp->gimage);
        }
334

335 336 337 338 339
      g_free (svg);
    }
  else
    {
      GimpBuffer *buffer;
340

341
      buffer = gimp_clipboard_get_buffer (gdisp->gimage->gimp);
342

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
      if (buffer)
        {
          GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (gdisp->shell);
          gint              x, y;
          gint              width, height;

          gimp_display_shell_untransform_viewport (shell,
                                                   &x, &y, &width, &height);

          if (gimp_edit_paste (gdisp->gimage,
                               gimp_image_active_drawable (gdisp->gimage),
                               buffer, paste_into, x, y, width, height))
            {
              gimp_image_flush (gdisp->gimage);
            }

          g_object_unref (buffer);
        }
361 362 363
    }
}

Michael Natterer's avatar
Michael Natterer committed
364
static void
Sven Neumann's avatar
Sven Neumann committed
365
cut_named_buffer_callback (GtkWidget   *widget,
Michael Natterer's avatar
Michael Natterer committed
366 367
                           const gchar *name,
                           gpointer     data)
Michael Natterer's avatar
Michael Natterer committed
368
{
Michael Natterer's avatar
Michael Natterer committed
369
  GimpImage        *gimage = GIMP_IMAGE (data);
370
  const GimpBuffer *cut_buffer;
371
  GimpDrawable     *drawable;
Michael Natterer's avatar
Michael Natterer committed
372

373
  drawable = gimp_image_active_drawable (gimage);
374

375
  if (! drawable)
376 377 378 379 380
    {
      g_message (_("There is no active layer or channel to cut from."));
      return;
    }

381
  cut_buffer = gimp_edit_cut (gimage, drawable,
382
                              gimp_get_user_context (gimage->gimp));
383 384

  if (cut_buffer)
Michael Natterer's avatar
Michael Natterer committed
385
    {
386 387
      GimpBuffer *new_buffer;

388 389 390
      if (! (name && strlen (name)))
        name = _("(Unnamed Buffer)");

391
      new_buffer = gimp_buffer_new (cut_buffer->tiles, name, TRUE);
Michael Natterer's avatar
Michael Natterer committed
392

393 394
      gimp_container_add (gimage->gimp->named_buffers,
                          GIMP_OBJECT (new_buffer));
Michael Natterer's avatar
Michael Natterer committed
395
      g_object_unref (new_buffer);
Michael Natterer's avatar
Michael Natterer committed
396

397 398
      gimp_image_flush (gimage);
    }
Michael Natterer's avatar
Michael Natterer committed
399 400 401
}

static void
402 403 404
copy_named_buffer_callback (GtkWidget   *widget,
			    const gchar *name,
			    gpointer     data)
Michael Natterer's avatar
Michael Natterer committed
405
{
Michael Natterer's avatar
Michael Natterer committed
406
  GimpImage        *gimage = GIMP_IMAGE (data);
407
  const GimpBuffer *copy_buffer;
408
  GimpDrawable     *drawable;
409

410
  drawable = gimp_image_active_drawable (gimage);
411

412
  if (! drawable)
413 414 415 416
    {
      g_message (_("There is no active layer or channel to copy from."));
      return;
    }
Michael Natterer's avatar
Michael Natterer committed
417

418
  copy_buffer = gimp_edit_copy (gimage, drawable,
419
                                gimp_get_user_context (gimage->gimp));
Michael Natterer's avatar
Michael Natterer committed
420

421
  if (copy_buffer)
Michael Natterer's avatar
Michael Natterer committed
422
    {
423 424
      GimpBuffer *new_buffer;

425 426 427
      if (! (name && strlen (name)))
        name = _("(Unnamed Buffer)");

428
      new_buffer = gimp_buffer_new (copy_buffer->tiles, name, TRUE);
Michael Natterer's avatar
Michael Natterer committed
429

430 431
      gimp_container_add (gimage->gimp->named_buffers,
                          GIMP_OBJECT (new_buffer));
Michael Natterer's avatar
Michael Natterer committed
432
      g_object_unref (new_buffer);
433 434

      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
435 436
    }
}