edit-cmds.c 73.6 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2
 * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
Elliot Lee's avatar
Elliot Lee committed
3
 *
4
 * This program is free software: you can redistribute it and/or modify
Elliot Lee's avatar
Elliot Lee committed
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
Elliot Lee's avatar
Elliot Lee committed
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
Manish Singh's avatar
Manish Singh committed
17

18
/* NOTE: This file is auto-generated by pdbgen.pl. */
Manish Singh's avatar
Manish Singh committed
19

20 21
#include "config.h"

22
#include <string.h>
23

24
#include <gegl.h>
Manish Singh's avatar
Manish Singh committed
25

26
#include "pdb-types.h"
27

28
#include "core/gimp-edit.h"
29
#include "core/gimp.h"
30 31 32
#include "core/gimpchannel.h"
#include "core/gimpdrawable-blend.h"
#include "core/gimpdrawable-bucket-fill.h"
Michael Natterer's avatar
Michael Natterer committed
33
#include "core/gimpdrawable.h"
34
#include "core/gimpimage-new.h"
35
#include "core/gimpimage.h"
36
#include "core/gimplayer.h"
37
#include "core/gimpparamspecs.h"
38
#include "core/gimpprogress.h"
39
#include "core/gimpstrokeoptions.h"
40
#include "vectors/gimpvectors.h"
Elliot Lee's avatar
Elliot Lee committed
41

42 43 44
#include "gimppdb.h"
#include "gimppdb-utils.h"
#include "gimpprocedure.h"
45
#include "internal-procs.h"
46

47 48
#include "gimp-intl.h"

Elliot Lee's avatar
Elliot Lee committed
49

50
static GValueArray *
51 52 53 54 55 56
edit_cut_invoker (GimpProcedure      *procedure,
                  Gimp               *gimp,
                  GimpContext        *context,
                  GimpProgress       *progress,
                  const GValueArray  *args,
                  GError            **error)
Elliot Lee's avatar
Elliot Lee committed
57
{
Manish Singh's avatar
Manish Singh committed
58
  gboolean success = TRUE;
59
  GValueArray *return_vals;
60
  GimpDrawable *drawable;
61
  gboolean non_empty = FALSE;
Elliot Lee's avatar
Elliot Lee committed
62

63
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
Elliot Lee's avatar
Elliot Lee committed
64 65 66

  if (success)
    {
67
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
68
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
69
        {
70 71 72 73
          GimpImage *image    = gimp_item_get_image (GIMP_ITEM (drawable));
          GError    *my_error = NULL;

          non_empty = gimp_edit_cut (image, drawable, context, &my_error) != NULL;
74

75 76
          if (! non_empty)
            {
77 78 79
              gimp_message_literal (gimp,
                                    G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                    my_error->message);
80 81
              g_clear_error (&my_error);
            }
82
        }
83 84
      else
        success = FALSE;
Elliot Lee's avatar
Elliot Lee committed
85 86
    }

87 88
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
89 90

  if (success)
91
    g_value_set_boolean (&return_vals->values[1], non_empty);
92

93
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
94 95
}

96
static GValueArray *
97 98 99 100 101 102
edit_copy_invoker (GimpProcedure      *procedure,
                   Gimp               *gimp,
                   GimpContext        *context,
                   GimpProgress       *progress,
                   const GValueArray  *args,
                   GError            **error)
Elliot Lee's avatar
Elliot Lee committed
103
{
Manish Singh's avatar
Manish Singh committed
104
  gboolean success = TRUE;
105
  GValueArray *return_vals;
106
  GimpDrawable *drawable;
107
  gboolean non_empty = FALSE;
Elliot Lee's avatar
Elliot Lee committed
108

109
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
Elliot Lee's avatar
Elliot Lee committed
110 111 112

  if (success)
    {
113
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, FALSE, error))
114
        {
115 116
          GimpImage *image    = gimp_item_get_image (GIMP_ITEM (drawable));
          GError    *my_error = NULL;
117

118 119 120 121
          non_empty = gimp_edit_copy (image, drawable, context, &my_error) != NULL;

          if (! non_empty)
            {
122 123 124
              gimp_message_literal (gimp,
                                    G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                    my_error->message);
125 126
              g_clear_error (&my_error);
            }
127
        }
