[calligra] krita/ui: Fixed positioning of the image pasted to Krita using Clipboard

Dmitry Kazakov dimula73 at gmail.com
Sun May 5 09:52:58 UTC 2013


Git commit e533c858f5793a2bae1d48a46bddc647f4f8cdc9 by Dmitry Kazakov.
Committed on 05/05/2013 at 11:52.
Pushed by dkazakov into branch 'master'.

Fixed positioning of the image pasted to Krita using Clipboard

Now it works the following way:

1) When copy-pasting from Krita it tries to paste the clip to the original
   position in the image.
2) When copy-pasting from other applications it pastes the clip to
   the center of the image

BUG:319330
CCMAIL:kimageshop at kde.org

M  +2    -26   krita/ui/actions/kis_selection_action_factories.cpp
M  +42   -35   krita/ui/kis_clipboard.cc
M  +2    -1    krita/ui/kis_clipboard.h
M  +2    -1    krita/ui/kis_view2.cpp
M  +2    -2    krita/ui/tests/kis_clipboard_test.cpp
M  +1    -1    krita/ui/widgets/kis_custom_image_widget.cc

http://commits.kde.org/calligra/e533c858f5793a2bae1d48a46bddc647f4f8cdc9

diff --git a/krita/ui/actions/kis_selection_action_factories.cpp b/krita/ui/actions/kis_selection_action_factories.cpp
index a38d0b7..4f72850 100644
--- a/krita/ui/actions/kis_selection_action_factories.cpp
+++ b/krita/ui/actions/kis_selection_action_factories.cpp
@@ -301,33 +301,9 @@ void KisCopyMergedActionFactory::run(KisView2 *view)
 void KisPasteActionFactory::run(KisView2 *view)
 {
     KisImageWSP image = view->image();
-
-    //figure out where to position the clip
-    // XXX: Fix this for internal points & zoom! (BSAR)
-    QWidget * w = view->canvas();
-    QPoint center = QPoint(w->width() / 2, w->height() / 2);
-    QPoint bottomright = QPoint(w->width(), w->height());
-    if (bottomright.x() > image->width())
-        center.setX(image->width() / 2);
-    if (bottomright.y() > image->height())
-        center.setY(image->height() / 2);
-
-    const KoCanvasBase* canvasBase = view->canvasBase();
-    const KoViewConverter* viewConverter = view->canvasBase()->viewConverter();
-
-    KisPaintDeviceSP clip = KisClipboard::instance()->clip(
-        QPoint(
-            viewConverter->viewToDocumentX(canvasBase->canvasController()->canvasOffsetX()) + center.x(),
-            viewConverter->viewToDocumentY(canvasBase->canvasController()->canvasOffsetY()) + center.y()));
+    KisPaintDeviceSP clip = KisClipboard::instance()->clip(image->bounds());
 
     if (clip) {
-        // Pasted layer content could be outside image bounds and invisible, if that is the case move content into the bounds
-        QRect exactBounds = clip->exactBounds();
-        if (!exactBounds.isEmpty() && !exactBounds.intersects(image->bounds())) {
-            clip->setX(clip->x() - exactBounds.x());
-            clip->setY(clip->y() - exactBounds.y());
-        }
-
         KisPaintLayer *newLayer = new KisPaintLayer(image.data(), image->nextLayerName() + i18n("(pasted)"), OPACITY_OPAQUE_U8, clip);
         KisNodeSP aboveNode = view->activeLayer();
         KisNodeSP parentNode = aboveNode ? aboveNode->parent() : image->root();
@@ -349,7 +325,7 @@ void KisPasteNewActionFactory::run(KisView2 *view)
 {
     Q_UNUSED(view);
 
-    KisPaintDeviceSP clip = KisClipboard::instance()->clip(QPoint());
+    KisPaintDeviceSP clip = KisClipboard::instance()->clip(QRect());
     if (!clip) return;
 
     QRect rect = clip->exactBounds();
diff --git a/krita/ui/kis_clipboard.cc b/krita/ui/kis_clipboard.cc
index 7373236..04663d9 100644
--- a/krita/ui/kis_clipboard.cc
+++ b/krita/ui/kis_clipboard.cc
@@ -160,19 +160,16 @@ void KisClipboard::setClip(KisPaintDeviceSP dev, const QPoint& topLeft)
 
 }
 
-KisPaintDeviceSP KisClipboard::clip(const QPoint& topLeftHint)
+KisPaintDeviceSP KisClipboard::clip(const QRect &imageBounds)
 {
-    bool customTopLeft = false; // will be true if pasting from a krita clip
-    QPoint topLeft = topLeftHint;
-    QClipboard *cb = QApplication::clipboard();
     QByteArray mimeType("application/x-krita-selection");
+
+    QClipboard *cb = QApplication::clipboard();
     const QMimeData *cbData = cb->mimeData();
+
     KisPaintDeviceSP clip;
 
-    bool asKrita = false;
     if (cbData && cbData->hasFormat(mimeType)) {
-        asKrita = true;
-        dbgUI << "Use clip as x-krita-selection";
         QByteArray encodedData = cbData->data(mimeType);
         QBuffer buffer(&encodedData);
         KoStore* store = KoStore::createStore(&buffer, KoStore::Read, mimeType);
@@ -181,20 +178,6 @@ KisPaintDeviceSP KisClipboard::clip(const QPoint& topLeftHint)
 
         QString csDepth, csModel;
 
-        // topLeft
-        if (store->hasFile("topLeft")) {
-            store->open("topLeft");
-            QString str = store->read(store->size());
-            store->close();
-            QStringList list = str.split(' ');
-            if (list.size() == 2) {
-                topLeft.setX(list[0].toInt());
-                topLeft.setY(list[1].toInt());
-                customTopLeft = true;
-            }
-            dbgUI << str << topLeft;
-        }
-
         // ColorSpace id of layer data
         if (store->hasFile("colormodel")) {
             store->open("colormodel");
@@ -218,24 +201,48 @@ KisPaintDeviceSP KisClipboard::clip(const QPoint& topLeftHint)
         }
 
         const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(csModel, csDepth, profile);
-        if (!cs) {
-            // we failed to create a colorspace, so let's try later on with the qimage part of the clip
-            asKrita = false;
-        }
-        if (asKrita) {
+        if (cs) {
             clip = new KisPaintDevice(cs);
 
             if (store->hasFile("layerdata")) {
                 store->open("layerdata");
-                asKrita = clip->read(store->device());
+                if (!clip->read(store->device())) {
+                    clip = 0;
+                }
                 store->close();
             }
+
+            if (clip && !imageBounds.isEmpty()) {
+
+                // load topLeft
+                if (store->hasFile("topLeft")) {
+                    store->open("topLeft");
+                    QString str = store->read(store->size());
+                    store->close();
+                    QStringList list = str.split(' ');
+                    if (list.size() == 2) {
+                        QPoint topLeft(list[0].toInt(), list[1].toInt());
+                        clip->setX(topLeft.x());
+                        clip->setY(topLeft.y());
+                    }
+                }
+
+                QRect clipBounds = clip->exactBounds();
+
+                if (!imageBounds.contains(clipBounds) &&
+                    !imageBounds.intersects(clipBounds)) {
+
+                    QPoint diff = imageBounds.center() - clipBounds.center();
+                    clip->setX(clip->x() + diff.x());
+                    clip->setY(clip->y() + diff.y());
+                }
+            }
         }
+
         delete store;
     }
 
-    if (!asKrita) {
-        dbgUI << "Use clip as QImage";
+    if (!clip) {
         QImage qimage = cb->image();
 
         if (qimage.isNull())
@@ -264,13 +271,13 @@ KisPaintDeviceSP KisClipboard::clip(const QPoint& topLeftHint)
         clip = new KisPaintDevice(cs);
         Q_CHECK_PTR(clip);
         clip->convertFromQImage(qimage, profile);
+
+        QRect clipBounds = clip->exactBounds();
+        QPoint diff = imageBounds.center() - clipBounds.center();
+        clip->setX(diff.x());
+        clip->setY(diff.y());
     }
-    if (!customTopLeft) {
-        QRect exactBounds = clip->exactBounds();
-        topLeft -= exactBounds.topLeft() / 2;
-    }
-    clip->setX(topLeft.x());
-    clip->setY(topLeft.y());
+
     return clip;
 }
 
diff --git a/krita/ui/kis_clipboard.h b/krita/ui/kis_clipboard.h
index b12e05c..a4fd09a 100644
--- a/krita/ui/kis_clipboard.h
+++ b/krita/ui/kis_clipboard.h
@@ -26,6 +26,7 @@
 #include <krita_export.h>
 
 class QImage;
+class QRect;
 
 enum enumPasteBehaviour {
     PASTE_ASSUME_WEB,
@@ -61,7 +62,7 @@ public:
     /**
      * Get the contents of the clipboard in the form of a paint device.
      */
-    KisPaintDeviceSP clip(const QPoint& topLeftHint);
+    KisPaintDeviceSP clip(const QRect &imageBounds);
 
     bool hasClip();
 
diff --git a/krita/ui/kis_view2.cpp b/krita/ui/kis_view2.cpp
index d01991f..7d4c6da 100644
--- a/krita/ui/kis_view2.cpp
+++ b/krita/ui/kis_view2.cpp
@@ -517,7 +517,8 @@ void KisView2::dropEvent(QDropEvent *event)
         if (node) {
             QRect bounds = node->projection()->exactBounds();
             if (alwaysRecenter || forceRecenter ||
-                !imageBounds.contains(bounds)) {
+                (!imageBounds.contains(bounds) &&
+                 !imageBounds.intersects(bounds))) {
 
                 QPoint pt = pasteCenter - bounds.center();
                 node->setX(pt.x());
diff --git a/krita/ui/tests/kis_clipboard_test.cpp b/krita/ui/tests/kis_clipboard_test.cpp
index ec2a4b5..8f87a77 100644
--- a/krita/ui/tests/kis_clipboard_test.cpp
+++ b/krita/ui/tests/kis_clipboard_test.cpp
@@ -44,7 +44,7 @@ void KisClipboardTest::testRoundTrip()
 
     QCOMPARE(dev->exactBounds(), fillRect);
     KisClipboard::instance()->setClip(dev, QPoint());
-    newDev = KisClipboard::instance()->clip(QPoint());
+    newDev = KisClipboard::instance()->clip(QRect());
     QCOMPARE(newDev->exactBounds().size(), fillRect.size());
     newDev->setX(dev->x());
     newDev->setY(dev->y());
@@ -56,7 +56,7 @@ void KisClipboardTest::testRoundTrip()
 
     QCOMPARE(dev->exactBounds(), fillRect.translated(offset));
     KisClipboard::instance()->setClip(dev, QPoint());
-    newDev = KisClipboard::instance()->clip(QPoint());
+    newDev = KisClipboard::instance()->clip(QRect());
     QCOMPARE(newDev->exactBounds().size(), fillRect.translated(offset).size());
     newDev->setX(dev->x());
     newDev->setY(dev->y());
diff --git a/krita/ui/widgets/kis_custom_image_widget.cc b/krita/ui/widgets/kis_custom_image_widget.cc
index dd0a75f..8a30d50 100644
--- a/krita/ui/widgets/kis_custom_image_widget.cc
+++ b/krita/ui/widgets/kis_custom_image_widget.cc
@@ -225,7 +225,7 @@ void KisCustomImageWidget::createImage()
 
         }
         if (chkFromClipboard->isChecked()) {
-            KisPaintDeviceSP clip = KisClipboard::instance()->clip(QPoint(0,0));
+            KisPaintDeviceSP clip = KisClipboard::instance()->clip(QRect());
             if (clip) {
                 QRect r = clip->exactBounds();
                 KisPainter painter;


More information about the kimageshop mailing list