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

#include "config.h"

23 24
#include <string.h>

25
#include <gegl.h>
26 27
#include <gtk/gtk.h>

28
#include "libgimpbase/gimpbase.h"
29 30 31
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"

32
#include "widgets-types.h"
33

34
#include "core/gimp.h"
35 36
#include "core/gimpcontainer.h"
#include "core/gimplayer.h"
37
#include "core/gimplayermask.h"
38
#include "core/gimpimage.h"
39
#include "core/gimpimage-undo.h"
40
#include "core/gimpitemundo.h"
41
#include "core/gimptreehandler.h"
42

43 44 45 46 47
#include "text/gimptextlayer.h"

#include "file/file-open.h"
#include "file/file-utils.h"

48
#include "gimpactiongroup.h"
49
#include "gimpcellrendererviewable.h"
50
#include "gimpcontainerview.h"
51
#include "gimpdnd.h"
52
#include "gimphelp-ids.h"
53
#include "gimplayertreeview.h"
54
#include "gimpviewrenderer.h"
55
#include "gimpuimanager.h"
Michael Natterer's avatar
Michael Natterer committed
56
#include "gimpwidgets-constructors.h"
57

58
#include "gimp-intl.h"
59 60


61 62 63 64 65 66 67 68 69 70 71 72 73 74
struct _GimpLayerTreeViewPriv
{
  GtkWidget       *paint_mode_menu;
  GtkAdjustment   *opacity_adjustment;
  GtkWidget       *lock_alpha_toggle;

  gint             model_column_mask;
  gint             model_column_mask_visible;

  GtkCellRenderer *mask_cell;

  PangoAttrList   *italic_attrs;
  PangoAttrList   *bold_attrs;

75 76 77 78 79
  GimpTreeHandler *mode_changed_handler;
  GimpTreeHandler *opacity_changed_handler;
  GimpTreeHandler *lock_alpha_changed_handler;
  GimpTreeHandler *mask_changed_handler;
  GimpTreeHandler *alpha_changed_handler;
80 81 82
};


83
static void  gimp_layer_tree_view_view_iface_init (GimpContainerViewInterface *iface);
84

85 86 87
static GObject * gimp_layer_tree_view_constructor (GType                type,
                                                   guint                n_params,
                                                   GObjectConstructParam *params);
88 89
static void   gimp_layer_tree_view_finalize       (GObject             *object);

90
static void   gimp_layer_tree_view_set_container  (GimpContainerView   *view,
91
                                                   GimpContainer       *container);
92 93
static void   gimp_layer_tree_view_set_context    (GimpContainerView   *view,
                                                   GimpContext         *context);
94 95
static gpointer gimp_layer_tree_view_insert_item  (GimpContainerView   *view,
                                                   GimpViewable        *viewable,
96
                                                   gpointer             parent_insert_data,
97
                                                   gint                 index);
98
static gboolean gimp_layer_tree_view_select_item  (GimpContainerView   *view,
99 100
                                                   GimpViewable        *item,
                                                   gpointer             insert_data);
101
static void    gimp_layer_tree_view_set_view_size (GimpContainerView   *view);
102

103
static gboolean gimp_layer_tree_view_drop_possible(GimpContainerTreeView *view,
104 105 106 107 108 109 110 111 112 113
                                                   GimpDndType          src_type,
                                                   GimpViewable        *src_viewable,
                                                   GimpViewable        *dest_viewable,
                                                   GtkTreeViewDropPosition  drop_pos,
                                                   GtkTreeViewDropPosition *return_drop_pos,
                                                   GdkDragAction       *return_drag_action);
static void    gimp_layer_tree_view_drop_color    (GimpContainerTreeView *view,
                                                   const GimpRGB       *color,
                                                   GimpViewable        *dest_viewable,
                                                   GtkTreeViewDropPosition  drop_pos);
114 115
static void    gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView *view,
                                                   GList               *uri_list,
116 117
                                                   GimpViewable        *dest_viewable,
                                                   GtkTreeViewDropPosition  drop_pos);
118
static void   gimp_layer_tree_view_drop_component (GimpContainerTreeView *tree_view,
119
                                                   GimpImage           *image,
120 121 122
                                                   GimpChannelType      component,
                                                   GimpViewable        *dest_viewable,
                                                   GtkTreeViewDropPosition  drop_pos);
123 124 125 126
static void   gimp_layer_tree_view_drop_pixbuf    (GimpContainerTreeView *tree_view,
                                                   GdkPixbuf           *pixbuf,
                                                   GimpViewable        *dest_viewable,
                                                   GtkTreeViewDropPosition  drop_pos);
127

128
static void   gimp_layer_tree_view_set_image      (GimpItemTreeView    *view,
129
                                                   GimpImage           *image);
130
static GimpItem * gimp_layer_tree_view_item_new   (GimpImage           *image);
131

132
static void   gimp_layer_tree_view_floating_selection_changed
133
                                                  (GimpImage           *image,
134 135
                                                   GimpLayerTreeView   *view);

136 137
static void   gimp_layer_tree_view_paint_mode_menu_callback
                                                  (GtkWidget           *widget,
138
                                                   GimpLayerTreeView   *view);
139 140
static void   gimp_layer_tree_view_opacity_scale_changed
                                                  (GtkAdjustment       *adj,
141
                                                   GimpLayerTreeView   *view);
142 143 144
static void   gimp_layer_tree_view_lock_alpha_button_toggled
                                                  (GtkWidget           *widget,
                                                   GimpLayerTreeView   *view);
145 146 147

static void   gimp_layer_tree_view_layer_signal_handler
                                                  (GimpLayer           *layer,
148
                                                   GimpLayerTreeView   *view);
149
static void   gimp_layer_tree_view_update_options (GimpLayerTreeView   *view,
150
                                                   GimpLayer           *layer);
151
static void   gimp_layer_tree_view_update_menu    (GimpLayerTreeView   *view,
152
                                                   GimpLayer           *layer);
153

154 155 156
static void   gimp_layer_tree_view_mask_update    (GimpLayerTreeView   *view,
                                                   GtkTreeIter         *iter,
                                                   GimpLayer           *layer);
157 158
static void   gimp_layer_tree_view_mask_changed   (GimpLayer           *layer,
                                                   GimpLayerTreeView   *view);
159
static void   gimp_layer_tree_view_renderer_update(GimpViewRenderer    *renderer,
160 161 162 163
                                                   GimpLayerTreeView   *view);

static void   gimp_layer_tree_view_update_borders (GimpLayerTreeView   *view,
                                                   GtkTreeIter         *iter);
164
static void   gimp_layer_tree_view_mask_callback  (GimpLayerMask       *mask,
165 166 167 168 169 170 171 172 173 174
                                                   GimpLayerTreeView   *view);
static void   gimp_layer_tree_view_layer_clicked  (GimpCellRendererViewable *cell,
                                                   const gchar         *path,
                                                   GdkModifierType      state,
                                                   GimpLayerTreeView   *view);
static void   gimp_layer_tree_view_mask_clicked   (GimpCellRendererViewable *cell,
                                                   const gchar         *path,
                                                   GdkModifierType      state,
                                                   GimpLayerTreeView   *view);

175 176 177 178 179 180
static void   gimp_layer_tree_view_alpha_update   (GimpLayerTreeView   *view,
                                                   GtkTreeIter         *iter,
                                                   GimpLayer           *layer);
static void   gimp_layer_tree_view_alpha_changed  (GimpLayer           *layer,
                                                   GimpLayerTreeView   *view);

181

182 183 184
G_DEFINE_TYPE_WITH_CODE (GimpLayerTreeView, gimp_layer_tree_view,
                         GIMP_TYPE_DRAWABLE_TREE_VIEW,
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONTAINER_VIEW,
185
                                                gimp_layer_tree_view_view_iface_init))
186

187 188
#define parent_class gimp_layer_tree_view_parent_class

189
static GimpContainerViewInterface *parent_view_iface = NULL;
190 191 192


