[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    [krita/krita/4.0] libs/ui: Fix copy-pasting pixel data from animated layers
From:       Boudewijn Rempt <null () kde ! org>
Date:       2018-05-02 11:54:31
Message-ID: E1fDqL9-0006GX-Sm () code ! kde ! org
[Download RAW message or body]

Git commit a4df42f88c2e9dd01e83110270ba5bfdf939d408 by Boudewijn Rempt, on behalf of \
Dmitry Kazakov. Committed on 02/05/2018 at 11:54.
Pushed by rempt into branch 'krita/4.0'.

Fix copy-pasting pixel data from animated layers

Now when you copy-paste animated frame data, it is pasted into
exactly the same time range position. It means that if you later
merge down this data back to the original layer, you will not get
a data loss. The data will be merged exactly into the position where
it has been taken from.

BUG:364162
CC:kimageshop@kde.org
(cherry picked from commit 39ec1d47a59425969814dc840209ec2433bdd133)

M  +18   -2    libs/ui/actions/KisPasteActionFactory.cpp
M  +17   -3    libs/ui/actions/kis_selection_action_factories.cpp
M  +30   -3    libs/ui/kis_clipboard.cc
M  +4    -1    libs/ui/kis_clipboard.h

https://commits.kde.org/krita/a4df42f88c2e9dd01e83110270ba5bfdf939d408

diff --git a/libs/ui/actions/KisPasteActionFactory.cpp \
b/libs/ui/actions/KisPasteActionFactory.cpp index 08e95446a1a..d2e9dea045a 100644
--- a/libs/ui/actions/KisPasteActionFactory.cpp
+++ b/libs/ui/actions/KisPasteActionFactory.cpp
@@ -39,6 +39,9 @@
 #include "kis_algebra_2d.h"
 #include <KoShapeMoveCommand.h>
 #include <KoShapeReorderCommand.h>
+#include "kis_time_range.h"
+#include "kis_keyframe_channel.h"
+#include "kis_raster_keyframe_channel.h"
 
 namespace {
 QPointF getFittingOffset(QList<KoShape*> shapes,
@@ -194,8 +197,9 @@ void KisPasteActionFactory::run(bool pasteAtCursorPosition, \
KisViewManager *view  return;
     }
 
+    KisTimeRange range;
     const QRect fittingBounds = pasteAtCursorPosition ? QRect() : image->bounds();
-    KisPaintDeviceSP clip = KisClipboard::instance()->clip(fittingBounds, true);
+    KisPaintDeviceSP clip = KisClipboard::instance()->clip(fittingBounds, true, \
&range);  
     if (clip) {
         if (pasteAtCursorPosition) {
@@ -209,10 +213,22 @@ void KisPasteActionFactory::run(bool pasteAtCursorPosition, \
KisViewManager *view  }
 
         KisImportCatcher::adaptClipToImageColorSpace(clip, image);
-        KisPaintLayer *newLayer = new KisPaintLayer(image.data(), \
image->nextLayerName() + i18n("(pasted)"), OPACITY_OPAQUE_U8, clip); +        \
KisPaintLayerSP newLayer = new KisPaintLayer(image.data(), +                          \
image->nextLayerName() + i18n("(pasted)"), +                                          \
OPACITY_OPAQUE_U8);  KisNodeSP aboveNode = view->activeLayer();
         KisNodeSP parentNode = aboveNode ? aboveNode->parent() : image->root();
 
+        if (range.isValid()) {
+            newLayer->enableAnimation();
+            KisKeyframeChannel *channel = \
newLayer->getKeyframeChannel(KisKeyframeChannel::Content.id(), true); +            \
KisRasterKeyframeChannel *rasterChannel = \
dynamic_cast<KisRasterKeyframeChannel*>(channel); +            \
rasterChannel->importFrame(range.start(), clip, 0); +            \
rasterChannel->addKeyframe(range.end() + 1, 0); +        } else {
+            newLayer->paintDevice()->makeCloneFromRough(clip, clip->extent());
+        }
+
         KUndo2Command *cmd = new KisImageLayerAddCommand(image, newLayer, \
parentNode, aboveNode);  KisProcessingApplicator *ap = beginAction(view, \
                cmd->text());
         ap->applyCommand(cmd, KisStrokeJobData::SEQUENTIAL, \
                KisStrokeJobData::NORMAL);
diff --git a/libs/ui/actions/kis_selection_action_factories.cpp \
b/libs/ui/actions/kis_selection_action_factories.cpp index 6fb605e286e..9116fcfeb4f \
                100644
--- a/libs/ui/actions/kis_selection_action_factories.cpp
+++ b/libs/ui/actions/kis_selection_action_factories.cpp
@@ -61,6 +61,9 @@
 #include "KisPart.h"
 #include "kis_shape_layer.h"
 #include <kis_shape_controller.h>
+#include "kis_image_animation_interface.h"
+#include "kis_time_range.h"
+#include "kis_keyframe_channel.h"
 
 
 #include <processing/fill_processing_visitor.h>
@@ -71,7 +74,10 @@
 
 namespace ActionHelper {
 
-    void copyFromDevice(KisViewManager *view, KisPaintDeviceSP device, bool \
makeSharpClip = false) +    void copyFromDevice(KisViewManager *view,
+                        KisPaintDeviceSP device,
+                        bool makeSharpClip = false,
+                        const KisTimeRange &range = KisTimeRange())
     {
         KisImageWSP image = view->image();
         if (!image) return;
@@ -126,7 +132,7 @@ namespace ActionHelper {
             }
         }
 
-        KisClipboard::instance()->setClip(clip, rc.topLeft());
+        KisClipboard::instance()->setClip(clip, rc.topLeft(), range);
     }
 
 }
@@ -303,7 +309,15 @@ void KisCutCopyActionFactory::run(bool willCut, bool \
makeSharpClip, KisViewManag  return;
             }
 
-            ActionHelper::copyFromDevice(view, dev, makeSharpClip);
+            KisTimeRange range;
+
+            KisKeyframeChannel *channel = \
node->getKeyframeChannel(KisKeyframeChannel::Content.id()); +            if (channel) \
{ +                const int currentTime = \
image->animationInterface()->currentTime(); +                range = \
channel->affectedFrames(currentTime); +            }
+
+            ActionHelper::copyFromDevice(view, dev, makeSharpClip, range);
         }
 
         if (willCut) {
diff --git a/libs/ui/kis_clipboard.cc b/libs/ui/kis_clipboard.cc
index 83a771e407a..6db87cdae6e 100644
--- a/libs/ui/kis_clipboard.cc
+++ b/libs/ui/kis_clipboard.cc
@@ -43,6 +43,7 @@
 #include <kis_annotation.h>
 #include <kis_node.h>
 #include <kis_image.h>
+#include <kis_time_range.h>
 
 // local
 #include "kis_config.h"
@@ -76,7 +77,7 @@ KisClipboard* KisClipboard::instance()
     return s_instance;
 }
 
-void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& topLeft)
+void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& topLeft, const \
KisTimeRange &range)  {
     if (!dev)
         return;
@@ -91,7 +92,6 @@ void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& \
topLeft)  Q_ASSERT(store);
     Q_ASSERT(!store->bad());
     
-
     // Layer data
     if (store->open("layerdata")) {
         if (!dev->write(writer)) {
@@ -103,6 +103,12 @@ void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& \
topLeft)  store->close();
     }
 
+    // copied frame time limits
+    if (range.isValid() && store->open("timeRange")) {
+        store->write(QString("%1 \
%2").arg(range.start()).arg(range.end()).toLatin1()); +        store->close();
+    }
+
     // Coordinates
     if (store->open("topLeft")) {
         store->write(QString("%1 %2").arg(topLeft.x()).arg(topLeft.y()).toLatin1());
@@ -163,10 +169,19 @@ void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& \
topLeft)  
 }
 
