Commit ed33ff18 authored by Joao Oliveira's avatar Joao Oliveira Committed by Joao Oliveira

Made Form validate the keystroke when focusing out, and when opening. Also...

Made Form validate the keystroke when focusing out, and when opening. Also made the WillCommit to the keystroke event, which will set the valid number to the form
parent 9fcd3359
Pipeline #6921 passed with stage
in 13 minutes and 40 seconds
......@@ -1148,6 +1148,10 @@ void DocumentPrivate::recalculateForms()
// Update text field from calculate
m_scripter->setEvent( nullptr );
const QString newVal = event->value().toString();
// Don't put NaN in event, keep old number.
if( newVal == QStringLiteral( "NaN") )
return;
if ( newVal != oldVal )
{
fft->setText( newVal );
......@@ -4365,7 +4369,7 @@ void Document::processFormatAction( const Action * action, Okular::FormFieldText
}
}
void Document::processKeystrokeAction( const Action * action, Okular::FormFieldText *fft, bool &returnCode )
void Document::processKeystrokeAction( const Action * action, Okular::FormFieldText *fft, bool &returnCode, bool changeFormText )
{
if ( action->actionType() != Action::Script )
{
......@@ -4403,6 +4407,8 @@ void Document::processKeystrokeAction( const Action * action, Okular::FormFieldT
// Clear out the event after execution
d->m_scripter->setEvent( nullptr );
returnCode = event->returnCode();
if( changeFormText )
fft->setText( event->value().toString() );
}
void Document::processSourceReference( const SourceReference * ref )
......@@ -5228,6 +5234,11 @@ QByteArray Document::requestSignedRevisionData( const Okular::SignatureInfo &inf
return data;
}
void Document::recalculateForms()
{
d->recalculateForms();
}
void DocumentPrivate::executeScript( const QString &function )
{
if( !m_scripter )
......
......@@ -678,9 +678,16 @@ class OKULARCORE_EXPORT Document : public QObject
/**
* Processes the given keystroke @p action on @p field.
*
* @param action Is the action to be executed by the function.
* @param field The field which this action will be executed for.
* @param returnCode This is the value returned by the JavaScript processed by the action, if true, the
* input is valid.
* @param changeFormText This dictates if the keystroke action will change the field. If true, we change
* the form value to the value returned by the JavaScript processed action.
*
* @since 1.9
*/
void processKeystrokeAction( const Action *action, Okular::FormFieldText *field, bool &returnCode );
void processKeystrokeAction( const Action *action, Okular::FormFieldText *field, bool &returnCode, bool changeFormText = false );
/**
* Returns a list of the bookmarked.pages
......@@ -1052,6 +1059,8 @@ class OKULARCORE_EXPORT Document : public QObject
*/
QByteArray requestSignedRevisionData( const Okular::SignatureInfo &info );
void recalculateForms();
Q_SIGNALS:
/**
* This signal is emitted whenever the document is about to close.
......
......@@ -472,6 +472,7 @@ FormLineEdit::FormLineEdit( Okular::FormFieldText * text, QWidget * parent )
m_prevCursorPos = cursorPosition();
m_prevAnchorPos = cursorPosition();
m_editing = false;
m_formatted = false;
connect( this, &QLineEdit::textEdited, this, &FormLineEdit::slotChanged );
connect( this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged );
......@@ -484,6 +485,32 @@ void FormLineEdit::setFormWidgetsController(FormWidgetsController* controller)
FormWidgetIface::setFormWidgetsController(controller);
connect( m_controller, &FormWidgetsController::formTextChangedByUndoRedo,
this, &FormLineEdit::slotHandleTextChangedByUndoRedo );
// We do these actions here because if we did in the initialization of FormLineEdit
// the controller would be null, and it would cause a segmentation fault.
m_lastValidText = text();
// If we have a keystroke action and the value is invalid we need to change the field to be valid.
Okular::FormFieldText *form = static_cast< Okular::FormFieldText * > ( m_ff );
if( form->additionalAction( Okular::FormField::FieldModified ) )
{
bool ok = false;
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok );
if( !ok )
{
// If it's invalid with the old text, try replacing dots for commas.
form->setText( text().replace( '.', ',' ) );
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok, true );
// If it's not invalid anymore, set the text with commas instead of dots.
if( ok )
m_lastValidText = text().replace( '.', ',' );
}
}
// If it has a format action, we do it here too.
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
}
}
bool FormLineEdit::event( QEvent* e )
......@@ -504,15 +531,45 @@ bool FormLineEdit::event( QEvent* e )
}
else if ( e->type() == QEvent::FocusIn )
{
const auto fft = static_cast< Okular::FormFieldText * > ( m_ff );
setText( fft->text() );
setText( m_lastValidText );
m_editing = true;
m_formatted = false;
}
else if ( e->type() == QEvent::FocusOut )
{
// If it's formatted, we don't need to process all these events again.
// It means they already were formatted.
if( m_formatted )
{
// Next time this function is called, will not be from format.
// Set it to false.
m_formatted = false;
return QLineEdit::event( e );
}
// Set the last valid text to this text, it will be used later when we focus in.
m_lastValidText = text();
Okular::FormFieldText *form = static_cast< Okular::FormFieldText * > ( m_ff );
// Also set the form text to the atual text, even if we don't have the next actions, the form needs to be
// updated, since we are only doing it here
form->setText( text() );
// If it has a keystroke action, it has to be done one last time before focusing out
// this sets willCommit to true, which will put a valid value in the form.
if( form->additionalAction( Okular::FormField::FieldModified ) && m_editing && !form->isReadOnly() )
{
bool ok = false;
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok, true );
}
m_editing = false;
emit m_controller->recalculateForms();
// If we have a format action, do it after everything was done
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{
m_formatted = true;
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
}
}
......@@ -556,26 +613,25 @@ void FormLineEdit::slotChanged()
if( form->additionalAction( Okular::FormField::FieldModified ) && m_editing && !form->isReadOnly() )
{
bool ok = false;
QString oldInputText = form->text();
QString oldFormText = form->text();
form->setText( text() );
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok );
form->setText( oldInputText );
form->setText( oldFormText );
if(!ok)
{
setText( oldInputText );
setText( m_lastValidText );
return;
}
m_lastValidText = text();
}
if ( contents != form->text() )
{
if( contents != form->text() && !m_formatted )
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
form,
contents,
cursorPos,
m_prevCursorPos,
m_prevAnchorPos );
}
m_prevCursorPos = cursorPos;
m_prevAnchorPos = cursorPos;
......@@ -629,7 +685,6 @@ TextAreaEdit::TextAreaEdit( Okular::FormFieldText * text, QWidget * parent )
setAlignment( text->textAlignment() );
setPlainText( text->text() );
setUndoRedoEnabled( false );
connect( this, &QTextEdit::textChanged, this, &TextAreaEdit::slotChanged );
connect( this, &QTextEdit::cursorPositionChanged, this, &TextAreaEdit::slotChanged );
connect( this, &KTextEdit::aboutToShowContextMenu,
......@@ -666,15 +721,44 @@ bool TextAreaEdit::event( QEvent* e )
}
else if ( e->type() == QEvent::FocusIn )
{
const auto fft = static_cast< Okular::FormFieldText * > ( m_ff );
setText( fft->text() );
setText( m_lastValidText );
m_editing = true;
}
else if ( e->type() == QEvent::FocusOut )
{
// If it's formatted, we don't need to process all these events again.
// It means they already were formatted.
if( m_formatted )
{
// Next time this function is called, will not be from format.
// Set it to false.
m_formatted = false;
return KTextEdit::event( e );
}
// Set the last valid text to this text, it will be used later when we focus in.
m_lastValidText = toPlainText();
Okular::FormFieldText *form = static_cast< Okular::FormFieldText * > ( m_ff );
// Also set the form text to the atual text, even if we don't have the next actions, the form needs to be
// updated, since we are only doing it here
form->setText( toPlainText() );
// If it has a keystroke action, it has to be done one last time before focusing out
// this sets willCommit to true, which will put a valid value in the form.
if( form->additionalAction( Okular::FormField::FieldModified ) && m_editing && !form->isReadOnly() )
{
bool ok = false;
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok, true );
}
m_editing = false;
// If we have a format action, do it after everything was done
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{
m_formatted = true;
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
}
}
......@@ -711,6 +795,32 @@ void TextAreaEdit::setFormWidgetsController( FormWidgetsController* controller )
FormWidgetIface::setFormWidgetsController( controller );
connect( m_controller, &FormWidgetsController::formTextChangedByUndoRedo,
this, &TextAreaEdit::slotHandleTextChangedByUndoRedo );
// We do these actions here because if we did in the initialization of FormLineEdit
// the controller would be null, and it would cause a segmentation fault.
m_lastValidText = toPlainText();
// If we have a keystroke action and the value is invalid we need to change the field to be valid.
Okular::FormFieldText *form = static_cast< Okular::FormFieldText * > ( m_ff );
if( form->additionalAction( Okular::FormField::FieldModified ) )
{
bool ok = false;
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok );
if( !ok )
{
// If it's invalid with the old text, try replacing dots for commas.
form->setText( toPlainText().replace( '.', ',' ) );
emit m_controller->keystrokeAction( form->additionalAction( Okular::FormField::FieldModified ), form, ok, true );
// If it's not invalid anymore, set the text with commas instead of dots.
if( ok )
m_lastValidText = toPlainText().replace( '.', ',' );
}
}
// If it has a format action, we do it here too.
if ( const Okular::Action *action = m_ff->additionalAction( Okular::FormField::FormatField ) )
{
emit m_controller->formatAction( action, static_cast< Okular::FormFieldText * > ( m_ff ) );
}
}
void TextAreaEdit::slotHandleTextChangedByUndoRedo( int pageNumber,
......@@ -752,17 +862,17 @@ void TextAreaEdit::slotChanged()
setText( oldInputText );
return;
}
m_lastValidText = toPlainText();
}
if (contents != form->text())
{
if( contents != form->text() && !m_formatted )
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
form,
contents,
cursorPos,
m_prevCursorPos,
m_prevAnchorPos );
}
m_prevCursorPos = cursorPos;
m_prevAnchorPos = textCursor().anchor();
}
......
......@@ -118,10 +118,12 @@ 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 keystrokeAction( const Okular::Action *action, Okular::FormFieldText *ff, bool &ok, bool willCommit = false );
void refreshFormWidget( Okular::FormField * form );
void recalculateForms();
private Q_SLOTS:
void slotButtonClicked( QAbstractButton *button );
void slotFormButtonsChangedByUndoRedo( int pageNumber,
......@@ -253,6 +255,8 @@ class FormLineEdit : public QLineEdit, public FormWidgetIface
int m_prevCursorPos;
int m_prevAnchorPos;
bool m_editing;
bool m_formatted;
QString m_lastValidText;
DECLARE_ADDITIONAL_ACTIONS
};
......@@ -285,6 +289,8 @@ class TextAreaEdit : public KTextEdit, public FormWidgetIface
int m_prevCursorPos;
int m_prevAnchorPos;
bool m_editing;
bool m_formatted;
QString m_lastValidText;
DECLARE_ADDITIONAL_ACTIONS
};
......
......@@ -269,10 +269,13 @@ FormWidgetsController* PageViewPrivate::formWidgetsController()
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 );
q, [this] (const Okular::Action *action, Okular::FormFieldText *fft, bool &ok, bool willCommit ) {
document->processKeystrokeAction( action, fft, ok, willCommit );
} );
}
QObject::connect( formsWidgetController, &FormWidgetsController::recalculateForms,
q, [this] () {
document->recalculateForms();
} ); }
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