static void
193
gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass)
194
{
195
  GObjectClass               *object_class = G_OBJECT_CLASS (klass);
196 197
  GimpContainerTreeViewClass *tree_view_class;
  GimpItemTreeViewClass      *item_view_class;
198

199 200
  tree_view_class = GIMP_CONTAINER_TREE_VIEW_CLASS (klass);
  item_view_class = GIMP_ITEM_TREE_VIEW_CLASS (klass);
201

202
  object_class->constructor = gimp_layer_tree_view_constructor;
203
  object_class->finalize    = gimp_layer_tree_view_finalize;
204

205
  tree_view_class->drop_possible   = gimp_layer_tree_view_drop_possible;
206
  tree_view_class->drop_color      = gimp_layer_tree_view_drop_color;
207
  tree_view_class->drop_uri_list   = gimp_layer_tree_view_drop_uri_list;
208
  tree_view_class->drop_component  = gimp_layer_tree_view_drop_component;
209
  tree_view_class->drop_pixbuf     = gimp_layer_tree_view_drop_pixbuf;
210

211 212 213
  item_view_class->item_type       = GIMP_TYPE_LAYER;
  item_view_class->signal_name     = "active-layer-changed";

214
  item_view_class->set_image       = gimp_layer_tree_view_set_image;
215 216 217
  item_view_class->get_container   = gimp_image_get_layers;
  item_view_class->get_active_item = (GimpGetItemFunc) gimp_image_get_active_layer;
  item_view_class->set_active_item = (GimpSetItemFunc) gimp_image_set_active_layer;
218
  item_view_class->reorder_item    = (GimpReorderItemFunc) gimp_image_reorder_layer;
219
  item_view_class->add_item        = (GimpAddItemFunc) gimp_image_add_layer;
220 221 222 223 224 225 226
  item_view_class->remove_item     = (GimpRemoveItemFunc) gimp_image_remove_layer;
  item_view_class->new_item        = gimp_layer_tree_view_item_new;

  item_view_class->action_group        = "layers";
  item_view_class->activate_action     = "layers-text-tool";
  item_view_class->edit_action         = "layers-edit-attributes";
  item_view_class->new_action          = "layers-new";
227
  item_view_class->new_default_action  = "layers-new-last-values";
228 229 230 231 232 233 234
  item_view_class->raise_action        = "layers-raise";
  item_view_class->raise_top_action    = "layers-raise-to-top";
  item_view_class->lower_action        = "layers-lower";
  item_view_class->lower_bottom_action = "layers-lower-to-bottom";
  item_view_class->duplicate_action    = "layers-duplicate";
  item_view_class->delete_action       = "layers-delete";
  item_view_class->reorder_desc        = _("Reorder Layer");
235 236

  g_type_class_add_private (klass, sizeof (GimpLayerTreeViewPriv));
237 238
}

239 240 241 242 243 244
static void
gimp_layer_tree_view_view_iface_init (GimpContainerViewInterface *iface)
{
  parent_view_iface = g_type_interface_peek_parent (iface);

  iface->set_container = gimp_layer_tree_view_set_container;
245
  iface->set_context   = gimp_layer_tree_view_set_context;
246 247 248
  iface->insert_item   = gimp_layer_tree_view_insert_item;
  iface->select_item   = gimp_layer_tree_view_select_item;
  iface->set_view_size = gimp_layer_tree_view_set_view_size;
249 250

  iface->model_is_tree = TRUE;
251 252
}

253
static void
254
gimp_layer_tree_view_init (GimpLayerTreeView *view)
255
{
256
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
257
  GtkWidget             *table;
258
  GtkWidget             *hbox;
259 260
  GtkWidget             *image;
  GtkIconSize            icon_size;
261
  PangoAttribute        *attr;
262

263 264 265 266
  view->priv = G_TYPE_INSTANCE_GET_PRIVATE (view,
                                            GIMP_TYPE_LAYER_TREE_VIEW,
                                            GimpLayerTreeViewPriv);

267 268 269 270 271 272 273 274 275
  /* The following used to read:
   *
   * tree_view->model_columns[tree_view->n_model_columns++] = ...
   *
   * but combining the two lead to gcc miscompiling the function on ppc/ia64
   * (model_column_mask and model_column_mask_visible would have the same
   * value, probably due to bad instruction reordering). See bug #113144 for
   * more info.
   */
276
  view->priv->model_column_mask = tree_view->n_model_columns;
277
  tree_view->model_columns[tree_view->n_model_columns] = GIMP_TYPE_VIEW_RENDERER;
278
  tree_view->n_model_columns++;
279

280
  view->priv->model_column_mask_visible = tree_view->n_model_columns;
281 282
  tree_view->model_columns[tree_view->n_model_columns] = G_TYPE_BOOLEAN;
  tree_view->n_model_columns++;
283 284 285

  /*  Paint mode menu  */

286
  view->priv->paint_mode_menu = gimp_paint_mode_menu_new (FALSE, FALSE);
287 288 289
  gimp_item_tree_view_add_options (GIMP_ITEM_TREE_VIEW (view),
                                   _("Mode:"),
                                   view->priv->paint_mode_menu);
290

291
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (view->priv->paint_mode_menu),
292 293 294 295
                              GIMP_NORMAL_MODE,
                              G_CALLBACK (gimp_layer_tree_view_paint_mode_menu_callback),
                              view);