-KisPaintDeviceSP KisClipboard::clip(const QRect &imageBounds, bool showPopup)
+void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& topLeft)
+{
+    setClip(dev, topLeft, KisTimeRange());
+}
+
+KisPaintDeviceSP KisClipboard::clip(const QRect &imageBounds, bool showPopup, \
KisTimeRange *clipRange)  {
     QByteArray mimeType("application/x-krita-selection");
 
+    if (clipRange) {
+        *clipRange = KisTimeRange();
+    }
+
     QClipboard *cb = QApplication::clipboard();
     const QMimeData *cbData = cb->mimeData();
 
@@ -239,6 +254,18 @@ KisPaintDeviceSP KisClipboard::clip(const QRect &imageBounds, \
bool showPopup)  clip->setX(clip->x() + diff.x());
                     clip->setY(clip->y() + diff.y());
                 }
+
+                if (store->hasFile("timeRange") && clipRange) {
+                    store->open("timeRange");
+                    QString str = store->read(store->size());
+                    store->close();
+                    QStringList list = str.split(' ');
+                    if (list.size() == 2) {
+                        KisTimeRange range(list[0].toInt(), list[1].toInt(), true);
+                        *clipRange = range;
+                        qDebug() << "Pasted time range" << range;
+                    }
+                }
             }
         }
 
diff --git a/libs/ui/kis_clipboard.h b/libs/ui/kis_clipboard.h
index 81bd0381303..12fe86a9a3d 100644
--- a/libs/ui/kis_clipboard.h
+++ b/libs/ui/kis_clipboard.h
@@ -27,6 +27,7 @@
 
 class QRect;
 class QMimeData;
+class KisTimeRange;
 class KisBlockUntilOperationsFinishedMediator;
 
 enum enumPasteBehaviour {
@@ -61,10 +62,12 @@ public:
      */
     void setClip(KisPaintDeviceSP dev, const QPoint& topLeft);
 
+    void setClip(KisPaintDeviceSP dev, const QPoint& topLeft, const KisTimeRange \
&range); +
     /**
      * Get the contents of the clipboard in the form of a paint device.
      */
-    KisPaintDeviceSP clip(const QRect &imageBounds, bool showPopup);
+    KisPaintDeviceSP clip(const QRect &imageBounds, bool showPopup, KisTimeRange \
*clipRange = 0);  
     bool hasClip() const;
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic