Add refresh widgets if underlying field changes

Summary:
If a field is updated because of a calculate form action /
a script execution, not only refresh the rendered pixmap but
also the corresponding formWidget.

Test Plan: Unittest in separate revision. Tested it manually, too.

Reviewers: #okular

Subscribers: aacid

Tags: #okular

Maniphest Tasks: T7805

Differential Revision: https://phabricator.kde.org/D10048
This commit is contained in:
Andre Heinecke 2018-02-21 23:56:43 +01:00 committed by Albert Astals Cid
parent d3a549ca25
commit d50c06df25
5 changed files with 75 additions and 0 deletions

View file

@ -16,6 +16,7 @@
#include "documentcommands_p.h"
#include <limits.h>
#include <memory>
#ifdef Q_OS_WIN
#define _WIN32_WINNT 0x0500
#include <windows.h>
@ -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> 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() );
}
}
}
}

View file

@ -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;

View file

@ -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
{

View file

@ -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<Okular::FormFieldText *> ( 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<Okular::FormFieldText *> ( form );
setPlainText( text->text() );
}
FileEdit::FileEdit( Okular::FormFieldText * text, QWidget * parent )
: KUrlRequester( parent ), FormWidgetIface( this, text, !text->isReadOnly() )

View file

@ -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;