Krita Source Code Documentation
Loading...
Searching...
No Matches
KisLayerManager Class Reference

#include <kis_layer_manager.h>

+ Inheritance diagram for KisLayerManager:

Public Member Functions

 KisLayerManager (KisViewManager *view)
 
void setView (QPointer< KisView >view)
 
 ~KisLayerManager () override
 

Private Slots

bool activeLayerHasSelection ()
 
KisNodeSP addAdjustmentLayer (KisNodeSP activeNode)
 
KisAdjustmentLayerSP addAdjustmentLayer (KisNodeSP activeNode, const QString &name, KisFilterConfigurationSP filter, KisSelectionSP selection, KisProcessingApplicator *applicator)
 
KisNodeSP addCloneLayer (KisNodeList nodes)
 
KisNodeSP addFileLayer (KisNodeSP activeNode)
 
KisNodeSP addGeneratorLayer (KisNodeSP activeNode)
 
KisGeneratorLayerSP addGeneratorLayer (KisNodeSP activeNode, const QString &name, KisFilterConfigurationSP filter, KisSelectionSP selection, KisProcessingApplicator *applicator)
 
KisNodeSP addGroupLayer (KisNodeSP activeNode)
 
KisLayerSP addPaintLayer (KisNodeSP activeNode)
 
KisNodeSP addShapeLayer (KisNodeSP activeNode)
 
void changeCloneSource ()
 
void convertGroupToAnimated ()
 
void convertLayerToFileLayer (KisNodeSP source)
 
void convertNodeToPaintLayer (KisNodeSP source)
 
void copyLayerStyle ()
 
void flattenImage ()
 
void flattenLayer ()
 
void imageResizeToActiveLayer ()
 
void layerProperties ()
 
void layerPropertiesDialogClosed ()
 
void layerStyle ()
 
void layersUpdated ()
 
void mergeLayer ()
 
void pasteLayerStyle ()
 
void saveGroupLayers ()
 
void trimToImage ()
 

Private Member Functions

void activateLayer (KisLayerSP layer)
 
KisPaintDeviceSP activeDevice ()
 
KisLayerSP activeLayer ()
 
void addLayerCommon (KisNodeSP activeNode, KisNodeSP layer, bool updateImage=true, KisProcessingApplicator *applicator=0)
 
void adjustLayerPosition (KisNodeSP node, KisNodeSP activeNode, KisNodeSP &parent, KisNodeSP &above)
 
void setup (KisActionManager *actionManager)
 
void updateGUI ()
 

Private Attributes

KisNodeCommandsAdapterm_commandsAdapter
 
KisActionm_convertGroupAnimated {0}
 
KisActionm_copyLayerStyle {0}
 
KisActionm_flattenLayer {0}
 
KisActionm_groupLayersSave {0}
 
KisActionm_imageFlatten {0}
 
KisActionm_imageMergeLayer {0}
 
KisActionm_imageResizeToLayer {0}
 
QPointer< KisViewm_imageView {0}
 
bool m_layerPropertiesDialogActive {false}
 
KisActionm_layerStyle {0}
 
KisActionm_pasteLayerStyle {0}
 
KisActionm_rasterizeLayer {0}
 
KisViewManagerm_view
 

Friends

class KisNodeManager
 

Detailed Description

KisLayerManager takes care of the gui around working with layers: adding, removing, editing. It also keeps track of the active layer for this view.

Definition at line 29 of file kis_layer_manager.h.

Constructor & Destructor Documentation

◆ KisLayerManager()

KisLayerManager::KisLayerManager ( KisViewManager * view)

Definition at line 105 of file kis_layer_manager.cc.

106 : m_view(view)
108
109{
110}
KisViewManager * m_view
KisNodeCommandsAdapter * m_commandsAdapter

◆ ~KisLayerManager()

KisLayerManager::~KisLayerManager ( )
override

Definition at line 112 of file kis_layer_manager.cc.

113{
114 delete m_commandsAdapter;
115}

References m_commandsAdapter.

Member Function Documentation

◆ activateLayer()

void KisLayerManager::activateLayer ( KisLayerSP layer)
private

Activate the specified layer. The layer may be 0.

Definition at line 138 of file kis_layer_manager.cc.

139{
140 if (m_imageView) {
142 if (layer) {
144 }
145 }
146}
void slotNodeActivated(const KisNodeSP node)
QPointer< KisView > m_imageView
KisCanvasResourceProvider * canvasResourceProvider()

References KisViewManager::canvasResourceProvider(), KisSharedPtr< T >::data(), layersUpdated(), m_imageView, m_view, and KisCanvasResourceProvider::slotNodeActivated().

◆ activeDevice()

KisPaintDeviceSP KisLayerManager::activeDevice ( )
private

Definition at line 130 of file kis_layer_manager.cc.

131{
132 if (activeLayer()) {
133 return activeLayer()->paintDevice();
134 }
135 return 0;
136}
KisLayerSP activeLayer()
virtual KisPaintDeviceSP paintDevice() const =0

References activeLayer(), and KisBaseNode::paintDevice().

◆ activeLayer()

KisLayerSP KisLayerManager::activeLayer ( )
private

Definition at line 122 of file kis_layer_manager.cc.

123{
124 if (m_imageView) {
125 return m_imageView->currentLayer();
126 }
127 return 0;
128}

References m_imageView.

◆ activeLayerHasSelection

bool KisLayerManager::activeLayerHasSelection ( )
privateslot

Definition at line 998 of file kis_layer_manager.cc.

999{
1000 return (activeLayer()->selection() != 0);
1001}

References activeLayer().

◆ addAdjustmentLayer [1/2]

KisNodeSP KisLayerManager::addAdjustmentLayer ( KisNodeSP activeNode)
privateslot

Definition at line 710 of file kis_layer_manager.cc.

711{
712 KisImageWSP image = m_view->image();
713
714 KisSelectionSP selection = m_view->selection();
715
718 kundo2_i18n("Add Layer"));
719
720
721 KisAdjustmentLayerSP adjl = addAdjustmentLayer(activeNode, QString(), 0, selection, &applicator);
722
723 KisPaintDeviceSP previewDevice = new KisPaintDevice(*adjl->original());
724
725 KisDlgAdjustmentLayer dlg(adjl, adjl.data(), previewDevice, image->nextLayerName(i18n("Filter Layer")), i18n("New Filter Layer"), m_view, qApp->activeWindow());
726 dlg.resize(dlg.minimumSizeHint());
727
728 // ensure that the device may be free'd by the dialog
729 // when it is not needed anymore
730 previewDevice = 0;
731
732 if (dlg.exec() != QDialog::Accepted || adjl->filter().isNull()) {
733 // XXX: add messagebox warning if there's no filter set!
734 applicator.cancel();
735 } else {
736 applicator.applyCommand(new KisNodeRenameCommand(adjl, adjl->name(), dlg.layerName()));
737 applicator.end();
738 }
739
740 return adjl;
741}
QVector< KisImageSignalType > KisImageSignalVector
QString nextLayerName(const QString &baseName="") const
Definition kis_image.cc:715
KisNodeSP addAdjustmentLayer(KisNodeSP activeNode)
The command for setting the node's name.
KisSelectionSP selection()
KisImageWSP image() const
Return the image this view is displaying.
KUndo2MagicString kundo2_i18n(const char *text)

References addAdjustmentLayer(), KisProcessingApplicator::applyCommand(), KisProcessingApplicator::cancel(), KisSharedPtr< T >::data(), KisProcessingApplicator::end(), KisViewManager::image(), kundo2_i18n(), KisDlgAdjustmentLayer::layerName(), m_view, KoDialog::minimumSizeHint(), KisImage::nextLayerName(), KisProcessingApplicator::NONE, and KisViewManager::selection().

◆ addAdjustmentLayer [2/2]

KisAdjustmentLayerSP KisLayerManager::addAdjustmentLayer ( KisNodeSP activeNode,
const QString & name,
KisFilterConfigurationSP filter,
KisSelectionSP selection,
KisProcessingApplicator * applicator )
privateslot

Definition at line 743 of file kis_layer_manager.cc.

747{
748 KisImageWSP image = m_view->image();
749 KisAdjustmentLayerSP layer = new KisAdjustmentLayer(image, name, filter ? filter->cloneWithResourcesSnapshot() : 0, selection);
750 addLayerCommon(activeNode, layer, true, applicator);
751
752 return layer;
753}
void addLayerCommon(KisNodeSP activeNode, KisNodeSP layer, bool updateImage=true, KisProcessingApplicator *applicator=0)

References addLayerCommon(), KisViewManager::image(), and m_view.

◆ addCloneLayer

KisNodeSP KisLayerManager::addCloneLayer ( KisNodeList nodes)
privateslot

Definition at line 679 of file kis_layer_manager.cc.

680{
681 KisImageWSP image = m_view->image();
682
684 if (filteredNodes.isEmpty()) return KisNodeSP();
685
686 KisNodeSP newAbove = filteredNodes.last();
687
688 KisNodeSP node, lastClonedNode;
689 Q_FOREACH (node, filteredNodes) {
690 lastClonedNode = new KisCloneLayer(qobject_cast<KisLayer*>(node.data()), image.data(), image->nextLayerName( i18n("Clone Layer") ), OPACITY_OPAQUE_U8);
691 addLayerCommon(newAbove, lastClonedNode, true, 0 );
692 }
693
694 return lastClonedNode;
695}
const quint8 OPACITY_OPAQUE_U8
KisSharedPtr< KisNode > KisNodeSP
Definition kis_types.h:86
KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks)

References addLayerCommon(), KisSharedPtr< T >::data(), KisWeakSharedPtr< T >::data(), KisViewManager::image(), m_view, KisImage::nextLayerName(), OPACITY_OPAQUE_U8, and KisLayerUtils::sortAndFilterMergeableInternalNodes().

◆ addFileLayer

KisNodeSP KisLayerManager::addFileLayer ( KisNodeSP activeNode)
privateslot

Definition at line 1003 of file kis_layer_manager.cc.

1004{
1005 QString basePath;
1006 QString path = m_view->document()->path();
1007 basePath = QFileInfo(path).absolutePath();
1008 KisImageWSP image = m_view->image();
1009
1010 KisDlgFileLayer dlg(basePath, image->nextLayerName(i18n("File Layer")), m_view->mainWindow());
1011 dlg.resize(dlg.minimumSizeHint());
1012
1013 if (dlg.exec() == QDialog::Accepted) {
1014 QString name = dlg.layerName();
1015 QString fileName = dlg.fileName();
1016
1017 if(fileName.isEmpty()){
1018 QMessageBox::critical(m_view->mainWindow(), i18nc("@title:window", "Krita"), i18n("No file name specified"));
1019 return 0;
1020 }
1021
1022 KisFileLayer::ScalingMethod scalingMethod = dlg.scaleToImageResolution();
1023 QString scalingFilter = dlg.scalingFilter();
1024 KisNodeSP node = new KisFileLayer(image, basePath, fileName, scalingMethod, scalingFilter, name, OPACITY_OPAQUE_U8);
1025 addLayerCommon(activeNode, node, true, 0);
1026 return node;
1027 }
1028 return 0;
1029}
QString path() const
The KisFileLayer class loads a particular file as a layer into the layer stack.
KisMainWindow * mainWindow() const
KisDocument * document() const
const char * name(StandardAction id)

References addLayerCommon(), KisViewManager::document(), KisDlgFileLayer::fileName(), KisViewManager::image(), KisDlgFileLayer::layerName(), m_view, KisViewManager::mainWindow(), KoDialog::minimumSizeHint(), KisImage::nextLayerName(), OPACITY_OPAQUE_U8, KisDocument::path(), KisDlgFileLayer::scaleToImageResolution(), and KisDlgFileLayer::scalingFilter().

◆ addGeneratorLayer [1/2]

KisNodeSP KisLayerManager::addGeneratorLayer ( KisNodeSP activeNode)
privateslot

Definition at line 764 of file kis_layer_manager.cc.

765{
766 KisImageWSP image = m_view->image();
767 KisSelectionSP selection = m_view->selection();
768 QColor currentForeground = m_view->canvasResourceProvider()->fgColor().toQColor();
769
771
772 KisGeneratorLayerSP node = addGeneratorLayer(activeNode, QString(), nullptr, selection, &applicator);
773
774 KisDlgGeneratorLayer dlg(image->nextLayerName(i18n("Fill Layer")), m_view, m_view->mainWindow(), node, nullptr, applicator.getStroke());
775 KisFilterConfigurationSP defaultConfig = dlg.configuration();
776 defaultConfig->setProperty("color", currentForeground);
777 dlg.setConfiguration(defaultConfig);
778
779 if (dlg.exec() == QDialog::Accepted) {
780 applicator.applyCommand(new KisNodeRenameCommand(node, node->name(), dlg.layerName()));
781 applicator.end();
782 return node;
783 }
784 else {
785 applicator.cancel();
786 return nullptr;
787 }
788}
KisNodeSP addGeneratorLayer(KisNodeSP activeNode)
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
QString name() const

References addGeneratorLayer(), KisProcessingApplicator::applyCommand(), KisProcessingApplicator::cancel(), KisViewManager::canvasResourceProvider(), KisDlgGeneratorLayer::configuration(), KisProcessingApplicator::end(), KisCanvasResourceProvider::fgColor(), KisProcessingApplicator::getStroke(), KisViewManager::image(), kundo2_i18n(), KisDlgGeneratorLayer::layerName(), m_view, KisViewManager::mainWindow(), KisBaseNode::name(), KisImage::nextLayerName(), KisProcessingApplicator::NONE, KisViewManager::selection(), KisDlgGeneratorLayer::setConfiguration(), and KoColor::toQColor().

◆ addGeneratorLayer [2/2]

KisGeneratorLayerSP KisLayerManager::addGeneratorLayer ( KisNodeSP activeNode,
const QString & name,
KisFilterConfigurationSP filter,
KisSelectionSP selection,
KisProcessingApplicator * applicator )
privateslot

Definition at line 755 of file kis_layer_manager.cc.

756{
757 KisImageWSP image = m_view->image();
758 auto layer = new KisGeneratorLayer(image, name, filter, selection);
759 addLayerCommon(activeNode, layer, true, applicator);
760
761 return layer;
762}

References addLayerCommon(), KisViewManager::image(), and m_view.

◆ addGroupLayer

KisNodeSP KisLayerManager::addGroupLayer ( KisNodeSP activeNode)
privateslot

Definition at line 671 of file kis_layer_manager.cc.

672{
673 KisImageWSP image = m_view->image();
674 KisGroupLayerSP group = new KisGroupLayer(image.data(), image->nextLayerName( i18nc("A group of layers", "Group") ), OPACITY_OPAQUE_U8);
675 addLayerCommon(activeNode, group, false, 0);
676 return group;
677}

References addLayerCommon(), KisWeakSharedPtr< T >::data(), KisViewManager::image(), m_view, KisImage::nextLayerName(), and OPACITY_OPAQUE_U8.

◆ addLayerCommon()

void KisLayerManager::addLayerCommon ( KisNodeSP activeNode,
KisNodeSP layer,
bool updateImage = true,
KisProcessingApplicator * applicator = 0 )
private

Definition at line 632 of file kis_layer_manager.cc.

633{
635 KisNodeSP above;
636 adjustLayerPosition(layer, activeNode, parent, above);
637
638 KisGroupLayer *group = dynamic_cast<KisGroupLayer*>(parent.data());
639
640 if (layer->inherits("KisGroupLayer") || layer->inherits("KisPaintLayer")) {
641 const KoColorSpace *colorSpace = group->colorSpace();
642
643 if (layer->inherits("KisGroupLayer")) {
644 KisGroupLayer *newLayer = dynamic_cast<KisGroupLayer*>(layer.data());
645 newLayer->resetCache(colorSpace);
646 } else {
647 KisPaintLayer *newLayer = qobject_cast<KisPaintLayer *>(layer.data());
648 newLayer->paintDevice()->convertTo(colorSpace);
649 }
650 }
651
652 const bool parentForceUpdate = group && !group->projectionIsValid();
653 updateImage |= parentForceUpdate;
654
655 m_commandsAdapter->addNodeAsync(layer, parent, above, updateImage, updateImage, applicator);
656}
void adjustLayerPosition(KisNodeSP node, KisNodeSP activeNode, KisNodeSP &parent, KisNodeSP &above)
void addNodeAsync(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis, bool doRedoUpdates=true, bool doUndoUpdates=true, KisProcessingApplicator *applicator=0)
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327
bool projectionIsValid() const
const KoColorSpace * colorSpace() const override
void resetCache(const KoColorSpace *colorSpace)
KisPaintDeviceSP paintDevice

