Commit 7a709c54 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix undo of replacing vector selection

When redoing KisTakeAllShapesCommand, we should keep the
selection projection, but when undoing it, we should start a
full-featured update to get a correct canvas state. It is needed
because pixel selection is used as a projection in shape-mode, so
undo/redo for it is not valid.

BUG:412808
parent 99b25ed8
......@@ -346,6 +346,11 @@ void KisSelection::requestCompressedProjectionUpdate(const QRect &rc)
m_d->updateCompressor->requestUpdate(rc);
}
void KisSelection::notifyShapeSelectionBecameEmpty()
{
m_d->pixelSelection->clear();
}
quint8 KisSelection::selected(qint32 x, qint32 y) const
{
KisHLineConstIteratorSP iter = m_d->pixelSelection->createHLineConstIteratorNG(x, y, 1);
......
......@@ -199,6 +199,8 @@ public:
*/
void requestCompressedProjectionUpdate(const QRect &rc);
void notifyShapeSelectionBecameEmpty();
/// XXX: This method was marked KDE_DEPRECATED but without information on what to
/// replace it with. Undeprecate, therefore.
quint8 selected(qint32 x, qint32 y) const;
......
......@@ -257,7 +257,7 @@ bool KisShapeSelection::updatesEnabled() const
KUndo2Command* KisShapeSelection::resetToEmpty()
{
return new KisTakeAllShapesCommand(this, true);
return new KisTakeAllShapesCommand(this, true, false);
}
bool KisShapeSelection::isEmpty() const
......
......@@ -97,6 +97,10 @@ void KisShapeSelectionModel::remove(KoShape *child)
updateRect = matrix.mapRect(updateRect);
if (m_shapeSelection) { // No m_shapeSelection indicates the selection is being deleted
requestUpdate(updateRect);
if (m_updatesEnabled && m_shapeMap.isEmpty()) {
m_parentSelection->notifyShapeSelectionBecameEmpty();
}
}
}
}
......
......@@ -23,10 +23,11 @@
#include <kis_image.h>
KisTakeAllShapesCommand::KisTakeAllShapesCommand(KisShapeSelection *shapeSelection, bool takeSilently)
KisTakeAllShapesCommand::KisTakeAllShapesCommand(KisShapeSelection *shapeSelection, bool takeSilently, bool restoreSilently)
: KUndo2Command(kundo2_i18n("Clear Vector Selection")),
m_shapeSelection(shapeSelection),
m_takeSilently(takeSilently)
m_takeSilently(takeSilently),
m_restoreSilently(restoreSilently)
{
}
......@@ -56,7 +57,7 @@ void KisTakeAllShapesCommand::redo()
void KisTakeAllShapesCommand::undo()
{
if (m_takeSilently) {
if (m_restoreSilently) {
m_shapeSelection->setUpdatesEnabled(false);
}
......@@ -66,7 +67,7 @@ void KisTakeAllShapesCommand::undo()
m_shapes.clear();
if (m_takeSilently) {
if (m_restoreSilently) {
m_shapeSelection->setUpdatesEnabled(true);
}
}
......
......@@ -33,7 +33,9 @@ class KisShapeSelection;
class KisTakeAllShapesCommand : public KUndo2Command
{
public:
KisTakeAllShapesCommand(KisShapeSelection *shapeSelection, bool takeSilently);
KisTakeAllShapesCommand(KisShapeSelection *shapeSelection,
bool takeSilently,
bool restoreSilently);
~KisTakeAllShapesCommand() override;
void redo() override;
......@@ -43,6 +45,7 @@ private:
KisShapeSelection *m_shapeSelection;
QList<KoShape*> m_shapes;
bool m_takeSilently;
bool m_restoreSilently;
};
#endif /* __KIS_TAKE_ALL_SHAPES_COMMAND_H */
......@@ -34,6 +34,7 @@
#include "kistest.h"
#include <KisPart.h>
#include <KisDocument.h>
#include "kis_transaction.h"
void KisShapeSelectionTest::testAddChild()
{
......@@ -80,6 +81,112 @@ void KisShapeSelectionTest::testAddChild()
QCOMPARE(selection->selectedExactRect(), QRect(50, 50, 100, 100));
}
KoPathShape *createRectangularShape(const QRectF &rect)
{
KoPathShape* shape = new KoPathShape();
shape->setShapeId(KoPathShapeId);
shape->moveTo(rect.topLeft());
shape->lineTo(rect.topRight());
shape->lineTo(rect.bottomRight());
shape->lineTo(rect.bottomLeft());
shape->close();
return shape;
}
void KisShapeSelectionTest::testUndoFlattening()
{
const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
KoColor bgColor(QColor(255, 255, 255, 0), cs);
doc->newImage("test", 300, 300, cs, bgColor, KisConfig::CANVAS_COLOR, 1, "test", 100);
KisImageSP image = doc->image();
QCOMPARE(image->locked(), false);
KisSelectionSP selection = new KisSelection();
QCOMPARE(selection->hasPixelSelection(), false);
QCOMPARE(selection->hasShapeSelection(), false);
selection->setParentNode(image->root());
KisPixelSelectionSP pixelSelection = selection->pixelSelection();
pixelSelection->select(QRect(0, 0, 100, 100));
QCOMPARE(TestUtil::alphaDevicePixel(pixelSelection, 25, 25), MAX_SELECTED);
QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 100, 100));
QTransform matrix;
matrix.scale(1 / image->xRes(), 1 / image->yRes());
const QRectF srcRect1(50, 50, 100, 100);
const QRectF rect1 = matrix.mapRect(srcRect1);
KisShapeSelection * shapeSelection = new KisShapeSelection(doc->shapeController(), image, selection);
selection->setShapeSelection(shapeSelection);
KoPathShape *shape1 = createRectangularShape(rect1);
shapeSelection->addShape(shape1);
QVERIFY(selection->hasShapeSelection());
selection->pixelSelection()->clear();
QCOMPARE(selection->selectedExactRect(), QRectF());
selection->updateProjection();
image->waitForDone();
QCOMPARE(selection->selectedExactRect(), srcRect1);
QCOMPARE(selection->outlineCacheValid(), true);
QCOMPARE(selection->outlineCache().boundingRect(), srcRect1);
QCOMPARE(selection->hasShapeSelection(), true);
KisTransaction t1(selection->pixelSelection());
selection->pixelSelection()->clear();
KUndo2Command *cmd1 = t1.endAndTake();
QTest::qWait(400);
image->waitForDone();
QCOMPARE(selection->selectedExactRect(), QRect());
QCOMPARE(selection->outlineCacheValid(), true);
QCOMPARE(selection->outlineCache().boundingRect(), QRectF());
QCOMPARE(selection->hasShapeSelection(), false);
const QRectF srcRect2(10, 10, 20, 20);
const QRectF rect2 = matrix.mapRect(srcRect2);
KoPathShape *shape2 = createRectangularShape(rect2);
shapeSelection->addShape(shape2);
QTest::qWait(400);
image->waitForDone();
QCOMPARE(selection->selectedExactRect(), srcRect2);
QCOMPARE(selection->outlineCacheValid(), true);
QCOMPARE(selection->outlineCache().boundingRect(), srcRect2);
QCOMPARE(selection->hasShapeSelection(), true);
shapeSelection->removeShape(shape2);
QTest::qWait(400);
image->waitForDone();
QCOMPARE(selection->selectedExactRect(), QRect());
QCOMPARE(selection->outlineCacheValid(), true);
QCOMPARE(selection->outlineCache().boundingRect(), QRectF());
QCOMPARE(selection->hasShapeSelection(), false);
cmd1->undo();
QTest::qWait(400);
image->waitForDone();
QCOMPARE(selection->selectedExactRect(), srcRect1);
QCOMPARE(selection->outlineCacheValid(), true);
QCOMPARE(selection->outlineCache().boundingRect(), srcRect1);
QCOMPARE(selection->hasShapeSelection(), true);
}
KISTEST_MAIN(KisShapeSelectionTest)
......@@ -28,6 +28,8 @@ class KisShapeSelectionTest : public QObject
private Q_SLOTS:
void testAddChild();
void testUndoFlattening();
};
#endif
......
  • I think this change broke the build.

    I'm getting:

    CMakeFiles/kis_shape_selection_test.dir/kis_shape_selection_test.cpp.o: In function `KisShapeSelectionTest::testUndoFlattening()':
    kis_shape_selection_test.cpp:(.text+0x3b73): undefined reference to `bool QTest::qCompare<QRect, QRectF>(QRect const&, QRectF const&, char const*, char const*, char const*, int)'
    kis_shape_selection_test.cpp:(.text+0x3c08): undefined reference to `bool QTest::qCompare<QRect, QRectF>(QRect const&, QRectF const&, char const*, char const*, char const*, int)'
    kis_shape_selection_test.cpp:(.text+0x4163): undefined reference to `bool QTest::qCompare<QRect, QRectF>(QRect const&, QRectF const&, char const*, char const*, char const*, int)'
    kis_shape_selection_test.cpp:(.text+0x4583): undefined reference to `bool QTest::qCompare<QRect, QRectF>(QRect const&, QRectF const&, char const*, char const*, char const*, int)'

    I think the root cause is that this test wants to qcompare QRect and QRectF, which is not allowed.

    see: https://github.com/bricke/Qt-AES/issues/10

  • Thanks! I'll check this :)

  • Shi Yan @shiyan

    mentioned in merge request !192 (merged)

    ·

    mentioned in merge request !192 (merged)

    Toggle commit list
  • Shi Yan @shiyan

    mentioned in commit dea9c67c

    ·

    mentioned in commit dea9c67c

    Toggle commit list
  • mentioned in commit f2394e71

    Toggle commit list
  • Shi Yan @shiyan

    mentioned in commit eaf1ece1

    ·

    mentioned in commit eaf1ece1

    Toggle commit list
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment