Commit b7249ce8 authored by Joao Oliveira's avatar Joao Oliveira Committed by Albert Astals Cid

Implemented support for keystroke actions

parent da487f3a
...@@ -4362,6 +4362,50 @@ void Document::processFormatAction( const Action * action, Okular::FormFieldText ...@@ -4362,6 +4362,50 @@ void Document::processFormatAction( const Action * action, Okular::FormFieldText
} }
} }
void Document::processKeystrokeAction( const Action * action, Okular::FormFieldText *fft, bool &returnCode )
{
if ( action->actionType() != Action::Script )
{
qCDebug( OkularCoreDebug ) << "Unsupported action type" << action->actionType() << "for keystroke.";
return;
}
// Lookup the page of the FormFieldText
int foundPage = -1;
for ( uint pageIdx = 0, nPages = pages(); pageIdx < nPages; pageIdx++ )
{
const Page *p = page( pageIdx );
if ( p && p->formFields().contains( fft ) )
{
foundPage = static_cast< int >( pageIdx );
break;
}
}
if ( foundPage == -1 )
{
qCDebug( OkularCoreDebug ) << "Could not find page for formfield!";
return;
}
std::shared_ptr< Event > event = Event::createKeystrokeEvent( fft, d->m_pagesVector[foundPage] );
const ScriptAction * linkscript = static_cast< const ScriptAction * >( action );
if ( !d->m_scripter )
{
d->m_scripter = new Scripter( d );
}
d->m_scripter->setEvent( event.get() );
d->m_scripter->execute( linkscript->scriptType(), linkscript->script() );
// Clear out the event after execution
d->m_scripter->setEvent( nullptr );
returnCode = event->returnCode();
if( returnCode )
{
fft->setInternalText( fft->text() );
}
}
void Document::processSourceReference( const SourceReference * ref ) void Document::processSourceReference( const SourceReference * ref )
{ {
if ( !ref ) if ( !ref )
......
...@@ -675,6 +675,13 @@ class OKULARCORE_EXPORT Document : public QObject ...@@ -675,6 +675,13 @@ class OKULARCORE_EXPORT Document : public QObject
*/ */
void processFormatAction( const Action *action, Okular::FormFieldText *field ); void processFormatAction( const Action *action, Okular::FormFieldText *field );
/**
* Processes the given keystroke @p action on @p field.
*
* @since 1.9
*/
void processKeystrokeAction( const Action *action, Okular::FormFieldText *field, bool &returnCode );
/** /**
* Returns a list of the bookmarked.pages * Returns a list of the bookmarked.pages
*/ */
......
...@@ -20,7 +20,8 @@ class Event::Private ...@@ -20,7 +20,8 @@ class Event::Private
m_targetPage( nullptr ), m_targetPage( nullptr ),
m_source( nullptr ), m_source( nullptr ),
m_sourcePage( nullptr ), m_sourcePage( nullptr ),
m_eventType( eventType ) m_eventType( eventType ),
m_returnCode( false )
{ {
} }
...@@ -31,6 +32,7 @@ class Event::Private ...@@ -31,6 +32,7 @@ class Event::Private
EventType m_eventType; EventType m_eventType;
QString m_targetName; QString m_targetName;
QVariant m_value; QVariant m_value;
bool m_returnCode;
}; };
Event::Event(): d( new Private( UnknownEvent ) ) Event::Event(): d( new Private( UnknownEvent ) )
...@@ -55,6 +57,8 @@ QString Event::name() const ...@@ -55,6 +57,8 @@ QString Event::name() const
return QStringLiteral( "Calculate" ); return QStringLiteral( "Calculate" );
case ( FieldFormat ): case ( FieldFormat ):
return QStringLiteral( "Format" ); return QStringLiteral( "Format" );
case ( FieldKeystroke ):
return QStringLiteral( "Keystroke" );
case ( UnknownEvent ): case ( UnknownEvent ):
default: default:
return QStringLiteral( "Unknown" ); return QStringLiteral( "Unknown" );
...@@ -67,6 +71,7 @@ QString Event::type() const ...@@ -67,6 +71,7 @@ QString Event::type() const
{ {
case ( FieldCalculate ): case ( FieldCalculate ):
case ( FieldFormat ): case ( FieldFormat ):
case ( FieldKeystroke ):
return QStringLiteral( "Field" ); return QStringLiteral( "Field" );
case ( UnknownEvent ): case ( UnknownEvent ):
default: default:
...@@ -139,6 +144,16 @@ void Event::setValue( const QVariant &val ) ...@@ -139,6 +144,16 @@ void Event::setValue( const QVariant &val )
d->m_value = val; d->m_value = val;
} }
bool Event::returnCode() const
{
return d->m_returnCode;
}
void Event::setReturnCode( bool returnCode )
{
d->m_returnCode = returnCode;
}
// static // static
std::shared_ptr<Event> Event::createFormCalculateEvent( FormField *target, std::shared_ptr<Event> Event::createFormCalculateEvent( FormField *target,
Page *targetPage, Page *targetPage,
...@@ -178,3 +193,19 @@ std::shared_ptr<Event> Event::createFormatEvent( FormField *target, ...@@ -178,3 +193,19 @@ std::shared_ptr<Event> Event::createFormatEvent( FormField *target,
} }
return ret; return ret;
} }
// static
std::shared_ptr<Event> Event::createKeystrokeEvent( FormField *target, Page *targetPage )
{
std::shared_ptr<Event> ret( new Event( Event::FieldKeystroke ) );
ret->setTarget( target );
ret->setTargetPage( targetPage );
FormFieldText *fft = dynamic_cast< FormFieldText * >(target);
if ( fft )
{
ret->setReturnCode( true );
ret->setValue( QVariant( fft->text() ) );
}
return ret;
}
...@@ -58,7 +58,7 @@ class Event ...@@ -58,7 +58,7 @@ class Event
FieldCalculate, /// < This event is defined in a field re-calculation. FieldCalculate, /// < This event is defined in a field re-calculation.
FieldFocus, /// < Not implemented. FieldFocus, /// < Not implemented.
FieldFormat, /// < When a format action is executed FieldFormat, /// < When a format action is executed
FieldKeystroke, /// < Not implemented. FieldKeystroke, /// < Checks if the entered value is valid.
FieldMouseDown, /// < Not implemented. FieldMouseDown, /// < Not implemented.
FieldMouseEnter, /// < Not implemented. FieldMouseEnter, /// < Not implemented.
FieldMouseExit, /// < Not implemented. FieldMouseExit, /// < Not implemented.
...@@ -97,6 +97,9 @@ class Event ...@@ -97,6 +97,9 @@ class Event
QVariant value() const; QVariant value() const;
void setValue(const QVariant &val); void setValue(const QVariant &val);
bool returnCode() const;
void setReturnCode(bool returnCode);
static std::shared_ptr<Event> createFormCalculateEvent( FormField *target, static std::shared_ptr<Event> createFormCalculateEvent( FormField *target,
Page *targetPage, Page *targetPage,
FormField *source = nullptr, FormField *source = nullptr,
...@@ -104,6 +107,7 @@ class Event ...@@ -104,6 +107,7 @@ class Event
const QString &targetName = QString() ); const QString &targetName = QString() );
static std::shared_ptr<Event> createFormatEvent( FormField *target, Page *targetPage, static std::shared_ptr<Event> createFormatEvent( FormField *target, Page *targetPage,
const QString &targetName = QString() ); const QString &targetName = QString() );
static std::shared_ptr<Event> createKeystrokeEvent( FormField *target, Page *targetPage );
private: private:
class Private; class Private;
std::shared_ptr<Private> d; std::shared_ptr<Private> d;
......
...@@ -66,11 +66,17 @@ static KJSObject eventGetSource( KJSContext *ctx, void *object ) ...@@ -66,11 +66,17 @@ static KJSObject eventGetSource( KJSContext *ctx, void *object )
static KJSObject eventGetTarget( KJSContext *ctx, void *object ) static KJSObject eventGetTarget( KJSContext *ctx, void *object )
{ {
const Event *event = reinterpret_cast< Event * >( object ); const Event *event = reinterpret_cast< Event * >( object );
if ( event->eventType() == Event::FieldCalculate ) switch( event->eventType() )
{ {
FormField *target = static_cast< FormField * >( event->target() ); case Event::FieldCalculate:
if ( target ) case Event::FieldFormat:
return JSField::wrapField( ctx, target, event->targetPage() ); case Event::FieldKeystroke:
{
FormField *target = static_cast< FormField * >( event->target() );
if ( target )
return JSField::wrapField( ctx, target, event->targetPage() );
break;
}
} }
return KJSUndefined(); return KJSUndefined();
} }
...@@ -89,6 +95,20 @@ static void eventSetValue( KJSContext *ctx, void *object, KJSObject value ) ...@@ -89,6 +95,20 @@ static void eventSetValue( KJSContext *ctx, void *object, KJSObject value )
event->setValue ( QVariant( value.toString ( ctx ) ) ); event->setValue ( QVariant( value.toString ( ctx ) ) );
} }
// Event.rc (getter)
static KJSObject eventGetReturnCode( KJSContext *, void *object )
{
const Event *event = reinterpret_cast< Event * >( object );
return KJSBoolean( event->returnCode() );
}
// Event.rc (setter)
static void eventSetReturnCode( KJSContext *ctx, void *object, KJSObject value )
{
Event *event = reinterpret_cast< Event * >( object );
event->setReturnCode ( value.toBoolean ( ctx ) );
}
void JSEvent::initType( KJSContext *ctx ) void JSEvent::initType( KJSContext *ctx )
{ {
static bool initialized = false; static bool initialized = false;
...@@ -106,6 +126,7 @@ void JSEvent::initType( KJSContext *ctx ) ...@@ -106,6 +126,7 @@ void JSEvent::initType( KJSContext *ctx )
g_eventProto->defineProperty( ctx, QStringLiteral( "source" ), eventGetSource ); g_eventProto->defineProperty( ctx, QStringLiteral( "source" ), eventGetSource );
g_eventProto->defineProperty( ctx, QStringLiteral( "target" ), eventGetTarget ); g_eventProto->defineProperty( ctx, QStringLiteral( "target" ), eventGetTarget );
g_eventProto->defineProperty( ctx, QStringLiteral( "value" ), eventGetValue, eventSetValue ); g_eventProto->defineProperty( ctx, QStringLiteral( "value" ), eventGetValue, eventSetValue );
g_eventProto->defineProperty( ctx, QStringLiteral( "rc" ), eventGetReturnCode, eventSetReturnCode );
} }
KJSObject JSEvent::wrapEvent( KJSContext *ctx, Event *event ) KJSObject JSEvent::wrapEvent( KJSContext *ctx, Event *event )
......
...@@ -292,6 +292,7 @@ void PopplerFormFieldText::setText( const QString& text ) ...@@ -292,6 +292,7 @@ void PopplerFormFieldText::setText( const QString& text )
m_field->setText( text ); m_field->setText( text );
} }
bool PopplerFormFieldText::isPassword() const bool PopplerFormFieldText::isPassword() const
{ {
return m_field->isPassword(); return m_field->isPassword();
......
...@@ -471,6 +471,7 @@ FormLineEdit::FormLineEdit( Okular::FormFieldText * text, QWidget * parent ) ...@@ -471,6 +471,7 @@ FormLineEdit::FormLineEdit( Okular::FormFieldText * text, QWidget * parent )
m_prevCursorPos = cursorPosition(); m_prevCursorPos = cursorPosition();
m_prevAnchorPos = cursorPosition(); m_prevAnchorPos = cursorPosition();
m_editing = false;
connect( this, &QLineEdit::textEdited, this, &FormLineEdit::slotChanged ); connect( this, &QLineEdit::textEdited, this, &FormLineEdit::slotChanged );
connect( this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged ); connect( this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged );
...@@ -505,9 +506,11 @@ bool FormLineEdit::event( QEvent* e ) ...@@ -505,9 +506,11 @@ bool FormLineEdit::event( QEvent* e )
{ {
const auto fft = static_cast< Okular::FormFieldText * > ( m_ff ); const auto fft = static_cast< Okular::FormFieldText * > ( m_ff );
setText( fft->internalText() ); setText( fft->internalText() );
m_editing = true;
} }
else if ( e->type() == QEvent::FocusOut ) else if ( e->type() == QEvent::FocusOut )
{ {
m_editing = false;
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) ) if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{ {
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) ); emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
...@@ -549,6 +552,21 @@ void FormLineEdit::slotChanged() ...@@ -549,6 +552,21 @@ void FormLineEdit::slotChanged()
Okular::FormFieldText *form = static_cast<Okular::FormFieldText *>(m_ff); Okular::FormFieldText *form = static_cast<Okular::FormFieldText *>(m_ff);
QString contents = text(); QString contents = text();
int cursorPos = cursorPosition(); int cursorPos = cursorPosition();
if( form->additionalAction( Okular::FormField::FieldModified ) && m_editing && !form->isReadOnly() )
{
bool ok = false;
QString oldText = form->text();
form->setText( text() );
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok );
form->setText( oldText );
if(!ok)
{
setText( oldText );
return;
}
}
if ( contents != form->text() ) if ( contents != form->text() )
{ {
m_controller->formTextChangedByWidget( pageItem()->pageNumber(), m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
...@@ -618,6 +636,7 @@ TextAreaEdit::TextAreaEdit( Okular::FormFieldText * text, QWidget * parent ) ...@@ -618,6 +636,7 @@ TextAreaEdit::TextAreaEdit( Okular::FormFieldText * text, QWidget * parent )
this, &TextAreaEdit::slotUpdateUndoAndRedoInContextMenu ); this, &TextAreaEdit::slotUpdateUndoAndRedoInContextMenu );
m_prevCursorPos = textCursor().position(); m_prevCursorPos = textCursor().position();
m_prevAnchorPos = textCursor().anchor(); m_prevAnchorPos = textCursor().anchor();
m_editing = false;
setVisible( text->isVisible() ); setVisible( text->isVisible() );
} }
...@@ -649,9 +668,11 @@ bool TextAreaEdit::event( QEvent* e ) ...@@ -649,9 +668,11 @@ bool TextAreaEdit::event( QEvent* e )
{ {
const auto fft = static_cast< Okular::FormFieldText * > ( m_ff ); const auto fft = static_cast< Okular::FormFieldText * > ( m_ff );
setText( fft->internalText() ); setText( fft->internalText() );
m_editing = true;
} }
else if ( e->type() == QEvent::FocusOut ) else if ( e->type() == QEvent::FocusOut )
{ {
m_editing = false;
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) ) if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{ {
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) ); emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
...@@ -718,6 +739,21 @@ void TextAreaEdit::slotChanged() ...@@ -718,6 +739,21 @@ void TextAreaEdit::slotChanged()
Okular::FormFieldText *form = static_cast<Okular::FormFieldText *>(m_ff); Okular::FormFieldText *form = static_cast<Okular::FormFieldText *>(m_ff);
QString contents = toPlainText(); QString contents = toPlainText();
int cursorPos = textCursor().position(); int cursorPos = textCursor().position();
if( form->additionalAction( Okular::FormField::FieldModified ) && m_editing && !form->isReadOnly() )
{
bool ok = false;
QString oldText = form->text();
form->setText( toPlainText() );
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok );
form->setText( oldText );
if(!ok)
{
setText( oldText );
return;
}
}
if (contents != form->text()) if (contents != form->text())
{ {
m_controller->formTextChangedByWidget( pageItem()->pageNumber(), m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
......
...@@ -118,6 +118,8 @@ class FormWidgetsController : public QObject ...@@ -118,6 +118,8 @@ class FormWidgetsController : public QObject
void formatAction( const Okular::Action *action, Okular::FormFieldText *ff ); void formatAction( const Okular::Action *action, Okular::FormFieldText *ff );
void keystrokeAction( const Okular::Action *action, Okular::FormFieldText *ff, bool &ok );
void refreshFormWidget( Okular::FormField * form ); void refreshFormWidget( Okular::FormField * form );
private Q_SLOTS: private Q_SLOTS:
...@@ -250,6 +252,7 @@ class FormLineEdit : public QLineEdit, public FormWidgetIface ...@@ -250,6 +252,7 @@ class FormLineEdit : public QLineEdit, public FormWidgetIface
private: private:
int m_prevCursorPos; int m_prevCursorPos;
int m_prevAnchorPos; int m_prevAnchorPos;
bool m_editing;
DECLARE_ADDITIONAL_ACTIONS DECLARE_ADDITIONAL_ACTIONS
}; };
...@@ -281,6 +284,7 @@ class TextAreaEdit : public KTextEdit, public FormWidgetIface ...@@ -281,6 +284,7 @@ class TextAreaEdit : public KTextEdit, public FormWidgetIface
private: private:
int m_prevCursorPos; int m_prevCursorPos;
int m_prevAnchorPos; int m_prevAnchorPos;
bool m_editing;
DECLARE_ADDITIONAL_ACTIONS DECLARE_ADDITIONAL_ACTIONS
}; };
......
...@@ -268,6 +268,10 @@ FormWidgetsController* PageViewPrivate::formWidgetsController() ...@@ -268,6 +268,10 @@ FormWidgetsController* PageViewPrivate::formWidgetsController()
q, [this] (const Okular::Action *action, Okular::FormFieldText *fft ) { q, [this] (const Okular::Action *action, Okular::FormFieldText *fft ) {
document->processFormatAction( action, fft ); document->processFormatAction( action, fft );
} ); } );
QObject::connect( formsWidgetController, &FormWidgetsController::keystrokeAction,
q, [this] (const Okular::Action *action, Okular::FormFieldText *fft, bool &ok ) {
document->processKeystrokeAction( action, fft, ok );
} );
} }
return formsWidgetController; return formsWidgetController;
......
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