296
  gimp_help_set_help_data (view->priv->paint_mode_menu, NULL,
297
                           GIMP_HELP_LAYER_DIALOG_PAINT_MODE_MENU);
298

299 300
  /*  Opacity scale  */

301 302
  table = gtk_table_new (2, 1, FALSE);

303
  view->priv->opacity_adjustment =
304 305
    GTK_ADJUSTMENT (gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
                                          NULL, -1, -1,
306 307 308 309
                                          100.0, 0.0, 100.0, 1.0, 10.0, 1,
                                          TRUE, 0.0, 0.0,
                                          NULL,
                                          GIMP_HELP_LAYER_DIALOG_OPACITY_SCALE));
310 311 312
  gimp_item_tree_view_add_options (GIMP_ITEM_TREE_VIEW (view),
                                   _("Opacity:"),
                                   table);
313

314
  g_signal_connect (view->priv->opacity_adjustment, "value-changed",
315 316 317 318
                    G_CALLBACK (gimp_layer_tree_view_opacity_scale_changed),
                    view);

  /*  Lock alpha toggle  */
319

320
  hbox = gimp_item_tree_view_get_lock_box (GIMP_ITEM_TREE_VIEW (view));
321

322
  view->priv->lock_alpha_toggle = gtk_toggle_button_new ();
323 324
  gtk_box_pack_start (GTK_BOX (hbox), view->priv->lock_alpha_toggle,
                      FALSE, FALSE, 0);
325
  gtk_widget_show (view->priv->lock_alpha_toggle);
326

327
  g_signal_connect (view->priv->lock_alpha_toggle, "toggled",
328
                    G_CALLBACK (gimp_layer_tree_view_lock_alpha_button_toggled),
329
                    view);
330

331
  gimp_help_set_help_data (view->priv->lock_alpha_toggle, _("Lock alpha channel"),
332
                           GIMP_HELP_LAYER_DIALOG_LOCK_ALPHA_BUTTON);
333

334
  gtk_widget_style_get (GTK_WIDGET (view),
335
                        "button-icon-size", &icon_size,
336 337 338
                        NULL);

  image = gtk_image_new_from_stock (GIMP_STOCK_TRANSPARENCY, icon_size);
339
  gtk_container_add (GTK_CONTAINER (view->priv->lock_alpha_toggle), image);
340 341
  gtk_widget_show (image);

342
  view->priv->italic_attrs = pango_attr_list_new ();
343 344 345
  attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
  attr->start_index = 0;
  attr->end_index   = -1;
346
  pango_attr_list_insert (view->priv->italic_attrs, attr);
347

348
  view->priv->bold_attrs = pango_attr_list_new ();
349 350 351
  attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
  attr->start_index = 0;
  attr->end_index   = -1;
352
  pango_attr_list_insert (view->priv->bold_attrs, attr);
353 354 355 356 357 358 359 360 361
}

static GObject *
gimp_layer_tree_view_constructor (GType                  type,
                                  guint                  n_params,
                                  GObjectConstructParam *params)
{
  GimpContainerTreeView *tree_view;
  GimpLayerTreeView     *layer_view;
362
  GtkWidget             *button;
363 364 365 366 367 368 369
  GObject               *object;

  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);

  tree_view  = GIMP_CONTAINER_TREE_VIEW (object);
  layer_view = GIMP_LAYER_TREE_VIEW (object);

370
  layer_view->priv->mask_cell = gimp_cell_renderer_viewable_new ();
371
  gtk_tree_view_column_pack_start (tree_view->main_column,
372
                                   layer_view->priv->mask_cell,
373 374
                                   FALSE);
  gtk_tree_view_column_set_attributes (tree_view->main_column,
375
                                       layer_view->priv->mask_cell,
376
                                       "renderer",
377
                                       layer_view->priv->model_column_mask,
378
                                       "visible",
379
                                       layer_view->priv->model_column_mask_visible,
380 381
                                       NULL);

Michael Natterer's avatar
Michael Natterer committed
382 383
  gimp_container_tree_view_add_renderer_cell (tree_view,
                                              layer_view->priv->mask_cell);
384 385 386 387

  g_signal_connect (tree_view->renderer_cell, "clicked",
                    G_CALLBACK (gimp_layer_tree_view_layer_clicked),
                    layer_view);
388
  g_signal_connect (layer_view->priv->mask_cell, "clicked",
389 390 391
                    G_CALLBACK (gimp_layer_tree_view_mask_clicked),
                    layer_view);

392 393 394 395 396 397 398 399
  gimp_dnd_uri_list_dest_add  (GTK_WIDGET (tree_view->view),
                               NULL, tree_view);
  gimp_dnd_component_dest_add (GTK_WIDGET (tree_view->view),
                               NULL, tree_view);
  gimp_dnd_viewable_dest_add  (GTK_WIDGET (tree_view->view), GIMP_TYPE_CHANNEL,
                               NULL, tree_view);
  gimp_dnd_viewable_dest_add  (GTK_WIDGET (tree_view->view), GIMP_TYPE_LAYER_MASK,
                               NULL, tree_view);
400 401
  gimp_dnd_pixbuf_dest_add    (GTK_WIDGET (tree_view->view),
                               NULL, tree_view);
402

403
  /*  hide basically useless edit button  */
404
  gtk_widget_hide (gimp_item_tree_view_get_edit_button (GIMP_ITEM_TREE_VIEW (layer_view)));
405

406 407 408 409 410
  button = gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
                                          "layers-new-group", NULL);
  gtk_box_reorder_child (GTK_BOX (GIMP_EDITOR (layer_view)->button_box),
                         button, 2);

411 412
  button = gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
                                          "layers-anchor", NULL);
413
  gimp_container_view_enable_dnd (GIMP_CONTAINER_VIEW (layer_view),
414
                                  GTK_BUTTON (button),
415
                                  GIMP_TYPE_LAYER);
416
  gtk_box_reorder_child (GTK_BOX (GIMP_EDITOR (layer_view)->button_box),
417
                         button, 6);
418

419
  return object;
420 421
}

422 423 424 425 426
static void
gimp_layer_tree_view_finalize (GObject *object)
{
  GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (object);

427
  if (layer_view->priv->italic_attrs)
428
    {
429 430
      pango_attr_list_unref (layer_view->priv->italic_attrs);
      layer_view->priv->italic_attrs = NULL;
431 432
    }

433
  if (layer_view->priv->bold_attrs)
434
    {
435 436
      pango_attr_list_unref (layer_view->priv->bold_attrs);
      layer_view->priv->bold_attrs = NULL;
437 438 439 440 441
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

442 443 444 445

/*  GimpContainerView methods  */

static void
446
gimp_layer_tree_view_set_container (GimpContainerView *view,
447
                                    GimpContainer     *container)
448
{
449 450
  GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
  GimpContainer     *old_container;
451

452
  old_container = gimp_container_view_get_container (view);
453

454
  if (old_container)
455
    {
456 457 458 459 460 461 462 463 464 465 466 467 468 469
      gimp_tree_handler_disconnect (layer_view->priv->mode_changed_handler);
      layer_view->priv->mode_changed_handler = NULL;

      gimp_tree_handler_disconnect (layer_view->priv->opacity_changed_handler);
      layer_view->priv->opacity_changed_handler = NULL;

      gimp_tree_handler_disconnect (layer_view->priv->lock_alpha_changed_handler);
      layer_view->priv->lock_alpha_changed_handler = NULL;

      gimp_tree_handler_disconnect (layer_view->priv->mask_changed_handler);
      layer_view->priv->mask_changed_handler = NULL;

      gimp_tree_handler_disconnect (layer_view->priv->alpha_changed_handler);
      layer_view->priv->alpha_changed_handler = NULL;
470 471
    }

472
  parent_view_iface->set_container (view, container);
473

474
  if (container)
475
    {
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
      layer_view->priv->mode_changed_handler =
        gimp_tree_handler_connect (container, "mode-changed",
                                   G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
                                   view);

      layer_view->priv->opacity_changed_handler =
        gimp_tree_handler_connect (container, "opacity-changed",
                                   G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
                                   view);

      layer_view->priv->lock_alpha_changed_handler =
        gimp_tree_handler_connect (container, "lock-alpha-changed",
                                   G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
                                   view);

      layer_view->priv->mask_changed_handler =
        gimp_tree_handler_connect (container, "mask-changed",
                                   G_CALLBACK (gimp_layer_tree_view_mask_changed),
                                   view);

      layer_view->priv->alpha_changed_handler =
        gimp_tree_handler_connect (container, "alpha-changed",
                                   G_CALLBACK (gimp_layer_tree_view_alpha_changed),
                                   view);
500 501 502
    }
}

503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
typedef struct
{
  gint         mask_column;
  GimpContext *context;
} SetContextForeachData;

static gboolean
gimp_layer_tree_view_set_context_foreach (GtkTreeModel *model,
                                          GtkTreePath  *path,
                                          GtkTreeIter  *iter,
                                          gpointer      data)
{
  SetContextForeachData *context_data = data;
  GimpViewRenderer      *renderer;

  gtk_tree_model_get (model, iter,
                      context_data->mask_column, &renderer,
                      -1);

  if (renderer)
    {
      gimp_view_renderer_set_context (renderer, context_data->context);

      g_object_unref (renderer);
    }

  return FALSE;
}

532 533 534 535 536 537 538 539 540 541 542
static void
gimp_layer_tree_view_set_context (GimpContainerView *view,
                                  GimpContext       *context)
{
  GimpContainerTreeView *tree_view  = GIMP_CONTAINER_TREE_VIEW (view);
  GimpLayerTreeView     *layer_view = GIMP_LAYER_TREE_VIEW (view);

  parent_view_iface->set_context (view, context);

  if (tree_view->model)
    {
543 544 545 546 547 548
      SetContextForeachData context_data = { layer_view->priv->model_column_mask,
                                             context };

      gtk_tree_model_foreach (tree_view->model,
                              gimp_layer_tree_view_set_context_foreach,
                              &context_data);
549 550 551
    }
}

552 553 554
static gpointer
gimp_layer_tree_view_insert_item (GimpContainerView *view,
                                  GimpViewable      *viewable,
555
                                  gpointer           parent_insert_data,
556 557
                                  gint               index)
{
558 559 560
  GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
  GimpLayer         *layer;
  GtkTreeIter       *iter;
561

562 563
  iter = parent_view_iface->insert_item (view, viewable,
                                         parent_insert_data, index);
564 565 566

  layer = GIMP_LAYER (viewable);

567 568 569
  if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
    gimp_layer_tree_view_alpha_update (layer_view, iter, layer);

570
  gimp_layer_tree_view_mask_update (layer_view, iter, layer);
571 572 573 574

  return iter;
}

575
static gboolean
576
gimp_layer_tree_view_select_item (GimpContainerView *view,
577 578
                                  GimpViewable      *item,
                                  gpointer           insert_data)
579
{
580 581
  GimpItemTreeView  *item_view  = GIMP_ITEM_TREE_VIEW (view);
  GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
582
  gboolean           success;
583

584
  success = parent_view_iface->select_item (view, item, insert_data);
585 586 587

  if (item)
    {
588 589 590 591 592
      if (success)
        {
          gimp_layer_tree_view_update_borders (layer_view,
                                               (GtkTreeIter *) insert_data);
          gimp_layer_tree_view_update_options (layer_view, GIMP_LAYER (item));
593
          gimp_layer_tree_view_update_menu (layer_view, GIMP_LAYER (item));
594
        }
595

596
      if (! success || gimp_layer_is_floating_sel (GIMP_LAYER (item)))
597
        {
598
          gtk_widget_set_sensitive (gimp_item_tree_view_get_edit_button (item_view), FALSE);
599
        }
600 601
    }

602
  return success;
603 604
}

605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
typedef struct
{
  gint mask_column;
  gint view_size;
  gint border_width;
} SetSizeForeachData;

static gboolean
gimp_layer_tree_view_set_view_size_foreach (GtkTreeModel *model,
                                            GtkTreePath  *path,
                                            GtkTreeIter  *iter,
                                            gpointer      data)
{
  SetSizeForeachData *size_data = data;
  GimpViewRenderer   *renderer;

  gtk_tree_model_get (model, iter,
                      size_data->mask_column, &renderer,
                      -1);

  if (renderer)
    {
      gimp_view_renderer_set_size (renderer,
                                   size_data->view_size,
                                   size_data->border_width);

      g_object_unref (renderer);
    }

  return FALSE;
}

637
static void
638
gimp_layer_tree_view_set_view_size (GimpContainerView *view)
639
{
640
  GimpContainerTreeView *tree_view  = GIMP_CONTAINER_TREE_VIEW (view);
641

642
  if (tree_view->model)
643
    {
644
      GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
645
      SetSizeForeachData size_data;
646

647
      size_data.mask_column = layer_view->priv->model_column_mask;
648

649 650
      size_data.view_size =
        gimp_container_view_get_view_size (view, &size_data.border_width);
651

652 653 654
      gtk_tree_model_foreach (tree_view->model,
                              gimp_layer_tree_view_set_view_size_foreach,
                              &size_data);
655 656
    }

657
  parent_view_iface->set_view_size (view);
658
}
659

660

661 662 663 664
/*  GimpContainerTreeView methods  */

static gboolean
gimp_layer_tree_view_drop_possible (GimpContainerTreeView   *tree_view,
665
                                    GimpDndType              src_type,
666 667 668
                                    GimpViewable            *src_viewable,
                                    GimpViewable            *dest_viewable,
                                    GtkTreeViewDropPosition  drop_pos,
669 670 671
                                    GtkTreeViewDropPosition *return_drop_pos,
                                    GdkDragAction           *return_drag_action)
{
672 673 674
  /* If we are dropping a new layer, check if the destionation image
   * has a floating selection.
   */
675 676 677
  if  (src_type == GIMP_DND_TYPE_URI_LIST     ||
       src_type == GIMP_DND_TYPE_TEXT_PLAIN   ||
       src_type == GIMP_DND_TYPE_NETSCAPE_URL ||
678
       src_type == GIMP_DND_TYPE_COMPONENT    ||
679
       src_type == GIMP_DND_TYPE_PIXBUF       ||
680
       GIMP_IS_DRAWABLE (src_viewable))
681
    {
682
      GimpImage *dest_image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (tree_view));
683

684
      if (gimp_image_get_floating_selection (dest_image))
685 686 687
        return FALSE;
    }

688 689 690 691 692 693 694
  return GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view,
                                                                       src_type,
                                                                       src_viewable,
                                                                       dest_viewable,
                                                                       drop_pos,
                                                                       return_drop_pos,
                                                                       return_drag_action);
695 696 697 698 699 700 701 702 703 704 705 706 707
}

static void
gimp_layer_tree_view_drop_color (GimpContainerTreeView   *view,
                                 const GimpRGB           *color,
                                 GimpViewable            *dest_viewable,
                                 GtkTreeViewDropPosition  drop_pos)
{
  if (gimp_drawable_is_text_layer (GIMP_DRAWABLE (dest_viewable)))
    {
      gimp_text_layer_set (GIMP_TEXT_LAYER (dest_viewable), NULL,
                           "color", color,
                           NULL);
708
      gimp_image_flush (gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view)));
709
      return;
710 711
    }

712 713 714
  GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_color (view, color,
                                                             dest_viewable,
                                                             drop_pos);
715 716 717
}

static void
718 719 720 721
gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView   *view,
                                    GList                   *uri_list,
                                    GimpViewable            *dest_viewable,
                                    GtkTreeViewDropPosition  drop_pos)
722
{
723 724
  GimpItemTreeView  *item_view = GIMP_ITEM_TREE_VIEW (view);
  GimpContainerView *cont_view = GIMP_CONTAINER_VIEW (view);
725
  GimpImage         *image     = gimp_item_tree_view_get_image (item_view);
726 727
  GimpLayer         *parent;
  gint               index;
728
  GList             *list;
729

730 731 732
  index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
                                              drop_pos,
                                              (GimpViewable **) &parent);
733

734
  for (list = uri_list; list; list = g_list_next (list))
735 736
    {
      const gchar       *uri   = list->data;
737
      GList             *new_layers;
738 739 740
      GimpPDBStatusType  status;
      GError            *error = NULL;

741 742 743 744 745 746
      new_layers = file_open_layers (image->gimp,
                                     gimp_container_view_get_context (cont_view),
                                     NULL,
                                     image, FALSE,
                                     uri, GIMP_RUN_INTERACTIVE, NULL,
                                     &status, &error);
747

748
      if (new_layers)
749
        {
750
          gimp_image_add_layers (image, new_layers, parent, index,
751 752 753 754
                                 0, 0,
                                 gimp_image_get_width (image),
                                 gimp_image_get_height (image),
                                 _("Drop layers"));
755

756
          index += g_list_length (new_layers);
757

758
          g_list_free (new_layers);
759 760 761
        }
      else if (status != GIMP_PDB_CANCEL)
        {
762
          gchar *filename = file_utils_uri_display_name (uri);
763

Sven Neumann's avatar
Sven Neumann committed
764
          gimp_message (image->gimp, G_OBJECT (view), GIMP_MESSAGE_ERROR,
765 766
                        _("Opening '%s' failed:\n\n%s"),
                        filename, error->message);
767 768 769 770 771 772

          g_clear_error (&error);
          g_free (filename);
        }
    }

