diff --git a/src/app/puzzle/carousel/vpcarrouselpiecelist.cpp b/src/app/puzzle/carousel/vpcarrouselpiecelist.cpp
index c8dc6ac49..3f5889162 100644
--- a/src/app/puzzle/carousel/vpcarrouselpiecelist.cpp
+++ b/src/app/puzzle/carousel/vpcarrouselpiecelist.cpp
@@ -39,6 +39,7 @@
 #include "vpmimedatapiece.h"
 #include "../layout/vpsheet.h"
 #include "../layout/vplayout.h"
+#include "../undocommands/vpundomovepieceonsheet.h"
 
 #include <QLoggingCategory>
 
@@ -203,20 +204,19 @@ void VPCarrouselPieceList::contextMenuEvent(QContextMenuEvent *event)
 
         if (selectedAction == moveAction)
         {
-            VPSheetPtr sheet = layout->GetFocusedSheet();
-            piece->SetSheet(sheet);
-            emit layout->PieceSheetChanged(piece);
+            piece->ClearTransformations();
+            auto *command = new VPUndoMovePieceOnSheet(layout->GetFocusedSheet(), piece);
+            layout->UndoStack()->push(command);
         }
         else if (selectedAction == deleteAction)
         {
-            VPSheetPtr sheet = layout->GetTrashSheet();
-            piece->SetSheet(sheet);
-            emit layout->PieceSheetChanged(piece);
+            auto *command = new VPUndoMovePieceOnSheet(layout->GetTrashSheet(), piece);
+            layout->UndoStack()->push(command);
         }
         else if (selectedAction == removeAction)
         {
-            piece->SetSheet(nullptr);
-            emit layout->PieceSheetChanged(piece);
+            auto *command = new VPUndoMovePieceOnSheet(VPSheetPtr(), piece);
+            layout->UndoStack()->push(command);
         }
     }
 }
diff --git a/src/app/puzzle/layout/vplayout.cpp b/src/app/puzzle/layout/vplayout.cpp
index beb19b081..e36af4d96 100644
--- a/src/app/puzzle/layout/vplayout.cpp
+++ b/src/app/puzzle/layout/vplayout.cpp
@@ -159,7 +159,7 @@ auto VPLayout::PiecesForSheet(const VPSheetPtr &sheet) const -> QList<VPPiecePtr
     QList<VPPiecePtr> list;
     list.reserve(m_pieces.size());
 