128 129
      else
        success = FALSE;
Elliot Lee's avatar
Elliot Lee committed
130 131
    }

132 133
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
134 135

  if (success)
136
    g_value_set_boolean (&return_vals->values[1], non_empty);
137

138
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
139 140
}

141
static GValueArray *
142 143 144 145 146 147
edit_copy_visible_invoker (GimpProcedure      *procedure,
                           Gimp               *gimp,
                           GimpContext        *context,
                           GimpProgress       *progress,
                           const GValueArray  *args,
                           GError            **error)
148 149
{
  gboolean success = TRUE;
150
  GValueArray *return_vals;
151 152 153
  GimpImage *image;
  gboolean non_empty = FALSE;

154
  image = gimp_value_get_image (&args->values[0], gimp);
155 156 157

  if (success)
    {
158 159 160 161 162 163
      GError *my_error = NULL;

      non_empty = gimp_edit_copy_visible (image, context, &my_error) != NULL;

      if (! non_empty)
        {
164 165 166
          gimp_message_literal (gimp,
                                G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                my_error->message);
167 168
          g_clear_error (&my_error);
        }
169 170
    }

171 172
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
173 174

  if (success)
175
    g_value_set_boolean (&return_vals->values[1], non_empty);
176

177
  return return_vals;
178 179
}

180
static GValueArray *
181 182 183 184 185 186
edit_paste_invoker (GimpProcedure      *procedure,
                    Gimp               *gimp,
                    GimpContext        *context,
                    GimpProgress       *progress,
                    const GValueArray  *args,
                    GError            **error)
Elliot Lee's avatar
Elliot Lee committed
187
{
Manish Singh's avatar
Manish Singh committed
188
  gboolean success = TRUE;
189
  GValueArray *return_vals;
190
  GimpDrawable *drawable;
Manish Singh's avatar
Manish Singh committed
191
  gboolean paste_into;
192
  GimpLayer *floating_sel = NULL;
Elliot Lee's avatar
Elliot Lee committed
193

194 195
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  paste_into = g_value_get_boolean (&args->values[1]);
Elliot Lee's avatar
Elliot Lee committed
196 197 198

  if (success)
    {
199
      if (gimp->global_buffer &&
200
          gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
201
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
202
        {
203 204 205
          floating_sel = gimp_edit_paste (gimp_item_get_image (GIMP_ITEM (drawable)),
                                          drawable, gimp->global_buffer,
                                          paste_into, -1, -1, -1, -1);
206

207
          if (! floating_sel)
208 209
            success = FALSE;
        }
210 211
      else
        success = FALSE;
Elliot Lee's avatar
Elliot Lee committed
212 213
    }

214 215
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
Elliot Lee's avatar
Elliot Lee committed
216

Manish Singh's avatar
Manish Singh committed
217
  if (success)
218
    gimp_value_set_layer (&return_vals->values[1], floating_sel);
Elliot Lee's avatar
Elliot Lee committed
219

220
  return return_vals;
Elliot Lee's avatar
Elliot Lee committed
221 222
}

223
static GValueArray *
224 225 226 227 228 229
edit_paste_as_new_invoker (GimpProcedure      *procedure,
                           Gimp               *gimp,
                           GimpContext        *context,
                           GimpProgress       *progress,
                           const GValueArray  *args,
                           GError            **error)
230 231
{
  gboolean success = TRUE;
232
  GValueArray *return_vals;
233 234
  GimpImage *image = NULL;

235
  if (gimp->global_buffer)
236
    {
237
      image = gimp_image_new_from_buffer (gimp, NULL, gimp->global_buffer);
238

239 240 241
      if (! image)
        success = FALSE;
    }
242
  else
243 244 245
    {
      image = NULL;
    }
246

247 248
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
249 250

  if (success)
251
    gimp_value_set_image (&return_vals->values[1], image);
252

253
  return return_vals;
254 255
}

256
static GValueArray *
257 258 259 260 261 262
edit_named_cut_invoker (GimpProcedure      *procedure,
                        Gimp               *gimp,
                        GimpContext        *context,
                        GimpProgress       *progress,
                        const GValueArray  *args,
                        GError            **error)
263 264
{
  gboolean success = TRUE;
265
  GValueArray *return_vals;
266
  GimpDrawable *drawable;
267
  const gchar *buffer_name;
268 269
  gchar *real_name = NULL;

270 271
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  buffer_name = g_value_get_string (&args->values[1]);
272 273 274

  if (success)
    {
275
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
276
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
277
        {
278 279 280 281 282 283 284 285 286 287 288 289
          GimpImage *image    = gimp_item_get_image (GIMP_ITEM (drawable));
          GError    *my_error = NULL;

          real_name = (gchar *) gimp_edit_named_cut (image, buffer_name,
                                                     drawable, context, &my_error);

          if (real_name)
            {
              real_name = g_strdup (real_name);
            }
          else
            {
290 291 292
              gimp_message_literal (gimp,
                                    G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                    my_error->message);
293 294
              g_clear_error (&my_error);
            }
295 296 297
        }
      else
        success = FALSE;
298 299
    }

300 301
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
302 303

  if (success)
304
    g_value_take_string (&return_vals->values[1], real_name);
305

306
  return return_vals;
307 308
}

309
static GValueArray *
310 311 312 313 314 315
edit_named_copy_invoker (GimpProcedure      *procedure,
                         Gimp               *gimp,
                         GimpContext        *context,
                         GimpProgress       *progress,
                         const GValueArray  *args,
                         GError            **error)
316 317
{
  gboolean success = TRUE;
318
  GValueArray *return_vals;
319
  GimpDrawable *drawable;
320
  const gchar *buffer_name;
321 322
  gchar *real_name = NULL;

323 324
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  buffer_name = g_value_get_string (&args->values[1]);
325 326 327

  if (success)
    {
328
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, FALSE, error))
329
        {
330 331 332 333 334 335 336 337 338 339 340 341
          GimpImage *image    = gimp_item_get_image (GIMP_ITEM (drawable));
          GError    *my_error = NULL;

          real_name = (gchar *) gimp_edit_named_copy (image, buffer_name,
                                                      drawable, context, &my_error);

          if (real_name)
            {
              real_name = g_strdup (real_name);
            }
          else
            {
342 343 344
              gimp_message_literal (gimp,
                                    G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                    my_error->message);
345 346
              g_clear_error (&my_error);
            }
347 348 349
        }
      else
        success = FALSE;
350 351
    }

352 353
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
354 355

  if (success)
356
    g_value_take_string (&return_vals->values[1], real_name);
357

358
  return return_vals;
359 360
}

361
static GValueArray *
362 363 364 365 366 367
edit_named_copy_visible_invoker (GimpProcedure      *procedure,
                                 Gimp               *gimp,
                                 GimpContext        *context,
                                 GimpProgress       *progress,
                                 const GValueArray  *args,
                                 GError            **error)
368 369
{
  gboolean success = TRUE;
370
  GValueArray *return_vals;
371
  GimpImage *image;
372
  const gchar *buffer_name;
373 374
  gchar *real_name = NULL;

375 376
  image = gimp_value_get_image (&args->values[0], gimp);
  buffer_name = g_value_get_string (&args->values[1]);
377 378 379

  if (success)
    {
380 381
      GError *my_error = NULL;

382
      real_name = (gchar *) gimp_edit_named_copy_visible (image, buffer_name,
383
                                                          context, &my_error);
384

385
      if (real_name)
386 387 388
        {
          real_name = g_strdup (real_name);
        }
389
      else
390
        {
391 392 393
          gimp_message_literal (gimp,
                                G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                my_error->message);
394 395
          g_clear_error (&my_error);
        }
396 397
    }

398 399
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
400 401

  if (success)
402
    g_value_take_string (&return_vals->values[1], real_name);
403

404
  return return_vals;
405 406
}

407
static GValueArray *
408 409 410 411 412 413
edit_named_paste_invoker (GimpProcedure      *procedure,
                          Gimp               *gimp,
                          GimpContext        *context,
                          GimpProgress       *progress,
                          const GValueArray  *args,
                          GError            **error)
414 415
{
  gboolean success = TRUE;
416
  GValueArray *return_vals;
417
  GimpDrawable *drawable;
418
  const gchar *buffer_name;
419
  gboolean paste_into;
420
  GimpLayer *floating_sel = NULL;
421

422 423 424
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  buffer_name = g_value_get_string (&args->values[1]);
  paste_into = g_value_get_boolean (&args->values[2]);
425 426 427

  if (success)
    {
428
      GimpBuffer *buffer = gimp_pdb_get_buffer (gimp, buffer_name, error);
429

430
      if (buffer &&
431
          gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
432
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
433
        {
434 435 436 437
          floating_sel = gimp_edit_paste (gimp_item_get_image (GIMP_ITEM (drawable)),
                                          drawable, buffer,
                                          paste_into, -1, -1, -1, -1);
          if (! floating_sel)
438 439
            success = FALSE;
        }
440 441
      else
        success = FALSE;
442 443
    }

444 445
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
446 447

  if (success)
448
    gimp_value_set_layer (&return_vals->values[1], floating_sel);
449

450
  return return_vals;
451 452
}

453
static GValueArray *
454 455 456 457 458 459
edit_named_paste_as_new_invoker (GimpProcedure      *procedure,
                                 Gimp               *gimp,
                                 GimpContext        *context,
                                 GimpProgress       *progress,
                                 const GValueArray  *args,
                                 GError            **error)
460 461
{
  gboolean success = TRUE;
462
  GValueArray *return_vals;
463
  const gchar *buffer_name;
464 465
  GimpImage *image = NULL;

466
  buffer_name = g_value_get_string (&args->values[0]);
467 468 469

  if (success)
    {
470
      GimpBuffer *buffer = gimp_pdb_get_buffer (gimp, buffer_name, error);
471

472
      if (buffer)
473
        {
474
          image = gimp_image_new_from_buffer (gimp, NULL, buffer);
475

476 477 478
          if (! image)
            success = FALSE;
        }
479 480
      else
        success = FALSE;
481 482
    }

483 484
  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);
485 486

  if (success)
487
    gimp_value_set_image (&return_vals->values[1], image);
488

489
  return return_vals;
490 491
}

492
static GValueArray *
493 494 495 496 497 498
edit_clear_invoker (GimpProcedure      *procedure,
                    Gimp               *gimp,
                    GimpContext        *context,
                    GimpProgress       *progress,
                    const GValueArray  *args,
                    GError            **error)
Elliot Lee's avatar
Elliot Lee committed
499
{
Manish Singh's avatar
Manish Singh committed
500
  gboolean success = TRUE;
501
  GimpDrawable *drawable;
Elliot Lee's avatar
Elliot Lee committed
502

503
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
Elliot Lee's avatar
Elliot Lee committed
504 505 506

  if (success)
    {
507
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
508
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
509
        {
510
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
511

512
          success = gimp_edit_clear (image, drawable, context);
513
        }
514 515
      else
        success = FALSE;
Elliot Lee's avatar
Elliot Lee committed
516 517
    }

518 519
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
Elliot Lee's avatar
Elliot Lee committed
520 521
}

522
static GValueArray *
523 524 525 526 527 528
edit_fill_invoker (GimpProcedure      *procedure,
                   Gimp               *gimp,
                   GimpContext        *context,
                   GimpProgress       *progress,
                   const GValueArray  *args,
                   GError            **error)
Elliot Lee's avatar
Elliot Lee committed
529
{
Manish Singh's avatar
Manish Singh committed
530
  gboolean success = TRUE;
531
  GimpDrawable *drawable;
532
  gint32 fill_type;
Elliot Lee's avatar
Elliot Lee committed
533

534 535
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  fill_type = g_value_get_enum (&args->values[1]);
536

Elliot Lee's avatar
Elliot Lee committed
537 538
  if (success)
    {
539
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
540
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
541
        {
542
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
543

544 545
          success = gimp_edit_fill (image, drawable, context,
                                    (GimpFillType) fill_type);
546
        }
547 548
      else
        success = FALSE;
Elliot Lee's avatar
Elliot Lee committed
549 550
    }

551 552
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
553
}
Elliot Lee's avatar
Elliot Lee committed
554

555
static GValueArray *
556 557 558 559 560 561
edit_bucket_fill_invoker (GimpProcedure      *procedure,
                          Gimp               *gimp,
                          GimpContext        *context,
                          GimpProgress       *progress,
                          const GValueArray  *args,
                          GError            **error)
562 563 564 565 566 567 568 569 570 571 572
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 fill_mode;
  gint32 paint_mode;
  gdouble opacity;
  gdouble threshold;
  gboolean sample_merged;
  gdouble x;
  gdouble y;

573 574 575 576 577 578 579 580
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  fill_mode = g_value_get_enum (&args->values[1]);
  paint_mode = g_value_get_enum (&args->values[2]);
  opacity = g_value_get_double (&args->values[3]);
  threshold = g_value_get_double (&args->values[4]);
  sample_merged = g_value_get_boolean (&args->values[5]);
  x = g_value_get_double (&args->values[6]);
  y = g_value_get_double (&args->values[7]);
581 582 583

  if (success)
    {
584
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
585
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
586
        {
587
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
588
          gboolean   do_seed_fill;
589

590
          do_seed_fill = gimp_channel_is_empty (gimp_image_get_mask (image));
591

Michael Natterer's avatar
Michael Natterer committed
592 593 594 595 596 597 598
          success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
                                               paint_mode, opacity / 100.0,
                                               do_seed_fill,
                                               FALSE /* don't fill transparent */,
                                               GIMP_SELECT_CRITERION_COMPOSITE,
                                               threshold, sample_merged, x, y,
                                               error);
599
        }
600 601
      else
        success = FALSE;
602 603
    }

604 605
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
606 607
}

608
static GValueArray *
609 610 611 612 613 614
edit_bucket_fill_full_invoker (GimpProcedure      *procedure,
                               Gimp               *gimp,
                               GimpContext        *context,
                               GimpProgress       *progress,
                               const GValueArray  *args,
                               GError            **error)
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 fill_mode;
  gint32 paint_mode;
  gdouble opacity;
  gdouble threshold;
  gboolean sample_merged;
  gboolean fill_transparent;
  gint32 select_criterion;
  gdouble x;
  gdouble y;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  fill_mode = g_value_get_enum (&args->values[1]);
  paint_mode = g_value_get_enum (&args->values[2]);
  opacity = g_value_get_double (&args->values[3]);
  threshold = g_value_get_double (&args->values[4]);
  sample_merged = g_value_get_boolean (&args->values[5]);
  fill_transparent = g_value_get_boolean (&args->values[6]);
  select_criterion = g_value_get_enum (&args->values[7]);
  x = g_value_get_double (&args->values[8]);
  y = g_value_get_double (&args->values[9]);

  if (success)
    {
641
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
642
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
643 644 645 646 647 648
        {
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
          gboolean   do_seed_fill;

          do_seed_fill = gimp_channel_is_empty (gimp_image_get_mask (image));

Michael Natterer's avatar
Michael Natterer committed
649 650 651 652 653 654 655
          success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
                                               paint_mode, opacity / 100.0,
                                               do_seed_fill,
                                               fill_transparent,
                                               select_criterion,
                                               threshold, sample_merged, x, y,
                                               error);
656 657 658 659 660
        }
      else
        success = FALSE;
    }

661 662
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
663 664
}

665
static GValueArray *
666 667 668 669 670 671
edit_blend_invoker (GimpProcedure      *procedure,
                    Gimp               *gimp,
                    GimpContext        *context,
                    GimpProgress       *progress,
                    const GValueArray  *args,
                    GError            **error)
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 blend_mode;
  gint32 paint_mode;
  gint32 gradient_type;
  gdouble opacity;
  gdouble offset;
  gint32 repeat;
  gboolean reverse;
  gboolean supersample;
  gint32 max_depth;
  gdouble threshold;
  gboolean dither;
  gdouble x1;
  gdouble y1;
  gdouble x2;
  gdouble y2;

691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  blend_mode = g_value_get_enum (&args->values[1]);
  paint_mode = g_value_get_enum (&args->values[2]);
  gradient_type = g_value_get_enum (&args->values[3]);
  opacity = g_value_get_double (&args->values[4]);
  offset = g_value_get_double (&args->values[5]);
  repeat = g_value_get_enum (&args->values[6]);
  reverse = g_value_get_boolean (&args->values[7]);
  supersample = g_value_get_boolean (&args->values[8]);
  max_depth = g_value_get_int (&args->values[9]);
  threshold = g_value_get_double (&args->values[10]);
  dither = g_value_get_boolean (&args->values[11]);
  x1 = g_value_get_double (&args->values[12]);
  y1 = g_value_get_double (&args->values[13]);
  x2 = g_value_get_double (&args->values[14]);
  y2 = g_value_get_double (&args->values[15]);
707 708 709

  if (success)
    {
710
      success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
711
                 gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error));
712

713 714 715 716 717 718 719 720 721
      if (success && supersample)
        {
          if (max_depth < 1 || max_depth > 9)
            success = FALSE;

          if (threshold < 0.0 || threshold > 4.0)
            success = FALSE;
        }

722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
      if (success)
        {
          if (progress)
            gimp_progress_start (progress, _("Blending"), FALSE);

          gimp_drawable_blend (drawable,
                               context,
                               blend_mode,
                               paint_mode,
                               gradient_type,
                               opacity / 100.0,
                               offset, repeat, reverse,
                               supersample, max_depth,
                               threshold, dither,
                               x1, y1, x2, y2,
                               progress);

          if (progress)
            gimp_progress_end (progress);
        }
    }

744 745
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
746 747 748
}

static GValueArray *
749 750 751 752 753 754
edit_stroke_invoker (GimpProcedure      *procedure,
                     Gimp               *gimp,
                     GimpContext        *context,
                     GimpProgress       *progress,
                     const GValueArray  *args,
                     GError            **error)
755 756 757 758 759 760 761 762
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);

  if (success)
    {
763
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
764
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
765
        {
766
          GimpImage         *image   = gimp_item_get_image (GIMP_ITEM (drawable));
767
          GimpStrokeOptions *options = gimp_stroke_options_new (gimp, context, TRUE);
768

769 770 771
          g_object_set (options,
                        "method", GIMP_STROKE_METHOD_PAINT_CORE,
                        NULL);
772 773

          success = gimp_item_stroke (GIMP_ITEM (gimp_image_get_mask (image)),
774 775
                                      drawable, context, options, TRUE, TRUE,
                                      progress, error);
776

777
          g_object_unref (options);
778 779 780 781 782
        }
      else
        success = FALSE;
    }

783 784
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
785 786
}

787
static GValueArray *
788 789 790 791 792 793
edit_stroke_vectors_invoker (GimpProcedure      *procedure,
                             Gimp               *gimp,
                             GimpContext        *context,
                             GimpProgress       *progress,
                             const GValueArray  *args,
                             GError            **error)
794 795 796 797 798 799 800 801 802 803
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  GimpVectors *vectors;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  vectors = gimp_value_get_vectors (&args->values[1], gimp);

  if (success)
    {
804
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
805
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
806 807
          gimp_pdb_item_is_attached (GIMP_ITEM (vectors),
                                     gimp_item_get_image (GIMP_ITEM (drawable)), FALSE, error))
808
        {
809
          GimpStrokeOptions *options = gimp_stroke_options_new (gimp, context, TRUE);
810

811 812 813
          g_object_set (options,
                        "method", GIMP_STROKE_METHOD_PAINT_CORE,
                        NULL);
814 815

          success = gimp_item_stroke (GIMP_ITEM (vectors),
816 817
                                      drawable, context, options, TRUE, TRUE,
                                      progress, error);
818

819
          g_object_unref (options);
820 821 822 823 824
        }
      else
        success = FALSE;
    }

825 826
  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
827 828
}

829
void
830
register_edit_procs (GimpPDB *pdb)
831 832 833 834 835 836
{
  GimpProcedure *procedure;

  /*
   * gimp-edit-cut
   */
837
  procedure = gimp_procedure_new (edit_cut_invoker);
838 839
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-cut");
840 841 842
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-cut",
                                     "Cut from the specified drawable.",
843
                                     "If there is a selection in the image, then the area specified by the selection is cut from the specified drawable and placed in an internal GIMP edit buffer. It can subsequently be retrieved using the 'gimp-edit-paste' command. If there is no selection, then the specified drawable will be removed and its contents stored in the internal GIMP edit buffer. This procedure will fail if the selected area lies completely outside the bounds of the current drawable and there is nothing to copy from.",
844 845 846 847 848 849 850 851
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1995-1996",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "The drawable to cut from",
852
                                                            pdb->gimp, FALSE,
853 854 855 856
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_boolean ("non-empty",
                                                         "non empty",
857
                                                         "TRUE if the cut was successful, FALSE if there was nothing to copy from",
858 859
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE));
860
  gimp_pdb_register_procedure (pdb, procedure);
861
  g_object_unref (procedure);
862 863 864 865

  /*
   * gimp-edit-copy
   */
866
  procedure = gimp_procedure_new (edit_copy_invoker);
867 868
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-copy");
869 870 871
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-copy",
                                     "Copy from the specified drawable.",
872
                                     "If there is a selection in the image, then the area specified by the selection is copied from the specified drawable and placed in an internal GIMP edit buffer. It can subsequently be retrieved using the 'gimp-edit-paste' command. If there is no selection, then the specified drawable's contents will be stored in the internal GIMP edit buffer. This procedure will fail if the selected area lies completely outside the bounds of the current drawable and there is nothing to copy from.",
873 874 875 876 877 878 879 880
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1995-1996",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "The drawable to copy from",
881
                                                            pdb->gimp, FALSE,
882 883 884 885
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_boolean ("non-empty",
                                                         "non empty",
886
                                                         "TRUE if the cut was successful, FALSE if there was nothing to copy from",
887 888
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE));
889
  gimp_pdb_register_procedure (pdb, procedure);
890
  g_object_unref (procedure);
891 892 893 894

  /*
   * gimp-edit-copy-visible
   */
895
  procedure = gimp_procedure_new (edit_copy_visible_invoker);
896 897
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-copy-visible");
898 899 900 901 902 903 904 905 906 907 908 909
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-copy-visible",
                                     "Copy from the projection.",
                                     "If there is a selection in the image, then the area specified by the selection is copied from the projection and placed in an internal GIMP edit buffer. It can subsequently be retrieved using the 'gimp-edit-paste' command. If there is no selection, then the projection's contents will be stored in the internal GIMP edit buffer.",
                                     "Michael Natterer <mitch@gimp.org>",
                                     "Michael Natterer",
                                     "2004",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "The image to copy from",
910
                                                         pdb->gimp, FALSE,
911 912 913 914
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_boolean ("non-empty",
                                                         "non empty",
915
                                                         "TRUE if the copy was successful",
916 917
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE));
918
  gimp_pdb_register_procedure (pdb, procedure);
919
  g_object_unref (procedure);
920 921 922 923

  /*
   * gimp-edit-paste
   */
924
  procedure = gimp_procedure_new (edit_paste_invoker);
925 926
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-paste");
927 928 929 930 931 932 933 934 935 936 937 938
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-paste",
                                     "Paste buffer to the specified drawable.",
                                     "This procedure pastes a copy of the internal GIMP edit buffer to the specified drawable. The GIMP edit buffer will be empty unless a call was previously made to either 'gimp-edit-cut' or 'gimp-edit-copy'. The \"paste_into\" option specifies whether to clear the current image selection, or to paste the buffer \"behind\" the selection. This allows the selection to act as a mask for the pasted buffer. Anywhere that the selection mask is non-zero, the pasted buffer will show through. The pasted buffer will be a new layer in the image which is designated as the image floating selection. If the image has a floating selection at the time of pasting, the old floating selection will be anchored to it's drawable before the new floating selection is added. This procedure returns the new floating layer. The resulting floating selection will already be attached to the specified drawable, and a subsequent call to floating_sel_attach is not needed.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1995-1996",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "The drawable to paste to",
939
                                                            pdb->gimp, FALSE,
940 941 942 943 944 945 946 947 948 949 950
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("paste-into",
                                                     "paste into",
                                                     "Clear selection, or paste behind it?",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_layer_id ("floating-sel",
                                                             "floating sel",
                                                             "The new floating selection",
951
                                                             pdb->gimp, FALSE,
952
                                                             GIMP_PARAM_READWRITE));
953
  gimp_pdb_register_procedure (pdb, procedure);
954
  g_object_unref (procedure);
955 956 957 958

  /*
   * gimp-edit-paste-as-new
   */
959
  procedure = gimp_procedure_new (edit_paste_as_new_invoker);
960 961
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-paste-as-new");
962 963 964
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-paste-as-new",
                                     "Paste buffer to a new image.",
965
                                     "This procedure pastes a copy of the internal GIMP edit buffer to a new image. The GIMP edit buffer will be empty unless a call was previously made to either 'gimp-edit-cut' or 'gimp-edit-copy'. This procedure returns the new image or -1 if the edit buffer was empty.",
966 967 968 969 970 971 972 973
                                     "Michael Natterer <mitch@gimp.org>",
                                     "Michael Natterer",
                                     "2005",
                                     NULL);
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_image_id ("image",
                                                             "image",
                                                             "The new image",
974
                                                             pdb->gimp, FALSE,
975
                                                             GIMP_PARAM_READWRITE));
976
  gimp_pdb_register_procedure (pdb, procedure);
977
  g_object_unref (procedure);
978 979 980 981

  /*
   * gimp-edit-named-cut
   */
982
  procedure = gimp_procedure_new (edit_named_cut_invoker);
983 984
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-named-cut");
985 986 987
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-named-cut",
                                     "Cut into a named buffer.",
988
                                     "This procedure works like 'gimp-edit-cut', but additionally stores the cut buffer into a named buffer that will stay available for later pasting, regardless of any intermediate copy or cut operations.",
989 990 991 992 993 994 995 996
                                     "Michael Natterer <mitch@gimp.org>",
                                     "Michael Natterer",
                                     "2005",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "The drawable to cut from",
997
                                                            pdb->gimp, FALSE,
998 999 1000 1001 1002
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("buffer-name",
                                                       "buffer name",
                                                       "The name of the buffer to create",
1003
                                                       FALSE, FALSE, TRUE,
1004 1005 1006 1007 1008
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("real-name",
                                                           "real name",
1009
                                                           "The real name given to the buffer, or NULL if the cut failed",
1010
                                                           FALSE, FALSE, FALSE,
1011 1012
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
1013
  gimp_pdb_register_procedure (pdb, procedure);
1014
  g_object_unref (procedure);
1015 1016 1017 1018

  /*
   * gimp-edit-named-copy
   */
1019
  procedure = gimp_procedure_new (edit_named_copy_invoker);
1020 1021
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-edit-named-copy");
1022 1023 1024
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-edit-named-copy",
                                     "Copy into a named buffer.",
1025
                                     "This procedure works like 'gimp-edit-copy', but additionally stores the copied buffer into a named buffer that will stay available for later pasting, regardless of any intermediate copy or cut operations.",
1026 1027 1028 1029 1030 1031 1032 1033
                                     "Michael Natterer <mitch@gimp.org>",
                                     "Michael Natterer",
                                     "2005",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "The drawable to copy from",
1034
                                                            pdb->gimp, FALSE,