gimpdisplayshell-dnd.c 24.1 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 <http://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 26
#include "libgimpbase/gimpbase.h"

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

#include "core/gimp.h"
30
#include "core/gimp-edit.h"
31
#include "core/gimpbuffer.h"
Michael Natterer's avatar
Michael Natterer committed
32
#include "core/gimpcontainer.h"
33 34 35
#include "core/gimpcontext.h"
#include "core/gimpdrawable-bucket-fill.h"
#include "core/gimpimage.h"
Sven Neumann's avatar
Sven Neumann committed
36
#include "core/gimpimage-colormap.h"
Michael Natterer's avatar
Michael Natterer committed
37
#include "core/gimpimage-merge.h"
38
#include "core/gimpimage-undo.h"
39
#include "core/gimplayer.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 46
#include "file/file-open.h"
#include "file/file-utils.h"

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

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

53 54
#include "widgets/gimpdnd.h"

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

60
#include "gimp-log.h"
61
#include "gimp-intl.h"
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 107
/*  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);
108 109 110 111 112
static void   gimp_display_shell_drop_pixbuf    (GtkWidget       *widget,
                                                 gint             x,
                                                 gint             y,
                                                 GdkPixbuf       *pixbuf,
                                                 gpointer         data);
113 114 115 116


/*  public functions  */

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

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


/*  private functions  */

160 161 162 163 164 165 166 167 168 169 170 171 172
/*
 * Position the dropped item in the middle of the viewport.
 */
static void
gimp_display_shell_dnd_position_item (GimpDisplayShell *shell,
                                      GimpItem         *item)
{
  gint x, y;
  gint width, height;
  gint off_x, off_y;

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

173
  gimp_item_get_offset (item, &off_x, &off_y);
174

175 176
  off_x = x + (width  - gimp_item_get_width  (item)) / 2 - off_x;
  off_y = y + (height - gimp_item_get_height (item)) / 2 - off_y;
177 178 179

  gimp_item_translate (item, off_x, off_y, FALSE);
}
180 181 182 183 184

static void
gimp_display_shell_dnd_flush (GimpDisplayShell *shell,
                              GimpImage        *image)
{
185
  gimp_display_shell_present (shell);
186 187 188

  gimp_image_flush (image);

189
  gimp_context_set_display (gimp_get_user_context (shell->display->gimp),
190 191 192
                            shell->display);
}

193
static void
194
gimp_display_shell_drop_drawable (GtkWidget    *widget,
195 196
                                  gint          x,
                                  gint          y,
197 198 199
                                  GimpViewable *viewable,
                                  gpointer      data)
{
Sven Neumann's avatar
Sven Neumann committed
200
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
201
  GimpImage        *image     = gimp_display_get_image (shell->display);
202 203
  GType             new_type;
  GimpItem         *new_item;
Sven Neumann's avatar
Sven Neumann committed
204
  gboolean          new_image = FALSE;
205

206
  GIMP_LOG (DND, NULL);
207

208 209 210 211
  if (shell->display->gimp->busy)
    return;

  if (! image)
212
    {
Sven Neumann's avatar
Sven Neumann committed
213 214 215 216 217 218 219 220 221
      GimpImage         *src_image = gimp_item_get_image (GIMP_ITEM (viewable));
      GimpDrawable      *drawable  = GIMP_DRAWABLE (viewable);
      GimpImageBaseType  type;
      gdouble            xres;
      gdouble            yres;

      type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));

      image = gimp_create_image (shell->display->gimp,
222 223
                                 gimp_item_get_width  (GIMP_ITEM (viewable)),
                                 gimp_item_get_height (GIMP_ITEM (viewable)),
Sven Neumann's avatar
Sven Neumann committed
224 225 226 227 228 229 230 231 232 233 234 235
                                 type, TRUE);
      gimp_image_undo_disable (image);

      if (type == GIMP_INDEXED)
        gimp_image_set_colormap (image,
                                 gimp_image_get_colormap (src_image),
                                 gimp_image_get_colormap_size (src_image),
                                 FALSE);

      gimp_image_get_resolution (src_image, &xres, &yres);
      gimp_image_set_resolution (image, xres, yres);
      gimp_image_set_unit (image, gimp_image_get_unit (src_image));
236 237

      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
Sven Neumann's avatar
Sven Neumann committed
238 239 240
      g_object_unref (image);

      new_image = TRUE;
241
    }
242

243 244 245 246 247
  if (GIMP_IS_LAYER (viewable))
    new_type = G_TYPE_FROM_INSTANCE (viewable);
  else
    new_type = GIMP_TYPE_LAYER;

248
  new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type);
249

250 251
  if (new_item)
    {
Sven Neumann's avatar
Sven Neumann committed
252
      GimpLayer *new_layer = GIMP_LAYER (new_item);
253

254
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
255
                                   _("Drop New Layer"));
256

Sven Neumann's avatar
Sven Neumann committed
257
      if (! new_image)
258
        gimp_display_shell_dnd_position_item (shell, new_item);
259

260
      gimp_item_set_visible (new_item, TRUE, FALSE);
261
      gimp_item_set_linked (new_item, FALSE, FALSE);
262

263 264
      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
265

266
      gimp_image_undo_group_end (image);
267

268
      gimp_display_shell_dnd_flush (shell, image);
269
    }
Sven Neumann's avatar
Sven Neumann committed
270 271 272

  if (new_image)
    gimp_image_undo_enable (image);
273 274
}

275
static void
276
gimp_display_shell_drop_vectors (GtkWidget    *widget,
277 278
                                 gint          x,
                                 gint          y,
279 280 281
                                 GimpViewable *viewable,
                                 gpointer      data)
{
282
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
283
  GimpImage        *image = gimp_display_get_image (shell->display);
Michael Natterer's avatar
Michael Natterer committed
284
  GimpItem         *new_item;
285

286
  GIMP_LOG (DND, NULL);
287

288 289 290 291
  if (shell->display->gimp->busy)
    return;

  if (! image)
292 293
    return;

294 295
  new_item = gimp_item_convert (GIMP_ITEM (viewable),
                                image, G_TYPE_FROM_INSTANCE (viewable));
296

297 298
  if (new_item)
    {
Michael Natterer's avatar
Michael Natterer committed
299
      GimpVectors *new_vectors = GIMP_VECTORS (new_item);
300

301
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
302
                                   _("Drop New Path"));
303

304 305
      gimp_image_add_vectors (image, new_vectors,
                              GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
306

307
      gimp_image_undo_group_end (image);
308

309
      gimp_display_shell_dnd_flush (shell, image);
310
    }
311 312
}

313
static void
314
gimp_display_shell_drop_svg (GtkWidget     *widget,
315 316
                             gint           x,
                             gint           y,
317
                             const guchar  *svg_data,
318
                             gsize          svg_data_len,
319 320
                             gpointer       data)
{
321
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
322
  GimpImage        *image = gimp_display_get_image (shell->display);
Michael Natterer's avatar
Michael Natterer committed
323
  GError           *error  = NULL;
324

325
  GIMP_LOG (DND, NULL);
326

327 328 329 330
  if (shell->display->gimp->busy)
    return;

  if (! image)
331 332
    return;

333
  if (! gimp_vectors_import_buffer (image,
334
                                    (const gchar *) svg_data, svg_data_len,
335 336 337
                                    TRUE, TRUE,
                                    GIMP_IMAGE_ACTIVE_PARENT, -1,
                                    NULL, &error))
338
    {
339 340 341
      gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
			    GIMP_MESSAGE_ERROR,
			    error->message);
342 343 344 345
      g_clear_error (&error);
    }
  else
    {
346
      gimp_display_shell_dnd_flush (shell, image);
347 348 349
    }
}

