diff --git a/core/document.cpp b/core/document.cpp index 5f5069cd6..33ac2107c 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -16,6 +16,7 @@ #include "documentcommands_p.h" #include +#include #ifdef Q_OS_WIN #define _WIN32_WINNT 0x0500 #include @@ -80,6 +81,7 @@ #include "page_p.h" #include "pagecontroller_p.h" #include "scripter.h" +#include "script/event_p.h" #include "settings_core.h" #include "sourcereference.h" #include "sourcereference_p.h" @@ -1118,13 +1120,40 @@ void DocumentPrivate::recalculateForms() const Page *p = m_parent->page( pageIdx ); if (p) { + bool pageNeedsRefresh = false; foreach( FormField *form, p->formFields() ) { if ( form->id() == formId ) { Action *action = form->additionalAction( FormField::CalculateField ); if (action) { + FormFieldText *fft = dynamic_cast< FormFieldText * >( form ); + std::shared_ptr event; + QString oldVal; + if ( fft ) + { + // Pepare text calculate event + event = Event::createFormCalculateEvent( fft, m_pagesVector[pageIdx] ); + if ( !m_scripter ) + m_scripter = new Scripter( this ); + m_scripter->setEvent( event.get() ); + // The value maybe changed in javascript so save it first. + oldVal = fft->text(); + } + m_parent->processAction( action ); + if ( event && fft ) + { + // Update text field from calculate + m_scripter->setEvent( nullptr ); + const QString newVal = event->value().toString(); + if ( newVal != oldVal ) + { + fft->setText( newVal ); + emit m_parent->refreshFormWidget( fft ); + pageNeedsRefresh = true; + } + } } else { @@ -1132,6 +1161,10 @@ void DocumentPrivate::recalculateForms() } } } + if ( pageNeedsRefresh ) + { + refreshPixmaps( p->number() ); + } } } } diff --git a/core/document.h b/core/document.h index f996f41f6..3354e55ae 100644 --- a/core/document.h +++ b/core/document.h @@ -48,6 +48,7 @@ class DocumentViewport; class EmbeddedFile; class ExportFormat; class FontInfo; +class FormField; class FormFieldText; class FormFieldButton; class FormFieldChoice; @@ -1192,6 +1193,13 @@ class OKULARCORE_EXPORT Document : public QObject * @since 0.17 (KDE 4.11) */ void formButtonsChangedByUndoRedo( int page, const QList< Okular::FormFieldButton* > & formButtons ); + + /** + * This signal is emmitted whenever a FormField was changed programatically and the + * according widget should be updated. + * @since 1.4 + */ + void refreshFormWidget( Okular::FormField *field ); private: /// @cond PRIVATE friend class DocumentPrivate; diff --git a/core/script/kjs_field.cpp b/core/script/kjs_field.cpp index 1e77913bb..b3798ebb7 100644 --- a/core/script/kjs_field.cpp +++ b/core/script/kjs_field.cpp @@ -171,6 +171,7 @@ static void fieldSetValue( KJSContext *context, void *object, KJSObject value ) { Document *doc = PagePrivate::get( page )->m_doc->m_parent; QMetaObject::invokeMethod( doc, "refreshPixmaps", Qt::QueuedConnection, Q_ARG( int, page->number() ) ); + emit doc->refreshFormWidget( field ); } else { diff --git a/ui/formwidgets.cpp b/ui/formwidgets.cpp index 7f3d188c8..d39bd2699 100644 --- a/ui/formwidgets.cpp +++ b/ui/formwidgets.cpp @@ -70,6 +70,10 @@ FormWidgetsController::FormWidgetsController( Okular::Document *doc ) this, &FormWidgetsController::canUndoChanged ); connect( doc, &Okular::Document::canRedoChanged, this, &FormWidgetsController::canRedoChanged ); + + // Connect the generic formWidget refresh signal + connect( doc, &Okular::Document::refreshFormWidget, + this, &FormWidgetsController::refreshFormWidget ); } FormWidgetsController::~FormWidgetsController() @@ -419,6 +423,8 @@ void FormLineEdit::setFormWidgetsController(FormWidgetsController* controller) FormWidgetIface::setFormWidgetsController(controller); connect( m_controller, &FormWidgetsController::formTextChangedByUndoRedo, this, &FormLineEdit::slotHandleTextChangedByUndoRedo ); + connect( m_controller, &FormWidgetsController::refreshFormWidget, + this, &FormLineEdit::slotRefresh ); } bool FormLineEdit::event( QEvent* e ) @@ -515,6 +521,17 @@ void FormLineEdit::slotHandleTextChangedByUndoRedo( int pageNumber, setFocus(); } +void FormLineEdit::slotRefresh( Okular::FormField *form ) +{ + if (form != m_ff) + { + return; + } + Okular::FormFieldText *text = static_cast ( form ); + + setText( text->text() ); +} + TextAreaEdit::TextAreaEdit( Okular::FormFieldText * text, QWidget * parent ) : KTextEdit( parent ), FormWidgetIface( this, text, true ) { @@ -582,6 +599,8 @@ void TextAreaEdit::setFormWidgetsController( FormWidgetsController* controller ) FormWidgetIface::setFormWidgetsController( controller ); connect( m_controller, &FormWidgetsController::formTextChangedByUndoRedo, this, &TextAreaEdit::slotHandleTextChangedByUndoRedo ); + connect( m_controller, &FormWidgetsController::refreshFormWidget, + this, &TextAreaEdit::slotRefresh ); } void TextAreaEdit::slotHandleTextChangedByUndoRedo( int pageNumber, @@ -623,6 +642,16 @@ void TextAreaEdit::slotChanged() m_prevAnchorPos = textCursor().anchor(); } +void TextAreaEdit::slotRefresh( Okular::FormField *form ) +{ + if (form != m_ff) + { + return; + } + Okular::FormFieldText *text = static_cast ( form ); + + setPlainText( text->text() ); +} FileEdit::FileEdit( Okular::FormFieldText * text, QWidget * parent ) : KUrlRequester( parent ), FormWidgetIface( this, text, !text->isReadOnly() ) diff --git a/ui/formwidgets.h b/ui/formwidgets.h index d8ba9619d..e0b1f03ae 100644 --- a/ui/formwidgets.h +++ b/ui/formwidgets.h @@ -113,6 +113,8 @@ class FormWidgetsController : public QObject void action( Okular::Action *action ); + void refreshFormWidget( Okular::FormField * form ); + private Q_SLOTS: void slotButtonClicked( QAbstractButton *button ); void slotFormButtonsChangedByUndoRedo( int pageNumber, @@ -223,6 +225,7 @@ class FormLineEdit : public QLineEdit, public FormWidgetIface int anchorPos ); private Q_SLOTS: void slotChanged(); + void slotRefresh(Okular::FormField* form); private: int m_prevCursorPos; @@ -249,6 +252,7 @@ class TextAreaEdit : public KTextEdit, public FormWidgetIface private Q_SLOTS: void slotChanged(); + void slotRefresh(Okular::FormField* form); private: int m_prevCursorPos;