-    for (auto piece : m_pieces)
+    for (const auto& piece : m_pieces)
     {
         if (not piece.isNull() && piece->Sheet() == sheet)
         {
@@ -171,12 +171,12 @@ auto VPLayout::PiecesForSheet(const VPSheetPtr &sheet) const -> QList<VPPiecePtr
 }
 
 //---------------------------------------------------------------------------------------------------------------------
-QList<VPPiecePtr> VPLayout::PiecesForSheet(const QUuid &uuid) const
+auto VPLayout::PiecesForSheet(const QUuid &uuid) const -> QList<VPPiecePtr>
 {
     QList<VPPiecePtr> list;
     list.reserve(m_pieces.size());
 
-    for (auto piece : m_pieces)
+    for (const auto& piece : m_pieces)
     {
         if (not piece.isNull())
         {
@@ -192,7 +192,7 @@ QList<VPPiecePtr> VPLayout::PiecesForSheet(const QUuid &uuid) const
 }
 
 //---------------------------------------------------------------------------------------------------------------------
-QUndoStack *VPLayout::UndoStack() const
+auto VPLayout::UndoStack() const -> QUndoStack *
 {
     return m_undoStack;
 }
@@ -222,4 +222,5 @@ void VPLayout::Clear()
 void VPLayout::AddTrashSheet(const VPSheetPtr &sheet)
 {
     m_trashSheet = sheet;
+    m_trashSheet->SetTrashSheet(true);
 }
diff --git a/src/app/puzzle/layout/vpsheet.cpp b/src/app/puzzle/layout/vpsheet.cpp
index 20b70b0b3..4de346e05 100644
--- a/src/app/puzzle/layout/vpsheet.cpp
+++ b/src/app/puzzle/layout/vpsheet.cpp
@@ -120,4 +120,17 @@ void VPSheet::Clear()
     m_name.clear();
     m_visible = true;
     m_transformationOrigin = VPTransformationOrigon();
+    m_trashSheet = false;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+auto VPSheet::TrashSheet() const -> bool
+{
+    return m_trashSheet;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+void VPSheet::SetTrashSheet(bool newTrashSheet)
+{
+    m_trashSheet = newTrashSheet;
 }
diff --git a/src/app/puzzle/layout/vpsheet.h b/src/app/puzzle/layout/vpsheet.h
index 4624c3ff8..81ac3907c 100644
--- a/src/app/puzzle/layout/vpsheet.h
+++ b/src/app/puzzle/layout/vpsheet.h
@@ -79,6 +79,9 @@ public:
 
     void Clear();
 
+    auto TrashSheet() const -> bool;
+    void SetTrashSheet(bool newTrashSheet);
+
 private:
     Q_DISABLE_COPY(VPSheet)
 
@@ -89,6 +92,7 @@ private:
     QUuid m_uuid{QUuid::createUuid()};
 
     bool m_visible{true};
+    bool m_trashSheet{false};
 
     VPTransformationOrigon m_transformationOrigin{};
 };
diff --git a/src/app/puzzle/puzzle.pri b/src/app/puzzle/puzzle.pri
index d8f1e8850..6f6d6de2e 100644
--- a/src/app/puzzle/puzzle.pri
+++ b/src/app/puzzle/puzzle.pri
@@ -8,6 +8,7 @@ SOURCES += \
     $$PWD/dialogs/vpdialogabout.cpp \
     $$PWD/main.cpp \
     $$PWD/undocommands/vpundocommand.cpp \
+    $$PWD/undocommands/vpundomovepieceonsheet.cpp \
     $$PWD/undocommands/vpundooriginmove.cpp \
     $$PWD/undocommands/vpundopiecemove.cpp \
     $$PWD/undocommands/vpundopiecerotate.cpp \
@@ -46,6 +47,7 @@ HEADERS += \
     $$PWD/scene/scenedef.h \
     $$PWD/stable.h \
     $$PWD/undocommands/vpundocommand.h \
+    $$PWD/undocommands/vpundomovepieceonsheet.h \
     $$PWD/undocommands/vpundooriginmove.h \
     $$PWD/undocommands/vpundopiecemove.h \
     $$PWD/undocommands/vpundopiecerotate.h \
diff --git a/src/app/puzzle/scene/vpgraphicspiece.cpp b/src/app/puzzle/scene/vpgraphicspiece.cpp
index dec2c2cea..81e2b2006 100644
--- a/src/app/puzzle/scene/vpgraphicspiece.cpp
+++ b/src/app/puzzle/scene/vpgraphicspiece.cpp
@@ -47,6 +47,7 @@
 #include "vplacelabelitem.h"
 
 #include "undocommands/vpundopiecemove.h"
+#include "undocommands/vpundomovepieceonsheet.h"
 
 #include <QLoggingCategory>
 Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece")
@@ -202,13 +203,13 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
 
     if (moveToActions.contains(selectedAction))
     {
-        piece->SetSheet(qvariant_cast<VPSheetPtr>(selectedAction->data()));
-        emit layout->PieceSheetChanged(piece);
+        auto *command = new VPUndoMovePieceOnSheet(qvariant_cast<VPSheetPtr>(selectedAction->data()), piece);
+        layout->UndoStack()->push(command);
     }
     else if (selectedAction == removeAction)
     {
-        piece->SetSheet(nullptr);
-        emit layout->PieceSheetChanged(piece);
+        auto *command = new VPUndoMovePieceOnSheet(VPSheetPtr(), piece);
+        layout->UndoStack()->push(command);
     }
 }
 
diff --git a/src/app/puzzle/scene/vpmaingraphicsview.cpp b/src/app/puzzle/scene/vpmaingraphicsview.cpp
index 13d5e0458..8ba4a9865 100644
--- a/src/app/puzzle/scene/vpmaingraphicsview.cpp
+++ b/src/app/puzzle/scene/vpmaingraphicsview.cpp
@@ -48,6 +48,7 @@
 #include "../undocommands/vpundopiecemove.h"
 #include "../undocommands/vpundopiecerotate.h"
 #include "../undocommands/vpundooriginmove.h"
+#include "../undocommands/vpundomovepieceonsheet.h"
 
 #include <QLoggingCategory>
 
@@ -237,17 +238,8 @@ void VPMainGraphicsView::dropEvent(QDropEvent *event)
             piece->ClearTransformations();
             piece->SetPosition(mapToScene(event->pos()));
 
-            // change the piecelist of the piece
-            piece->SetSheet(layout->GetFocusedSheet());
-
-            auto *graphicsPiece = new VPGraphicsPiece(piece);
-            m_graphicsPieces.append(graphicsPiece);
-
-            scene()->addItem(graphicsPiece);
-
-            ConnectPiece(graphicsPiece);
-
-            event->acceptProposedAction();
+            auto *command = new VPUndoMovePieceOnSheet(layout->GetFocusedSheet(), piece);
+            layout->UndoStack()->push(command);
         }
     }
 }