References KisNodeCommandsAdapter::addNodeAsync(), adjustLayerPosition(), KisGroupLayer::colorSpace(), KisPaintDevice::convertTo(), KisSharedPtr< T >::data(), m_commandsAdapter, KisPaintLayer::paintDevice, KisGroupLayer::projectionIsValid(), and KisGroupLayer::resetCache().

◆ addPaintLayer

KisLayerSP KisLayerManager::addPaintLayer ( KisNodeSP activeNode)
privateslot

Definition at line 658 of file kis_layer_manager.cc.

659{
660 KisImageWSP image = m_view->image();
661 KisLayerSP layer = new KisPaintLayer(image.data(), image->nextLayerName( i18n("Paint Layer") ), OPACITY_OPAQUE_U8, image->colorSpace());
662
663 KisConfig cfg(true);
664 layer->setPinnedToTimeline(cfg.autoPinLayersToTimeline());
665
666 addLayerCommon(activeNode, layer, false, 0);
667
668 return layer;
669}
const KoColorSpace * colorSpace() const
void setPinnedToTimeline(bool pinned)

References addLayerCommon(), KisConfig::autoPinLayersToTimeline(), KisImage::colorSpace(), KisWeakSharedPtr< T >::data(), KisViewManager::image(), m_view, KisImage::nextLayerName(), OPACITY_OPAQUE_U8, and KisBaseNode::setPinnedToTimeline().

◆ addShapeLayer

KisNodeSP KisLayerManager::addShapeLayer ( KisNodeSP activeNode)
privateslot

Definition at line 697 of file kis_layer_manager.cc.

698{
699 if (!m_view) return 0;
700 if (!m_view->document()) return 0;
701
702 KisImageWSP image = m_view->image();
703 KisShapeLayerSP layer = new KisShapeLayer(m_view->document()->shapeController(), image.data(), image->nextLayerName(i18n("Vector Layer")), OPACITY_OPAQUE_U8);
704
705 addLayerCommon(activeNode, layer, false, 0);
706
707 return layer;
708}
KisShapeController * shapeController

References addLayerCommon(), KisWeakSharedPtr< T >::data(), KisViewManager::document(), KisViewManager::image(), m_view, KisImage::nextLayerName(), OPACITY_OPAQUE_U8, and KisDocument::shapeController.

◆ adjustLayerPosition()

void KisLayerManager::adjustLayerPosition ( KisNodeSP node,
KisNodeSP activeNode,
KisNodeSP & parent,
KisNodeSP & above )
private

Definition at line 603 of file kis_layer_manager.cc.

604{
605 Q_ASSERT(activeNode);
606
607 parent = activeNode;
608 above = parent->lastChild();
609
610 if (parent->inherits("KisGroupLayer") && parent->collapsed()) {
611 above = parent;
612 parent = parent->parent();
613 return;
614 }
615
616 while (parent &&
617 (!parent->allowAsChild(node) || !parent->isEditable(false))) {
618
619 above = parent;
620 parent = parent->parent();
621 }
622
623 if (!parent) {
624 warnKrita << "KisLayerManager::adjustLayerPosition:"
625 << "No node accepted newly created node";
626
627 parent = m_view->image()->root();
628 above = parent->lastChild();
629 }
630}
#define warnKrita
Definition kis_debug.h:87

References KisViewManager::image(), m_view, KisNodeFacade::root, and warnKrita.

◆ changeCloneSource

void KisLayerManager::changeCloneSource ( )
privateslot

Definition at line 373 of file kis_layer_manager.cc.

374{
375 QList<KisNodeSP> selectedNodes = m_view->nodeManager()->selectedNodes();
376 if (selectedNodes.isEmpty()) {
377 return;
378 }
379
380 QList<KisCloneLayerSP> cloneLayers;
381 KisNodeSP node;
382 Q_FOREACH (node, selectedNodes) {
383 KisCloneLayerSP cloneLayer(qobject_cast<KisCloneLayer *>(node.data()));
384 if (cloneLayer) {
385 cloneLayers << cloneLayer;
386 }
387 }
388
389 if (cloneLayers.isEmpty()) {
390 return;
391 }
392
393 if (!m_view->nodeManager()->canModifyLayers(implicitCastList<KisNodeSP>(cloneLayers))) return;
394
396 dialog->setCaption(i18n("Change Clone Layer"));
397 dialog->resize(dialog->minimumSizeHint());
398 dialog->setAttribute(Qt::WA_DeleteOnClose);
399 Qt::WindowFlags flags = dialog->windowFlags();
400 dialog->setWindowFlags(flags | Qt::Tool | Qt::Dialog);
401 dialog->show();
402 dialog->activateWindow();
403}
KisNodeList selectedNodes()
bool canModifyLayers(KisNodeList nodes, bool showWarning=true)
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.

References KisNodeManager::canModifyLayers(), KisSharedPtr< T >::data(), m_view, KisViewManager::nodeManager(), and KisNodeManager::selectedNodes().

◆ convertGroupToAnimated

void KisLayerManager::convertGroupToAnimated ( )
privateslot

Definition at line 483 of file kis_layer_manager.cc.

484{
485 KisGroupLayerSP targetGroup = dynamic_cast<KisGroupLayer*>(activeLayer().data());
486 if (targetGroup.isNull()) {
487 // Try containing group, if it exists...
489 if (!parent->parent()) return; // watch out for the root node!
490 targetGroup = dynamic_cast<KisGroupLayer*>(parent.data());
491 }
492
493 if (targetGroup.isNull()) return;
494 if (!m_view->nodeManager()->canModifyLayer(targetGroup)) return;
495
496 KisPaintLayerSP animatedLayer = new KisPaintLayer(m_view->image(), targetGroup->name(), OPACITY_OPAQUE_U8);
497 animatedLayer->enableAnimation();
498 KisRasterKeyframeChannel *keyframeChannel = dynamic_cast<KisRasterKeyframeChannel*>(
499 animatedLayer->getKeyframeChannel(KisKeyframeChannel::Raster.id(), true));
500 KIS_ASSERT_RECOVER_RETURN(keyframeChannel);
501
502 KisNodeSP childNode = targetGroup->firstChild();
503 int time = 0;
504 while (childNode) {
505 keyframeChannel->importFrame(time, childNode->projection(), NULL);
506 time++;
507
508 childNode = childNode->nextSibling();
509 }
510
511 m_commandsAdapter->beginMacro(kundo2_i18n("Convert Group to Animated Layer"));
512 m_commandsAdapter->addNode(animatedLayer, targetGroup->parent(), targetGroup);
513 m_commandsAdapter->removeNode(targetGroup);
515}
static const KoID Raster
void addNode(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis, KisImageLayerAddCommand::Flags flags=KisImageLayerAddCommand::DoRedoUpdates|KisImageLayerAddCommand::DoUndoUpdates)
void beginMacro(const KUndo2MagicString &macroName)
bool canModifyLayer(KisNodeSP node, bool showWarning=true)
The KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
void importFrame(int time, KisPaintDeviceSP sourceDevice, KUndo2Command *parentCommand)
bool isNull() const
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
virtual KisPaintDeviceSP projection() const =0
KisKeyframeChannel * getKeyframeChannel(const QString &id, bool create)
void enableAnimation()
KisNodeSP firstChild() const
Definition kis_node.cpp:361
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP nextSibling() const
Definition kis_node.cpp:408

