edit-commands.c 11.5 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
#include "display/gimpdisplay.h"
39
40
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-transform.h"
41

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

48
#include "dialogs/dialogs.h"
Michael Natterer's avatar
Michael Natterer committed
49

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

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


/*  local function prototypes  */

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


/*  public functions  */

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

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

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

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

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

108
109
110
111
112
113
114
115
116
  dialog = gimp_message_dialog_new (_("Clear Undo History"), GIMP_STOCK_WARNING,
                                    widget, 0,
                                    gimp_standard_help_func, NULL,

                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    GTK_STOCK_CLEAR,  GTK_RESPONSE_OK,

                                    NULL);

117
118
119
120
121
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

122
123
124
125
126
127
128
129
130
131
132
  g_signal_connect_object (gimage, "disconnect",
                           G_CALLBACK (gtk_widget_destroy),
                           dialog, G_CONNECT_SWAPPED);

  g_signal_connect (dialog, "response",
                    G_CALLBACK (edit_undo_clear_response),
                    gimage);

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

133
134
135
136
137
138
139
140
141
142
143
144
145
146
  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);

147
148
149
  gtk_widget_show (dialog);
}

Michael Natterer's avatar
Michael Natterer committed
150
void
151
edit_cut_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
152
                       gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
153
{
154
155
156
  GimpImage    *gimage;
  GimpDrawable *drawable;
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
157

158
  if (gimp_edit_cut (gimage, drawable, action_data_get_context (data)))
159
    gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
160
161
162
}

void
163
edit_copy_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
164
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
165
{
166
167
168
  GimpImage    *gimage;
  GimpDrawable *drawable;
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
169

170
  if (gimp_edit_copy (gimage, drawable, action_data_get_context (data)))
171
    gimp_image_flush (gimage);
172
173
174
175
176
177
178
179
180
181
182
}

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
183
184
}

185
void
186
edit_paste_cmd_callback (GtkAction *action,
187
188
189
190
191
192
193
194
195
                         gpointer   data)
{
  GimpDisplay *gdisp;
  return_if_no_display (gdisp, data);

  edit_paste (gdisp, FALSE);
}

void
196
edit_paste_into_cmd_callback (GtkAction *action,
197
198
199
200
201
202
203
204
                              gpointer   data)
{
  GimpDisplay *gdisp;
  return_if_no_display (gdisp, data);

  edit_paste (gdisp, TRUE);
}

Michael Natterer's avatar
Michael Natterer committed
205
void
206
edit_paste_as_new_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
207
                                gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
208
{
209
210
  Gimp       *gimp;
  GimpBuffer *buffer;
211
  return_if_no_gimp (gimp, data);
Michael Natterer's avatar
Michael Natterer committed
212

213
  buffer = gimp_clipboard_get_buffer (gimp);
214
215
216
217
218
219
220

  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
221
222
223
}

void
224
edit_named_cut_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
225
                             gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
226
{
227
228
  GimpImage *gimage;
  GtkWidget *widget;
229
  GtkWidget *dialog;
230
231
  return_if_no_image (gimage, data);
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
232

233
234
235
236
237
238
239
240
  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
241
242
243
}

void
244
edit_named_copy_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
245
                              gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
246
{
247
248
  GimpImage *gimage;
  GtkWidget *widget;
249
  GtkWidget *dialog;
250
251
  return_if_no_image (gimage, data);
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
252

253
254
255
256
257
258
259
260
  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
261
262
263
}

void
264
edit_named_paste_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
265
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
266
{
267
268
  GtkWidget *widget;
  return_if_no_widget (widget, data);
269

270
  gimp_dialog_factory_dialog_raise (global_dock_factory,
271
                                    gtk_widget_get_screen (widget),
272
                                    "gimp-buffer-list|gimp-buffer-grid", -1);
Michael Natterer's avatar
Michael Natterer committed
273
274
275
}

void
276
edit_clear_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
277
                         gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
278
{
279
280
281
  GimpImage    *gimage;
  GimpDrawable *drawable;
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
282

283
  gimp_edit_clear (gimage, drawable, action_data_get_context (data));
284
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
285
286
287
}