773
  gimp_image_flush (image);
774 775
}

776 777 778 779 780 781 782
static void
gimp_layer_tree_view_drop_component (GimpContainerTreeView   *tree_view,
                                     GimpImage               *src_image,
                                     GimpChannelType          component,
                                     GimpViewable            *dest_viewable,
                                     GtkTreeViewDropPosition  drop_pos)
{
783
  GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (tree_view);
784
  GimpImage        *image     = gimp_item_tree_view_get_image (item_view);
785
  GimpChannel      *channel;
786
  GimpItem         *new_item;
787 788
  GimpLayer        *parent;
  gint              index;
789 790
  const gchar      *desc;

791 792 793
  index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
                                              drop_pos,
                                              (GimpViewable **) &parent);
794 795 796

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

797
  new_item = gimp_item_convert (GIMP_ITEM (channel), image,
798
                                GIMP_TYPE_LAYER);
799 800 801 802 803

  g_object_unref (channel);

  gimp_enum_get_value (GIMP_TYPE_CHANNEL_TYPE, component,
                       NULL, NULL, &desc, NULL);
804 805
  gimp_object_take_name (GIMP_OBJECT (new_item),
                         g_strdup_printf (_("%s Channel Copy"), desc));
806

807 808 809
  gimp_image_add_layer (image, GIMP_LAYER (new_item), parent, index, TRUE);

  gimp_image_flush (image);
810 811
}

812 813 814 815 816 817 818
static void
gimp_layer_tree_view_drop_pixbuf (GimpContainerTreeView   *tree_view,
                                  GdkPixbuf               *pixbuf,
                                  GimpViewable            *dest_viewable,
                                  GtkTreeViewDropPosition  drop_pos)
{
  GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (tree_view);
819
  GimpImage        *image     = gimp_item_tree_view_get_image (item_view);
820
  GimpLayer        *new_layer;
821 822
  GimpLayer        *parent;
  gint              index;
823

824 825 826
  index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
                                              drop_pos,
                                              (GimpViewable **) &parent);
827 828 829 830 831 832 833

  new_layer =
    gimp_layer_new_from_pixbuf (pixbuf, image,
                                gimp_image_base_type_with_alpha (image),
                                _("Dropped Buffer"),
                                GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

834 835
  gimp_image_add_layer (image, new_layer, parent, index, TRUE);

836 837 838
  gimp_image_flush (image);
}

839

840 841
/*  GimpItemTreeView methods  */

842 843
static void
gimp_layer_tree_view_set_image (GimpItemTreeView *view,
844
                                GimpImage        *image)
845
{
846 847
  if (gimp_item_tree_view_get_image (view))
    g_signal_handlers_disconnect_by_func (gimp_item_tree_view_get_image (view),
848 849 850
                                          gimp_layer_tree_view_floating_selection_changed,
                                          view);

851
  GIMP_ITEM_TREE_VIEW_CLASS (parent_class)->set_image (view, image);
852

853 854
  if (gimp_item_tree_view_get_image (view))
    g_signal_connect (gimp_item_tree_view_get_image (view),
855
                      "floating-selection-changed",
856 857 858 859
                      G_CALLBACK (gimp_layer_tree_view_floating_selection_changed),
                      view);
}

860 861
static GimpItem *
gimp_layer_tree_view_item_new (GimpImage *image)
862
{
863 864 865 866 867 868 869 870 871 872 873
  GimpLayer *new_layer;

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                               _("New Layer"));

  new_layer = gimp_layer_new (image,
                              gimp_image_get_width (image),
                              gimp_image_get_height (image),
                              gimp_image_base_type_with_alpha (image),
                              _("Empty Layer"), 1.0, GIMP_NORMAL_MODE);

874 875
  gimp_image_add_layer (image, new_layer,
                        GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
876 877 878 879

  gimp_image_undo_group_end (image);

  return GIMP_ITEM (new_layer);
880 881 882
}


883 884 885
/*  callbacks  */