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
}
}
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 )
{
if ( !ref )
......
......@@ -675,6 +675,13 @@ class OKULARCORE_EXPORT Document : public QObject
*/
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
*/
......
......@@ -20,7 +20,8 @@ class Event::Private
m_targetPage( nullptr ),
m_source( nullptr ),
m_sourcePage( nullptr ),
m_eventType( eventType )
m_eventType( eventType ),
m_returnCode( false )
{
}
......@@ -31,6 +32,7 @@ class Event::Private
EventType m_eventType;
QString m_targetName;
QVariant m_value;
bool m_returnCode;
};
Event::Event(): d( new Private( UnknownEvent ) )
......@@ -55,6 +57,8 @@ QString Event::name() const
return QStringLiteral( "Calculate" );
case ( FieldFormat ):
return QStringLiteral( "Format" );
case ( FieldKeystroke ):
return QStringLiteral( "Keystroke" );
case ( UnknownEvent ):
default:
return QStringLiteral( "Unknown" );
......@@ -67,6 +71,7 @@ QString Event::type() const
{
case ( FieldCalculate ):
case ( FieldFormat ):
case ( FieldKeystroke ):
return QStringLiteral( "Field" );
case ( UnknownEvent ):
default:
......@@ -139,6 +144,16 @@ void Event::setValue( const QVariant &val )
d->m_value = val;
}
bool Event::returnCode() const
{
return d->m_returnCode;
}
void Event::setReturnCode( bool returnCode )
{
d->m_returnCode = returnCode;
}
// static
std::shared_ptr<Event> Event::createFormCalculateEvent( FormField *target,
Page *targetPage,
......@@ -178,3 +193,19 @@ std::shared_ptr<Event> Event::createFormatEvent( FormField *target,
}
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
FieldCalculate, /// < This event is defined in a field re-calculation.
FieldFocus, /// < Not implemented.
FieldFormat, /// < When a format action is executed
FieldKeystroke, /// < Not implemented.
FieldKeystroke, /// < Checks if the entered value is valid.
FieldMouseDown, /// < Not implemented.
FieldMouseEnter, /// < Not implemented.
FieldMouseExit, /// < Not implemented.
......@@ -97,6 +97,9 @@ class Event
QVariant value() const;
void setValue(const QVariant &val);
bool returnCode() const;
void setReturnCode(bool returnCode);
static std::shared_ptr<Event> createFormCalculateEvent( FormField *target,
Page *targetPage,
FormField *source = nullptr,
......@@ -104,6 +107,7 @@ class Event
const QString &targetName = QString() );
static std::shared_ptr<Event> createFormatEvent( FormField *target, Page *targetPage,
const QString &targetName = QString() );
static std::shared_ptr<Event> createKeystrokeEvent( FormField *target, Page *targetPage );
private:
class Private;
std::shared_ptr<Private> d;
......
......@@ -66,11 +66,17 @@ static KJSObject eventGetSource( KJSContext *ctx, void *object )
static KJSObject eventGetTarget( KJSContext *ctx, void *object )
{
const Event *event = reinterpret_cast< Event * >( object );
if ( event->eventType() == Event::FieldCalculate )
switch( event->eventType() )
{
FormField *target = static_cast< FormField * >( event->target() );
if ( target )
return JSField::wrapField( ctx, target, event->targetPage() );
case Event::FieldCalculate:
case Event::FieldFormat:
case Event::FieldKeystroke:
{
FormField *target = static_cast< FormField * >( event->target() );
if ( target )
return JSField::wrapField( ctx, target, event->targetPage() );
break;
}
}
return KJSUndefined();
}
......@@ -89,6 +95,20 @@ static void eventSetValue( KJSContext *ctx, void *object, KJSObject value )
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 )
{
static bool initialized = false;
......@@ -106,6 +126,7 @@ void JSEvent::initType( KJSContext *ctx )
g_eventProto->defineProperty( ctx, QStringLiteral( "source" ), eventGetSource );
g_eventProto->defineProperty( ctx, QStringLiteral( "target" ), eventGetTarget );
g_eventProto->defineProperty( ctx, QStringLiteral( "value" ), eventGetValue, eventSetValue );
g_eventProto->defineProperty( ctx, QStringLiteral( "rc" ), eventGetReturnCode, eventSetReturnCode );
}
KJSObject JSEvent::wrapEvent( KJSContext *ctx, Event *event )
......
......@@ -292,6 +292,7 @@ void PopplerFormFieldText::setText( const QString& text )
m_field->setText( text );
}
bool PopplerFormFieldText::isPassword() const
{
return m_field->isPassword();
......
......@@ -471,6 +471,7 @@ FormLineEdit::FormLineEdit( Okular::FormFieldText * text, QWidget * parent )
m_prevCursorPos = cursorPosition();
m_prevAnchorPos = cursorPosition();
m_editing = false;
connect( this, &QLineEdit::textEdited, this, &FormLineEdit::slotChanged );
connect( this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged );
......@@ -505,9 +506,11 @@ bool FormLineEdit::event( QEvent* e )
{
const auto fft = static_cast< Okular::FormFieldText * > ( m_ff );
setText( fft->internalText() );
m_editing = true;
}
else if ( e->type() == QEvent::FocusOut )
{
m_editing = false;
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
......@@ -549,6 +552,21 @@ void FormLineEdit::slotChanged()
Okular::FormFieldText *form = static_cast<Okular::FormFieldText *>(m_ff);
QString contents = text();
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() )
{
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
......@@ -618,6 +636,7 @@ TextAreaEdit::TextAreaEdit( Okular::FormFieldText * text, QWidget * parent )
this, &TextAreaEdit::slotUpdateUndoAndRedoInContextMenu );
m_prevCursorPos = textCursor().position();
m_prevAnchorPos = textCursor().anchor();
m_editing = false;
setVisible( text->isVisible() );
}
......@@ -649,9 +668,11 @@ bool TextAreaEdit::event( QEvent* e )
{
const auto fft = static_cast< Okular::FormFieldText * > ( m_ff );
setText( fft->internalText() );
m_editing = true;
}
else if ( e->type() == QEvent::FocusOut )
{
m_editing = false;
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
......@@ -718,6 +739,21 @@ void TextAreaEdit::slotChanged()
Okular::FormFieldText *form = static_cast<Okular::FormFieldText *>(m_ff);
QString contents = toPlainText();
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())
{
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
......
......@@ -118,6 +118,8 @@ class FormWidgetsController : public QObject
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 );
private Q_SLOTS:
......@@ -250,6 +252,7 @@ class FormLineEdit : public QLineEdit, public FormWidgetIface
private:
int m_prevCursorPos;
int m_prevAnchorPos;
bool m_editing;
DECLARE_ADDITIONAL_ACTIONS
};
......@@ -281,6 +284,7 @@ class TextAreaEdit : public KTextEdit, public FormWidgetIface
private:
int m_prevCursorPos;
int m_prevAnchorPos;
bool m_editing;
DECLARE_ADDITIONAL_ACTIONS
};
......
......@@ -268,6 +268,10 @@ FormWidgetsController* PageViewPrivate::formWidgetsController()
q, [this] (const Okular::Action *action, Okular::FormFieldText *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;
......
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