gimpdisplayshell-dnd.c 25.7 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
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
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 <https://www.gnu.org/licenses/>.
16 17 18 19
 */

#include "config.h"

20 21
#include <string.h>

22
#include <gegl.h>
23 24
#include <gtk/gtk.h>

25
#include "libgimpbase/gimpbase.h"
26
#include "libgimpwidgets/gimpwidgets.h"
27

28 29 30
#include "display-types.h"

#include "core/gimp.h"
31
#include "core/gimp-edit.h"
32
#include "core/gimpbuffer.h"
33
#include "core/gimpdrawable-edit.h"
34
#include "core/gimpfilloptions.h"
35
#include "core/gimpimage.h"
36
#include "core/gimpimage-new.h"
37
#include "core/gimpimage-undo.h"
38
#include "core/gimplayer.h"
39
#include "core/gimplayer-new.h"
40
#include "core/gimplayermask.h"
41
#include "core/gimppattern.h"
42
#include "core/gimpprogress.h"
43

Michael Natterer's avatar
Michael Natterer committed
44 45
#include "file/file-open.h"

46 47 48
#include "text/gimptext.h"
#include "text/gimptextlayer.h"

49
#include "vectors/gimpvectors.h"
50
#include "vectors/gimpvectors-import.h"
51

52 53
#include "widgets/gimpdnd.h"

54 55 56
#include "gimpdisplay.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-dnd.h"
57
#include "gimpdisplayshell-transform.h"
58

59
#include "gimp-log.h"
60
#include "gimp-intl.h"
61

62

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
/*  local function prototypes  */

static void   gimp_display_shell_drop_drawable  (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GimpViewable    *viewable,
                                                 gpointer         data);
static void   gimp_display_shell_drop_vectors   (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GimpViewable    *viewable,
                                                 gpointer         data);
static void   gimp_display_shell_drop_svg       (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 const guchar    *svg_data,
                                                 gsize            svg_data_length,
                                                 gpointer         data);
static void   gimp_display_shell_drop_pattern   (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GimpViewable    *viewable,
                                                 gpointer         data);
static void   gimp_display_shell_drop_color     (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 const GimpRGB   *color,
                                                 gpointer         data);
static void   gimp_display_shell_drop_buffer    (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GimpViewable    *viewable,
                                                 gpointer         data);
static void   gimp_display_shell_drop_uri_list  (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GList           *uri_list,
                                                 gpointer         data);
static void   gimp_display_shell_drop_component (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GimpImage       *image,
                                                 GimpChannelType  component,
                                                 gpointer         data);
107 108 109 110 111
static void   gimp_display_shell_drop_pixbuf    (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GdkPixbuf       *pixbuf,
                                                 gpointer         data);
112 113 114 115


/*  public functions  */

116
void
117 118 119 120
gimp_display_shell_dnd_init (GimpDisplayShell *shell)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

121
  gimp_dnd_viewable_dest_add  (shell->canvas, GIMP_TYPE_LAYER,
122 123
                               gimp_display_shell_drop_drawable,
                               shell);
124
  gimp_dnd_viewable_dest_add  (shell->canvas, GIMP_TYPE_LAYER_MASK,
125 126
                               gimp_display_shell_drop_drawable,
                               shell);
127
  gimp_dnd_viewable_dest_add  (shell->canvas, GIMP_TYPE_CHANNEL,
128 129
                               gimp_display_shell_drop_drawable,
                               shell);
130
  gimp_dnd_viewable_dest_add  (shell->canvas, GIMP_TYPE_VECTORS,
131 132
                               gimp_display_shell_drop_vectors,
                               shell);
133
  gimp_dnd_viewable_dest_add  (shell->canvas, GIMP_TYPE_PATTERN,
134 135
                               gimp_display_shell_drop_pattern,
                               shell);
136
  gimp_dnd_viewable_dest_add  (shell->canvas, GIMP_TYPE_BUFFER,
137 138
                               gimp_display_shell_drop_buffer,
                               shell);
139
  gimp_dnd_color_dest_add     (shell->canvas,
140 141
                               gimp_display_shell_drop_color,
                               shell);
142
  gimp_dnd_component_dest_add (shell->canvas,
143 144
                               gimp_display_shell_drop_component,
                               shell);
145 146 147
  gimp_dnd_uri_list_dest_add  (shell->canvas,
                               gimp_display_shell_drop_uri_list,
                               shell);
148 149 150 151 152 153
  gimp_dnd_svg_dest_add       (shell->canvas,
                               gimp_display_shell_drop_svg,
                               shell);
  gimp_dnd_pixbuf_dest_add    (shell->canvas,
                               gimp_display_shell_drop_pixbuf,
                               shell);
154 155 156 157 158
}


/*  private functions  */

159 160 161 162 163
/*
 * Position the dropped item in the middle of the viewport.
 */
static void
gimp_display_shell_dnd_position_item (GimpDisplayShell *shell,
164
                                      GimpImage        *image,
165 166
                                      GimpItem         *item)
{
167 168
  gint item_width  = gimp_item_get_width  (item);
  gint item_height = gimp_item_get_height (item);
169
  gint off_x, off_y;
170

171 172 173
  if (item_width  >= gimp_image_get_width  (image) &&
      item_height >= gimp_image_get_height (image))
    {
174 175
      off_x = (gimp_image_get_width  (image) - item_width)  / 2;
      off_y = (gimp_image_get_height (image) - item_height) / 2;
176 177 178 179 180
    }
  else
    {
      gint x, y;
      gint width, height;
181

182 183
      gimp_display_shell_untransform_viewport (shell, ! shell->show_all,
                                               &x, &y, &width, &height);
184

185 186
      off_x = x + (width  - item_width)  / 2;
      off_y = y + (height - item_height) / 2;
187
    }
188 189 190 191 192

  gimp_item_translate (item,
                       off_x - gimp_item_get_offset_x (item),
                       off_y - gimp_item_get_offset_y (item),
                       FALSE);
193
}
194 195 196 197 198

static void
gimp_display_shell_dnd_flush (GimpDisplayShell *shell,
                              GimpImage        *image)
{
199
  gimp_display_shell_present (shell);
200 201 202

  gimp_image_flush (image);

203
  gimp_context_set_display (gimp_get_user_context (shell->display->gimp),
204 205 206
                            shell->display);
}

207
static void
208
gimp_display_shell_drop_drawable (GtkWidget    *widget,
209 210
                                  gint          x,
                                  gint          y,
211 212 213
                                  GimpViewable *viewable,
                                  gpointer      data)
{
Sven Neumann's avatar
Sven Neumann committed
214
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
215
  GimpImage        *image     = gimp_display_get_image (shell->display);
216 217
  GType             new_type;
  GimpItem         *new_item;
218

219
  GIMP_LOG (DND, NULL);
220

221 222 223 224
  if (shell->display->gimp->busy)
    return;

  if (! image)
225
    {
226 227
      image = gimp_image_new_from_drawable (shell->display->gimp,
                                            GIMP_DRAWABLE (viewable));
228
      gimp_create_display (shell->display->gimp, image, GIMP_UNIT_PIXEL, 1.0,
229
                           G_OBJECT (gimp_widget_get_monitor (widget)));
Sven Neumann's avatar
Sven Neumann committed
230 231
      g_object_unref (image);

232
      return;
233
    }
234

235 236 237 238 239
  if (GIMP_IS_LAYER (viewable))
    new_type = G_TYPE_FROM_INSTANCE (viewable);
  else
    new_type = GIMP_TYPE_LAYER;

240
  new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type);
241

242 243
  if (new_item)
    {
Sven Neumann's avatar
Sven Neumann committed
244
      GimpLayer *new_layer = GIMP_LAYER (new_item);
245

246
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
247
                                   _("Drop New Layer"));
248

249
      gimp_display_shell_dnd_position_item (shell, image, new_item);
250

251
      gimp_item_set_visible (new_item, TRUE, FALSE);
252
      gimp_item_set_linked (new_item, FALSE, FALSE);
253

254 255
      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
256

257
      gimp_image_undo_group_end (image);
258

259
      gimp_display_shell_dnd_flush (shell, image);
260
    }
261 262
}

263
static void
264
gimp_display_shell_drop_vectors (GtkWidget    *widget,
265 266
                                 gint          x,
                                 gint          y,
267 268 269
                                 GimpViewable *viewable,
                                 gpointer      data)
{
270
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
271
  GimpImage        *image = gimp_display_get_image (shell->display);
Michael Natterer's avatar
Michael Natterer committed
272
  GimpItem         *new_item;
273

274
  GIMP_LOG (DND, NULL);
275

276 277 278 279
  if (shell->display->gimp->busy)
    return;

  if (! image)
280 281
    return;

282 283
  new_item = gimp_item_convert (GIMP_ITEM (viewable),
                                image, G_TYPE_FROM_INSTANCE (viewable));
284

285 286
  if (new_item)
    {
Michael Natterer's avatar
Michael Natterer committed
287
      GimpVectors *new_vectors = GIMP_VECTORS (new_item);
288

289
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
290
                                   _("Drop New Path"));
291

292 293
      gimp_image_add_vectors (image, new_vectors,
                              GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
294

295
      gimp_image_undo_group_end (image);
296

297
      gimp_display_shell_dnd_flush (shell, image);
298
    }
299 300
}

301
static void
302
gimp_display_shell_drop_svg (GtkWidget     *widget,
303 304
                             gint           x,
                             gint           y,
305
                             const guchar  *svg_data,
306
                             gsize          svg_data_len,
307 308
                             gpointer       data)
{
309
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
310
  GimpImage        *image = gimp_display_get_image (shell->display);
Michael Natterer's avatar
Michael Natterer committed
311
  GError           *error  = NULL;
312

313
  GIMP_LOG (DND, NULL);
314

315 316 317 318
  if (shell->display->gimp->busy)
    return;

  if (! image)
319 320
    return;

321
  if (! gimp_vectors_import_buffer (image,
322
                                    (const gchar *) svg_data, svg_data_len,
323
                                    TRUE, FALSE,
324 325
                                    GIMP_IMAGE_ACTIVE_PARENT, -1,
                                    NULL, &error))
326
    {
327
      gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
328 329
                            GIMP_MESSAGE_ERROR,
                            error->message);
330 331 332 333
      g_clear_error (&error);
    }
  else
    {
334
      gimp_display_shell_dnd_flush (shell, image);
335 336 337
    }
}

338
static void
339
gimp_display_shell_dnd_fill (GimpDisplayShell *shell,
340 341
                             GimpFillOptions  *options,
                             const gchar      *undo_desc)
342
{
343
  GimpImage    *image = gimp_display_get_image (shell->display);
344 345
  GimpDrawable *drawable;

346 347 348 349
  if (shell->display->gimp->busy)
    return;

  if (! image)
350 351
    return;

352
  drawable = gimp_image_get_active_drawable (image);
353 354 355 356

  if (! drawable)
    return;

357 358 359 360
  if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
    {
      gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                            GIMP_MESSAGE_ERROR,
361
                            _("Cannot modify the pixels of layer groups."));
362 363 364
      return;
    }

365
  if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
366 367 368 369 370 371 372
    {
      gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                            GIMP_MESSAGE_ERROR,
                            _("The active layer's pixels are locked."));
      return;
    }

373
  /* FIXME: there should be a virtual method for this that the
374 375
   *        GimpTextLayer can override.
   */
376 377
  if (gimp_fill_options_get_style (options) == GIMP_FILL_STYLE_SOLID &&
      gimp_item_is_text_layer (GIMP_ITEM (drawable)))
378
    {
379 380 381 382
      GimpRGB color;

      gimp_context_get_foreground (GIMP_CONTEXT (options), &color);

383
      gimp_text_layer_set (GIMP_TEXT_LAYER (drawable), NULL,
384
                           "color", &color,
385
                           NULL);
386 387 388
    }
  else
    {
389
      gimp_drawable_edit_fill (drawable, options, undo_desc);
390
    }
Michael Natterer's avatar
Michael Natterer committed
391

392
  gimp_display_shell_dnd_flush (shell, image);
393 394
}