References activeLayer(), KisNodeCommandsAdapter::addNode(), KisNodeCommandsAdapter::beginMacro(), KisNodeManager::canModifyLayer(), KisSharedPtr< T >::data(), KisBaseNode::enableAnimation(), KisNodeCommandsAdapter::endMacro(), KisNode::firstChild(), KisBaseNode::getKeyframeChannel(), KisViewManager::image(), KisRasterKeyframeChannel::importFrame(), KisSharedPtr< T >::isNull(), KIS_ASSERT_RECOVER_RETURN, kundo2_i18n(), m_commandsAdapter, m_view, KisBaseNode::name(), KisNode::nextSibling(), KisViewManager::nodeManager(), OPACITY_OPAQUE_U8, KisNode::parent, KisBaseNode::projection(), KisKeyframeChannel::Raster, and KisNodeCommandsAdapter::removeNode().

◆ convertLayerToFileLayer

void KisLayerManager::convertLayerToFileLayer ( KisNodeSP source)
privateslot

Definition at line 517 of file kis_layer_manager.cc.

518{
519 KisImageSP image = m_view->image();
520 if (!image) return;
521
522 // this precondition must be checked at higher level
523 KIS_SAFE_ASSERT_RECOVER_RETURN(source->isEditable(false));
524
526
527 KoDialog dlg;
528 QWidget *page = new QWidget(&dlg);
529 dlg.setMainWidget(page);
530 QBoxLayout *layout = new QVBoxLayout(page);
531 dlg.setWindowTitle(i18n("Save layers to..."));
532 QLabel *lbl = new QLabel(i18n("Choose the location where the layer will be saved to. The new file layer will then reference this location."));
533 lbl->setWordWrap(true);
534 layout->addWidget(lbl);
535 KisFileNameRequester *urlRequester = new KisFileNameRequester(page);
536 urlRequester->setMode(KoFileDialog::SaveFile);
537 urlRequester->setMimeTypeFilters(listMimeFilter);
538 urlRequester->setFileName(m_view->document()->path());
539 if (!m_view->document()->path().isEmpty()) {
540 QFileInfo location = QFileInfo(m_view->document()->path());
541 location.setFile(location.dir(), location.completeBaseName() + "_" + source->name() + ".png");
542 urlRequester->setFileName(location.absoluteFilePath());
543 }
544 else {
545 const QFileInfo location = QFileInfo(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
546 const QString proposedFileName = QDir(location.absoluteFilePath()).absoluteFilePath(source->name() + ".png");
547 urlRequester->setFileName(proposedFileName);
548 }
549
550 layout->addWidget(urlRequester);
551 if (!dlg.exec()) return;
552
553 QString path = urlRequester->fileName();
554
555 if (path.isEmpty()) return;
556
557 QFileInfo f(path);
558
559 QString mimeType= KisMimeDatabase::mimeTypeForFile(f.fileName());
560 if (mimeType.isEmpty()) {
561 mimeType = "image/png";
562 }
563 QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
564
565 QRect bounds = source->exactBounds();
566 if (bounds.isEmpty()) {
567 bounds = image->bounds();
568 }
569 KisImageSP dst = new KisImage(doc->createUndoStore(),
570 image->width(),
571 image->height(),
573 source->name());
574 dst->setResolution(image->xRes(), image->yRes());
575 doc->setFileBatchMode(false);
576 doc->setCurrentImage(dst);
577 KisNodeSP node = source->clone();
578 dst->addNode(node);
579 dst->initialRefreshGraph();
580 dst->cropImage(bounds);
581 dst->waitForDone();
582
583 bool r = doc->exportDocumentSync(path, mimeType.toLatin1());
584 if (!r) {
585
586 qWarning() << "Converting layer to file layer. path:"<< path << "gave errors" << doc->errorMessage();
587 } else {
588 QString basePath = QFileInfo(m_view->document()->path()).absolutePath();
589 QString relativePath = QDir(basePath).relativeFilePath(path);
590 KisFileLayer *fileLayer = new KisFileLayer(image, basePath, relativePath, KisFileLayer::None, "Bicubic", source->name(), OPACITY_OPAQUE_U8);
591 fileLayer->setX(bounds.x());
592 fileLayer->setY(bounds.y());
593 KisNodeSP dstParent = source->parent();
594 KisNodeSP dstAboveThis = source->prevSibling();
595 m_commandsAdapter->beginMacro(kundo2_i18n("Convert to a file layer"));
597 m_commandsAdapter->addNode(fileLayer, dstParent, dstAboveThis);
599 }
600 doc->closePath(false);
601}
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
void setMimeTypeFilters(const QStringList &filterList, QString defaultFilter=QString())
void setMode(KoFileDialog::DialogType mode)
void setFileName(const QString &path)
void waitForDone()
KisPaintDeviceSP projection() const
qint32 width() const
void cropImage(const QRect &newRect)
start asynchronous operation on cropping the image
Definition kis_image.cc:870
void initialRefreshGraph()
double xRes() const
double yRes() const
qint32 height() const
QRect bounds() const override
void setResolution(double xres, double yres)
static QStringList supportedMimeTypes(Direction direction)
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
virtual const KoColorSpace * compositionSourceColorSpace() const
static KisPart * instance()
Definition KisPart.cpp:131
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define bounds(x, a, b)
KisDocument * createDocument(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
void setX(qint32 x) override
Definition kis_layer.cc:983
void setY(qint32 y) override
Definition kis_layer.cc:989
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)

References KisNodeCommandsAdapter::addNode(), KisNodeFacade::addNode(), KisNodeCommandsAdapter::beginMacro(), KisImage::bounds(), bounds, KisPaintDevice::compositionSourceColorSpace(), createDocument(), KisImage::cropImage(), KisViewManager::document(), KisNodeCommandsAdapter::endMacro(), KisImportExportManager::Export, KisFileNameRequester::fileName(), KisImage::height(), KisViewManager::image(), KisImage::initialRefreshGraph(), KisPart::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN, kundo2_i18n(), m_commandsAdapter, m_view, KisMimeDatabase::mimeTypeForFile(), KisFileLayer::None, OPACITY_OPAQUE_U8, KisDocument::path(), KisImage::projection(), KisNodeCommandsAdapter::removeNode(), KoFileDialog::SaveFile, KisFileNameRequester::setFileName(), KoDialog::setMainWidget(), KisFileNameRequester::setMimeTypeFilters(), KisFileNameRequester::setMode(), KisImage::setResolution(), KisLayer::setX(), KisLayer::setY(), source(), KisImportExportManager::supportedMimeTypes(), KisImage::waitForDone(), KisImage::width(), KisImage::xRes(), and KisImage::yRes().

◆ convertNodeToPaintLayer

void KisLayerManager::convertNodeToPaintLayer ( KisNodeSP source)
privateslot

Definition at line 466 of file kis_layer_manager.cc.

467{
468 KisImageWSP image = m_view->image();
469 if (!image) return;
470
471 // this precondition must be checked at higher level
472 KIS_SAFE_ASSERT_RECOVER_RETURN(source->isEditable(false));
473
474 KisLayer *srcLayer = qobject_cast<KisLayer*>(source.data());
475 if (srcLayer && (srcLayer->inherits("KisGroupLayer") || srcLayer->layerStyle() || srcLayer->childCount() > 0)) {
476 image->flattenLayer(srcLayer);
477 return;
478 }
479
481}
void flattenLayer(KisLayerSP layer)
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
std::future< KisNodeSP > convertToPaintLayer(KisImageSP image, KisNodeSP src)
KisPSDLayerStyleSP layerStyle
Definition kis_layer.cc:171
quint32 childCount() const
Definition kis_node.cpp:414

References KisNode::childCount(), KisLayerUtils::convertToPaintLayer(), KisImage::flattenLayer(), KisViewManager::image(), KIS_SAFE_ASSERT_RECOVER_RETURN, KisLayer::layerStyle, m_view, source(), and void().

◆ copyLayerStyle

void KisLayerManager::copyLayerStyle ( )
privateslot

Definition at line 405 of file kis_layer_manager.cc.

406{
407 KisImageSP image = m_view->image();
408 if (!image) return;
409
410 KisLayerSP layer = activeLayer();
411 if (!layer) return;
412
414 if (!layerStyle) return;
415
418 QString psdxml = serializer.formPsdXmlDocument().toString();
419
420 if (!psdxml.isEmpty()) {
421 QMimeData *mimeData = new QMimeData;
422
423 mimeData->setText(psdxml);
424 mimeData->setData("application/x-krita-layer-style", psdxml.toUtf8());
425
426 QGuiApplication::clipboard()->setMimeData(mimeData);
427 }
428}
void setStyles(const QVector< KisPSDLayerStyleSP > &styles)

References activeLayer(), KisAslLayerStyleSerializer::formPsdXmlDocument(), KisViewManager::image(), KisLayer::layerStyle, layerStyle(), m_view, and KisAslLayerStyleSerializer::setStyles().

◆ flattenImage

void KisLayerManager::flattenImage ( )
privateslot

Definition at line 790 of file kis_layer_manager.cc.

791{
792 KisImageSP image = m_view->image();
793
794 if (!m_view->blockUntilOperationsFinished(image)) return;
795
796 if (image) {
797 bool doIt = true;
798
799 if (image->nHiddenLayers() > 0) {
800 int answer = QMessageBox::warning(m_view->mainWindow(),
801 i18nc("@title:window", "Flatten Image"),
802 i18n("The image contains hidden layers that will be lost. Do you want to flatten the image?"),
803 QMessageBox::Yes | QMessageBox::No,
804 QMessageBox::No);
805
806 if (answer != QMessageBox::Yes) {
807 doIt = false;
808 }
809 }
810
811 if (doIt) {
812 image->flatten(m_view->activeNode());
813 }
814 }
815}
void flatten(KisNodeSP activeNode)
qint32 nHiddenLayers() const
bool blockUntilOperationsFinished(KisImageSP image)
blockUntilOperationsFinished blocks the GUI of the application until execution of actions on image is...
KisNodeSP activeNode()

References KisViewManager::activeNode(), KisViewManager::blockUntilOperationsFinished(), KisImage::flatten(), KisViewManager::image(), m_view, KisViewManager::mainWindow(), and KisImage::nHiddenLayers().

◆ flattenLayer

void KisLayerManager::flattenLayer ( )
privateslot

Definition at line 929 of file kis_layer_manager.cc.

930{
931 KisImageSP image = m_view->image();
932 if (!image) return;
933
934 KisLayerSP layer = activeLayer();
935 if (!layer) return;
936
937 if (!m_view->blockUntilOperationsFinished(image)) return;
938 if (!m_view->nodeManager()->canModifyLayer(layer)) return;
939
941 m_view->updateGUI();
942}
void convertNodeToPaintLayer(KisNodeSP source)

References activeLayer(), KisViewManager::blockUntilOperationsFinished(), KisNodeManager::canModifyLayer(), convertNodeToPaintLayer(), KisViewManager::image(), m_view, KisViewManager::nodeManager(), and KisViewManager::updateGUI().

◆ imageResizeToActiveLayer

void KisLayerManager::imageResizeToActiveLayer ( )
privateslot

Definition at line 205 of file kis_layer_manager.cc.

206{
207 KisLayerSP layer;
208 KisImageWSP image = m_view->image();
209
210 if (image && (layer = activeLayer())) {
211 QRect cropRect = layer->projection()->nonDefaultPixelArea();
212 if (!cropRect.isEmpty()) {
213 image->cropImage(cropRect);
214 } else {
216 i18nc("floating message in layer manager",
217 "Layer is empty "),
218 QIcon(), 2000, KisFloatingMessage::Low);
219 }
220 }
221}
QRect nonDefaultPixelArea() const
void showFloatingMessage(const QString &message, const QIcon &icon, int timeout=4500, KisFloatingMessage::Priority priority=KisFloatingMessage::Medium, int alignment=Qt::AlignCenter|Qt::TextWordWrap)
shows a floating message in the top right corner of the canvas
KisPaintDeviceSP projection() const override
Definition kis_layer.cc:820