350
static void
351 352 353 354
gimp_display_shell_dnd_bucket_fill (GimpDisplayShell   *shell,
                                    GimpBucketFillMode  fill_mode,
                                    const GimpRGB      *color,
                                    GimpPattern        *pattern)
355
{
356
  GimpImage    *image = gimp_display_get_image (shell->display);
357 358
  GimpDrawable *drawable;

359 360 361 362
  if (shell->display->gimp->busy)
    return;

  if (! image)
363 364
    return;

365
  drawable = gimp_image_get_active_drawable (image);
366 367 368 369

  if (! drawable)
    return;

370 371 372 373
  if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
    {
      gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                            GIMP_MESSAGE_ERROR,
374
                            _("Cannot modify the pixels of layer groups."));
375 376 377
      return;
    }

378
  if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
379 380 381 382 383 384 385
    {
      gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                            GIMP_MESSAGE_ERROR,
                            _("The active layer's pixels are locked."));
      return;
    }

386
  /* FIXME: there should be a virtual method for this that the
387 388 389
   *        GimpTextLayer can override.
   */
  if (color && gimp_drawable_is_text_layer (drawable))
390
    {
391 392 393
      gimp_text_layer_set (GIMP_TEXT_LAYER (drawable), NULL,
                           "color", color,
                           NULL);
394 395 396 397 398 399 400
    }
  else
    {
      gimp_drawable_bucket_fill_full (drawable,
                                      fill_mode,
                                      GIMP_NORMAL_MODE, GIMP_OPACITY_OPAQUE,
                                      FALSE,             /* no seed fill */
401 402 403
                                      FALSE,             /* don't fill transp */
                                      GIMP_SELECT_CRITERION_COMPOSITE,
                                      0.0, FALSE,        /* fill params  */
404 405 406
                                      0.0, 0.0,          /* ignored      */
                                      color, pattern);
    }
Michael Natterer's avatar
Michael Natterer committed
407

408
  gimp_display_shell_dnd_flush (shell, image);
409 410
}

411
static void
412
gimp_display_shell_drop_pattern (GtkWidget    *widget,
413 414
                                 gint          x,
                                 gint          y,
415 416 417
                                 GimpViewable *viewable,
                                 gpointer      data)
{
418
  GIMP_LOG (DND, NULL);
419

420
  if (GIMP_IS_PATTERN (viewable))
421 422 423
    gimp_display_shell_dnd_bucket_fill (GIMP_DISPLAY_SHELL (data),
                                        GIMP_PATTERN_BUCKET_FILL,
                                        NULL, GIMP_PATTERN (viewable));
424 425
}

426
static void
427
gimp_display_shell_drop_color (GtkWidget     *widget,
428 429
                               gint           x,
                               gint           y,
430 431 432
                               const GimpRGB *color,
                               gpointer       data)
{
433
  GIMP_LOG (DND, NULL);
434

435 436 437
  gimp_display_shell_dnd_bucket_fill (GIMP_DISPLAY_SHELL (data),
                                      GIMP_FG_BUCKET_FILL,
                                      color, NULL);
438 439
}

440
static void
441
gimp_display_shell_drop_buffer (GtkWidget    *widget,
442 443
                                gint          drop_x,
                                gint          drop_y,
444 445 446
                                GimpViewable *viewable,
                                gpointer      data)
{
447
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
448
  GimpImage        *image = gimp_display_get_image (shell->display);
449
  GimpDrawable     *drawable;
450 451
  GimpBuffer       *buffer;
  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
    return;

461 462
  drawable = gimp_image_get_active_drawable (image);

463
  if (drawable)
464
    {
465 466 467 468
      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_ERROR,
469
                                _("Cannot modify the pixels of layer groups."));
470 471 472
          return;
        }

473
      if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
474 475 476 477 478 479
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_ERROR,
                                _("The active layer's pixels are locked."));
          return;
        }
480 481
    }

482 483
  buffer = GIMP_BUFFER (viewable);

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

486 487
  /* FIXME: popup a menu for selecting "Paste Into" */

488
  gimp_edit_paste (image, drawable, buffer, FALSE,
489 490
                   x, y, width, height);

491
  gimp_display_shell_dnd_flush (shell, image);
492
}
Michael Natterer's avatar
Michael Natterer committed
493

494
static void
495
gimp_display_shell_drop_uri_list (GtkWidget *widget,
496 497
                                  gint       x,
                                  gint       y,
498 499
                                  GList     *uri_list,
                                  gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
500
{
501
  GimpDisplayShell *shell   = GIMP_DISPLAY_SHELL (data);
502
  GimpImage        *image   = gimp_display_get_image (shell->display);
503
  GimpContext      *context = gimp_get_user_context (shell->display->gimp);
Michael Natterer's avatar
Michael Natterer committed
504
  GList            *list;
505
  gboolean          open_as_layers;
Michael Natterer's avatar
Michael Natterer committed
506

507
  GIMP_LOG (DND, NULL);
508

509
  open_as_layers = (image != NULL);
510

511
  for (list = uri_list; list; list = g_list_next (list))
Michael Natterer's avatar
Michael Natterer committed
512
    {
513
      const gchar       *uri   = list->data;
Michael Natterer's avatar
Michael Natterer committed
514
      GimpPDBStatusType  status;
515
      GError            *error = NULL;
516
      gboolean           warn  = FALSE;
Michael Natterer's avatar
Michael Natterer committed
517

518
      if (open_as_layers)
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
        {
          GList *new_layers;

          new_layers = file_open_layers (shell->display->gimp, context,
                                         GIMP_PROGRESS (shell->display),
                                         image, FALSE,
                                         uri, GIMP_RUN_INTERACTIVE, NULL,
                                         &status, &error);

          if (new_layers)
            {
              gint x, y;
              gint width, height;

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

536 537
              gimp_image_add_layers (image, new_layers,
                                     GIMP_IMAGE_ACTIVE_PARENT, -1,
538 539 540 541 542 543 544 545 546 547
                                     x, y, width, height,
                                     _("Drop layers"));

              g_list_free (new_layers);
            }
          else if (status != GIMP_PDB_CANCEL)
            {
              warn = TRUE;
            }
        }
548
      else if (gimp_display_get_image (shell->display))
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
        {
          /*  open any subsequent images in a new display  */
          GimpImage *new_image;

          new_image = file_open_with_display (shell->display->gimp, context,
                                              NULL,
                                              uri, FALSE,
                                              &status, &error);

          if (! new_image && status != GIMP_PDB_CANCEL)
            warn = TRUE;
        }
      else
        {
          /*  open the first image in the empty display  */
          image = file_open_with_display (shell->display->gimp, context,
                                          GIMP_PROGRESS (shell->display),
                                          uri, FALSE,
                                          &status, &error);

          if (! image && status != GIMP_PDB_CANCEL)
            warn = TRUE;
        }
572

573
      if (warn)
574
        {
575
          gchar *filename = file_utils_uri_display_name (uri);
576

577
          gimp_message (shell->display->gimp, G_OBJECT (shell->display),
578
                        GIMP_MESSAGE_ERROR,
579 580
                        _("Opening '%s' failed:\n\n%s"),
                        filename, error->message);
581 582 583 584

          g_clear_error (&error);
          g_free (filename);
        }
Michael Natterer's avatar
Michael Natterer committed
585 586
    }

587 588
  if (image)
    gimp_display_shell_dnd_flush (shell, image);
Michael Natterer's avatar
Michael Natterer committed
589
}
590

591
static void
592 593 594 595 596 597 598 599
gimp_display_shell_drop_component (GtkWidget       *widget,
                                   gint             x,
                                   gint             y,
                                   GimpImage       *image,
                                   GimpChannelType  component,
                                   gpointer         data)
{
  GimpDisplayShell *shell      = GIMP_DISPLAY_SHELL (data);
600
  GimpImage        *dest_image = gimp_display_get_image (shell->display);
601 602 603 604
  GimpChannel      *channel;
  GimpItem         *new_item;
  const gchar      *desc;

605
  GIMP_LOG (DND, NULL);
606

607 608 609 610
  if (shell->display->gimp->busy)
    return;

  if (! dest_image)
611 612 613 614
    return;

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

615 616
  new_item = gimp_item_convert (GIMP_ITEM (channel),
                                dest_image, GIMP_TYPE_LAYER);
617 618 619 620 621 622 623 624
  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);
625 626
      gimp_object_take_name (GIMP_OBJECT (new_layer),
                             g_strdup_printf (_("%s Channel Copy"), desc));
627 628 629 630

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

631
      gimp_display_shell_dnd_position_item (shell, new_item);
632

633 634
      gimp_image_add_layer (dest_image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
635 636 637

      gimp_image_undo_group_end (dest_image);

638
      gimp_display_shell_dnd_flush (shell, dest_image);
639 640
    }
}
641 642 643 644 645 646 647 648

static void
gimp_display_shell_drop_pixbuf (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                GdkPixbuf *pixbuf,
                                gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
649
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
650
  GimpImage        *image     = gimp_display_get_image (shell->display);
651
  GimpLayer        *new_layer;
Sven Neumann's avatar
Sven Neumann committed
652 653
  GimpImageType     image_type;
  gboolean          new_image = FALSE;
654

655
  GIMP_LOG (DND, NULL);
656

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

Sven Neumann's avatar
Sven Neumann committed
660 661 662 663 664 665 666 667 668 669 670 671 672
  switch (gdk_pixbuf_get_n_channels (pixbuf))
    {
    case 1: image_type = GIMP_GRAY_IMAGE;  break;
    case 2: image_type = GIMP_GRAYA_IMAGE; break;
    case 3: image_type = GIMP_RGB_IMAGE;   break;
    case 4: image_type = GIMP_RGBA_IMAGE;  break;
      break;

    default:
      g_return_if_reached ();
      break;
    }

673
  if (! image)
674
    {
Sven Neumann's avatar
Sven Neumann committed
675 676 677 678 679 680
      image = gimp_create_image (shell->display->gimp,
                                 gdk_pixbuf_get_width (pixbuf),
                                 gdk_pixbuf_get_height (pixbuf),
                                 GIMP_IMAGE_TYPE_BASE_TYPE (image_type),
                                 FALSE);

681
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
Sven Neumann's avatar
Sven Neumann committed
682 683 684 685 686
      g_object_unref (image);

      gimp_image_undo_disable (image);

      new_image = TRUE;
687
    }
688 689

  new_layer =
Sven Neumann's avatar
Sven Neumann committed
690
    gimp_layer_new_from_pixbuf (pixbuf, image, image_type,
691 692 693 694 695
                                _("Dropped Buffer"),
                                GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

  if (new_layer)
    {
Sven Neumann's avatar
Sven Neumann committed
696
      GimpItem *new_item = GIMP_ITEM (new_layer);
697 698 699

      new_item = GIMP_ITEM (new_layer);

700
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
701 702
                                   _("Drop New Layer"));

Sven Neumann's avatar
Sven Neumann committed
703
      if (! new_image)
704
        gimp_display_shell_dnd_position_item (shell, new_item);
705

706 707
      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
708

709
      gimp_image_undo_group_end (image);
710

711
      gimp_display_shell_dnd_flush (shell, image);
712
    }
Sven Neumann's avatar
Sven Neumann committed
713 714 715

  if (new_image)
    gimp_image_undo_enable (image);
716
}