void
288
289
290
edit_fill_cmd_callback (GtkAction *action,
                        gint       value,
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
291
{
292
  GimpImage    *gimage;
293
  GimpDrawable *drawable;
294
  GimpFillType  fill_type;
295
  return_if_no_drawable (gimage, drawable, data);
Michael Natterer's avatar
Michael Natterer committed
296

297
  fill_type = (GimpFillType) value;
Michael Natterer's avatar
Michael Natterer committed
298

299
  gimp_edit_fill (gimage, drawable, action_data_get_context (data),
300
                  fill_type);
301
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
302
303
304
305
306
}


/*  private functions  */

307
308
309
310
static void
edit_paste (GimpDisplay *gdisp,
            gboolean     paste_into)
{
311
  GimpBuffer *buffer = gimp_clipboard_get_buffer (gdisp->gimage->gimp);
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

  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);
    }
}

static void
333
334
335
edit_undo_clear_response (GtkWidget *dialog,
                          gint       response_id,
                          GimpImage *gimage)
336
{
337
  gtk_widget_destroy (dialog);
338

339
340
  if (response_id == GTK_RESPONSE_OK)
    {
341
342
343
344
345
346
      gimp_image_undo_disable (gimage);
      gimp_image_undo_enable (gimage);
      gimp_image_flush (gimage);
    }
}

Michael Natterer's avatar
Michael Natterer committed
347
static void
Sven Neumann's avatar
Sven Neumann committed
348
cut_named_buffer_callback (GtkWidget   *widget,
Michael Natterer's avatar
Michael Natterer committed
349
350
                           const gchar *name,
                           gpointer     data)
Michael Natterer's avatar
Michael Natterer committed
351
{
Michael Natterer's avatar
Michael Natterer committed
352
  GimpImage        *gimage = GIMP_IMAGE (data);
353
  const GimpBuffer *cut_buffer;
354
  GimpDrawable     *drawable;
Michael Natterer's avatar
Michael Natterer committed
355

356
  drawable = gimp_image_active_drawable (gimage);
357

358
  if (! drawable)
359
360
361
362
363
    {
      g_message (_("There is no active layer or channel to cut from."));
      return;
    }

364
  cut_buffer = gimp_edit_cut (gimage, drawable,
365
                              gimp_get_user_context (gimage->gimp));
366
367

  if (cut_buffer)
Michael Natterer's avatar
Michael Natterer committed
368
    {
369
370
      GimpBuffer *new_buffer;

371
372
373
      if (! (name && strlen (name)))
        name = _("(Unnamed Buffer)");

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

376
377
      gimp_container_add (gimage->gimp->named_buffers,
                          GIMP_OBJECT (new_buffer));
Michael Natterer's avatar
Michael Natterer committed
378
      g_object_unref (new_buffer);
Michael Natterer's avatar
Michael Natterer committed
379

380
381
      gimp_image_flush (gimage);
    }
Michael Natterer's avatar
Michael Natterer committed
382
383
384
}

static void
385
386
387
copy_named_buffer_callback (GtkWidget   *widget,
			    const gchar *name,
			    gpointer     data)
Michael Natterer's avatar
Michael Natterer committed
388
{
Michael Natterer's avatar
Michael Natterer committed
389
  GimpImage        *gimage = GIMP_IMAGE (data);
390
  const GimpBuffer *copy_buffer;
391
  GimpDrawable     *drawable;
392

393
  drawable = gimp_image_active_drawable (gimage);
394

395
  if (! drawable)
396
397
398
399
    {
      g_message (_("There is no active layer or channel to copy from."));
      return;
    }
Michael Natterer's avatar
Michael Natterer committed
400

401
  copy_buffer = gimp_edit_copy (gimage, drawable,
402
                                gimp_get_user_context (gimage->gimp));
Michael Natterer's avatar
Michael Natterer committed
403

404
  if (copy_buffer)
Michael Natterer's avatar
Michael Natterer committed
405
    {
406
407
      GimpBuffer *new_buffer;

408
409
410
      if (! (name && strlen (name)))
        name = _("(Unnamed Buffer)");

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

413
414
      gimp_container_add (gimage->gimp->named_buffers,
                          GIMP_OBJECT (new_buffer));
Michael Natterer's avatar
Michael Natterer committed
415
      g_object_unref (new_buffer);
416
417

      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
418
419
    }
}