mirror of
https://invent.kde.org/graphics/okular
synced 2024-08-24 18:35:37 +00:00
Add support for chained / next actions
Summary: This adds support for multiple actions following each other through the "Next" value of Action dictionaries. Test Plan: Activates the corresponding part of the visibilitytest. Reviewers: #okular Subscribers: sander, aacid Tags: #okular Maniphest Tasks: T8278 Differential Revision: https://phabricator.kde.org/D11609
This commit is contained in:
parent
cc052577a4
commit
1de0f5465b
|
@ -166,15 +166,7 @@ void VisibilityTest::testActionVisibility()
|
|||
|
||||
m_document->processAction( hideBtn->activationAction() );
|
||||
|
||||
// XXX For now poppler only provides the first action
|
||||
// in a chain. So only the first hide action is executed.
|
||||
// The first hide action targets the Button. So for now
|
||||
// only check this.
|
||||
//
|
||||
// This should work in principle:
|
||||
// verifyTargetStates( false );
|
||||
|
||||
QCOMPARE( m_fields[QStringLiteral( "TargetButton" )]->isVisible(), false );
|
||||
verifyTargetStates( false );
|
||||
|
||||
m_document->processAction( showBtn->activationAction() );
|
||||
|
||||
|
|
|
@ -29,9 +29,11 @@ class Okular::ActionPrivate
|
|||
|
||||
virtual ~ActionPrivate()
|
||||
{
|
||||
qDeleteAll( m_nextActions );
|
||||
}
|
||||
|
||||
QVariant m_nativeId;
|
||||
QVector< Action * > m_nextActions;
|
||||
};
|
||||
|
||||
Action::Action( ActionPrivate &dd )
|
||||
|
@ -61,6 +63,18 @@ QVariant Action::nativeId() const
|
|||
return d->m_nativeId;
|
||||
}
|
||||
|
||||
QVector< Action * > Action::nextActions() const
|
||||
{
|
||||
Q_D( const Action );
|
||||
return d->m_nextActions;
|
||||
}
|
||||
|
||||
void Action::setNextActions( const QVector< Action * > &actions )
|
||||
{
|
||||
Q_D( Action );
|
||||
d->m_nextActions = actions;
|
||||
}
|
||||
|
||||
// GotoAction
|
||||
|
||||
class Okular::GotoActionPrivate : public Okular::ActionPrivate
|
||||
|
|
|
@ -97,6 +97,21 @@ class OKULARCORE_EXPORT Action
|
|||
*/
|
||||
QVariant nativeId() const;
|
||||
|
||||
/**
|
||||
* Returns the next actions to be executed after.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
QVector< Action * > nextActions() const;
|
||||
|
||||
/**
|
||||
* Sets the next actions.
|
||||
*
|
||||
* Takes ownership of the objects in the actions vector.
|
||||
* @since 1.5
|
||||
*/
|
||||
void setNextActions( const QVector< Action * > &actions );
|
||||
|
||||
protected:
|
||||
/// @cond PRIVATE
|
||||
Action( ActionPrivate &dd );
|
||||
|
|
|
@ -4074,14 +4074,14 @@ void Document::processAction( const Action * action )
|
|||
if ( go->isExternal() && !d->openRelativeFile( go->fileName() ) )
|
||||
{
|
||||
qCWarning(OkularCoreDebug).nospace() << "Action: Error opening '" << go->fileName() << "'.";
|
||||
return;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const DocumentViewport nextViewport = d->nextDocumentViewport();
|
||||
// skip local links that point to nowhere (broken ones)
|
||||
if ( !nextViewport.isValid() )
|
||||
return;
|
||||
break;
|
||||
|
||||
setViewport( nextViewport, nullptr, true );
|
||||
d->m_nextDocumentViewport = DocumentViewport();
|
||||
|
@ -4096,7 +4096,7 @@ void Document::processAction( const Action * action )
|
|||
if ( fileName.endsWith( QLatin1String(".pdf"), Qt::CaseInsensitive ) )
|
||||
{
|
||||
d->openRelativeFile( fileName );
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
// Albert: the only pdf i have that has that kind of link don't define
|
||||
|
@ -4118,7 +4118,7 @@ void Document::processAction( const Action * action )
|
|||
// this case is a link pointing to an executable with a parameter
|
||||
// that also is an executable, possibly a hand-crafted pdf
|
||||
KMessageBox::information( d->m_widget, i18n("The document is trying to execute an external application and, for your safety, Okular does not allow that.") );
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4126,7 +4126,7 @@ void Document::processAction( const Action * action )
|
|||
// this case is a link pointing to an executable with no parameters
|
||||
// core developers find unacceptable executing it even after asking the user
|
||||
KMessageBox::information( d->m_widget, i18n("The document is trying to execute an external application and, for your safety, Okular does not allow that.") );
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4208,7 +4208,7 @@ void Document::processAction( const Action * action )
|
|||
if ((url.scheme() == "http") && url.host().isEmpty() && url.fileName().endsWith("pdf"))
|
||||
{
|
||||
d->openRelativeFile(url.fileName());
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
// handle documents with relative path
|
||||
|
@ -4252,6 +4252,11 @@ void Document::processAction( const Action * action )
|
|||
} break;
|
||||
|
||||
}
|
||||
|
||||
for ( const Action *a : action->nextActions() )
|
||||
{
|
||||
processAction( a );
|
||||
}
|
||||
}
|
||||
|
||||
void Document::processSourceReference( const SourceReference * ref )
|
||||
|
|
|
@ -75,11 +75,14 @@ int main()
|
|||
check_cxx_source_compiles("
|
||||
#include <poppler-qt5.h>
|
||||
#include <poppler-form.h>
|
||||
#include <poppler-link.h>
|
||||
int main()
|
||||
{
|
||||
Poppler::FormField *f;
|
||||
f->setReadOnly(true);
|
||||
f->setVisible(true);
|
||||
Poppler::Link *l;
|
||||
l->nextLinks();
|
||||
}
|
||||
" HAVE_POPPLER_0_64)
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <config-okular-poppler.h>
|
||||
|
||||
extern Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink);
|
||||
extern Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink, bool deletePopplerLink = true);
|
||||
|
||||
#ifdef HAVE_POPPLER_0_53
|
||||
#define SET_ACTIONS \
|
||||
|
|
|
@ -311,7 +311,7 @@ QPair<Okular::Movie*, Okular::EmbeddedFile*> createMovieFromPopplerRichMedia( co
|
|||
/**
|
||||
* Note: the function will take ownership of the popplerLink object.
|
||||
*/
|
||||
Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
|
||||
Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink, bool deletePopplerLink = true)
|
||||
{
|
||||
if (!popplerLink)
|
||||
return nullptr;
|
||||
|
@ -327,8 +327,6 @@ Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
|
|||
const Poppler::LinkRendition *popplerLinkRendition;
|
||||
Okular::DocumentViewport viewport;
|
||||
|
||||
bool deletePopplerLink = true;
|
||||
|
||||
switch(popplerLink->linkType())
|
||||
{
|
||||
case Poppler::Link::None:
|
||||
|
@ -384,6 +382,17 @@ Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
|
|||
|
||||
case Poppler::Link::Rendition:
|
||||
{
|
||||
if (!deletePopplerLink)
|
||||
{
|
||||
// If links should not be deleted it probably means that they
|
||||
// are part of a nextActions chain. There is no support
|
||||
// to resolveMediaLinkReferences on nextActions. It would also
|
||||
// be neccessary to ensure that resolveMediaLinkReferences does
|
||||
// not delete the Links which are part of a nextActions list
|
||||
// to avoid a double deletion.
|
||||
qCDebug(OkularPdfDebug) << "parsing rendition link without deletion is not supported. Action chain might be broken.";
|
||||
break;
|
||||
}
|
||||
deletePopplerLink = false; // we'll delete it inside resolveMediaLinkReferences() after we have resolved all references
|
||||
|
||||
popplerLinkRendition = static_cast<const Poppler::LinkRendition *>( popplerLink );
|
||||
|
@ -420,6 +429,12 @@ Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
|
|||
|
||||
case Poppler::Link::Movie:
|
||||
{
|
||||
if (!deletePopplerLink)
|
||||
{
|
||||
// See comment above in Link::Rendition
|
||||
qCDebug(OkularPdfDebug) << "parsing movie link without deletion is not supported. Action chain might be broken.";
|
||||
break;
|
||||
}
|
||||
deletePopplerLink = false; // we'll delete it inside resolveMediaLinkReferences() after we have resolved all references
|
||||
|
||||
popplerLinkMovie = static_cast<const Poppler::LinkMovie *>( popplerLink );
|
||||
|
@ -462,6 +477,18 @@ Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_POPPLER_0_64
|
||||
if (link)
|
||||
{
|
||||
QVector< Okular::Action * > nextActions;
|
||||
for ( const Poppler::Link *nl : popplerLink->nextLinks() )
|
||||
{
|
||||
nextActions << createLinkFromPopplerLink( nl, false );
|
||||
}
|
||||
link->setNextActions( nextActions );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( deletePopplerLink )
|
||||
delete popplerLink;
|
||||
|
||||
|
|
Loading…
Reference in a new issue