File indexing completed on 2024-05-12 04:33:31

0001 /*
0002     SPDX-FileCopyrightText: 2013 Jon Mease <jon.mease@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <QTest>
0008 
0009 #include "../settings_core.h"
0010 #include "core/annotations.h"
0011 #include "core/document.h"
0012 #include "testingutils.h"
0013 #include <QMimeDatabase>
0014 #include <QMimeType>
0015 
0016 Okular::LineAnnotation *getNewLineAnnotation(double startX, double startY, double endX, double endY)
0017 {
0018     Okular::LineAnnotation *line = new Okular::LineAnnotation;
0019     line->setLinePoints({Okular::NormalizedPoint(startX, startY), Okular::NormalizedPoint(endX, endY)});
0020 
0021     double left = qMin(startX, endX);
0022     double top = qMin(startY, endY);
0023     double right = qMax(startX, endX);
0024     double bottom = qMax(startY, endY);
0025 
0026     line->setBoundingRectangle(Okular::NormalizedRect(left, top, right, bottom));
0027     return line;
0028 }
0029 
0030 class TranslateAnnotationTest : public QObject
0031 {
0032     Q_OBJECT
0033 
0034 private Q_SLOTS:
0035     void initTestCase();
0036     void cleanupTestCase();
0037     void init();
0038     void cleanup();
0039     void testTranslateAnnotation();
0040     void testSequentialTranslationsMergedIfBeingMovedIsSet();
0041     void testSequentialTranslationsNotMergedIfBeingMovedIsNotSet();
0042     void testAlternateTranslationsNotMerged();
0043 
0044 private:
0045     Okular::Document *m_document;
0046     Okular::LineAnnotation *m_annot1;
0047     Okular::LineAnnotation *m_annot2;
0048 
0049     Okular::NormalizedPoint m_deltaA;
0050     Okular::NormalizedPoint m_deltaB;
0051 
0052     QList<Okular::NormalizedPoint> m_origPoints1;
0053     QList<Okular::NormalizedPoint> m_origPoints2;
0054 
0055     QList<Okular::NormalizedPoint> m_points1DeltaA;
0056     QList<Okular::NormalizedPoint> m_points1DeltaAB;
0057     QList<Okular::NormalizedPoint> m_points2DeltaA;
0058     QList<Okular::NormalizedPoint> m_points2DeltaAB;
0059 };
0060 
0061 void TranslateAnnotationTest::initTestCase()
0062 {
0063     Okular::SettingsCore::instance(QStringLiteral("editannotationcontentstest"));
0064     m_document = new Okular::Document(nullptr);
0065 
0066     // translate m_annot1
0067     m_deltaA = Okular::NormalizedPoint(0.05, 0.1);
0068     m_deltaB = Okular::NormalizedPoint(0.1, 0.2);
0069 
0070     // Build lists of expected points for various states
0071     m_origPoints1 = {Okular::NormalizedPoint(0.1, 0.1), Okular::NormalizedPoint(0.2, 0.3)};
0072 
0073     m_points1DeltaA = {Okular::NormalizedPoint(0.15, 0.2), Okular::NormalizedPoint(0.25, 0.4)};
0074 
0075     m_points1DeltaAB = {Okular::NormalizedPoint(0.25, 0.4), Okular::NormalizedPoint(0.35, 0.6)};
0076 
0077     m_origPoints2 = {Okular::NormalizedPoint(0.1, 0.1), Okular::NormalizedPoint(0.3, 0.4)};
0078 
0079     m_points2DeltaA = {Okular::NormalizedPoint(0.15, 0.2), Okular::NormalizedPoint(0.35, 0.5)};
0080 
0081     m_points2DeltaAB = {Okular::NormalizedPoint(0.25, 0.4), Okular::NormalizedPoint(0.45, 0.7)};
0082 }
0083 
0084 void TranslateAnnotationTest::cleanupTestCase()
0085 {
0086     delete m_document;
0087 }
0088 
0089 void TranslateAnnotationTest::init()
0090 {
0091     const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf");
0092     QMimeDatabase db;
0093     const QMimeType mime = db.mimeTypeForFile(testFile);
0094     QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess);
0095 
0096     // Undo and Redo should be unavailable when docuemnt is first opened.
0097     QVERIFY(!m_document->canUndo());
0098     QVERIFY(!m_document->canRedo());
0099 
0100     // Create two distinct line annotations and add them to the document
0101     m_annot1 = getNewLineAnnotation(m_origPoints1.first().x, m_origPoints1.first().y, m_origPoints1.last().x, m_origPoints1.last().y);
0102     m_document->addPageAnnotation(0, m_annot1);
0103 
0104     m_annot2 = getNewLineAnnotation(m_origPoints2.first().x, m_origPoints2.first().y, m_origPoints2.last().x, m_origPoints2.last().y);
0105     m_document->addPageAnnotation(0, m_annot2);
0106 }
0107 
0108 void TranslateAnnotationTest::cleanup()
0109 {
0110     m_document->closeDocument();
0111     // m_annot1 and m_annot2 are deleted when document is closed
0112 }
0113 
0114 void TranslateAnnotationTest::testTranslateAnnotation()
0115 {
0116     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0117     m_document->translatePageAnnotation(0, m_annot1, m_deltaA);
0118     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0119 
0120     // undo and ensure m_annot1 is back to where it started
0121     m_document->undo();
0122     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0123 
0124     // redo then translate m_annot1 by m_deltaB
0125     m_document->redo();
0126     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0127 }
0128 
0129 void TranslateAnnotationTest::testSequentialTranslationsMergedIfBeingMovedIsSet()
0130 {
0131     // mark m_annot1 as BeingMoved but not m_annot2
0132     m_annot1->setFlags(m_annot1->flags() | Okular::Annotation::BeingMoved);
0133 
0134     // Verify initial positions
0135     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0136     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2));
0137 
0138     // Translate m_annot1 by m_deltaA then m_deltaB
0139     m_document->translatePageAnnotation(0, m_annot1, m_deltaA);
0140     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0141     m_document->translatePageAnnotation(0, m_annot1, m_deltaB);
0142     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB));
0143 
0144     // Now undo and verify that these two translations were merged into one undo command
0145     m_document->undo();
0146     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0147 }
0148 
0149 void TranslateAnnotationTest::testSequentialTranslationsNotMergedIfBeingMovedIsNotSet()
0150 {
0151     // mark m_annot1 as not BeingMoved
0152     m_annot1->setFlags(m_annot1->flags() & ~Okular::Annotation::BeingMoved);
0153 
0154     // Verify initial positions
0155     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0156     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2));
0157 
0158     // Translate m_annot1 by m_deltaA then m_deltaB
0159     m_document->translatePageAnnotation(0, m_annot1, m_deltaA);
0160     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0161     m_document->translatePageAnnotation(0, m_annot1, m_deltaB);
0162     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB));
0163 
0164     // Now undo and verify that these two translations were NOT merged into one undo command
0165     m_document->undo();
0166     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0167 
0168     m_document->undo();
0169     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0170 }
0171 
0172 void TranslateAnnotationTest::testAlternateTranslationsNotMerged()
0173 {
0174     // Set both m_annot1 and m_annot2 to BeingMoved
0175     m_annot1->setFlags(m_annot1->flags() | Okular::Annotation::BeingMoved);
0176     m_annot2->setFlags(m_annot2->flags() | Okular::Annotation::BeingMoved);
0177 
0178     m_document->translatePageAnnotation(0, m_annot1, m_deltaA);
0179     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0180     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2));
0181     m_document->translatePageAnnotation(0, m_annot2, m_deltaA);
0182     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0183     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA));
0184     m_document->translatePageAnnotation(0, m_annot1, m_deltaB);
0185     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB));
0186     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA));
0187     m_document->translatePageAnnotation(0, m_annot2, m_deltaB);
0188     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB));
0189     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaAB));
0190 
0191     // First undo should move only m_annot2 back by m_deltaB
0192     m_document->undo();
0193     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB));
0194     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA));
0195 
0196     // Next undo should move only m_annot1 back by m_deltaB
0197     m_document->undo();
0198     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0199     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA));
0200 
0201     // Next Undo should move only m_annot2 back to its original location
0202     m_document->undo();
0203     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA));
0204     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2));
0205 
0206     // Next undo should move m_annot1 back to its original location
0207     m_document->undo();
0208     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1));
0209     QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2));
0210 }
0211 
0212 QTEST_MAIN(TranslateAnnotationTest)
0213 #include "translateannotationtest.moc"