diff --git a/autotests/data/additionalFormActions.pdf b/autotests/data/additionalFormActions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c26379dd715ae720ffbbad63e1cc13d17f4a865d GIT binary patch literal 45857 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 G6#pM=o`Q`4 literal 0 Hc$@visibleRegion().rects().count() == 4); } +// Helper for testAdditionalActionTriggers +static void verifyTargetStates( const QString & triggerName, + const QMap &fields, + bool focusVisible, bool cursorVisible, bool mouseVisible, + int line) +{ + Okular::FormField *focusTarget = fields.value( triggerName + QStringLiteral ("_focus_target") ); + Okular::FormField *cursorTarget = fields.value( triggerName + QStringLiteral ("_cursor_target") ); + Okular::FormField *mouseTarget = fields.value( triggerName + QStringLiteral ("_mouse_target") ); + + QVERIFY( focusTarget ); + QVERIFY( cursorTarget ); + QVERIFY( mouseTarget ); + + QVERIFY2( focusTarget->isVisible() == focusVisible, + QStringLiteral ("line: %1 focus for %2 not matched. Expected %3 Actual %4"). + arg( line ).arg( triggerName ).arg( focusTarget->isVisible() ).arg( focusVisible ).toUtf8().constData() ); + QVERIFY2( cursorTarget->isVisible() == cursorVisible, + QStringLiteral ("line: %1 cursor for %2 not matched. Actual %3 Expected %4"). + arg( line ).arg( triggerName ).arg( cursorTarget->isVisible() ).arg( cursorVisible ).toUtf8().constData() ); + QVERIFY2( mouseTarget->isVisible() == mouseVisible, + QStringLiteral ("line: %1 mouse for %2 not matched. Expected %3 Actual %4"). + arg( line ).arg( triggerName ).arg( mouseTarget->isVisible() ).arg( mouseVisible ).toUtf8().constData() ); } +void PartTest::testAdditionalActionTriggers() +{ +#ifndef HAVE_POPPLER_0_65 + return; +#endif + const QString testFile = QStringLiteral( KDESRCDIR "data/additionalFormActions.pdf" ); + Okular::Part part( nullptr, nullptr, QVariantList() ); + part.openDocument( testFile ); + part.widget()->resize(800, 600); + + part.widget()->show(); + QVERIFY( QTest::qWaitForWindowExposed( part.widget() ) ); + + QMap fields; + // Field names in test document are: + // For trigger fields: tf, cb, rb, dd, pb + // For target fields: _focus_target, _cursor_target, + // _mouse_target + const Okular::Page* page = part.m_document->page( 0 ); + for ( Okular::FormField *ff: page->formFields() ) + { + fields.insert( ff->name(), static_cast< Okular::FormField* >( ff ) ); + } + + // Verify that everything is set up. + verifyTargetStates( QStringLiteral( "tf" ), fields, true, true, true, __LINE__ ); + verifyTargetStates( QStringLiteral( "cb" ), fields, true, true, true, __LINE__ ); + verifyTargetStates( QStringLiteral( "rb" ), fields, true, true, true, __LINE__ ); + verifyTargetStates( QStringLiteral( "dd" ), fields, true, true, true, __LINE__ ); + verifyTargetStates( QStringLiteral( "pb" ), fields, true, true, true, __LINE__ ); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + + part.m_pageView->viewport()->height(); + + part.m_document->setViewportPage( 0 ); + + // wait for pixmap + QTRY_VERIFY( part.m_document->page( 0 )->hasPixmap( part.m_pageView) ); + + part.actionCollection()->action( QStringLiteral( "view_toggle_forms" ) )->trigger(); + QTest::qWait( 100 ); + + QPoint tfPos( width * 0.045, height * 0.05 ); + QPoint cbPos( width * 0.045, height * 0.08 ); + QPoint rbPos( width * 0.045, height * 0.12 ); + QPoint ddPos( width * 0.045, height * 0.16 ); + QPoint pbPos( width * 0.045, height * 0.26 ); + + // Test text field + auto widget = part.m_pageView->viewport()->childAt( tfPos ); + QVERIFY( widget ); + + QTest::mouseMove( part.m_pageView->viewport(), QPoint( tfPos )); + QTest::qWait( 100 ); + verifyTargetStates( QStringLiteral( "tf" ), fields, true, false, true, __LINE__ ); + QTest::mousePress( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "tf" ), fields, false, false, false, __LINE__ ); + QTest::mouseRelease( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "tf" ), fields, false, false, true, __LINE__ ); + + // Checkbox + widget = part.m_pageView->viewport()->childAt( cbPos ); + QVERIFY( widget ); + + QTest::mouseMove( part.m_pageView->viewport(), QPoint( cbPos ) ); + QTest::qWait( 100 ); + verifyTargetStates( QStringLiteral( "cb" ), fields, true, false, true, __LINE__ ); + QTest::mousePress( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "cb" ), fields, false, false, false, __LINE__ ); + // Confirm that the textfield no longer has any invisible + verifyTargetStates( QStringLiteral( "tf" ), fields, true, true, true, __LINE__ ); + QTest::mouseRelease( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "cb" ), fields, false, false, true, __LINE__ ); + + // Radio + widget = part.m_pageView->viewport()->childAt( rbPos ); + QVERIFY( widget ); + + QTest::mouseMove( part.m_pageView->viewport(), QPoint( rbPos ) ); + QTest::qWait( 100 ); + verifyTargetStates( QStringLiteral( "rb" ), fields, true, false, true, __LINE__ ); + QTest::mousePress( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "rb" ), fields, false, false, false, __LINE__ ); + QTest::mouseRelease( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "rb" ), fields, false, false, true, __LINE__ ); + + // Dropdown + widget = part.m_pageView->viewport()->childAt( ddPos ); + QVERIFY( widget ); + + QTest::mouseMove( part.m_pageView->viewport(), QPoint( ddPos ) ); + QTest::qWait( 100 ); + verifyTargetStates( QStringLiteral( "dd" ), fields, true, false, true, __LINE__ ); + QTest::mousePress( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "dd" ), fields, false, false, false, __LINE__ ); + QTest::mouseRelease( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "dd" ), fields, false, false, true, __LINE__ ); + + // Pushbutton + widget = part.m_pageView->viewport()->childAt( pbPos ); + QVERIFY( widget ); + + QTest::mouseMove( part.m_pageView->viewport(), QPoint( pbPos ) ); + QTest::qWait( 100 ); + verifyTargetStates( QStringLiteral( "pb" ), fields, true, false, true, __LINE__ ); + QTest::mousePress( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "pb" ), fields, false, false, false, __LINE__ ); + QTest::mouseRelease( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "pb" ), fields, false, false, true, __LINE__ ); + + // Confirm that a mouse release outside does not trigger the show action. + QTest::mousePress( widget, Qt::LeftButton, Qt::NoModifier, QPoint( 5, 5 ) ); + verifyTargetStates( QStringLiteral( "pb" ), fields, false, false, false, __LINE__ ); + QTest::mouseRelease( part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, tfPos ); + verifyTargetStates( QStringLiteral( "pb" ), fields, false, false, false, __LINE__ ); +} + +} // namespace Okular + int main(int argc, char *argv[]) { // Force consistent locale