395
static void
396
gimp_display_shell_drop_pattern (GtkWidget    *widget,
397 398
                                 gint          x,
                                 gint          y,
399 400 401
                                 GimpViewable *viewable,
                                 gpointer      data)
{
402
  GimpDisplayShell *shell   = GIMP_DISPLAY_SHELL (data);
403 404
  GimpFillOptions  *options = gimp_fill_options_new (shell->display->gimp,
                                                     NULL, FALSE);
405

406
  GIMP_LOG (DND, NULL);
407

408 409 410 411 412 413 414
  gimp_fill_options_set_style (options, GIMP_FILL_STYLE_PATTERN);
  gimp_context_set_pattern (GIMP_CONTEXT (options), GIMP_PATTERN (viewable));

  gimp_display_shell_dnd_fill (shell, options,
                               C_("undo-type", "Drop pattern to layer"));

  g_object_unref (options);
415 416
}

417
static void
418
gimp_display_shell_drop_color (GtkWidget     *widget,
419 420
                               gint           x,
                               gint           y,
421 422 423
                               const GimpRGB *color,
                               gpointer       data)
{
424
  GimpDisplayShell *shell   = GIMP_DISPLAY_SHELL (data);
425 426
  GimpFillOptions  *options = gimp_fill_options_new (shell->display->gimp,
                                                     NULL, FALSE);
427

428
  GIMP_LOG (DND, NULL);
429

430 431 432 433 434 435 436
  gimp_fill_options_set_style (options, GIMP_FILL_STYLE_SOLID);
  gimp_context_set_foreground (GIMP_CONTEXT (options), color);

  gimp_display_shell_dnd_fill (shell, options,
                               C_("undo-type", "Drop color to layer"));

  g_object_unref (options);
437 438
}

439
static void
440
gimp_display_shell_drop_buffer (GtkWidget    *widget,
441 442
                                gint          drop_x,
                                gint          drop_y,
443 444 445
                                GimpViewable *viewable,
                                gpointer      data)
{
446
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
447
  GimpImage        *image = gimp_display_get_image (shell->display);
448
  GimpDrawable     *drawable;
449
  GimpBuffer       *buffer;
450
  GimpPasteType     paste_type;
451
  gint              x, y, width, height;
452

453
  GIMP_LOG (DND, NULL);
454

455 456 457 458
  if (shell->display->gimp->busy)
    return;

  if (! image)
459
    {
460
      image = gimp_image_new_from_buffer (shell->display->gimp,
461
                                          GIMP_BUFFER (viewable));
462
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
463
                           G_OBJECT (gimp_widget_get_monitor (widget)));
464 465 466 467
      g_object_unref (image);

      return;
    }
468

469 470
  paste_type = GIMP_PASTE_TYPE_FLOATING;

471 472
  drawable = gimp_image_get_active_drawable (image);

473
  if (drawable)
474
    {
475 476 477
      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
478 479 480
                                GIMP_MESSAGE_INFO,
                                _("Pasted as new layer because the "
                                  "target is a layer group."));
481

482 483 484
          paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
        }
      else if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
485 486 487
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_ERROR,
488 489 490 491
                                _("Pasted as new layer because the "
                                  "target's pixels are locked."));

          paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
492
        }
493 494
    }

495 496
  buffer = GIMP_BUFFER (viewable);

497 498
  gimp_display_shell_untransform_viewport (shell, ! shell->show_all,
                                           &x, &y, &width, &height);
499

500 501
  /* FIXME: popup a menu for selecting "Paste Into" */

502 503
  gimp_edit_paste (image, drawable, GIMP_OBJECT (buffer),
                   paste_type, x, y, width, height);
504

505
  gimp_display_shell_dnd_flush (shell, image);
506
}
Michael Natterer's avatar
Michael Natterer committed
507