References activeLayer(), KisImage::cropImage(), KisViewManager::image(), KisFloatingMessage::Low, m_view, KisPaintDevice::nonDefaultPixelArea(), KisLayer::projection(), and KisViewManager::showFloatingMessage().

◆ layerProperties

void KisLayerManager::layerProperties ( )
privateslot

Definition at line 231 of file kis_layer_manager.cc.

232{
233 if (!m_view) return;
234 if (!m_view->document()) return;
235
236 // For non-modal dialogs, only allow one instance of the dialog to exist.
237 // Modal dialogs won't set this.
239
240 KisLayerSP layer = activeLayer();
241 if (!layer) return;
242
243 const QList<KisNodeSP> selectedNodes = m_view->nodeManager()->selectedNodes();
244 const bool multipleLayersSelected = selectedNodes.size() > 1;
245
246 if (!m_view->nodeManager()->canModifyLayers(selectedNodes)) return;
247
248 KisAdjustmentLayerSP adjustmentLayer = KisAdjustmentLayerSP(dynamic_cast<KisAdjustmentLayer*>(layer.data()));
249 KisGeneratorLayerSP generatorLayer = KisGeneratorLayerSP(dynamic_cast<KisGeneratorLayer*>(layer.data()));
250 KisFileLayerSP fileLayer = KisFileLayerSP(dynamic_cast<KisFileLayer*>(layer.data()));
251
252 if (adjustmentLayer && !multipleLayersSelected) {
253
254 KisPaintDeviceSP dev = adjustmentLayer->projection();
255
256 KisDlgAdjLayerProps dlg(adjustmentLayer, adjustmentLayer.data(), dev, m_view, adjustmentLayer->filter().data(), adjustmentLayer->name(), i18n("Filter Layer Properties"), m_view->mainWindow(), "dlgadjlayerprops");
257 dlg.resize(dlg.minimumSizeHint());
258
259
260 KisFilterConfigurationSP configBefore(adjustmentLayer->filter());
261 KIS_ASSERT_RECOVER_RETURN(configBefore);
262 QString xmlBefore = configBefore->toXML();
263
264
265 if (dlg.exec() == QDialog::Accepted) {
266
267 adjustmentLayer->setName(dlg.layerName());
268
269 KisFilterConfigurationSP configAfter(dlg.filterConfiguration());
270 Q_ASSERT(configAfter);
271 QString xmlAfter = configAfter->toXML();
272
273 if(xmlBefore != xmlAfter) {
275 = new KisChangeFilterCmd(adjustmentLayer,
276 configBefore->cloneWithResourcesSnapshot(),
277 configAfter->cloneWithResourcesSnapshot());
278 // FIXME: check whether is needed
279 cmd->redo();
281 m_view->document()->setModified(true);
282 }
283 }
284 else {
285 KisFilterConfigurationSP configAfter(dlg.filterConfiguration());
286 Q_ASSERT(configAfter);
287 QString xmlAfter = configAfter->toXML();
288
289 if(xmlBefore != xmlAfter) {
290 adjustmentLayer->setFilter(configBefore->cloneWithResourcesSnapshot());
291 adjustmentLayer->setDirty();
292 }
293 }
294 }
295 else if (fileLayer && !multipleLayersSelected){
296 QString basePath = QFileInfo(m_view->document()->path()).absolutePath();
297 QString fileNameOld = fileLayer->fileName();
298 KisFileLayer::ScalingMethod scalingMethodOld = fileLayer->scalingMethod();
299 QString scalingFilterOld = fileLayer->scalingFilter();
300 KisDlgFileLayer dlg(basePath, fileLayer->name(), m_view->mainWindow());
301 dlg.setCaption(i18n("File Layer Properties"));
302 dlg.setFileName(fileNameOld);
303 dlg.setScalingMethod(scalingMethodOld);
304 dlg.setScalingFilter(scalingFilterOld);
305
306 if (dlg.exec() == QDialog::Accepted) {
307 const QString fileNameNew = dlg.fileName();
308 KisFileLayer::ScalingMethod scalingMethodNew = dlg.scaleToImageResolution();
309 QString scalingFilterNew = dlg.scalingFilter();
310
311 if(fileNameNew.isEmpty()){
312 QMessageBox::critical(m_view->mainWindow(), i18nc("@title:window", "Krita"), i18n("No file name specified"));
313 return;
314 }
315 fileLayer->setName(dlg.layerName());
316
317 if (fileNameOld!= fileNameNew || scalingMethodOld != scalingMethodNew || scalingFilterOld != scalingFilterNew) {
319 = new KisChangeFileLayerCmd(fileLayer,
320 basePath,
321 fileNameOld,
322 scalingMethodOld,
323 scalingFilterOld,
324 basePath,
325 fileNameNew,
326 scalingMethodNew,
327 scalingFilterNew);
329 }
330 }
331 } else {
332 QDialog* dlg = nullptr;
333
334 if (generatorLayer && !multipleLayersSelected) {
335 KisFilterConfigurationSP configBefore(generatorLayer->filter());
336 Q_ASSERT(configBefore);
337
338 auto* genDlg = new KisDlgGeneratorLayer(generatorLayer->name(), m_view, m_view->canvas(), generatorLayer, configBefore, KisStrokeId());
339 genDlg->setWindowTitle(i18n("Fill Layer Properties"));
340 genDlg->setConfiguration(configBefore.data());
341
342 dlg = genDlg;
343 }
344
345 // Handle these layer(s) as normal painting layer, vector layer, or group layer
346 if (!dlg) {
347 dlg = new KisDlgLayerProperties(selectedNodes, m_view, m_view->canvas());
348 }
349
350 dlg->resize(dlg->minimumSizeHint());
351 dlg->setAttribute(Qt::WA_DeleteOnClose);
352
353 const Qt::WindowFlags flags = dlg->windowFlags();
354#ifdef Q_OS_ANDROID
355 // a Qt::Tool window seems incapable of receiving keyboard focus
356 dlg->setWindowFlags(flags | Qt::Dialog);
357#else
358 dlg->setWindowFlags(flags | Qt::Tool | Qt::Dialog);
359#endif
360 connect(dlg, SIGNAL(destroyed()), this, SLOT(layerPropertiesDialogClosed()));
362
363 dlg->show();
364 dlg->activateWindow();
365 }
366}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void setModified(bool _mod)
ScalingMethod scalingMethod() const
QString fileName() const
QString scalingFilter() const
virtual KisFilterConfigurationSP filter() const
virtual void addCommand(KUndo2Command *cmd)=0
KisUndoAdapter * undoAdapter()
The undo adapter is used to add commands to the undo stack.
QWidget * canvas() const
Return the actual widget that is displaying the current image.
KisSharedPtr< KisFileLayer > KisFileLayerSP
Definition kis_types.h:145
KisSharedPtr< KisAdjustmentLayer > KisAdjustmentLayerSP
Definition kis_types.h:131
KisSharedPtr< KisGeneratorLayer > KisGeneratorLayerSP
Definition kis_types.h:134
void setName(const QString &name)

