diff --git a/krita/krita.action b/krita/krita.action --- a/krita/krita.action +++ b/krita/krita.action @@ -2267,6 +2267,18 @@ false + + + &New Layer From Visible + + New layer from visible + New layer from visible + 1000 + 0 + + false + + duplicatelayer &Duplicate Layer or Mask diff --git a/krita/krita.xmlgui b/krita/krita.xmlgui --- a/krita/krita.xmlgui +++ b/krita/krita.xmlgui @@ -159,6 +159,7 @@ New + diff --git a/libs/image/kis_layer_utils.h b/libs/image/kis_layer_utils.h --- a/libs/image/kis_layer_utils.h +++ b/libs/image/kis_layer_utils.h @@ -58,6 +58,8 @@ KRITAIMAGE_EXPORT QSet fetchLayerFramesRecursive(KisNodeSP rootNode); KRITAIMAGE_EXPORT void mergeMultipleLayers(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter); + KRITAIMAGE_EXPORT void newLayerFromVisible(KisImageSP image, KisNodeSP putAfter); + KRITAIMAGE_EXPORT bool tryMergeSelectionMasks(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter); KRITAIMAGE_EXPORT void flattenLayer(KisImageSP image, KisLayerSP layer); diff --git a/libs/image/kis_layer_utils.cpp b/libs/image/kis_layer_utils.cpp --- a/libs/image/kis_layer_utils.cpp +++ b/libs/image/kis_layer_utils.cpp @@ -252,17 +252,25 @@ }; struct CreateMergedLayerMultiple : public KisCommandUtils::AggregateCommand { - CreateMergedLayerMultiple(MergeMultipleInfoSP info) : m_info(info) {} + CreateMergedLayerMultiple(MergeMultipleInfoSP info, const QString name = QString() ) + : m_info(info), + m_name(name) {} void populateChildCommands() { - const QString mergedLayerSuffix = i18n("Merged"); - QString mergedLayerName = m_info->mergedNodes.first()->name(); - - if (!mergedLayerName.endsWith(mergedLayerSuffix)) { - mergedLayerName = QString("%1 %2") - .arg(mergedLayerName).arg(mergedLayerSuffix); + QString mergedLayerName; + + if (m_name.isEmpty()){ + const QString mergedLayerSuffix = i18n("Merged"); + mergedLayerName = m_info->mergedNodes.first()->name(); + + if (!mergedLayerName.endsWith(mergedLayerSuffix)) { + mergedLayerName = QString("%1 %2") + .arg(mergedLayerName).arg(mergedLayerSuffix); + } + } else { + mergedLayerName = m_name; } - + m_info->dstNode = new KisPaintLayer(m_info->image, mergedLayerName, OPACITY_OPAQUE_U8); if (m_info->frames.size() > 0) { @@ -300,6 +308,7 @@ private: MergeMultipleInfoSP m_info; + QString m_name; }; struct MergeLayers : public KisCommandUtils::AggregateCommand { @@ -480,6 +489,30 @@ addCommand(cmd); } + struct InsertNode : public KisCommandUtils::AggregateCommand { + InsertNode(MergeDownInfoBaseSP info, KisNodeSP putAfter) + : m_info(info), m_putAfter(putAfter) {} + + void populateChildCommands() { + addCommand(new KisImageLayerAddCommand(m_info->image, + m_info->dstNode, + m_putAfter->parent(), + m_putAfter, + true, false)); + + } + + private: + virtual void addCommandImpl(KUndo2Command *cmd) { + addCommand(cmd); + } + + private: + MergeDownInfoBaseSP m_info; + KisNodeSP m_putAfter; + }; + + struct CleanUpNodes : private RemoveNodeHelper, public KisCommandUtils::AggregateCommand { CleanUpNodes(MergeDownInfoBaseSP info, KisNodeSP putAfter) : m_info(info), m_putAfter(putAfter) {} @@ -922,7 +955,9 @@ applicator.end(); } - void mergeMultipleLayersImpl(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, bool flattenSingleLayer, const KUndo2MagicString &actionName) + void mergeMultipleLayersImpl(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, + bool flattenSingleLayer, const KUndo2MagicString &actionName, + bool cleanupNodes = true, const QString layerName = QString()) { filterMergableNodes(mergedNodes); { @@ -961,7 +996,7 @@ applicator.applyCommand(new KeepMergedNodesSelected(info, putAfter, false)); applicator.applyCommand(new FillSelectionMasks(info)); - applicator.applyCommand(new CreateMergedLayerMultiple(info), KisStrokeJobData::BARRIER); + applicator.applyCommand(new CreateMergedLayerMultiple(info, layerName), KisStrokeJobData::BARRIER); if (info->frames.size() > 0) { foreach (int frame, info->frames) { @@ -979,9 +1014,15 @@ } //applicator.applyCommand(new MergeMetaData(info, strategy), KisStrokeJobData::BARRIER); - applicator.applyCommand(new CleanUpNodes(info, putAfter), - KisStrokeJobData::SEQUENTIAL, - KisStrokeJobData::EXCLUSIVE); + if (cleanupNodes){ + applicator.applyCommand(new CleanUpNodes(info, putAfter), + KisStrokeJobData::SEQUENTIAL, + KisStrokeJobData::EXCLUSIVE); + } else { + applicator.applyCommand(new InsertNode(info, putAfter), + KisStrokeJobData::SEQUENTIAL, + KisStrokeJobData::EXCLUSIVE); + } applicator.applyCommand(new KeepMergedNodesSelected(info, putAfter, true)); } @@ -991,7 +1032,15 @@ void mergeMultipleLayers(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter) { - mergeMultipleLayersImpl(image, mergedNodes, putAfter, false, kundo2_i18n("Merge Selected Nodes")); + mergeMultipleLayersImpl(image, mergedNodes, putAfter, false, kundo2_i18n("Merge Selected Nodes"), false); + } + + void newLayerFromVisible(KisImageSP image, KisNodeSP putAfter) + { + KisNodeList mergedNodes; + mergedNodes << image->root(); + + mergeMultipleLayersImpl(image, mergedNodes, putAfter, true, kundo2_i18n("New From Visible"), false, i18n("Visible Layer")); } struct MergeSelectionMasks : public KisCommandUtils::AggregateCommand { diff --git a/libs/ui/kis_node_manager.h b/libs/ui/kis_node_manager.h --- a/libs/ui/kis_node_manager.h +++ b/libs/ui/kis_node_manager.h @@ -153,6 +153,10 @@ */ void copyNodesDirect(KisNodeList nodes, KisNodeSP parent, KisNodeSP aboveThis); + /** + * Create new layer from actually visible + */ + void createFromVisible(); void toggleIsolateActiveNode(); void toggleIsolateMode(bool checked); diff --git a/libs/ui/kis_node_manager.cpp b/libs/ui/kis_node_manager.cpp --- a/libs/ui/kis_node_manager.cpp +++ b/libs/ui/kis_node_manager.cpp @@ -282,6 +282,9 @@ action = actionManager->createAction("select_unlocked_layers"); connect(action, SIGNAL(triggered()), this, SLOT(selectUnlockedNodes())); + action = actionManager->createAction("new_from_visible"); + connect(action, SIGNAL(triggered()), this, SLOT(createFromVisible())); + NEW_LAYER_ACTION("add_new_paint_layer", "KisPaintLayer"); NEW_LAYER_ACTION("add_new_group_layer", "KisGroupLayer"); @@ -496,6 +499,11 @@ } +void KisNodeManager::createFromVisible() +{ + KisLayerUtils::newLayerFromVisible(m_d->view->image(), m_d->view->image()->root()->lastChild()); +} + KisLayerSP KisNodeManager::createPaintLayer() { KisNodeSP activeNode = this->activeNode();