|
|
|
/*
|
|
|
|
* kis_layerbox.cc - part of Chalk aka Krayon aka KimageShop
|
|
|
|
*
|
|
|
|
* Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
|
|
|
|
* Copyright (C) 2006 Gábor Lehel <illissius@gmail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (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
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqbutton.h>
|
|
|
|
#include <tqtoolbutton.h>
|
|
|
|
#include <tqbrush.h>
|
|
|
|
#include <tqfont.h>
|
|
|
|
#include <tqfontmetrics.h>
|
|
|
|
#include <tqhbox.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpoint.h>
|
|
|
|
#include <tqrect.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqstyle.h>
|
|
|
|
#include <tqtooltip.h>
|
|
|
|
#include <tqwidget.h>
|
|
|
|
#include <tqcombobox.h>
|
|
|
|
#include <tqcheckbox.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <tdepopupmenu.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kpushbutton.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kicontheme.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
#include <KoPartSelectAction.h>
|
|
|
|
|
|
|
|
#include "kis_layerlist.h"
|
|
|
|
#include "kis_cmb_composite.h"
|
|
|
|
#include "kis_int_spinbox.h"
|
|
|
|
#include "wdglayerbox.h"
|
|
|
|
#include "kis_colorspace.h"
|
|
|
|
#include "kis_paint_device.h"
|
|
|
|
#include "kis_layer.h"
|
|
|
|
#include "kis_group_layer.h"
|
|
|
|
#include "kis_image.h"
|
|
|
|
|
|
|
|
#include "kis_populate_visitor.h"
|
|
|
|
|
|
|
|
#include "kis_layerbox.h"
|
|
|
|
|
|
|
|
KisLayerBox::KisLayerBox(KisCanvasSubject *subject, TQWidget *parent, const char *name)
|
|
|
|
: super(parent, name), m_image(0)
|
|
|
|
{
|
|
|
|
TQVBoxLayout *vbox = new TQVBoxLayout(this);
|
|
|
|
vbox->setAutoAdd(true);
|
|
|
|
|
|
|
|
m_lst = new WdgLayerBox(this);
|
|
|
|
setMinimumSize(m_lst->minimumSizeHint());
|
|
|
|
|
|
|
|
TQToolTip::add(m_lst->bnAdd, i18n("Create new layer"));
|
|
|
|
|
|
|
|
TQToolTip::add(m_lst->bnDelete, i18n("Remove current layer"));
|
|
|
|
|
|
|
|
TQToolTip::add(m_lst->bnRaise, i18n("Raise current layer"));
|
|
|
|
m_lst->bnRaise->setEnabled(false);
|
|
|
|
|
|
|
|
m_lst->bnLower->setEnabled(false);
|
|
|
|
TQToolTip::add(m_lst->bnLower, i18n("Lower current layer"));
|
|
|
|
|
|
|
|
TQToolTip::add(m_lst->bnProperties, i18n("Properties for layer"));
|
|
|
|
|
|
|
|
TDEIconLoader il( "chalk" );
|
|
|
|
|
|
|
|
list()->setPreviewsShown(true);
|
|
|
|
|
|
|
|
list()->setFoldersCanBeActive(true);
|
|
|
|
|
|
|
|
list()->addProperty("visible", i18n("Visible"), loadPixmap("visible.png", il, TDEIcon::SizeSmallMedium),
|
|
|
|
loadPixmap("novisible.png", il, TDEIcon::SizeSmallMedium), true);
|
|
|
|
|
|
|
|
list()->addProperty("locked", i18n("Locked"), loadPixmap("locked.png", il, TDEIcon::SizeSmallMedium),
|
|
|
|
loadPixmap("unlocked.png", il, TDEIcon::SizeSmallMedium));
|
|
|
|
|
|
|
|
|
|
|
|
connect(list()->contextMenu(), TQT_SIGNAL(aboutToShow()), TQT_SLOT(slotAboutToShow()));
|
|
|
|
connect(list(), TQT_SIGNAL(activated(LayerItem*)),
|
|
|
|
TQT_SLOT(slotLayerActivated(LayerItem*)));
|
|
|
|
connect(list(), TQT_SIGNAL(displayNameChanged(LayerItem*, const TQString&)),
|
|
|
|
TQT_SLOT(slotLayerDisplayNameChanged(LayerItem*, const TQString&)));
|
|
|
|
connect(list(), TQT_SIGNAL(propertyChanged(LayerItem*, const TQString&, bool)),
|
|
|
|
TQT_SLOT(slotLayerPropertyChanged(LayerItem*, const TQString&, bool)));
|
|
|
|
connect(list(), TQT_SIGNAL(layerMoved(LayerItem*, LayerItem*, LayerItem*)),
|
|
|
|
TQT_SLOT(slotLayerMoved(LayerItem*, LayerItem*, LayerItem*)));
|
|
|
|
connect(list(), TQT_SIGNAL(requestNewLayer(LayerItem*, LayerItem*)),
|
|
|
|
TQT_SLOT(slotRequestNewLayer(LayerItem*, LayerItem*)));
|
|
|
|
connect(list(), TQT_SIGNAL(requestNewFolder(LayerItem*, LayerItem*)),
|
|
|
|
TQT_SLOT(slotRequestNewFolder(LayerItem*, LayerItem*)));
|
|
|
|
connect(list(), TQT_SIGNAL(requestNewAdjustmentLayer(LayerItem*, LayerItem*)),
|
|
|
|
TQT_SLOT(slotRequestNewAdjustmentLayer(LayerItem*, LayerItem*)));
|
|
|
|
connect(list(), TQT_SIGNAL(requestNewObjectLayer(LayerItem*, LayerItem*, const KoDocumentEntry&)),
|
|
|
|
TQT_SLOT(slotRequestNewObjectLayer(LayerItem*, LayerItem*, const KoDocumentEntry&)));
|
|
|
|
connect(list(), TQT_SIGNAL(requestRemoveLayer(LayerItem*)),
|
|
|
|
TQT_SLOT(slotRequestRemoveLayer(LayerItem*)));
|
|
|
|
connect(list(), TQT_SIGNAL(requestLayerProperties(LayerItem*)),
|
|
|
|
TQT_SLOT(slotRequestLayerProperties(LayerItem*)));
|
|
|
|
|
|
|
|
m_newLayerMenu = new TDEPopupMenu(this);
|
|
|
|
m_lst->bnAdd->setPopup(m_newLayerMenu);
|
|
|
|
m_lst->bnAdd->setPopupDelay(1);
|
|
|
|
m_newLayerMenu->insertItem( SmallIconSet( "filenew" ), i18n( "&New Layer..." ), PAINT_LAYER );
|
|
|
|
m_newLayerMenu->insertItem( SmallIconSet( "folder" ), i18n( "New &Group Layer..." ), GROUP_LAYER );
|
|
|
|
m_newLayerMenu->insertItem( SmallIconSet( "tool_filter" ), i18n( "New &Adjustment Layer..." ), ADJUSTMENT_LAYER );
|
|
|
|
m_partLayerAction = new KoPartSelectAction( i18n( "New &Object Layer" ), "gear", TQT_TQOBJECT(this) );
|
|
|
|
m_partLayerAction->plug( m_newLayerMenu );
|
|
|
|
connect(m_partLayerAction, TQT_SIGNAL(activated()), this, TQT_SLOT(slotAddMenuActivated()));
|
|
|
|
connect(m_newLayerMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotAddMenuActivated(int)));
|
|
|
|
|
|
|
|
|
|
|
|
connect(m_lst->bnDelete, TQT_SIGNAL(clicked()), TQT_SLOT(slotRmClicked()));
|
|
|
|
connect(m_lst->bnRaise, TQT_SIGNAL(clicked()), TQT_SLOT(slotRaiseClicked()));
|
|
|
|
connect(m_lst->bnLower, TQT_SIGNAL(clicked()), TQT_SLOT(slotLowerClicked()));
|
|
|
|
connect(m_lst->bnProperties, TQT_SIGNAL(clicked()), TQT_SLOT(slotPropertiesClicked()));
|
|
|
|
connect(m_lst->intOpacity, TQT_SIGNAL(valueChanged(int, bool)), TQT_SIGNAL(sigOpacityChanged(int, bool)));
|
|
|
|
connect(m_lst->intOpacity, TQT_SIGNAL(finishedChanging(int, int)), TQT_SIGNAL(sigOpacityFinishedChanging(int, int)));
|
|
|
|
connect(m_lst->cmbComposite, TQT_SIGNAL(activated(const KisCompositeOp&)), TQT_SIGNAL(sigItemComposite(const KisCompositeOp&)));
|
|
|
|
|
|
|
|
Q_ASSERT(subject->document() != 0);
|
|
|
|
|
|
|
|
if (subject->document()) {
|
|
|
|
connect(subject->document(), TQT_SIGNAL(sigCommandExecuted()), TQT_SLOT(updateThumbnails()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KisLayerBox::~KisLayerBox()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KisLayerList* KisLayerBox::list() const
|
|
|
|
{
|
|
|
|
return m_lst->listLayers;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::setImage(KisImageSP img)
|
|
|
|
{
|
|
|
|
if (m_image == img)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (m_image)
|
|
|
|
m_image->disconnect(this);
|
|
|
|
|
|
|
|
m_image = img;
|
|
|
|
|
|
|
|
if (img)
|
|
|
|
{
|
|
|
|
connect(img, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP)));
|
|
|
|
connect(img, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), this, TQT_SLOT(slotLayerAdded(KisLayerSP)));
|
|
|
|
connect(img, TQT_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)),
|
|
|
|
this, TQT_SLOT(slotLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)));
|
|
|
|
connect(img, TQT_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)),
|
|
|
|
this, TQT_SLOT(slotLayerPropertiesChanged(KisLayerSP)));
|
|
|
|
connect(img, TQT_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)),
|
|
|
|
this, TQT_SLOT(slotLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)));
|
|
|
|
connect(img, TQT_SIGNAL(sigLayersChanged(KisGroupLayerSP)), this, TQT_SLOT(slotLayersChanged(KisGroupLayerSP)));
|
|
|
|
connect(img, TQT_SIGNAL(sigLayerUpdated(KisLayerSP, TQRect)), this, TQT_SLOT(slotLayerUpdated(KisLayerSP, TQRect)));
|
|
|
|
slotLayersChanged(img->rootLayer());
|
|
|
|
updateThumbnails();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerActivated(KisLayerSP layer)
|
|
|
|
{
|
|
|
|
if (layer)
|
|
|
|
list()->setActiveLayer(layer->id());
|
|
|
|
else
|
|
|
|
list()->setActiveLayer(-1);
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerAdded(KisLayerSP layer)
|
|
|
|
{
|
|
|
|
if (layer.data() == m_image->rootLayer().data() || list()->layer(layer->id()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
vKisLayerSP layersAdded;
|
|
|
|
|
|
|
|
if (layer->parent() == m_image->rootLayer())
|
|
|
|
{
|
|
|
|
KisPopulateVisitor visitor(list());
|
|
|
|
layer->accept(visitor);
|
|
|
|
layersAdded = visitor.layersAdded();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KisPopulateVisitor visitor(static_cast<KisLayerItem*>(list()->layer(layer->parent()->id())));
|
|
|
|
layer->accept(visitor);
|
|
|
|
layersAdded = visitor.layersAdded();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (vKisLayerSP::iterator it = layersAdded.begin(); it != layersAdded.end(); ++it) {
|
|
|
|
markModified(*it);
|
|
|
|
}
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerRemoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP)
|
|
|
|
{
|
|
|
|
list()->removeLayer(layer->id());
|
|
|
|
m_modified.remove(layer->id());
|
|
|
|
markModified(wasParent);
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerMoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP)
|
|
|
|
{
|
|
|
|
int parentID = layer->parent()->id();
|
|
|
|
if (layer->parent() == m_image->rootLayer())
|
|
|
|
parentID = -1;
|
|
|
|
|
|
|
|
int siblingID = -1;
|
|
|
|
if (layer->prevSibling())
|
|
|
|
siblingID = layer->prevSibling()->id();
|
|
|
|
|
|
|
|
list()->moveLayer(layer->id(), parentID, siblingID);
|
|
|
|
|
|
|
|
markModified(layer->parent());
|
|
|
|
markModified(wasParent);
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerPropertiesChanged(KisLayerSP layer)
|
|
|
|
{
|
|
|
|
if (KisLayerItem* item = dynamic_cast<KisLayerItem*>(list()->layer(layer->id())))
|
|
|
|
{
|
|
|
|
Q_ASSERT(item->layer() == layer.data());
|
|
|
|
item->sync();
|
|
|
|
updateUI();
|
|
|
|
markModified(layer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayersChanged(KisGroupLayerSP rootLayer)
|
|
|
|
{
|
|
|
|
list()->clear();
|
|
|
|
KisPopulateVisitor visitor(list());
|
|
|
|
for (KisLayerSP layer = rootLayer->firstChild(); layer; layer = layer->nextSibling())
|
|
|
|
layer->accept(visitor);
|
|
|
|
m_modified.clear();
|
|
|
|
for (TQListViewItemIterator it(list()->lastItem()); *it; --it)
|
|
|
|
m_modified.append(static_cast<LayerItem*>(*it)->id());
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerUpdated(KisLayerSP layer, TQRect)
|
|
|
|
{
|
|
|
|
markModified(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerActivated(LayerItem* item)
|
|
|
|
{
|
|
|
|
if (item)
|
|
|
|
m_image->activate(m_image->findLayer(item->id()));
|
|
|
|
else
|
|
|
|
m_image->activate(0);
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerDisplayNameChanged(LayerItem* item, const TQString& displayName)
|
|
|
|
{
|
|
|
|
if(KisLayerSP layer = m_image->findLayer(item->id()))
|
|
|
|
layer->setName(displayName);
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerPropertyChanged(LayerItem* item, const TQString& name, bool on)
|
|
|
|
{
|
|
|
|
if (KisLayerSP layer = m_image->findLayer(item->id()))
|
|
|
|
{
|
|
|
|
if (name == "visible")
|
|
|
|
layer->setVisible(on);
|
|
|
|
else if (name == "locked")
|
|
|
|
layer->setLocked(on);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLayerMoved(LayerItem* item, LayerItem*, LayerItem*)
|
|
|
|
{
|
|
|
|
KisLayerSP layer = m_image->findLayer(item->id());
|
|
|
|
KisGroupLayerSP parent;
|
|
|
|
if( item->parent() )
|
|
|
|
parent = dynamic_cast<KisGroupLayer*>(m_image->findLayer(item->parent()->id()).data());
|
|
|
|
if( !parent )
|
|
|
|
parent = m_image->rootLayer();
|
|
|
|
KisLayerSP above = 0;
|
|
|
|
if (item->nextSibling())
|
|
|
|
above = m_image->findLayer(item->nextSibling()->id());
|
|
|
|
if (layer)
|
|
|
|
m_image->moveLayer(layer, parent.data(), above);
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRequestNewLayer(LayerItem* p, LayerItem* after)
|
|
|
|
{
|
|
|
|
KisLayer* l = m_image->rootLayer().data();
|
|
|
|
if (p)
|
|
|
|
l = m_image->findLayer(p->id()).data();
|
|
|
|
KisGroupLayerSP parent = dynamic_cast<KisGroupLayer*>(l);
|
|
|
|
|
|
|
|
KisLayerSP above = 0;
|
|
|
|
if (after && after->nextSibling())
|
|
|
|
above = m_image->findLayer(after->nextSibling()->id());
|
|
|
|
else if (after)
|
|
|
|
above = 0;
|
|
|
|
else if (p && p->firstChild())
|
|
|
|
above = parent->firstChild();
|
|
|
|
else if (!p && m_image->rootLayer()->childCount())
|
|
|
|
above = m_image->rootLayer()->firstChild();
|
|
|
|
emit sigRequestLayer(parent, above);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRequestNewFolder(LayerItem* p, LayerItem* after)
|
|
|
|
{
|
|
|
|
KisLayer* l = m_image->rootLayer().data(); //FIXME I hate copy-pasting like this.
|
|
|
|
if (p)
|
|
|
|
l = m_image->findLayer(p->id()).data();
|
|
|
|
KisGroupLayerSP parent = dynamic_cast<KisGroupLayer*>(l);
|
|
|
|
|
|
|
|
KisLayerSP above = 0;
|
|
|
|
if (after && after->nextSibling())
|
|
|
|
above = m_image->findLayer(after->nextSibling()->id());
|
|
|
|
else if (after)
|
|
|
|
above = 0;
|
|
|
|
else if (p && p->firstChild())
|
|
|
|
above = parent->firstChild();
|
|
|
|
else if (!p && m_image->rootLayer()->childCount())
|
|
|
|
above = m_image->rootLayer()->firstChild();
|
|
|
|
emit sigRequestGroupLayer(parent, above);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRequestNewAdjustmentLayer(LayerItem* p, LayerItem* after)
|
|
|
|
{
|
|
|
|
KisLayer* l = m_image->rootLayer().data(); //FIXME here too.
|
|
|
|
if (p)
|
|
|
|
l = m_image->findLayer(p->id()).data();
|
|
|
|
KisGroupLayerSP parent = dynamic_cast<KisGroupLayer*>(l);
|
|
|
|
|
|
|
|
KisLayerSP above = 0;
|
|
|
|
if (after && after->nextSibling())
|
|
|
|
above = m_image->findLayer(after->nextSibling()->id());
|
|
|
|
else if (after)
|
|
|
|
above = 0;
|
|
|
|
else if (p && p->firstChild())
|
|
|
|
above = parent->firstChild();
|
|
|
|
else if (!p && m_image->rootLayer()->childCount())
|
|
|
|
above = m_image->rootLayer()->firstChild();
|
|
|
|
emit sigRequestAdjustmentLayer(parent, above);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRequestNewObjectLayer(LayerItem* p, LayerItem* after, const KoDocumentEntry& entry)
|
|
|
|
{
|
|
|
|
KisLayer* l = m_image->rootLayer().data(); //FIXME and here.
|
|
|
|
if (p)
|
|
|
|
l = m_image->findLayer(p->id()).data();
|
|
|
|
KisGroupLayerSP parent = dynamic_cast<KisGroupLayer*>(l);
|
|
|
|
|
|
|
|
KisLayerSP above = 0;
|
|
|
|
if (after && after->nextSibling())
|
|
|
|
above = m_image->findLayer(after->nextSibling()->id());
|
|
|
|
else if (after)
|
|
|
|
above = 0;
|
|
|
|
else if (p && p->firstChild())
|
|
|
|
above = parent->firstChild();
|
|
|
|
else if (!p && m_image->rootLayer()->childCount())
|
|
|
|
above = m_image->rootLayer()->firstChild();
|
|
|
|
emit sigRequestPartLayer(parent, above, entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRequestRemoveLayer(LayerItem* item)
|
|
|
|
{
|
|
|
|
if (KisLayerSP layer = m_image->findLayer(item->id())) {
|
|
|
|
m_image->removeLayer(layer);
|
|
|
|
}
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRequestLayerProperties(LayerItem* item)
|
|
|
|
{
|
|
|
|
if (KisLayerSP layer = m_image->findLayer(item->id()))
|
|
|
|
{
|
|
|
|
emit sigRequestLayerProperties(layer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::updateUI()
|
|
|
|
{
|
|
|
|
m_lst->bnDelete->setEnabled(list()->activeLayer());
|
|
|
|
m_lst->bnRaise->setEnabled(list()->activeLayer() && (list()->activeLayer()->prevSibling() || list()->activeLayer()->parent()));
|
|
|
|
m_lst->bnLower->setEnabled(list()->activeLayer() && list()->activeLayer()->nextSibling());
|
|
|
|
m_lst->intOpacity->setEnabled(list()->activeLayer());
|
|
|
|
m_lst->cmbComposite->setEnabled(list()->activeLayer());
|
|
|
|
if (m_image)
|
|
|
|
if (KisLayerSP active = m_image->activeLayer())
|
|
|
|
{
|
|
|
|
if (m_image->activeDevice())
|
|
|
|
slotSetColorSpace(m_image->activeDevice()->colorSpace());
|
|
|
|
else
|
|
|
|
slotSetColorSpace(m_image->colorSpace());
|
|
|
|
slotSetOpacity(int(float(active->opacity() * 100) / 255 + 0.5));
|
|
|
|
slotSetCompositeOp(active->compositeOp());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotAboutToShow()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotSetCompositeOp(const KisCompositeOp& compositeOp)
|
|
|
|
{
|
|
|
|
m_lst->cmbComposite->blockSignals(true);
|
|
|
|
m_lst->cmbComposite->setCurrentItem(compositeOp);
|
|
|
|
m_lst->cmbComposite->blockSignals(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotSetColorSpace(const KisColorSpace * colorSpace)
|
|
|
|
{
|
|
|
|
m_lst->cmbComposite->blockSignals(true);
|
|
|
|
m_lst->cmbComposite->setCompositeOpList(colorSpace->userVisiblecompositeOps());
|
|
|
|
m_lst->cmbComposite->blockSignals(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// range: 0-100
|
|
|
|
void KisLayerBox::slotSetOpacity(int opacity)
|
|
|
|
{
|
|
|
|
m_lst->intOpacity->blockSignals(true);
|
|
|
|
m_lst->intOpacity->setValue(opacity);
|
|
|
|
m_lst->intOpacity->blockSignals(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::clear()
|
|
|
|
{
|
|
|
|
list()->clear();
|
|
|
|
updateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotAddMenuActivated(int type)
|
|
|
|
{
|
|
|
|
if(type == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
KisGroupLayerSP root = m_image->rootLayer();
|
|
|
|
KisGroupLayerSP parent;
|
|
|
|
KisLayerSP above;
|
|
|
|
if (KisLayerSP active = m_image->activeLayer())
|
|
|
|
{
|
|
|
|
parent = root;
|
|
|
|
above = active;
|
|
|
|
if (active->parent())
|
|
|
|
parent = active->parent();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parent = root;
|
|
|
|
above = m_image->rootLayer()->firstChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case PAINT_LAYER:
|
|
|
|
emit sigRequestLayer(parent, above);
|
|
|
|
break;
|
|
|
|
case GROUP_LAYER:
|
|
|
|
emit sigRequestGroupLayer(parent, above);
|
|
|
|
break;
|
|
|
|
case ADJUSTMENT_LAYER:
|
|
|
|
emit sigRequestAdjustmentLayer(parent, above);
|
|
|
|
break;
|
|
|
|
case OBJECT_LAYER:
|
|
|
|
default: //TQt doesn't emit activated for default-assigned IDs, so this does nothing
|
|
|
|
emit sigRequestPartLayer(parent, above, m_partLayerAction->documentEntry());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRmClicked()
|
|
|
|
{
|
|
|
|
TQValueList<int> l = list()->selectedLayerIDs();
|
|
|
|
if (l.count() < 2 && list()->activeLayer() && !l.contains(list()->activeLayer()->id()))
|
|
|
|
{
|
|
|
|
l.clear();
|
|
|
|
l.append(list()->activeLayer()->id());
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0, n = l.count(); i < n; ++i)
|
|
|
|
{
|
|
|
|
m_modified.remove(l[i]);
|
|
|
|
m_image->removeLayer(m_image->findLayer(l[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotRaiseClicked()
|
|
|
|
{
|
|
|
|
TQValueList<int> l = list()->selectedLayerIDs();
|
|
|
|
if (l.count() < 2 && list()->activeLayer() && !l.contains(list()->activeLayer()->id()))
|
|
|
|
{
|
|
|
|
l.clear();
|
|
|
|
l.append(list()->activeLayer()->id());
|
|
|
|
}
|
|
|
|
|
|
|
|
KisLayerSP layer = m_image->findLayer(l.first());
|
|
|
|
if( l.count() == 1 && layer == layer->parent()->firstChild() && layer->parent() != m_image->rootLayer())
|
|
|
|
{
|
|
|
|
if (KisGroupLayerSP grandparent = layer->parent()->parent())
|
|
|
|
m_image->moveLayer(layer, grandparent, layer->parent().data());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0, n = l.count(); i < n; ++i)
|
|
|
|
if (KisLayerSP li = m_image->findLayer(l[i]))
|
|
|
|
if (li->prevSibling())
|
|
|
|
m_image->moveLayer(li, li->parent(), li->prevSibling());
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !l.isEmpty() )
|
|
|
|
list()->ensureItemVisible( list()->layer( l.first() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotLowerClicked()
|
|
|
|
{
|
|
|
|
TQValueList<LayerItem*> l = list()->selectedLayers();
|
|
|
|
if (l.count() < 2 && list()->activeLayer() && !l.contains(list()->activeLayer()))
|
|
|
|
{
|
|
|
|
l.clear();
|
|
|
|
l.append(list()->activeLayer());
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = l.count() - 1; i >= 0; --i)
|
|
|
|
if (LayerItem *layer = l[i])
|
|
|
|
if (layer->nextSibling())
|
|
|
|
list()->moveLayer(layer, layer->parent(), layer->nextSibling());
|
|
|
|
|
|
|
|
if( !l.isEmpty() )
|
|
|
|
list()->ensureItemVisible( l.last() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::slotPropertiesClicked()
|
|
|
|
{
|
|
|
|
if (KisLayerSP active = m_image->activeLayer())
|
|
|
|
emit sigRequestLayerProperties(active);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::updateThumbnails()
|
|
|
|
{
|
|
|
|
bool again = true;
|
|
|
|
while (m_modified.count() && again)
|
|
|
|
{
|
|
|
|
//again = false;
|
|
|
|
KisLayerItem* item = static_cast<KisLayerItem*>(list()->layer(m_modified.last()));
|
|
|
|
m_modified.pop_back();
|
|
|
|
if (!item || !item->updatePreview())
|
|
|
|
again = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::setUpdatesAndSignalsEnabled(bool enable)
|
|
|
|
{
|
|
|
|
setUpdatesEnabled(enable);
|
|
|
|
m_lst->intOpacity->setUpdatesEnabled(enable);
|
|
|
|
m_lst->cmbComposite->setUpdatesEnabled(enable);
|
|
|
|
|
|
|
|
list()->blockSignals(!enable);
|
|
|
|
m_lst->intOpacity->blockSignals(!enable);
|
|
|
|
m_lst->cmbComposite->blockSignals(!enable);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQPixmap KisLayerBox::loadPixmap(const TQString& filename, const TDEIconLoader&
|
|
|
|
il, int size)
|
|
|
|
{
|
|
|
|
TQPixmap pixmap = il.loadIcon(filename, TDEIcon::NoGroup, size);
|
|
|
|
|
|
|
|
if (pixmap.isNull())
|
|
|
|
KMessageBox::error(0, i18n("Cannot find %1").arg(filename),
|
|
|
|
i18n("Canvas"));
|
|
|
|
|
|
|
|
return pixmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::markModified(KisLayer* layer)
|
|
|
|
{
|
|
|
|
if( !layer )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQValueList<int> v;
|
|
|
|
while (layer && layer != m_image->rootLayer().data())
|
|
|
|
{
|
|
|
|
v.append(layer->id());
|
|
|
|
layer = layer->parent();
|
|
|
|
}
|
|
|
|
for (int i = v.count() - 1; i >= 0; --i)
|
|
|
|
if (!m_modified.contains(v[i]))
|
|
|
|
m_modified.append(v[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::printChalkLayers() const
|
|
|
|
{
|
|
|
|
static int indent = 0;
|
|
|
|
static KisLayer *root = 0;
|
|
|
|
if( !root )
|
|
|
|
root = m_image->rootLayer();
|
|
|
|
if( !root )
|
|
|
|
return;
|
|
|
|
TQString s = root->name();
|
|
|
|
if( dynamic_cast<KisGroupLayer*>( root ) )
|
|
|
|
s = TQString("[%1]").arg( s );
|
|
|
|
if( m_image->activeLayer().data() == root )
|
|
|
|
s.prepend("*");
|
|
|
|
kdDebug() << (TQString().fill(' ', indent) + s) << endl;
|
|
|
|
for (KisLayer* layer = root->firstChild(); layer; layer = layer->nextSibling())
|
|
|
|
{
|
|
|
|
indent += 2;
|
|
|
|
root = layer;
|
|
|
|
printChalkLayers();
|
|
|
|
indent -= 2;
|
|
|
|
root = layer->parent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisLayerBox::printLayerboxLayers() const
|
|
|
|
{
|
|
|
|
static int indent = 0;
|
|
|
|
static LayerItem *root = 0;
|
|
|
|
if( !root )
|
|
|
|
{
|
|
|
|
for (LayerItem* layer = list()->firstChild(); layer; layer = layer->nextSibling())
|
|
|
|
{
|
|
|
|
indent += 2;
|
|
|
|
root = layer;
|
|
|
|
printLayerboxLayers();
|
|
|
|
indent -= 2;
|
|
|
|
root = layer->parent();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
TQString s = root->displayName();
|
|
|
|
if( root->isFolder() )
|
|
|
|
s = TQString("[%1]").arg( s );
|
|
|
|
if( list()->activeLayer() == root )
|
|
|
|
s.prepend("*");
|
|
|
|
kdDebug() << (TQString().fill(' ', indent) + s) << endl;
|
|
|
|
for (LayerItem* layer = root->firstChild(); layer; layer = layer->nextSibling())
|
|
|
|
{
|
|
|
|
indent += 2;
|
|
|
|
root = layer;
|
|
|
|
printLayerboxLayers();
|
|
|
|
indent -= 2;
|
|
|
|
root = layer->parent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kis_layerbox.moc"
|