References activeLayer(), KisUndoAdapter::addCommand(), KisNodeManager::canModifyLayers(), KisViewManager::canvas(), connect(), KisSharedPtr< T >::data(), KisViewManager::document(), KisDlgFileLayer::fileName(), KisFileLayer::fileName(), KisNodeFilterInterface::filter(), KisDlgAdjLayerProps::filterConfiguration(), KIS_ASSERT_RECOVER_RETURN, KisDlgAdjLayerProps::layerName(), KisDlgFileLayer::layerName(), layerPropertiesDialogClosed(), m_layerPropertiesDialogActive, m_view, KisViewManager::mainWindow(), KoDialog::minimumSizeHint(), KisBaseNode::name(), KisViewManager::nodeManager(), KisDocument::path(), KisChangeFilterCmd::redo(), KisDlgFileLayer::scaleToImageResolution(), KisDlgFileLayer::scalingFilter(), KisFileLayer::scalingFilter(), KisFileLayer::scalingMethod(), KisNodeManager::selectedNodes(), KoDialog::setCaption(), KisDlgFileLayer::setFileName(), KisDocument::setModified(), KisBaseNode::setName(), KisDlgFileLayer::setScalingFilter(), KisDlgFileLayer::setScalingMethod(), and KisViewManager::undoAdapter().

◆ layerPropertiesDialogClosed

void KisLayerManager::layerPropertiesDialogClosed ( )
privateslot

Definition at line 368 of file kis_layer_manager.cc.

369{
371}

References m_layerPropertiesDialogActive.

◆ layerStyle

void KisLayerManager::layerStyle ( )
privateslot

Definition at line 1039 of file kis_layer_manager.cc.

1040{
1041 KisImageWSP image = m_view->image();
1042 if (!image) return;
1043
1044 KisLayerSP layer = activeLayer();
1045 if (!layer) return;
1046
1047 if (!m_view->blockUntilOperationsFinished(image)) return;
1048 if (!m_view->nodeManager()->canModifyLayer(layer)) return;
1049
1050 KoCanvasResourcesInterfaceSP canvasResourcesInterface = m_view->canvasBase()->resourceManager()->canvasResourcesInterface();
1051
1052 KisPSDLayerStyleSP oldStyle;
1053 if (layer->layerStyle()) {
1054 oldStyle = layer->layerStyle()->clone().dynamicCast<KisPSDLayerStyle>();
1055
1056 } else {
1058 ->cloneWithResourcesSnapshot(KisGlobalResourcesInterface::instance(),
1059 canvasResourcesInterface);
1060 }
1061
1062 KisPSDLayerStyleSP newStyle = oldStyle->clone().dynamicCast<KisPSDLayerStyle>();
1063 // We want to also change the UUID, else it might be considered the same style after save and won't load correctly
1064 newStyle->setUuid(QUuid::createUuid());
1065 newStyle->setResourcesInterface(KisGlobalResourcesInterface::instance());
1066
1068
1069 std::function<void ()> updateCall(std::bind(updateLayerStyles, layer, &dlg, canvasResourcesInterface));
1070 SignalToFunctionProxy proxy(updateCall);
1071 connect(&dlg, SIGNAL(configChanged()), &proxy, SLOT(start()));
1072
1073 if (dlg.exec() == QDialog::Accepted) {
1074 KisPSDLayerStyleSP newStyle =
1075 dlg.style()->cloneWithResourcesSnapshot(KisGlobalResourcesInterface::instance(),
1076 canvasResourcesInterface);
1077
1078 KUndo2CommandSP command = toQShared(
1079 new KisSetLayerStyleCommand(layer, oldStyle, newStyle));
1080
1081 image->postExecutionUndoAdapter()->addCommand(command);
1082 }
1083}
static KisResourcesInterfaceSP instance()
KisPostExecutionUndoAdapter * postExecutionUndoAdapter() const override
KisCanvas2 * canvasBase() const
Return the canvas base class.
QPointer< KoCanvasResourceProvider > resourceManager
void updateLayerStyles(KisLayerSP layer, KisDlgLayerStyle *dlg, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
QSharedPointer< T > toQShared(T *ptr)
The KisPSDLayerStyle class implements loading, saving and applying the PSD layer effects.

References activeLayer(), KisPostExecutionUndoAdapter::addCommand(), KisViewManager::blockUntilOperationsFinished(), KisNodeManager::canModifyLayer(), KisViewManager::canvasBase(), KisViewManager::canvasResourceProvider(), connect(), KisViewManager::image(), KisGlobalResourcesInterface::instance(), KisLayer::layerStyle, m_view, KisViewManager::nodeManager(), KisImage::postExecutionUndoAdapter(), KoCanvasBase::resourceManager, KisDlgLayerStyle::style(), toQShared(), updateLayerStyles(), and void().

◆ layersUpdated

void KisLayerManager::layersUpdated ( )
privateslot

Definition at line 944 of file kis_layer_manager.cc.

945{
946 KisLayerSP layer = activeLayer();
947 if (!layer) return;
948
949 m_view->updateGUI();
950}

References activeLayer(), m_view, and KisViewManager::updateGUI().

◆ mergeLayer

void KisLayerManager::mergeLayer ( )
privateslot

Definition at line 856 of file kis_layer_manager.cc.

857{
858 KisImageSP image = m_view->image();
859 if (!image) return;
860
861 KisLayerSP layer = activeLayer();
862 if (!layer) return;
863
864 if (!m_view->blockUntilOperationsFinished(image)) return;
865
866 QList<KisNodeSP> selectedNodes = m_view->nodeManager()->selectedNodes();
867
868 // check if all the layers are a part of a locked group
869 bool hasEditableLayer = false;
870 Q_FOREACH (KisNodeSP node, selectedNodes) {
871 if (node->isEditable(false)) {
872 hasEditableLayer = true;
873 break;
874 }
875 }
876
877 if (!hasEditableLayer) {
879 i18ncp("floating message in layer manager",
880 "Layer is locked", "Layers are locked", selectedNodes.size()),
881 QIcon(), 2000, KisFloatingMessage::Low);
882 return;
883 }
884
885 if (selectedNodes.size() > 1) {
886 image->mergeMultipleLayers(selectedNodes, m_view->activeNode());
887 }
888
889 else if (tryMergeSelectionMasks(m_view->activeNode(), image)) {
890 // already done!
891 } else if (tryFlattenGroupLayer(m_view->activeNode(), image)) {
892 // already done!
893 } else {
894
895 if (!layer->prevSibling()) return;
896 KisLayer *prevLayer = qobject_cast<KisLayer*>(layer->prevSibling().data());
897 if (!prevLayer) return;
898
899 if (prevLayer->userLocked()) {
901 i18nc("floating message in layer manager when previous layer is locked",
902 "Layer is locked"),
903 QIcon(), 2000, KisFloatingMessage::Low);
904 } else {
905 const KisMetaData::MergeStrategy* strategy = nullptr;
906
907 if (layer->metaData()->isEmpty() && prevLayer->metaData()->isEmpty()) {
909 }
910 else {
912 }
913
914 if (!strategy) return;
915
916 if (!layer->isAnimated() && prevLayer->isAnimated()) {
918 i18nc("floating message in layer manager when trying to merge a non-animated layer into an animated one",
919 "Non-animated layer is merged into the current frame. To merge it into the whole clip, create at least one frame"),
920 QIcon(), 5000, KisFloatingMessage::Medium);
921 }
922 image->mergeDown(layer, strategy);
923 }
924 }
925
926 m_view->updateGUI();
927}
void mergeMultipleLayers(QList< KisNodeSP > mergedLayers, KisNodeSP putAfter)
void mergeDown(KisLayerSP l, const KisMetaData::MergeStrategy *strategy)
static const KisMetaData::MergeStrategy * showDialog(QWidget *parent)
T get(const QString &id) const
bool tryMergeSelectionMasks(KisNodeSP currentNode, KisImageSP image)
bool tryFlattenGroupLayer(KisNodeSP currentNode, KisImageSP image)
bool isEditable(bool checkVisibility=true) const
bool userLocked() const
bool isAnimated() const
KisMetaData::Store * metaData()
KisNodeSP prevSibling() const
Definition kis_node.cpp:402

