23#include <tqtoolbutton.h>
26#include <tqfontmetrics.h>
36#include <tqcombobox.h>
37#include <tqcheckbox.h>
41#include <tdepopupmenu.h>
42#include <tdemessagebox.h>
43#include <kpushbutton.h>
44#include <kiconloader.h>
45#include <kicontheme.h>
48#include <KoPartSelectAction.h>
50#include "kis_layerlist.h"
51#include "kis_cmb_composite.h"
52#include "kis_int_spinbox.h"
53#include "wdglayerbox.h"
54#include "kis_colorspace.h"
55#include "kis_paint_device.h"
57#include "kis_group_layer.h"
60#include "kis_populate_visitor.h"
62#include "kis_layerbox.h"
64KisLayerBox::KisLayerBox(
KisCanvasSubject *subject, TQWidget *parent,
const char *name)
65 : super(parent, name), m_image(0)
67 TQVBoxLayout *vbox =
new TQVBoxLayout(
this);
68 vbox->setAutoAdd(
true);
70 m_lst =
new WdgLayerBox(
this);
71 setMinimumSize(m_lst->minimumSizeHint());
73 TQToolTip::add(m_lst->bnAdd, i18n(
"Create new layer"));
75 TQToolTip::add(m_lst->bnDelete, i18n(
"Remove current layer"));
77 TQToolTip::add(m_lst->bnRaise, i18n(
"Raise current layer"));
78 m_lst->bnRaise->setEnabled(
false);
80 m_lst->bnLower->setEnabled(
false);
81 TQToolTip::add(m_lst->bnLower, i18n(
"Lower current layer"));
83 TQToolTip::add(m_lst->bnProperties, i18n(
"Properties for layer"));
85 TDEIconLoader il(
"chalk" );
87 list()->setPreviewsShown(
true);
89 list()->setFoldersCanBeActive(
true);
91 list()->addProperty(
"visible", i18n(
"Visible"), loadPixmap(
"visible.png", il, TDEIcon::SizeSmallMedium),
92 loadPixmap(
"novisible.png", il, TDEIcon::SizeSmallMedium),
true);
94 list()->addProperty(
"locked", i18n(
"Locked"), loadPixmap(
"locked.png", il, TDEIcon::SizeSmallMedium),
95 loadPixmap(
"unlocked.png", il, TDEIcon::SizeSmallMedium));
98 connect(list()->contextMenu(), TQ_SIGNAL(aboutToShow()), TQ_SLOT(slotAboutToShow()));
99 connect(list(), TQ_SIGNAL(activated(LayerItem*)),
100 TQ_SLOT(slotLayerActivated(LayerItem*)));
101 connect(list(), TQ_SIGNAL(displayNameChanged(LayerItem*,
const TQString&)),
102 TQ_SLOT(slotLayerDisplayNameChanged(LayerItem*,
const TQString&)));
103 connect(list(), TQ_SIGNAL(propertyChanged(LayerItem*,
const TQString&,
bool)),
104 TQ_SLOT(slotLayerPropertyChanged(LayerItem*,
const TQString&,
bool)));
105 connect(list(), TQ_SIGNAL(layerMoved(LayerItem*, LayerItem*, LayerItem*)),
106 TQ_SLOT(slotLayerMoved(LayerItem*, LayerItem*, LayerItem*)));
107 connect(list(), TQ_SIGNAL(requestNewLayer(LayerItem*, LayerItem*)),
108 TQ_SLOT(slotRequestNewLayer(LayerItem*, LayerItem*)));
109 connect(list(), TQ_SIGNAL(requestNewFolder(LayerItem*, LayerItem*)),
110 TQ_SLOT(slotRequestNewFolder(LayerItem*, LayerItem*)));
111 connect(list(), TQ_SIGNAL(requestNewAdjustmentLayer(LayerItem*, LayerItem*)),
112 TQ_SLOT(slotRequestNewAdjustmentLayer(LayerItem*, LayerItem*)));
113 connect(list(), TQ_SIGNAL(requestNewObjectLayer(LayerItem*, LayerItem*,
const KoDocumentEntry&)),
114 TQ_SLOT(slotRequestNewObjectLayer(LayerItem*, LayerItem*,
const KoDocumentEntry&)));
115 connect(list(), TQ_SIGNAL(requestRemoveLayer(LayerItem*)),
116 TQ_SLOT(slotRequestRemoveLayer(LayerItem*)));
117 connect(list(), TQ_SIGNAL(requestLayerProperties(LayerItem*)),
118 TQ_SLOT(slotRequestLayerProperties(LayerItem*)));
120 m_newLayerMenu =
new TDEPopupMenu(
this);
121 m_lst->bnAdd->setPopup(m_newLayerMenu);
122 m_lst->bnAdd->setPopupDelay(1);
123 m_newLayerMenu->insertItem( SmallIconSet(
"document-new" ), i18n(
"&New Layer..." ), PAINT_LAYER );
124 m_newLayerMenu->insertItem( SmallIconSet(
"folder" ), i18n(
"New &Group Layer..." ), GROUP_LAYER );
125 m_newLayerMenu->insertItem( SmallIconSet(
"tool_filter" ), i18n(
"New &Adjustment Layer..." ), ADJUSTMENT_LAYER );
126 m_partLayerAction =
new KoPartSelectAction( i18n(
"New &Object Layer" ),
"gear",
this );
127 m_partLayerAction->plug( m_newLayerMenu );
128 connect(m_partLayerAction, TQ_SIGNAL(activated()),
this, TQ_SLOT(slotAddMenuActivated()));
129 connect(m_newLayerMenu, TQ_SIGNAL(activated(
int)),
this, TQ_SLOT(slotAddMenuActivated(
int)));
132 connect(m_lst->bnDelete, TQ_SIGNAL(clicked()), TQ_SLOT(slotRmClicked()));
133 connect(m_lst->bnRaise, TQ_SIGNAL(clicked()), TQ_SLOT(slotRaiseClicked()));
134 connect(m_lst->bnLower, TQ_SIGNAL(clicked()), TQ_SLOT(slotLowerClicked()));
135 connect(m_lst->bnProperties, TQ_SIGNAL(clicked()), TQ_SLOT(slotPropertiesClicked()));
136 connect(m_lst->intOpacity, TQ_SIGNAL(valueChanged(
int,
bool)), TQ_SIGNAL(sigOpacityChanged(
int,
bool)));
137 connect(m_lst->intOpacity, TQ_SIGNAL(finishedChanging(
int,
int)), TQ_SIGNAL(sigOpacityFinishedChanging(
int,
int)));
138 connect(m_lst->cmbComposite, TQ_SIGNAL(activated(
const KisCompositeOp&)), TQ_SIGNAL(sigItemComposite(
const KisCompositeOp&)));
143 connect(subject->
document(), TQ_SIGNAL(sigCommandExecuted()), TQ_SLOT(updateThumbnails()));
147KisLayerBox::~KisLayerBox()
151KisLayerList* KisLayerBox::list()
const
153 return m_lst->listLayers;
156void KisLayerBox::setImage(KisImageSP img)
162 m_image->disconnect(
this);
168 connect(img, TQ_SIGNAL(sigLayerActivated(KisLayerSP)),
this, TQ_SLOT(slotLayerActivated(KisLayerSP)));
169 connect(img, TQ_SIGNAL(sigLayerAdded(KisLayerSP)),
this, TQ_SLOT(slotLayerAdded(KisLayerSP)));
170 connect(img, TQ_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)),
171 this, TQ_SLOT(slotLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)));
172 connect(img, TQ_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)),
173 this, TQ_SLOT(slotLayerPropertiesChanged(KisLayerSP)));
174 connect(img, TQ_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)),
175 this, TQ_SLOT(slotLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)));
176 connect(img, TQ_SIGNAL(sigLayersChanged(KisGroupLayerSP)),
this, TQ_SLOT(slotLayersChanged(KisGroupLayerSP)));
177 connect(img, TQ_SIGNAL(sigLayerUpdated(KisLayerSP, TQRect)),
this, TQ_SLOT(slotLayerUpdated(KisLayerSP, TQRect)));
178 slotLayersChanged(img->rootLayer());
187void KisLayerBox::slotLayerActivated(KisLayerSP layer)
190 list()->setActiveLayer(layer->id());
192 list()->setActiveLayer(-1);
196void KisLayerBox::slotLayerAdded(KisLayerSP layer)
198 if (layer.data() == m_image->rootLayer().data() || list()->layer(layer->id()))
201 vKisLayerSP layersAdded;
203 if (layer->parent() == m_image->rootLayer())
205 KisPopulateVisitor visitor(list());
206 layer->accept(visitor);
207 layersAdded = visitor.layersAdded();
211 KisPopulateVisitor visitor(
static_cast<KisLayerItem*
>(list()->layer(layer->parent()->id())));
212 layer->accept(visitor);
213 layersAdded = visitor.layersAdded();
216 for (vKisLayerSP::iterator it = layersAdded.begin(); it != layersAdded.end(); ++it) {
222void KisLayerBox::slotLayerRemoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP)
224 list()->removeLayer(layer->id());
225 m_modified.remove(layer->id());
226 markModified(wasParent);
230void KisLayerBox::slotLayerMoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP)
232 int parentID = layer->parent()->id();
233 if (layer->parent() == m_image->rootLayer())
237 if (layer->prevSibling())
238 siblingID = layer->prevSibling()->id();
240 list()->moveLayer(layer->id(), parentID, siblingID);
242 markModified(layer->parent());
243 markModified(wasParent);
247void KisLayerBox::slotLayerPropertiesChanged(KisLayerSP layer)
249 if (KisLayerItem* item =
dynamic_cast<KisLayerItem*
>(list()->layer(layer->id())))
251 Q_ASSERT(item->layer() == layer.data());
258void KisLayerBox::slotLayersChanged(KisGroupLayerSP rootLayer)
261 KisPopulateVisitor visitor(list());
262 for (KisLayerSP layer = rootLayer->firstChild(); layer; layer = layer->nextSibling())
263 layer->accept(visitor);
265 for (TQListViewItemIterator it(list()->lastItem()); *it; --it)
266 m_modified.append(
static_cast<LayerItem*
>(*it)->id());
270void KisLayerBox::slotLayerUpdated(KisLayerSP layer, TQRect)
275void KisLayerBox::slotLayerActivated(LayerItem* item)
278 m_image->activate(m_image->findLayer(item->id()));
280 m_image->activate(0);
284void KisLayerBox::slotLayerDisplayNameChanged(LayerItem* item,
const TQString& displayName)
286 if(KisLayerSP layer = m_image->findLayer(item->id()))
287 layer->setName(displayName);
291void KisLayerBox::slotLayerPropertyChanged(LayerItem* item,
const TQString& name,
bool on)
293 if (KisLayerSP layer = m_image->findLayer(item->id()))
295 if (name ==
"visible")
296 layer->setVisible(on);
297 else if (name ==
"locked")
298 layer->setLocked(on);
302void KisLayerBox::slotLayerMoved(LayerItem* item, LayerItem*, LayerItem*)
304 KisLayerSP layer = m_image->findLayer(item->id());
305 KisGroupLayerSP parent;
307 parent =
dynamic_cast<KisGroupLayer*
>(m_image->findLayer(item->parent()->id()).data());
309 parent = m_image->rootLayer();
310 KisLayerSP above = 0;
311 if (item->nextSibling())
312 above = m_image->findLayer(item->nextSibling()->id());
314 m_image->moveLayer(layer, parent.data(), above);
318void KisLayerBox::slotRequestNewLayer(LayerItem* p, LayerItem* after)
320 KisLayer* l = m_image->rootLayer().data();
323 KisGroupLayerSP parent =
dynamic_cast<KisGroupLayer*
>(l);
325 KisLayerSP above = 0;
326 if (after && after->nextSibling())
327 above = m_image->findLayer(after->nextSibling()->id());
330 else if (p && p->firstChild())
331 above = parent->firstChild();
332 else if (!p && m_image->rootLayer()->childCount())
333 above = m_image->rootLayer()->firstChild();
334 emit sigRequestLayer(parent, above);
337void KisLayerBox::slotRequestNewFolder(LayerItem* p, LayerItem* after)
339 KisLayer* l = m_image->rootLayer().data();
342 KisGroupLayerSP parent =
dynamic_cast<KisGroupLayer*
>(l);
344 KisLayerSP above = 0;
345 if (after && after->nextSibling())
346 above = m_image->findLayer(after->nextSibling()->id());
349 else if (p && p->firstChild())
350 above = parent->firstChild();
351 else if (!p && m_image->rootLayer()->childCount())
352 above = m_image->rootLayer()->firstChild();
353 emit sigRequestGroupLayer(parent, above);
356void KisLayerBox::slotRequestNewAdjustmentLayer(LayerItem* p, LayerItem* after)
358 KisLayer* l = m_image->rootLayer().data();
361 KisGroupLayerSP parent =
dynamic_cast<KisGroupLayer*
>(l);
363 KisLayerSP above = 0;
364 if (after && after->nextSibling())
365 above = m_image->findLayer(after->nextSibling()->id());
368 else if (p && p->firstChild())
369 above = parent->firstChild();
370 else if (!p && m_image->rootLayer()->childCount())
371 above = m_image->rootLayer()->firstChild();
372 emit sigRequestAdjustmentLayer(parent, above);
375void KisLayerBox::slotRequestNewObjectLayer(LayerItem* p, LayerItem* after,
const KoDocumentEntry& entry)
377 KisLayer* l = m_image->rootLayer().data();
380 KisGroupLayerSP parent =
dynamic_cast<KisGroupLayer*
>(l);
382 KisLayerSP above = 0;
383 if (after && after->nextSibling())
384 above = m_image->findLayer(after->nextSibling()->id());
387 else if (p && p->firstChild())
388 above = parent->firstChild();
389 else if (!p && m_image->rootLayer()->childCount())
390 above = m_image->rootLayer()->firstChild();
391 emit sigRequestPartLayer(parent, above, entry);
394void KisLayerBox::slotRequestRemoveLayer(LayerItem* item)
396 if (KisLayerSP layer = m_image->findLayer(item->id())) {
397 m_image->removeLayer(layer);
402void KisLayerBox::slotRequestLayerProperties(LayerItem* item)
404 if (KisLayerSP layer = m_image->findLayer(item->id()))
406 emit sigRequestLayerProperties(layer);
410void KisLayerBox::updateUI()
412 m_lst->bnDelete->setEnabled(list()->activeLayer());
413 m_lst->bnRaise->setEnabled(list()->activeLayer() && (list()->activeLayer()->prevSibling() || list()->activeLayer()->parent()));
414 m_lst->bnLower->setEnabled(list()->activeLayer() && list()->activeLayer()->nextSibling());
415 m_lst->intOpacity->setEnabled(list()->activeLayer());
416 m_lst->cmbComposite->setEnabled(list()->activeLayer());
418 if (KisLayerSP active = m_image->activeLayer())
420 if (m_image->activeDevice())
421 slotSetColorSpace(m_image->activeDevice()->colorSpace());
423 slotSetColorSpace(m_image->colorSpace());
424 slotSetOpacity(
int(
float(active->opacity() * 100) / 255 + 0.5));
425 slotSetCompositeOp(active->compositeOp());
429void KisLayerBox::slotAboutToShow()
433void KisLayerBox::slotSetCompositeOp(
const KisCompositeOp& compositeOp)
435 m_lst->cmbComposite->blockSignals(
true);
436 m_lst->cmbComposite->setCurrentItem(compositeOp);
437 m_lst->cmbComposite->blockSignals(
false);
440void KisLayerBox::slotSetColorSpace(
const KisColorSpace * colorSpace)
442 m_lst->cmbComposite->blockSignals(
true);
444 m_lst->cmbComposite->blockSignals(
false);
448void KisLayerBox::slotSetOpacity(
int opacity)
450 m_lst->intOpacity->blockSignals(
true);
451 m_lst->intOpacity->setValue(opacity);
452 m_lst->intOpacity->blockSignals(
false);
455void KisLayerBox::clear()
461void KisLayerBox::slotAddMenuActivated(
int type)
466 KisGroupLayerSP root = m_image->rootLayer();
467 KisGroupLayerSP parent;
469 if (KisLayerSP active = m_image->activeLayer())
473 if (active->parent())
474 parent = active->parent();
479 above = m_image->rootLayer()->firstChild();
485 emit sigRequestLayer(parent, above);
488 emit sigRequestGroupLayer(parent, above);
490 case ADJUSTMENT_LAYER:
491 emit sigRequestAdjustmentLayer(parent, above);
495 emit sigRequestPartLayer(parent, above, m_partLayerAction->documentEntry());
499void KisLayerBox::slotRmClicked()
501 TQValueList<int> l = list()->selectedLayerIDs();
502 if (l.count() < 2 && list()->activeLayer() && !l.contains(list()->activeLayer()->
id()))
505 l.append(list()->activeLayer()->
id());
508 for (
int i = 0, n = l.count(); i < n; ++i)
510 m_modified.remove(l[i]);
511 m_image->removeLayer(m_image->findLayer(l[i]));
515void KisLayerBox::slotRaiseClicked()
517 TQValueList<int> l = list()->selectedLayerIDs();
518 if (l.count() < 2 && list()->activeLayer() && !l.contains(list()->activeLayer()->
id()))
521 l.append(list()->activeLayer()->
id());
524 KisLayerSP layer = m_image->findLayer(l.first());
525 if( l.count() == 1 && layer == layer->parent()->firstChild() && layer->parent() != m_image->rootLayer())
527 if (KisGroupLayerSP grandparent = layer->parent()->parent())
528 m_image->moveLayer(layer, grandparent, layer->parent().data());
532 for (
int i = 0, n = l.count(); i < n; ++i)
533 if (KisLayerSP li = m_image->findLayer(l[i]))
534 if (li->prevSibling())
535 m_image->moveLayer(li, li->parent(), li->prevSibling());
539 list()->ensureItemVisible( list()->layer( l.first() ) );
542void KisLayerBox::slotLowerClicked()
544 TQValueList<LayerItem*> l = list()->selectedLayers();
545 if (l.count() < 2 && list()->activeLayer() && !l.contains(list()->activeLayer()))
548 l.append(list()->activeLayer());
551 for (
int i = l.count() - 1; i >= 0; --i)
552 if (LayerItem *layer = l[i])
553 if (layer->nextSibling())
554 list()->moveLayer(layer, layer->parent(), layer->nextSibling());
557 list()->ensureItemVisible( l.last() );
560void KisLayerBox::slotPropertiesClicked()
562 if (KisLayerSP active = m_image->activeLayer())
563 emit sigRequestLayerProperties(active);
566void KisLayerBox::updateThumbnails()
569 while (m_modified.count() && again)
572 KisLayerItem* item =
static_cast<KisLayerItem*
>(list()->layer(m_modified.last()));
573 m_modified.pop_back();
574 if (!item || !item->updatePreview())
579void KisLayerBox::setUpdatesAndSignalsEnabled(
bool enable)
581 setUpdatesEnabled(enable);
582 m_lst->intOpacity->setUpdatesEnabled(enable);
583 m_lst->cmbComposite->setUpdatesEnabled(enable);
585 list()->blockSignals(!enable);
586 m_lst->intOpacity->blockSignals(!enable);
587 m_lst->cmbComposite->blockSignals(!enable);
591TQPixmap KisLayerBox::loadPixmap(
const TQString& filename,
const TDEIconLoader&
594 TQPixmap pixmap = il.loadIcon(filename, TDEIcon::NoGroup, size);
597 KMessageBox::error(0, i18n(
"Cannot find %1").arg(filename),
603void KisLayerBox::markModified(
KisLayer* layer)
609 while (layer && layer != m_image->rootLayer().data())
611 v.append(layer->
id());
614 for (
int i = v.count() - 1; i >= 0; --i)
615 if (!m_modified.contains(v[i]))
616 m_modified.append(v[i]);
619void KisLayerBox::printChalkLayers()
const
621 static int indent = 0;
622 static KisLayer *root = 0;
624 root = m_image->rootLayer();
627 TQString s = root->name();
628 if(
dynamic_cast<KisGroupLayer*
>( root ) )
629 s = TQString(
"[%1]").arg( s );
630 if( m_image->activeLayer().data() == root )
632 kdDebug() << (TQString().fill(
' ', indent) + s) << endl;
643void KisLayerBox::printLayerboxLayers()
const
645 static int indent = 0;
646 static LayerItem *root = 0;
649 for (LayerItem* layer = list()->firstChild(); layer; layer = layer->
nextSibling())
653 printLayerboxLayers();
659 TQString s = root->displayName();
660 if( root->isFolder() )
661 s = TQString(
"[%1]").arg( s );
662 if( list()->activeLayer() == root )
664 kdDebug() << (TQString().fill(
' ', indent) + s) << endl;
665 for (LayerItem* layer = root->firstChild(); layer; layer = layer->
nextSibling())
669 printLayerboxLayers();
675#include "kis_layerbox.moc"
KisCanvasSubject is part of the Observer pattern.
virtual KisDoc * document() const =0
XXX: Remove this method.
A colorspace is the definition of a certain color model in Chalk.
virtual KisCompositeOpList userVisiblecompositeOps() const =0
Returns the list of user-visible composite ops supported by this colourspace.
Abstract class that represents the concept of a Layer in Chalk.
virtual KisLayerSP nextSibling() const
Returns the next sibling of this layer in the parent's list.
int id() const
Returns the ID of the layer, which is guaranteed to be unique among all KisLayers.
virtual KisLayerSP firstChild() const
Returns the first child layer of this layer (if it supports that).
virtual KisLayerSP findLayer(const TQString &name) const
Recursively searches this layer and any child layers for a layer with the specified name.
virtual KisGroupLayerSP parent() const
Returns the parent layer of a layer.