@@ -264,9 +256,13 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
             if(not piece.isNull() && piece->IsSelected())
             {
                 piece->SetSelected(false);
-                piece->SetSheet(VPSheetPtr());
-                m_graphicsPieces.removeAll(graphicsPiece);
-                delete graphicsPiece;
+
+                VPLayoutPtr layout = m_layout.toStrongRef();
+                if (not layout.isNull())
+                {
+                    auto *command = new VPUndoMovePieceOnSheet(VPSheetPtr(), piece);
+                    layout->UndoStack()->push(command);
+                }
             }
         }
     }
@@ -611,7 +607,6 @@ void VPMainGraphicsView::on_PieceSheetChanged(const VPPiecePtr &piece)
     {
         if(_graphicsPiece == nullptr)
         {
-            piece->ClearTransformations();
             _graphicsPiece = new VPGraphicsPiece(piece);
             m_graphicsPieces.append(_graphicsPiece);
             ConnectPiece(_graphicsPiece);
diff --git a/src/app/puzzle/undocommands/vpundocommand.h b/src/app/puzzle/undocommands/vpundocommand.h
index 3d81dcc57..3e8b02e1e 100644
--- a/src/app/puzzle/undocommands/vpundocommand.h
+++ b/src/app/puzzle/undocommands/vpundocommand.h
@@ -41,6 +41,7 @@ enum class UndoCommand: qint8
     RotatePiece = 2,
     RotatePieces = 3,
     MoveOrigin = 4,
+    MoveOnSheet = 5,
 };
 }
 