References activeLayer(), KisViewManager::activeNode(), KisViewManager::blockUntilOperationsFinished(), KisSharedPtr< T >::data(), KoGenericRegistry< T >::get(), KisViewManager::image(), KisMetaData::MergeStrategyRegistry::instance(), KisBaseNode::isAnimated(), KisBaseNode::isEditable(), KisMetaData::Store::isEmpty(), KisFloatingMessage::Low, m_view, KisViewManager::mainWindow(), KisFloatingMessage::Medium, KisImage::mergeDown(), KisImage::mergeMultipleLayers(), KisLayer::metaData(), KisViewManager::nodeManager(), KisNode::prevSibling(), KisNodeManager::selectedNodes(), KisMetaDataMergeStrategyChooserWidget::showDialog(), KisViewManager::showFloatingMessage(), tryFlattenGroupLayer(), tryMergeSelectionMasks(), KisViewManager::updateGUI(), and KisBaseNode::userLocked().

◆ pasteLayerStyle

void KisLayerManager::pasteLayerStyle ( )
privateslot

Definition at line 430 of file kis_layer_manager.cc.

431{
432 KisImageSP image = m_view->image();
433 if (!image) return;
434
435 KisLayerSP layer = activeLayer();
436 if (!layer) return;
437
438 QString aslXml;
439
440 if (KisClipboard::instance()->hasLayerStyles()) {
441 aslXml = QString::fromUtf8(QGuiApplication::clipboard()->mimeData()->data("application/x-krita-layer-style"));
442 } else {
443 aslXml = QGuiApplication::clipboard()->text();
444 }
445
446 if (aslXml.isEmpty()) return;
447
448 QDomDocument aslDoc;
449 if (!aslDoc.setContent(aslXml)) return;
450
452 serializer.registerPSDPattern(aslDoc);
453 serializer.readFromPSDXML(aslDoc);
454
455 if (serializer.styles().size() != 1) return;
456
457 KisPSDLayerStyleSP newStyle = serializer.styles().first()->cloneWithResourcesSnapshot(
459 m_view->canvasBase()->resourceManager()->canvasResourcesInterface());
460 KUndo2Command *cmd = new KisSetLayerStyleCommand(layer, layer->layerStyle(), newStyle);
461
463 image->waitForDone();
464}
QVector< KisPSDLayerStyleSP > styles() const
void readFromPSDXML(const QDomDocument &doc)
void registerPSDPattern(const QDomDocument &doc)
static KisClipboard * instance()
static void runSingleCommandStroke(KisImageSP image, KUndo2Command *cmd, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
runSingleCommandStroke creates a stroke and runs cmd in it. The text() field of cmd is used as a titl...

References activeLayer(), KisViewManager::canvasBase(), KisViewManager::image(), KisGlobalResourcesInterface::instance(), KisClipboard::instance(), KisLayer::layerStyle, m_view, KisAslLayerStyleSerializer::readFromPSDXML(), KisAslLayerStyleSerializer::registerPSDPattern(), KoCanvasBase::resourceManager, KisProcessingApplicator::runSingleCommandStroke(), KisAslLayerStyleSerializer::styles(), and KisImage::waitForDone().

◆ saveGroupLayers

void KisLayerManager::saveGroupLayers ( )
privateslot

Definition at line 952 of file kis_layer_manager.cc.

953{
955
956 KoDialog dlg;
957 QWidget *page = new QWidget(&dlg);
958 dlg.setMainWidget(page);
959 QBoxLayout *layout = new QVBoxLayout(page);
960
961 KisFileNameRequester *urlRequester = new KisFileNameRequester(page);
962 urlRequester->setMode(KoFileDialog::SaveFile);
963 urlRequester->setStartDir(QFileInfo(m_view->document()->path()).absolutePath());
964 urlRequester->setMimeTypeFilters(listMimeFilter);
965 urlRequester->setFileName(m_view->document()->path());
966 layout->addWidget(urlRequester);
967
968 QCheckBox *chkInvisible = new QCheckBox(i18n("Convert Invisible Groups"), page);
969 chkInvisible->setChecked(false);
970 layout->addWidget(chkInvisible);
971 QCheckBox *chkDepth = new QCheckBox(i18n("Export Only Toplevel Groups"), page);
972 chkDepth->setChecked(true);
973 layout->addWidget(chkDepth);
974
975 if (!dlg.exec()) return;
976
977 QString path = urlRequester->fileName();
978
979 if (path.isEmpty()) return;
980
981 QFileInfo f(path);
982
983 QString mimeType= KisMimeDatabase::mimeTypeForFile(f.fileName(), false);
984 if (mimeType.isEmpty()) {
985 mimeType = "image/png";
986 }
987 QString extension = KisMimeDatabase::suffixesForMimeType(mimeType).first();
988 QString basename = f.completeBaseName();
989
990 KisImageSP image = m_view->image();
991 if (!image) return;
992
993 KisSaveGroupVisitor v(image, chkInvisible->isChecked(), chkDepth->isChecked(), f.absolutePath(), basename, extension, mimeType);
994 image->rootLayer()->accept(v);
995
996}
qreal v
void setStartDir(const QString &path)
KisGroupLayerSP rootLayer() const
static QStringList suffixesForMimeType(const QString &mimeType)
The KisSaveGroupVisitor class saves the groups in a Krita image to separate images.
bool accept(KisNodeVisitor &v) override

References KisGroupLayer::accept(), KisViewManager::document(), KisImportExportManager::Export, KisFileNameRequester::fileName(), KisViewManager::image(), m_view, KisMimeDatabase::mimeTypeForFile(), KisDocument::path(), KisImage::rootLayer(), KoFileDialog::SaveFile, KisFileNameRequester::setFileName(), KoDialog::setMainWidget(), KisFileNameRequester::setMimeTypeFilters(), KisFileNameRequester::setMode(), KisFileNameRequester::setStartDir(), KisMimeDatabase::suffixesForMimeType(), KisImportExportManager::supportedMimeTypes(), and v.

◆ setup()

void KisLayerManager::setup ( KisActionManager * actionManager)
private

Definition at line 149 of file kis_layer_manager.cc.

150{
151 m_imageFlatten = actionManager->createAction("flatten_image");
152 connect(m_imageFlatten, SIGNAL(triggered()), this, SLOT(flattenImage()));
153
154 m_imageMergeLayer = actionManager->createAction("merge_layer");
155 connect(m_imageMergeLayer, SIGNAL(triggered()), this, SLOT(mergeLayer()));
156
157 m_flattenLayer = actionManager->createAction("flatten_layer");
158 connect(m_flattenLayer, SIGNAL(triggered()), this, SLOT(flattenLayer()));
159
160 m_groupLayersSave = actionManager->createAction("save_groups_as_images");
161 connect(m_groupLayersSave, SIGNAL(triggered()), this, SLOT(saveGroupLayers()));
162
163 m_convertGroupAnimated = actionManager->createAction("convert_group_to_animated");
164 connect(m_convertGroupAnimated, SIGNAL(triggered()), this, SLOT(convertGroupToAnimated()));
165
166 m_imageResizeToLayer = actionManager->createAction("resizeimagetolayer");
167 connect(m_imageResizeToLayer, SIGNAL(triggered()), this, SLOT(imageResizeToActiveLayer()));
168
169 KisAction *action = actionManager->createAction("trim_to_image");
170 connect(action, SIGNAL(triggered()), this, SLOT(trimToImage()));
171
172 m_layerStyle = actionManager->createAction("layer_style");
173 connect(m_layerStyle, SIGNAL(triggered()), this, SLOT(layerStyle()));
174
175 m_copyLayerStyle = actionManager->createAction("copy_layer_style");
176 connect(m_copyLayerStyle, SIGNAL(triggered()), this, SLOT(copyLayerStyle()));
177
178 m_pasteLayerStyle = actionManager->createAction("paste_layer_style");
179 connect(m_pasteLayerStyle, SIGNAL(triggered()), this, SLOT(pasteLayerStyle()));
180}
KisAction * createAction(const QString &name)
KisAction * m_imageResizeToLayer
KisAction * m_copyLayerStyle
KisAction * m_layerStyle
KisAction * m_flattenLayer
KisAction * m_convertGroupAnimated
KisAction * m_imageFlatten
KisAction * m_pasteLayerStyle
KisAction * m_imageMergeLayer
KisAction * m_groupLayersSave

References connect(), convertGroupToAnimated(), copyLayerStyle(), KisActionManager::createAction(), flattenImage(), flattenLayer(), imageResizeToActiveLayer(), layerStyle(), m_convertGroupAnimated, m_copyLayerStyle, m_flattenLayer, m_groupLayersSave, m_imageFlatten, m_imageMergeLayer, m_imageResizeToLayer, m_layerStyle, m_pasteLayerStyle, mergeLayer(), pasteLayerStyle(), saveGroupLayers(), and trimToImage().

◆ setView()

void KisLayerManager::setView ( QPointer< KisView > view)

Definition at line 117 of file kis_layer_manager.cc.

118{
119 m_imageView = view;
120}

References m_imageView.

◆ trimToImage

void KisLayerManager::trimToImage ( )
privateslot

Definition at line 223 of file kis_layer_manager.cc.

224{
225 KisImageWSP image = m_view->image();
226 if (image) {
227 image->cropImage(image->bounds());
228 }
229}

References KisImage::bounds(), KisImage::cropImage(), KisViewManager::image(), and m_view.

◆ updateGUI()

void KisLayerManager::updateGUI ( )
private

Definition at line 182 of file kis_layer_manager.cc.

183{
184 KisImageSP image = m_view->image();
185 KisLayerSP layer = activeLayer();
186
187 const bool isGroupLayer = layer && layer->inherits("KisGroupLayer");
188
189 QString mergeLayerText;
190 if (m_view->nodeManager()->selectedNodes().size() > 1) {
191 mergeLayerText = i18nc("@action:inmenu", "Merge Selected Layers");
192 } else if (isGroupLayer) {
193 mergeLayerText = i18nc("@action:inmenu", "Merge Group");
194 } else {
195 mergeLayerText = i18nc("@action:inmenu", "Merge with Layer Below");
196 }
197 m_imageMergeLayer->setText(mergeLayerText);
198
199 m_flattenLayer->setVisible(!isGroupLayer);
200
201 if (m_view->statusBar())
202 m_view->statusBar()->setProfile(image);
203}
void setProfile(KisImageWSP image)
KisStatusBar * statusBar() const
Return the wrapper class around the statusbar.

References activeLayer(), KisViewManager::image(), m_flattenLayer, m_imageMergeLayer, m_view, KisViewManager::nodeManager(), KisNodeManager::selectedNodes(), KisStatusBar::setProfile(), and KisViewManager::statusBar().

Friends And Related Symbol Documentation

◆ KisNodeManager

friend class KisNodeManager
friend

Definition at line 44 of file kis_layer_manager.h.

Member Data Documentation

◆ m_commandsAdapter

KisNodeCommandsAdapter* KisLayerManager::m_commandsAdapter
private

Definition at line 122 of file kis_layer_manager.h.

◆ m_convertGroupAnimated

KisAction* KisLayerManager::m_convertGroupAnimated {0}
private

Definition at line 118 of file kis_layer_manager.h.

118{0};

◆ m_copyLayerStyle

KisAction* KisLayerManager::m_copyLayerStyle {0}
private

Definition at line 125 of file kis_layer_manager.h.

125{0};

◆ m_flattenLayer

KisAction* KisLayerManager::m_flattenLayer {0}
private

Definition at line 120 of file kis_layer_manager.h.

120{0};

◆ m_groupLayersSave

KisAction* KisLayerManager::m_groupLayersSave {0}
private

Definition at line 117 of file kis_layer_manager.h.

117{0};

◆ m_imageFlatten

KisAction* KisLayerManager::m_imageFlatten {0}
private

Definition at line 115 of file kis_layer_manager.h.

115{0};

◆ m_imageMergeLayer

KisAction* KisLayerManager::m_imageMergeLayer {0}
private

Definition at line 116 of file kis_layer_manager.h.

116{0};

◆ m_imageResizeToLayer

KisAction* KisLayerManager::m_imageResizeToLayer {0}
private

Definition at line 119 of file kis_layer_manager.h.

119{0};

◆ m_imageView

QPointer<KisView> KisLayerManager::m_imageView {0}
private

Definition at line 113 of file kis_layer_manager.h.

113{0};

◆ m_layerPropertiesDialogActive

bool KisLayerManager::m_layerPropertiesDialogActive {false}
private

Definition at line 128 of file kis_layer_manager.h.

128{false};

◆ m_layerStyle

KisAction* KisLayerManager::m_layerStyle {0}
private

Definition at line 124 of file kis_layer_manager.h.

124{0};

◆ m_pasteLayerStyle

KisAction* KisLayerManager::m_pasteLayerStyle {0}
private

Definition at line 126 of file kis_layer_manager.h.

126{0};

◆ m_rasterizeLayer

KisAction* KisLayerManager::m_rasterizeLayer {0}
private

Definition at line 121 of file kis_layer_manager.h.

121{0};

◆ m_view

KisViewManager* KisLayerManager::m_view
private

Definition at line 112 of file kis_layer_manager.h.


The documentation for this class was generated from the following files: