File indexing completed on 2024-12-22 04:16:52

0001 /*
0002  *  SPDX-FileCopyrightText: 2024 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #include "TransformStrokeStrategyTest.h"
0007 
0008 #include <stroke_testing_utils.h>
0009 #include <strokes/inplace_transform_stroke_strategy.h>
0010 
0011 #include "kis_selection.h"
0012 
0013 #include <testutil.h>
0014 #include "kistest.h"
0015 #include "kis_transform_mask.h"
0016 #include "KisTransformMaskTestingInterface.h"
0017 
0018 #include "kis_paint_device_debug_utils.h"
0019 
0020 #include "kis_transform_mask_params_factory_registry.h"
0021 #include "kis_transform_mask_adapter.h"
0022 #include "KisAnimatedTransformMaskParamsHolder.h"
0023 
0024 namespace {
0025 
0026 KisAnimatedTransformParamsHolderInterfaceSP createAnimatedParamsHolder(KisDefaultBoundsBaseSP defaultBounds)
0027 {
0028     return toQShared(new KisAnimatedTransformMaskParamsHolder(defaultBounds));
0029 }
0030 
0031 }
0032 
0033 void TransformStrokeStrategyTest::initTestCase()
0034 {
0035     KisTransformMaskParamsFactoryRegistry::instance()->setAnimatedParamsHolderFactory(&createAnimatedParamsHolder);
0036     KisTransformMaskParamsFactoryRegistry::instance()->addFactory("tooltransformparams", &KisTransformMaskAdapter::fromXML);
0037     qRegisterMetaType<TransformTransactionProperties>("TransformTransactionProperties");
0038     qRegisterMetaType<ToolTransformArgs>("ToolTransformArgs");
0039 }
0040 
0041 struct TestingInterface : KisTransformMaskTestingInterface
0042 {
0043     struct Data : boost::equality_comparable<Data>
0044     {
0045         int forceUpdateTimedNode = 0;
0046         int threadSafeForceStaticImageUpdate = 0;
0047         int slotDelayedStaticImageUpdate = 0;
0048         int decorateRectTriggeredStaticImageUpdate = 0;
0049         int recalculateStaticImage = 0;
0050 
0051         bool operator==(const Data &rhs) const {
0052             return
0053                 rhs.forceUpdateTimedNode == forceUpdateTimedNode &&
0054                 rhs.threadSafeForceStaticImageUpdate == threadSafeForceStaticImageUpdate &&
0055                 rhs.slotDelayedStaticImageUpdate == slotDelayedStaticImageUpdate &&
0056                 bool(rhs.decorateRectTriggeredStaticImageUpdate > 0) ==
0057                 bool(decorateRectTriggeredStaticImageUpdate > 0) &&
0058                 rhs.recalculateStaticImage == recalculateStaticImage;
0059         }
0060     };
0061 
0062     void notifyForceUpdateTimedNode() override {
0063         QMutexLocker l(&m_mutex);
0064         m_data.forceUpdateTimedNode++;
0065     }
0066     void notifyThreadSafeForceStaticImageUpdate() override {
0067         QMutexLocker l(&m_mutex);
0068         m_data.threadSafeForceStaticImageUpdate++;
0069     }
0070     void notifySlotDelayedStaticUpdate() override {
0071         QMutexLocker l(&m_mutex);
0072         m_data.slotDelayedStaticImageUpdate++;
0073     }
0074     void notifyDecorateRectTriggeredStaticImageUpdate() override {
0075         QMutexLocker l(&m_mutex);
0076         m_data.decorateRectTriggeredStaticImageUpdate++;
0077     }
0078     void notifyRecalculateStaticImage() override {
0079         QMutexLocker l(&m_mutex);
0080         m_data.recalculateStaticImage++;
0081     }
0082 
0083     Data stats() const {
0084         QMutexLocker l(&m_mutex);
0085         return m_data;
0086     }
0087     void clear() {
0088         QMutexLocker l(&m_mutex);
0089         m_data = Data();
0090     }
0091 
0092 private:
0093     mutable QMutex m_mutex;
0094     Data m_data;
0095 };
0096 
0097 struct TestPlan {
0098     using Data = TestingInterface::Data;
0099 
0100     Data initializationPhase;
0101     Data jobsPhase;
0102     Data finalizationPhase;
0103 };
0104 
0105 inline QDebug operator<<(QDebug dbg, const TestingInterface::Data &d)
0106 {
0107     dbg.nospace() << "("
0108                   << ppVar(d.decorateRectTriggeredStaticImageUpdate) << " "
0109                   << ppVar(d.slotDelayedStaticImageUpdate) << " "
0110                   << ppVar(d.forceUpdateTimedNode) << " "
0111                   << ppVar(d.threadSafeForceStaticImageUpdate) << " "
0112                   << ppVar(d.recalculateStaticImage)
0113                   << " )";
0114 
0115     return dbg.space();
0116 }
0117 
0118 
0119 class InplaceStrokeTester : public QObject, public utils::StrokeTester
0120 {
0121     Q_OBJECT
0122 public:
0123 
0124     InplaceStrokeTester(const QString &name)
0125         : utils::StrokeTester(name, QSize(512, 512))
0126     {
0127     }
0128 
0129     QPointF m_offset = QPointF(-2.5, 0);
0130 
0131     QVector<TestPlan> m_testPlan;
0132     int m_lodLevel = 0;
0133 
0134 protected:
0135 
0136     void initImage(KisImageWSP image, KisNodeSP activeNode, int iteration) override
0137     {
0138         ENTER_FUNCTION();
0139 
0140         if (iteration == 0) {
0141 
0142             if (m_lodLevel > 0) {
0143                 image->setLodPreferences(KisLodPreferences(KisLodPreferences::LodPreferred |
0144                                                                KisLodPreferences::LodSupported, 2));
0145             }
0146 
0147             QTest::qWait(500);
0148 
0149             image->waitForDone();
0150             m_node = activeNode;
0151             KisPaintDeviceSP dev = m_node->paintDevice();
0152 
0153             KoColor c(dev->colorSpace());
0154 
0155             c.fromQColor(Qt::green);
0156             dev->fill(QRect(300,300, 100, 100), c);
0157 
0158             c.fromQColor(Qt::red);
0159             dev->fill(QRect(310,300, 80, 10), c);
0160 
0161             m_transformMask = new KisTransformMask(image, "tmask");
0162             m_transformMask->setTestingInterface(new TestingInterface());
0163             image->addNode(m_transformMask, m_node);
0164 
0165             m_transformMask->forceUpdateTimedNode();
0166             image->waitForDone();
0167 
0168             //KIS_DUMP_DEVICE_2(m_node->paintDevice(), QRect(0,0,512,512), "00_initial_pd", "dd");
0169             //KIS_DUMP_DEVICE_2(m_node->projection(), QRect(0,0,512,512), "01_initial_proj", "dd");
0170 
0171             m_offset = QPointF(-2.5, 0);
0172 
0173         } else if (iteration == 1) {
0174             m_offset = QPointF(0, -2.5);
0175         }
0176 
0177         // clear stats
0178         testingInterface()->clear();
0179 
0180         LEAVE_FUNCTION();
0181     }
0182 
0183     TestingInterface* testingInterface() const {
0184         TestingInterface *iface = dynamic_cast<TestingInterface*>(m_transformMask->testingInterface());
0185         KIS_ASSERT(iface);
0186         return iface;
0187     }
0188 
0189     TestingInterface::Data stats() const {
0190         return testingInterface()->stats();
0191     }
0192 
0193     TestingInterface::Data takeStats() const {
0194         auto s = testingInterface()->stats();
0195         testingInterface()->clear();
0196         return s;
0197     }
0198 
0199     void addPaintingJobs(KisImageWSP image,
0200                          KisResourcesSnapshotSP resources,
0201                          int iteration) override
0202     {
0203         Q_UNUSED(iteration);
0204         Q_UNUSED(resources);
0205 
0206         while (m_transaction.transformedNodes().isEmpty()) {
0207             qDebug() << "Waiting for the transaction to appear...";
0208             QTest::qWait(5);
0209         }
0210 
0211         compareStats("INITIALIZATION", m_testPlan[iteration].initializationPhase);
0212 
0213         m_updatesHelper.startUpdateStream(image.data(), strokeId());
0214 
0215         for (int i = 0; i < 100; i++) {
0216             QTest::qWait(20);
0217 
0218             m_currentArgs.setTransformedCenter(m_currentArgs.transformedCenter() + m_offset);
0219             m_currentArgs.setAZ(m_currentArgs.aZ() + 1.0 * M_PI / 180.0);
0220             image->addJob(strokeId(),
0221                           new InplaceTransformStrokeStrategy::UpdateTransformData(
0222                               m_currentArgs,
0223                               InplaceTransformStrokeStrategy::UpdateTransformData::PAINT_DEVICE));
0224         }
0225 
0226 
0227         m_updatesHelper.endUpdateStream();
0228 
0229 
0230         /**
0231          * HINT: we cannot read data from the device at this point when working LoD is
0232          *       non-zero, because this LoD is actual only at the context of the
0233          *       jobs actually executing the update request
0234          */
0235         ENTER_FUNCTION() << ppVar(image->currentLevelOfDetail());
0236         QTest::qWait(200);
0237         //KIS_DUMP_DEVICE_2(m_node->paintDevice(), QRect(0,0,512,512), "80_semi-ended_pd", "dd");
0238         //KIS_DUMP_DEVICE_2(m_node->projection(), QRect(0,0,512,512), "81_semi-ended_proj", "dd");
0239 
0240         compareStats("JOBS", m_testPlan[iteration].jobsPhase);
0241     }
0242 
0243 
0244     void compareStats(const char *title, TestingInterface::Data &expected)
0245     {
0246         TestingInterface::Data data = takeStats();
0247 
0248         if (data != expected) {
0249             qDebug("FAIL: the update stats are not correct as stage \"%s\"", title);
0250             qDebug() << "   expected:" << expected;
0251             qDebug() << "   real    :" << data;
0252             qFatal("compared data is not the same!");
0253         }
0254     }
0255 
0256     void iterationEndedCallback(KisImageWSP image, KisNodeSP activeNode, int iteration) override
0257     {
0258         qDebug() << "Waiting for the final update...";
0259         /// the delay in the mask is 3000ms, so we should wait a little bit longer to catch
0260         /// spurious updates
0261         QTest::qWait(4000);
0262         qDebug() << "(done)";
0263 
0264         //KIS_DUMP_DEVICE_2(m_node->paintDevice(), QRect(0,0,512,512), "90_ended_pd", "dd");
0265         //KIS_DUMP_DEVICE_2(m_node->projection(), QRect(0,0,512,512), "91_ended_proj", "dd");
0266 
0267         compareStats("FINALIZATION", m_testPlan[iteration].finalizationPhase);
0268     }
0269 
0270     KisStrokeStrategy* createStroke(KisResourcesSnapshotSP resources,
0271                                     KisImageWSP image) override
0272     {
0273         Q_UNUSED(resources);
0274 
0275         const bool forceLodMode = true;
0276 
0277         InplaceTransformStrokeStrategy *strategy =
0278             new InplaceTransformStrokeStrategy(ToolTransformArgs::FREE_TRANSFORM,
0279                                                "Bilinear",
0280                                                false,
0281                                                {m_transformMask},
0282                                                nullptr,
0283                                                nullptr,
0284                                                image.data(),
0285                                                image.data(),
0286                                                image->root(),
0287                                                forceLodMode);
0288 
0289         m_currentArgs = ToolTransformArgs();
0290         m_transaction = TransformTransactionProperties(QRectF(), &m_currentArgs, KisNodeList(), {});
0291 
0292         connect(strategy, SIGNAL(sigTransactionGenerated(TransformTransactionProperties, ToolTransformArgs, void*)), SLOT(slotTransactionGenerated(TransformTransactionProperties, ToolTransformArgs, void*)));
0293 
0294         m_strokeStrategyCookie = strategy;
0295         return strategy;
0296     }
0297 
0298 private Q_SLOTS:
0299     void slotTransactionGenerated(TransformTransactionProperties transaction, ToolTransformArgs args, void *strokeStrategyCookie)
0300     {
0301         KIS_ASSERT(strokeId());
0302         KIS_ASSERT(strokeStrategyCookie == m_strokeStrategyCookie);
0303 
0304         ENTER_FUNCTION() << ppVar(transaction.originalRect()) << ppVar(transaction.transformedNodes());
0305         qDebug() << "           " <<  ppVar(args.originalCenter()) << ppVar(args.transformedCenter());
0306 
0307         m_transaction = transaction;
0308         m_currentArgs = args;
0309         m_transaction.setCurrentConfigLocation(&m_currentArgs);
0310     }
0311 
0312 private:
0313     ToolTransformArgs m_currentArgs;
0314     TransformTransactionProperties m_transaction;
0315 
0316     KisAsynchronousStrokeUpdateHelper m_updatesHelper;
0317     void *m_strokeStrategyCookie;
0318 
0319     KisNodeSP m_node;
0320     KisTransformMaskSP m_transformMask;
0321 };
0322 
0323 void TransformStrokeStrategyTest::testLod2()
0324 {
0325     InplaceStrokeTester tester("inplace-lod2");
0326     tester.setNumIterations(2);
0327     tester.m_lodLevel = 2;
0328 
0329     {
0330         TestingInterface::Data init;
0331         init.decorateRectTriggeredStaticImageUpdate = 0;
0332         init.slotDelayedStaticImageUpdate = 0;
0333         init.forceUpdateTimedNode = 1;
0334         init.threadSafeForceStaticImageUpdate = 0;
0335         init.recalculateStaticImage = 0;
0336 
0337         TestingInterface::Data jobs;
0338         jobs.decorateRectTriggeredStaticImageUpdate = 0;
0339         jobs.slotDelayedStaticImageUpdate = 0;
0340         jobs.forceUpdateTimedNode = 0;
0341         jobs.threadSafeForceStaticImageUpdate = 0;
0342         jobs.recalculateStaticImage = 0;
0343 
0344         TestingInterface::Data end;
0345         end.decorateRectTriggeredStaticImageUpdate = 0;
0346         end.slotDelayedStaticImageUpdate = 0;
0347         end.forceUpdateTimedNode = 0;
0348         end.threadSafeForceStaticImageUpdate = 1;
0349         end.recalculateStaticImage = 1;
0350         tester.m_testPlan << TestPlan{init, jobs, end};
0351     }
0352 
0353     {
0354         TestingInterface::Data init;
0355         init.decorateRectTriggeredStaticImageUpdate = 0;
0356         init.slotDelayedStaticImageUpdate = 0;
0357         init.forceUpdateTimedNode = 1;
0358         init.threadSafeForceStaticImageUpdate = 1; // we have one more call due to undo() step in the commands
0359         init.recalculateStaticImage = 2;
0360 
0361         TestingInterface::Data jobs;
0362         jobs.decorateRectTriggeredStaticImageUpdate = 0;
0363         jobs.slotDelayedStaticImageUpdate = 0;
0364         jobs.forceUpdateTimedNode = 0;
0365         jobs.threadSafeForceStaticImageUpdate = 0;
0366         jobs.recalculateStaticImage = 0;
0367 
0368         TestingInterface::Data end;
0369         end.decorateRectTriggeredStaticImageUpdate = 0;
0370         end.slotDelayedStaticImageUpdate = 0;
0371         end.forceUpdateTimedNode = 0;
0372         end.threadSafeForceStaticImageUpdate = 1;
0373         end.recalculateStaticImage = 1;
0374         tester.m_testPlan << TestPlan{init, jobs, end};
0375     }
0376 
0377     tester.testSimpleStroke();
0378 }
0379 
0380 void TransformStrokeStrategyTest::testLod2Cancelled()
0381 {
0382     InplaceStrokeTester tester("inplace-lod2-cancelled");
0383     tester.setNumIterations(1);
0384     tester.m_lodLevel = 2;
0385 
0386     {
0387         TestingInterface::Data init;
0388         init.decorateRectTriggeredStaticImageUpdate = 0;
0389         init.slotDelayedStaticImageUpdate = 0;
0390         init.forceUpdateTimedNode = 1;
0391         init.threadSafeForceStaticImageUpdate = 0;
0392         init.recalculateStaticImage = 0;
0393 
0394         TestingInterface::Data jobs;
0395         jobs.decorateRectTriggeredStaticImageUpdate = 0;
0396         jobs.slotDelayedStaticImageUpdate = 0;
0397         jobs.forceUpdateTimedNode = 0;
0398         jobs.threadSafeForceStaticImageUpdate = 0;
0399         jobs.recalculateStaticImage = 0;
0400 
0401         TestingInterface::Data end;
0402         end.decorateRectTriggeredStaticImageUpdate = 0;
0403         end.slotDelayedStaticImageUpdate = 0;
0404         end.forceUpdateTimedNode = 0;
0405         end.threadSafeForceStaticImageUpdate = 2;
0406         end.recalculateStaticImage = 1;
0407         tester.m_testPlan << TestPlan{init, jobs, end};
0408     }
0409 
0410     tester.testSimpleStrokeCancelled();
0411 }
0412 
0413 void TransformStrokeStrategyTest::testLod2ContinueAndCancel()
0414 {
0415     InplaceStrokeTester tester("inplace-lod2-continue-and-cancel");
0416     tester.setNumIterations(2);
0417     tester.setCancelOnIteration(1);
0418     tester.m_lodLevel = 2;
0419 
0420     {
0421         TestingInterface::Data init;
0422         init.decorateRectTriggeredStaticImageUpdate = 0;
0423         init.slotDelayedStaticImageUpdate = 0;
0424         init.forceUpdateTimedNode = 1;
0425         init.threadSafeForceStaticImageUpdate = 0;
0426         init.recalculateStaticImage = 0;
0427 
0428         TestingInterface::Data jobs;
0429         jobs.decorateRectTriggeredStaticImageUpdate = 0;
0430         jobs.slotDelayedStaticImageUpdate = 0;
0431         jobs.forceUpdateTimedNode = 0;
0432         jobs.threadSafeForceStaticImageUpdate = 0;
0433         jobs.recalculateStaticImage = 0;
0434 
0435         TestingInterface::Data end;
0436         end.decorateRectTriggeredStaticImageUpdate = 0;
0437         end.slotDelayedStaticImageUpdate = 0;
0438         end.forceUpdateTimedNode = 0;
0439         end.threadSafeForceStaticImageUpdate = 1;
0440         end.recalculateStaticImage = 1;
0441         tester.m_testPlan << TestPlan{init, jobs, end};
0442     }
0443 
0444     {
0445         TestingInterface::Data init;
0446         init.decorateRectTriggeredStaticImageUpdate = 0;
0447         init.slotDelayedStaticImageUpdate = 0;
0448         init.forceUpdateTimedNode = 1;
0449         init.threadSafeForceStaticImageUpdate = 1; // we have one more call due to undo() step in the commands
0450         init.recalculateStaticImage = 2;
0451 
0452         TestingInterface::Data jobs;
0453         jobs.decorateRectTriggeredStaticImageUpdate = 0;
0454         jobs.slotDelayedStaticImageUpdate = 0;
0455         jobs.forceUpdateTimedNode = 0;
0456         jobs.threadSafeForceStaticImageUpdate = 0;
0457         jobs.recalculateStaticImage = 0;
0458 
0459         TestingInterface::Data end;
0460         end.decorateRectTriggeredStaticImageUpdate = 0;
0461         end.slotDelayedStaticImageUpdate = 0;
0462         end.forceUpdateTimedNode = 0;
0463         end.threadSafeForceStaticImageUpdate = 2;
0464         end.recalculateStaticImage = 1;
0465         tester.m_testPlan << TestPlan{init, jobs, end};
0466     }
0467 
0468     tester.testSimpleStrokeCancelled();
0469 }
0470 
0471 void TransformStrokeStrategyTest::testLod0()
0472 {
0473     InplaceStrokeTester tester("inplace-lod0");
0474     tester.setNumIterations(2);
0475     tester.m_lodLevel = 0;
0476 
0477     {
0478         TestingInterface::Data init;
0479         init.decorateRectTriggeredStaticImageUpdate = 0;
0480         init.slotDelayedStaticImageUpdate = 0;
0481         init.forceUpdateTimedNode = 1;
0482         init.threadSafeForceStaticImageUpdate = 0;
0483         init.recalculateStaticImage = 0;
0484 
0485         TestingInterface::Data jobs;
0486         jobs.decorateRectTriggeredStaticImageUpdate = 10000;
0487         jobs.slotDelayedStaticImageUpdate = 0;
0488         jobs.forceUpdateTimedNode = 0;
0489         jobs.threadSafeForceStaticImageUpdate = 0;
0490         jobs.recalculateStaticImage = 0;
0491 
0492         TestingInterface::Data end;
0493         end.decorateRectTriggeredStaticImageUpdate = 0;
0494         end.slotDelayedStaticImageUpdate = 0;
0495         end.forceUpdateTimedNode = 0;
0496         end.threadSafeForceStaticImageUpdate = 0;
0497         end.recalculateStaticImage = 0;
0498         tester.m_testPlan << TestPlan{init, jobs, end};
0499     }
0500 
0501     {
0502         TestingInterface::Data init;
0503         init.decorateRectTriggeredStaticImageUpdate = 0;
0504         init.slotDelayedStaticImageUpdate = 0;
0505         init.forceUpdateTimedNode = 1;
0506         init.threadSafeForceStaticImageUpdate = 1; // we have one more call due to undo() step in the commands
0507         init.recalculateStaticImage = 2;
0508 
0509         TestingInterface::Data jobs;
0510         jobs.decorateRectTriggeredStaticImageUpdate = 10000;
0511         jobs.slotDelayedStaticImageUpdate = 0;
0512         jobs.forceUpdateTimedNode = 0;
0513         jobs.threadSafeForceStaticImageUpdate = 0;
0514         jobs.recalculateStaticImage = 0;
0515 
0516         TestingInterface::Data end;
0517         end.decorateRectTriggeredStaticImageUpdate = 0;
0518         end.slotDelayedStaticImageUpdate = 0;
0519         end.forceUpdateTimedNode = 0;
0520         end.threadSafeForceStaticImageUpdate = 0;
0521         end.recalculateStaticImage = 0;
0522         tester.m_testPlan << TestPlan{init, jobs, end};
0523     }
0524 
0525     tester.testSimpleStroke();
0526 }
0527 
0528 void TransformStrokeStrategyTest::testLod0Cancelled()
0529 {
0530     InplaceStrokeTester tester("inplace-lod0-cancelled");
0531     tester.setNumIterations(1);
0532     tester.m_lodLevel = 0;
0533 
0534     {
0535         TestingInterface::Data init;
0536         init.decorateRectTriggeredStaticImageUpdate = 0;
0537         init.slotDelayedStaticImageUpdate = 0;
0538         init.forceUpdateTimedNode = 1;
0539         init.threadSafeForceStaticImageUpdate = 0;
0540         init.recalculateStaticImage = 0;
0541 
0542         TestingInterface::Data jobs;
0543         jobs.decorateRectTriggeredStaticImageUpdate = 10000;
0544         jobs.slotDelayedStaticImageUpdate = 0;
0545         jobs.forceUpdateTimedNode = 0;
0546         jobs.threadSafeForceStaticImageUpdate = 0;
0547         jobs.recalculateStaticImage = 0;
0548 
0549         TestingInterface::Data end;
0550         end.decorateRectTriggeredStaticImageUpdate = 1;
0551         end.slotDelayedStaticImageUpdate = 0;
0552         end.forceUpdateTimedNode = 0;
0553         end.threadSafeForceStaticImageUpdate = 2; // TODO: check why we get dirty?
0554         end.recalculateStaticImage = 1;
0555         tester.m_testPlan << TestPlan{init, jobs, end};
0556     }
0557 
0558     tester.testSimpleStrokeCancelled();
0559 }
0560 
0561 void TransformStrokeStrategyTest::testLod0ContinueAndCancel()
0562 {
0563     InplaceStrokeTester tester("inplace-lod0-continue-and-cancel");
0564     tester.setNumIterations(2);
0565     tester.setCancelOnIteration(1);
0566     tester.m_lodLevel = 0;
0567 
0568     {
0569         TestingInterface::Data init;
0570         init.decorateRectTriggeredStaticImageUpdate = 0;
0571         init.slotDelayedStaticImageUpdate = 0;
0572         init.forceUpdateTimedNode = 1;
0573         init.threadSafeForceStaticImageUpdate = 0;
0574         init.recalculateStaticImage = 0;
0575 
0576         TestingInterface::Data jobs;
0577         jobs.decorateRectTriggeredStaticImageUpdate = 10000;
0578         jobs.slotDelayedStaticImageUpdate = 0;
0579         jobs.forceUpdateTimedNode = 0;
0580         jobs.threadSafeForceStaticImageUpdate = 0;
0581         jobs.recalculateStaticImage = 0;
0582 
0583         TestingInterface::Data end;
0584         end.decorateRectTriggeredStaticImageUpdate = 0;
0585         end.slotDelayedStaticImageUpdate = 0;
0586         end.forceUpdateTimedNode = 0;
0587         end.threadSafeForceStaticImageUpdate = 0;
0588         end.recalculateStaticImage = 0;
0589         tester.m_testPlan << TestPlan{init, jobs, end};
0590     }
0591 
0592     {
0593         TestingInterface::Data init;
0594         init.decorateRectTriggeredStaticImageUpdate = 0;
0595         init.slotDelayedStaticImageUpdate = 0;
0596         init.forceUpdateTimedNode = 1;
0597         init.threadSafeForceStaticImageUpdate = 1; // we have one more call due to undo() step in the commands
0598         init.recalculateStaticImage = 2;
0599 
0600         TestingInterface::Data jobs;
0601         jobs.decorateRectTriggeredStaticImageUpdate = 10000;
0602         jobs.slotDelayedStaticImageUpdate = 0;
0603         jobs.forceUpdateTimedNode = 0;
0604         jobs.threadSafeForceStaticImageUpdate = 0;
0605         jobs.recalculateStaticImage = 0;
0606 
0607         TestingInterface::Data end;
0608         end.decorateRectTriggeredStaticImageUpdate = 1;
0609         end.slotDelayedStaticImageUpdate = 0;
0610         end.forceUpdateTimedNode = 0;
0611         end.threadSafeForceStaticImageUpdate = 1;
0612         end.recalculateStaticImage = 1;
0613         tester.m_testPlan << TestPlan{init, jobs, end};
0614     }
0615 
0616     tester.testSimpleStrokeCancelled();
0617 }
0618 
0619 #define TESTRESOURCES
0620 #define TESTPIGMENT
0621 #define TESTIMAGE
0622 #define TESTBRUSH
0623 #define TESTUI
0624 
0625 KISTEST_MAIN(TransformStrokeStrategyTest)
0626 
0627 #include <TransformStrokeStrategyTest.moc>