diff --git a/src/app/puzzle/undocommands/vpundomovepieceonsheet.cpp b/src/app/puzzle/undocommands/vpundomovepieceonsheet.cpp
new file mode 100644
index 000000000..32a0c1a76
--- /dev/null
+++ b/src/app/puzzle/undocommands/vpundomovepieceonsheet.cpp
@@ -0,0 +1,117 @@
+/************************************************************************
+ **
+ **  @file   vpundomovepieceonsheet.cpp
+ **  @author Roman Telezhynskyi <dismine(at)gmail.com>
+ **  @date   19 8, 2021
+ **
+ **  @brief
+ **  @copyright
+ **  This source code is part of the Valentina project, a pattern making
+ **  program, whose allow create and modeling patterns of clothing.
+ **  Copyright (C) 2021 Valentina project
+ **  <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
+ **
+ **  Valentina 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 3 of the License, or
+ **  (at your option) any later version.
+ **
+ **  Valentina 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 Valentina.  If not, see <http://www.gnu.org/licenses/>.
+ **
+ *************************************************************************/
+#include "vpundomovepieceonsheet.h"
+#include "../vmisc/def.h"
+#include "../layout/vpsheet.h"
+#include "../layout/vplayout.h"
+#include "../layout/vppiece.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+VPUndoMovePieceOnSheet::VPUndoMovePieceOnSheet(const VPSheetPtr &sheet, const VPPiecePtr &piece, QUndoCommand *parent)
+    : VPUndoCommand(false, parent),
+      m_sheet(sheet),
+      m_piece(piece)
+{
+    SCASSERT(not piece.isNull())
+
+    m_oldSheet = piece->Sheet();
+
+    setText(tr("move piece on sheet"));
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+void VPUndoMovePieceOnSheet::undo()
+{
+    VPSheetPtr sourceSheet = m_oldSheet.toStrongRef();
+    VPSheetPtr activateSheet = sourceSheet;
+    if (activateSheet.isNull())
+    {
+        activateSheet = m_sheet.toStrongRef();
+    }
+
+    VPLayoutPtr layout;
+
+    if (not activateSheet.isNull())
+    {
+        layout = activateSheet->GetLayout();
+        if (not layout.isNull() && not activateSheet->TrashSheet())
+        {
+            layout->SetFocusedSheet(activateSheet);
+        }
+    }
+
+    VPPiecePtr piece = m_piece.toStrongRef();
+    if (not piece.isNull())
+    {
+        piece->SetSheet(sourceSheet);
+
+        if (not layout.isNull())
+        {
+            emit layout->PieceSheetChanged(piece);
+        }
+    }
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+void VPUndoMovePieceOnSheet::redo()
+{
+    VPSheetPtr sourceSheet = m_sheet.toStrongRef();
+    VPSheetPtr activateSheet = sourceSheet;
+    if (activateSheet.isNull())
+    {
+        activateSheet = m_oldSheet.toStrongRef();
+    }
+
+    VPLayoutPtr layout;
+
+    if (not activateSheet.isNull())
+    {
+        layout = activateSheet->GetLayout();
+        if (not layout.isNull() && not activateSheet->TrashSheet())
+        {
+            layout->SetFocusedSheet(activateSheet);
+        }
+    }
+
+    VPPiecePtr piece = m_piece.toStrongRef();
+    if (not piece.isNull())
+    {
+        piece->SetSheet(sourceSheet);
+
+        if (not layout.isNull())
+        {
+            emit layout->PieceSheetChanged(piece);
+        }
+    }
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+auto VPUndoMovePieceOnSheet::id() const -> int
+{
+    return static_cast<int>(ML::UndoCommand::MoveOnSheet);
+}
diff --git a/src/app/puzzle/undocommands/vpundomovepieceonsheet.h b/src/app/puzzle/undocommands/vpundomovepieceonsheet.h
new file mode 100644
index 000000000..a80173c15
--- /dev/null
+++ b/src/app/puzzle/undocommands/vpundomovepieceonsheet.h
@@ -0,0 +1,53 @@
+/************************************************************************
+ **
+ **  @file   vpundomovepieceonsheet.h
+ **  @author Roman Telezhynskyi <dismine(at)gmail.com>
+ **  @date   19 8, 2021
+ **
+ **  @brief
+ **  @copyright
+ **  This source code is part of the Valentina project, a pattern making
+ **  program, whose allow create and modeling patterns of clothing.
+ **  Copyright (C) 2021 Valentina project
+ **  <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
+ **
+ **  Valentina 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 3 of the License, or
+ **  (at your option) any later version.
+ **
+ **  Valentina 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 Valentina.  If not, see <http://www.gnu.org/licenses/>.
+ **
+ *************************************************************************/
+#ifndef VPUNDOMOVEPIECEONSHEET_H
+#define VPUNDOMOVEPIECEONSHEET_H
+
+#include "vpundocommand.h"
+
+#include "../layout/layoutdef.h"
+
+class VPUndoMovePieceOnSheet : public VPUndoCommand
+{
+public:
+    VPUndoMovePieceOnSheet(const VPSheetPtr &sheet, const VPPiecePtr &piece, QUndoCommand *parent = nullptr);
+    virtual ~VPUndoMovePieceOnSheet()=default;
+
+    virtual void undo() override;
+    virtual void redo() override;
+    virtual auto id() const -> int override;
+
+private:
+    Q_DISABLE_COPY(VPUndoMovePieceOnSheet)
+
+    VPSheetWeakPtr m_oldSheet{};
+    VPSheetWeakPtr m_sheet;
+    VPPieceWeakPtr m_piece;
+};
+
+#endif // VPUNDOMOVEPIECEONSHEET_H
diff --git a/src/app/puzzle/undocommands/vpundooriginmove.cpp b/src/app/puzzle/undocommands/vpundooriginmove.cpp
index 7bc6d3fe5..b2e5e21b6 100644
--- a/src/app/puzzle/undocommands/vpundooriginmove.cpp
+++ b/src/app/puzzle/undocommands/vpundooriginmove.cpp
@@ -41,7 +41,7 @@ VPUndoOriginMove::VPUndoOriginMove(const VPSheetPtr &sheet, const VPTransformati
 
     m_oldOrigin = sheet->TransformationOrigin();
 
-    setText(QObject::tr("move transformation origin"));
+    setText(tr("move transformation origin"));
 }
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -83,7 +83,7 @@ void VPUndoOriginMove::redo()
     layout->SetFocusedSheet(sheet);
 
     sheet->SetTransformationOrigin(m_origin);
-    layout->TransformationOriginChanged();
+    emit layout->TransformationOriginChanged();
 }
 
 //---------------------------------------------------------------------------------------------------------------------
diff --git a/src/app/puzzle/undocommands/vpundooriginmove.h b/src/app/puzzle/undocommands/vpundooriginmove.h
index ed80a8cfc..837092508 100644
--- a/src/app/puzzle/undocommands/vpundooriginmove.h
+++ b/src/app/puzzle/undocommands/vpundooriginmove.h
@@ -44,7 +44,7 @@ public:
     virtual void redo() override;
     // cppcheck-suppress unusedFunction
     virtual auto mergeWith(const QUndoCommand *command) -> bool override;
-    virtual auto id() const -> int override ;
+    virtual auto id() const -> int override;
 
     auto Sheet() const -> VPSheetWeakPtr;
     auto Origin() const -> const VPTransformationOrigon &;
diff --git a/src/app/puzzle/undocommands/vpundopiecemove.cpp b/src/app/puzzle/undocommands/vpundopiecemove.cpp
index daee56760..3b90642bd 100644
--- a/src/app/puzzle/undocommands/vpundopiecemove.cpp
+++ b/src/app/puzzle/undocommands/vpundopiecemove.cpp
@@ -41,7 +41,7 @@ VPUndoPieceMove::VPUndoPieceMove(const VPPiecePtr &piece, qreal dx, qreal dy, bo
 
     m_oldTransform = piece->GetMatrix();
 
-    setText(QObject::tr("move piece"));
+    setText(tr("move piece"));
 }
 
 //---------------------------------------------------------------------------------------------------------------------
diff --git a/src/app/puzzle/undocommands/vpundopiecerotate.cpp b/src/app/puzzle/undocommands/vpundopiecerotate.cpp
index a2ca91c54..f947c4d94 100644
--- a/src/app/puzzle/undocommands/vpundopiecerotate.cpp
+++ b/src/app/puzzle/undocommands/vpundopiecerotate.cpp
@@ -41,7 +41,7 @@ VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &ori
 
     m_oldTransform = piece->GetMatrix();
 
-    setText(QObject::tr("rotate piece"));
+    setText(tr("rotate piece"));
 }
 
 //---------------------------------------------------------------------------------------------------------------------