508
static void
509
gimp_display_shell_drop_uri_list (GtkWidget *widget,
510 511
                                  gint       x,
                                  gint       y,
512 513
                                  GList     *uri_list,
                                  gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
514
{
515
  GimpDisplayShell *shell   = GIMP_DISPLAY_SHELL (data);
516 517
  GimpImage        *image;
  GimpContext      *context;
Michael Natterer's avatar
Michael Natterer committed
518
  GList            *list;
519
  gboolean          open_as_layers;
Michael Natterer's avatar
Michael Natterer committed
520

521 522 523
  /* If the app is already being torn down, shell->display might be
   * NULL here.  Play it safe.
   */
524
  if (! shell->display)
525
    return;
526 527 528 529

  image = gimp_display_get_image (shell->display);
  context = gimp_get_user_context (shell->display->gimp);

530
  GIMP_LOG (DND, NULL);
531

532
  open_as_layers = (image != NULL);
533

534 535 536
  if (image)
    g_object_ref (image);

537
  for (list = uri_list; list; list = g_list_next (list))
Michael Natterer's avatar
Michael Natterer committed
538
    {
539
      GFile             *file  = g_file_new_for_uri (list->data);
Michael Natterer's avatar
Michael Natterer committed
540
      GimpPDBStatusType  status;
541
      GError            *error = NULL;
542
      gboolean           warn  = FALSE;
Michael Natterer's avatar
Michael Natterer committed
543

544 545 546
      if (! shell->display)
        {
          /* It seems as if GIMP is being torn down for quitting. Bail out. */
547
          g_object_unref (file);
548
          g_clear_object (&image);
549 550 551
          return;
        }

552
      if (open_as_layers)
553 554 555 556 557 558
        {
          GList *new_layers;

          new_layers = file_open_layers (shell->display->gimp, context,
                                         GIMP_PROGRESS (shell->display),
                                         image, FALSE,
559
                                         file, GIMP_RUN_INTERACTIVE, NULL,
560 561 562 563
                                         &status, &error);

          if (new_layers)
            {
564 565 566 567
              gint x      = 0;
              gint y      = 0;
              gint width  = gimp_image_get_width  (image);
              gint height = gimp_image_get_height (image);
568

569
              if (gimp_display_get_image (shell->display))
570 571 572
                gimp_display_shell_untransform_viewport (shell,
                                                         ! shell->show_all,
                                                         &x, &y,
573
                                                         &width, &height);
574

575 576
              gimp_image_add_layers (image, new_layers,
                                     GIMP_IMAGE_ACTIVE_PARENT, -1,
577 578 579 580 581
                                     x, y, width, height,
                                     _("Drop layers"));

              g_list_free (new_layers);
            }
582
          else if (status != GIMP_PDB_CANCEL && status != GIMP_PDB_SUCCESS)
583 584 585 586
            {
              warn = TRUE;
            }
        }
587
      else if (gimp_display_get_image (shell->display))
588 589 590 591 592 593
        {
          /*  open any subsequent images in a new display  */
          GimpImage *new_image;

          new_image = file_open_with_display (shell->display->gimp, context,
                                              NULL,
594
                                              file, FALSE,
595
                                              G_OBJECT (gimp_widget_get_monitor (widget)),
596 597
                                              &status, &error);

598
          if (! new_image && status != GIMP_PDB_CANCEL && status != GIMP_PDB_SUCCESS)
599 600 601 602 603 604 605
            warn = TRUE;
        }
      else
        {
          /*  open the first image in the empty display  */
          image = file_open_with_display (shell->display->gimp, context,
                                          GIMP_PROGRESS (shell->display),
606
                                          file, FALSE,
607
                                          G_OBJECT (gimp_widget_get_monitor (widget)),
608 609
                                          &status, &error);

610 611 612 613
          if (image)
            {
              g_object_ref (image);
            }
614
          else if (status != GIMP_PDB_CANCEL && status != GIMP_PDB_SUCCESS)
615 616 617
            {
              warn = TRUE;
            }
618
        }
619

620 621
      /* Something above might have run a few rounds of the main loop. Check
       * that shell->display is still there, otherwise ignore this as the app
622 623
       * is being torn down for quitting.
       */
624
      if (warn && shell->display)
625
        {
626
          gimp_message (shell->display->gimp, G_OBJECT (shell->display),
627
                        GIMP_MESSAGE_ERROR,
628
                        _("Opening '%s' failed:\n\n%s"),
629
                        gimp_file_get_utf8_name (file), error->message);
630 631
          g_clear_error (&error);
        }
632 633

      g_object_unref (file);
Michael Natterer's avatar
Michael Natterer committed
634 635
    }

636 637
  if (image)
    gimp_display_shell_dnd_flush (shell, image);
638 639

  g_clear_object (&image);
Michael Natterer's avatar
Michael Natterer committed
640
}
641

642
static void
643 644 645 646 647 648 649 650
gimp_display_shell_drop_component (GtkWidget       *widget,
                                   gint             x,
                                   gint             y,
                                   GimpImage       *image,
                                   GimpChannelType  component,
                                   gpointer         data)
{
  GimpDisplayShell *shell      = GIMP_DISPLAY_SHELL (data);
651
  GimpImage        *dest_image = gimp_display_get_image (shell->display);
652 653 654 655
  GimpChannel      *channel;
  GimpItem         *new_item;
  const gchar      *desc;

656
  GIMP_LOG (DND, NULL);
657

658 659 660 661
  if (shell->display->gimp->busy)
    return;

  if (! dest_image)
662 663 664
    {
      dest_image = gimp_image_new_from_component (image->gimp,
                                                  image, component);
665
      gimp_create_display (dest_image->gimp, dest_image, GIMP_UNIT_PIXEL, 1.0,
666
                           G_OBJECT (gimp_widget_get_monitor (widget)));
667 668 669 670
      g_object_unref (dest_image);

      return;
    }
671 672 673

  channel = gimp_channel_new_from_component (image, component, NULL, NULL);

674 675
  new_item = gimp_item_convert (GIMP_ITEM (channel),
                                dest_image, GIMP_TYPE_LAYER);
676 677 678 679 680 681 682 683
  g_object_unref (channel);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_enum_get_value (GIMP_TYPE_CHANNEL_TYPE, component,
                           NULL, NULL, &desc, NULL);
684 685
      gimp_object_take_name (GIMP_OBJECT (new_layer),
                             g_strdup_printf (_("%s Channel Copy"), desc));
686 687 688 689

      gimp_image_undo_group_start (dest_image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

690
      gimp_display_shell_dnd_position_item (shell, image, new_item);
691

692 693
      gimp_image_add_layer (dest_image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
694 695 696

      gimp_image_undo_group_end (dest_image);

697
      gimp_display_shell_dnd_flush (shell, dest_image);
698 699
    }
}
700 701 702 703 704 705 706 707

static void
gimp_display_shell_drop_pixbuf (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                GdkPixbuf *pixbuf,
                                gpointer   data)
{
708 709
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = gimp_display_get_image (shell->display);
710
  GimpLayer        *new_layer;
711
  gboolean          has_alpha = FALSE;
712

713
  GIMP_LOG (DND, NULL);
714

715 716 717
  if (shell->display->gimp->busy)
    return;

718 719 720 721
  if (! image)
    {
      image = gimp_image_new_from_pixbuf (shell->display->gimp, pixbuf,
                                          _("Dropped Buffer"));
722
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
723
                           G_OBJECT (gimp_widget_get_monitor (widget)));
724 725 726 727 728
      g_object_unref (image);

      return;
    }

729 730
  if (gdk_pixbuf_get_n_channels (pixbuf) == 2 ||
      gdk_pixbuf_get_n_channels (pixbuf) == 4)
Sven Neumann's avatar
Sven Neumann committed
731
    {
732
      has_alpha = TRUE;
Sven Neumann's avatar
Sven Neumann committed
733 734
    }

735
  new_layer =
736
    gimp_layer_new_from_pixbuf (pixbuf, image,
737
                                gimp_image_get_layer_format (image, has_alpha),
738
                                _("Dropped Buffer"),
739
                                GIMP_OPACITY_OPAQUE,
740
                                gimp_image_get_default_new_layer_mode (image));
741 742 743

  if (new_layer)
    {
Sven Neumann's avatar
Sven Neumann committed
744
      GimpItem *new_item = GIMP_ITEM (new_layer);
745

746
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
747 748
                                   _("Drop New Layer"));

749
      gimp_display_shell_dnd_position_item (shell, image, new_item);
750

751 752
      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
753

754
      gimp_image_undo_group_end (image);
755

756
      gimp_display_shell_dnd_flush (shell, image);
757 758
    }
}