diff --git a/src/commands/cmd_duplicate_layer.cpp b/src/commands/cmd_duplicate_layer.cpp index e25d3edb3..5c8542d0b 100644 --- a/src/commands/cmd_duplicate_layer.cpp +++ b/src/commands/cmd_duplicate_layer.cpp @@ -68,11 +68,11 @@ void DuplicateLayerCommand::onExecute(Context* context) // Create a new layer UniquePtr newLayerPtr(new LayerImage(sprite)); - // Copy the layer name - newLayerPtr->setName(sourceLayer->getName() + " Copy"); - // Copy the layer content (cels + images) - document->copyLayerContent(sourceLayer, newLayerPtr); + document->copyLayerContent(sourceLayer, document, newLayerPtr); + + // Copy the layer name + newLayerPtr->setName(newLayerPtr->getName() + " Copy"); // Add the new layer in the sprite. if (undo->isEnabled()) diff --git a/src/document.cpp b/src/document.cpp index 4e9f8b292..d53f83ccf 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -288,39 +288,87 @@ void Document::setMaskVisible(bool visible) ////////////////////////////////////////////////////////////////////// // Copying -void Document::copyLayerContent(const LayerImage* sourceLayer, LayerImage* destLayer) const +void Document::copyLayerContent(const Layer* sourceLayer0, Document* destDoc, Layer* destLayer0) const { - // copy cels - CelConstIterator it = sourceLayer->getCelBegin(); - CelConstIterator end = sourceLayer->getCelEnd(); + // Copy the layer name + destLayer0->setName(sourceLayer0->getName()); - for (; it != end; ++it) { - const Cel* sourceCel = *it; - Cel* newCel = new Cel(*sourceCel); + if (sourceLayer0->is_image() && destLayer0->is_image()) { + const LayerImage* sourceLayer = static_cast(sourceLayer0); + LayerImage* destLayer = static_cast(destLayer0); - ASSERT((sourceCel->getImage() >= 0) && - (sourceCel->getImage() < sourceLayer->getSprite()->getStock()->size())); + // copy cels + CelConstIterator it = sourceLayer->getCelBegin(); + CelConstIterator end = sourceLayer->getCelEnd(); - const Image* sourceImage = sourceLayer->getSprite()->getStock()->getImage(sourceCel->getImage()); - ASSERT(sourceImage != NULL); + for (; it != end; ++it) { + const Cel* sourceCel = *it; + UniquePtr newCel(new Cel(*sourceCel)); - Image* newImage = image_new_copy(sourceImage); + ASSERT((sourceCel->getImage() >= 0) && + (sourceCel->getImage() < sourceLayer->getSprite()->getStock()->size())); - newCel->setImage(destLayer->getSprite()->getStock()->addImage(newImage)); + const Image* sourceImage = sourceLayer->getSprite()->getStock()->getImage(sourceCel->getImage()); + ASSERT(sourceImage != NULL); - if (m_undoHistory->isEnabled()) - m_undoHistory->undo_add_image(destLayer->getSprite()->getStock(), newCel->getImage()); + Image* newImage = image_new_copy(sourceImage); - destLayer->addCel(newCel); + newCel->setImage(destLayer->getSprite()->getStock()->addImage(newImage)); + + if (destDoc->getUndoHistory()->isEnabled()) + destDoc->getUndoHistory()->undo_add_image(destLayer->getSprite()->getStock(), + newCel->getImage()); + + destLayer->addCel(newCel); + newCel.release(); + } + } + else if (sourceLayer0->is_folder() && destLayer0->is_folder()) { + const LayerFolder* sourceLayer = static_cast(sourceLayer0); + LayerFolder* destLayer = static_cast(destLayer0); + + LayerConstIterator it = sourceLayer->get_layer_begin(); + LayerConstIterator end = sourceLayer->get_layer_end(); + + for (; it != end; ++it) { + Layer* sourceChild = *it; + UniquePtr destChild(NULL); + + if (sourceChild->is_image()) { + destChild.reset(new LayerImage(destLayer->getSprite())); + copyLayerContent(sourceChild, destDoc, destChild); + } + else if (sourceChild->is_folder()) { + destChild.reset(new LayerFolder(destLayer->getSprite())); + copyLayerContent(sourceChild, destDoc, destChild); + } + else { + ASSERT(false); + } + + ASSERT(destChild != NULL); + + // Add the new layer in the sprite. + if (destDoc->getUndoHistory()->isEnabled()) + destDoc->getUndoHistory()->undo_add_layer(destLayer, destChild); + + destLayer->add_layer(destChild); + destChild.release(); + } + } + else { + ASSERT(false && "Trying to copy two incompatible layers"); } } Document* Document::duplicate(DuplicateType type) const { const Sprite* sourceSprite = getSprite(); - UniquePtr spriteCopy(new Sprite(sourceSprite->getImgType(), - sourceSprite->getWidth(), - sourceSprite->getHeight(), sourceSprite->getPalette(0)->size())); + UniquePtr spriteCopyPtr(new Sprite(sourceSprite->getImgType(), + sourceSprite->getWidth(), + sourceSprite->getHeight(), sourceSprite->getPalette(0)->size())); + UniquePtr documentCopy(new Document(spriteCopyPtr)); + Sprite* spriteCopy = spriteCopyPtr.release(); spriteCopy->setTotalFrames(sourceSprite->getTotalFrames()); spriteCopy->setCurrentFrame(sourceSprite->getCurrentFrame()); @@ -342,9 +390,20 @@ Document* Document::duplicate(DuplicateType type) const switch (type) { case DuplicateExactCopy: + // Disable the undo + documentCopy->getUndoHistory()->setEnabled(false); + + // Copy the layer folder + copyLayerContent(getSprite()->getFolder(), documentCopy, spriteCopy->getFolder()); + + // Set as current layer the same layer as the source { - // TODO IMPLEMENT THIS + int index = sourceSprite->layerToIndex(sourceSprite->getCurrentLayer()); + spriteCopy->setCurrentLayer(spriteCopy->indexToLayer(index)); } + + // Re-enable the undo + documentCopy->getUndoHistory()->setEnabled(true); break; case DuplicateWithFlattenLayers: @@ -370,9 +429,6 @@ Document* Document::duplicate(DuplicateType type) const break; } - UniquePtr documentCopy(new Document(spriteCopy)); - spriteCopy.release(); - documentCopy->setMask(getMask()); documentCopy->m_maskVisible = m_maskVisible; documentCopy->m_preferred = m_preferred; diff --git a/src/document.h b/src/document.h index 554384e19..48ea6db92 100644 --- a/src/document.h +++ b/src/document.h @@ -29,7 +29,7 @@ class Cel; class FormatOptions; class Image; -class LayerImage; +class Layer; class Mask; class Mutex; class Sprite; @@ -146,8 +146,7 @@ public: ////////////////////////////////////////////////////////////////////// // Copying - void copyLayerContent(const LayerImage* sourceLayer, LayerImage* destLayer) const; - + void copyLayerContent(const Layer* sourceLayer, Document* destDoc, Layer* destLayer) const; Document* duplicate(DuplicateType type) const; //////////////////////////////////////////////////////////////////////