Undo support for PDF forms

Together with the already commited support for undo in annotations fixes 177501
BUGS: 177501
REVIEW: 110589
FIXED-IN: 4.11.0
This commit is contained in:
Jon Mease 2013-06-03 22:46:41 +02:00 committed by Albert Astals Cid
parent 8d98819184
commit b7ce9114c5
8 changed files with 1140 additions and 89 deletions

View file

@ -83,6 +83,7 @@
#include "utils_p.h"
#include "view.h"
#include "view_p.h"
#include "form.h"
#include <memory>
@ -3408,6 +3409,54 @@ void Document::redo()
d->m_undoStack->redo();
}
void Document::editFormText( int pageNumber,
Okular::FormFieldText* form,
const QString & newContents,
int newCursorPos,
int prevCursorPos,
int prevAnchorPos )
{
QUndoCommand *uc = new EditFormTextCommand( this, form, pageNumber, newContents, newCursorPos, form->text(), prevCursorPos, prevAnchorPos );
d->m_undoStack->push( uc );
}
void Document::editFormList( int pageNumber,
FormFieldChoice* form,
const QList< int > & newChoices )
{
const QList< int > prevChoices = form->currentChoices();
QUndoCommand *uc = new EditFormListCommand( this, form, pageNumber, newChoices, prevChoices );
d->m_undoStack->push( uc );
}
void Document::editFormCombo( int pageNumber,
FormFieldChoice* form,
const QString & newText,
int newCursorPos,
int prevCursorPos,
int prevAnchorPos )
{
QString prevText;
if ( form->currentChoices().isEmpty() )
{
prevText = form->editChoice();
}
else
{
prevText = form->choices()[form->currentChoices()[0]];
}
QUndoCommand *uc = new EditFormComboCommand( this, form, pageNumber, newText, newCursorPos, prevText, prevCursorPos, prevAnchorPos );
d->m_undoStack->push( uc );
}
void Document::editFormButtons( int pageNumber, const QList< FormFieldButton* >& formButtons, const QList< bool >& newButtonStates )
{
QUndoCommand *uc = new EditFormButtonsCommand( this, pageNumber, formButtons, newButtonStates );
d->m_undoStack->push( uc );
}
BookmarkManager * Document::bookmarkManager() const
{
return d->m_bookmarkManager;

View file

@ -44,6 +44,9 @@ class DocumentViewport;
class EmbeddedFile;
class ExportFormat;
class FontInfo;
class FormFieldText;
class FormFieldButton;
class FormFieldChoice;
class Generator;
class Action;
class MovieAction;
@ -746,6 +749,52 @@ class OKULAR_EXPORT Document : public QObject
*/
void redo();
/**
* Edit the text contents of the specified @p form on page @p page to be @p newContents.
* The new text cursor position (@p newCursorPos), previous text cursor position (@p prevCursorPos),
* and previous cursor anchor position will be restored by the undo / redo commands.
* @since 0.17 (KDE 4.11)
*/
void editFormText( int pageNumber,
Okular::FormFieldText* form,
const QString & newContents,
int newCursorPos,
int prevCursorPos,
int prevAnchorPos );
/**
* Edit the selected list entries in @p form on page @p page to be @p newChoices.
* @since 0.17 (KDE 4.11)
*/
void editFormList( int pageNumber,
Okular::FormFieldChoice* form,
const QList<int> & newChoices );
/**
* Set the active choice in the combo box @p form on page @p page to @p newText
* The new cursor position (@p newCursorPos), previous cursor position
* (@p prevCursorPos), and previous anchor position (@p prevAnchorPos)
* will be restored by the undo / redo commands.
*
* @since 0.17 (KDE 4.11)
*/
void editFormCombo( int pageNumber,
Okular::FormFieldChoice *form,
const QString & newText,
int newCursorPos,
int prevCursorPos,
int prevAnchorPos );
/**
* Set the states of the group of form buttons @p formButtons on page @p page to @p newButtonStates.
* The lists @p formButtons and @p newButtonStates should be the same length and true values
* in @p newButtonStates indicate that the corresponding entry in @p formButtons should be enabled.
*/
void editFormButtons( int pageNumber,
const QList< Okular::FormFieldButton* > & formButtons,
const QList< bool > & newButtonStates );
Q_SIGNALS:
/**
* This signal is emitted whenever an action requests a
@ -882,12 +931,46 @@ class OKULAR_EXPORT Document : public QObject
*/
void annotationContentsChangedByUndoRedo( Okular::Annotation* annotation, const QString & contents, int cursorPos, int anchorPos );
/**
* This signal is emmitted whenever the text contents of the given text @p form on the given @p page
* are changed by an undo or redo action.
*
* The new text contents (@p contents), cursor position (@p cursorPos), and anchor position (@p anchorPos) are
* included
* @since 0.17 (KDE 4.11)
*/
void formTextChangedByUndoRedo( int page, Okular::FormFieldText* form, const QString & contents, int cursorPos, int anchorPos );
/**
* This signal is emmitted whenever the selected @p choices for the given list @p form on the
* given @p page are changed by an undo or redo action.
* @since 0.17 (KDE 4.11)
*/
void formListChangedByUndoRedo( int page, Okular::FormFieldChoice* form, const QList< int > & choices );
/**
* This signal is emmitted whenever the active @p text for the given combo @p form on the
* given @p page is changed by an undo or redo action.
* @since 0.17 (KDE 4.11)
*/
void formComboChangedByUndoRedo( int page, Okular::FormFieldChoice* form, const QString & text, int cursorPos, int anchorPos );
/**
* This signal is emmitted whenever the state of the specified group of form buttons (@p formButtons) on the
* given @p page is changed by an undo or redo action.
* @since 0.17 (KDE 4.11)
*/
void formButtonsChangedByUndoRedo( int page, const QList< Okular::FormFieldButton* > & formButtons );
private:
/// @cond PRIVATE
friend class DocumentPrivate;
friend class Part;
friend class ::DocumentItem;
friend class EditAnnotationContentsCommand;
friend class EditFormTextCommand;
friend class EditFormListCommand;
friend class EditFormComboCommand;
friend class EditFormButtonsCommand;
/// @endcond
DocumentPrivate *const d;

View file

@ -12,6 +12,7 @@
#include "annotations.h"
#include "debug_p.h"
#include "document_p.h"
#include "form.h"
#include <KLocalizedString>
@ -288,5 +289,209 @@ bool EditAnnotationContentsCommand::mergeWith(const QUndoCommand* uc)
}
}
EditFormTextCommand::EditFormTextCommand( Okular::Document* doc,
Okular::FormFieldText* form,
int pageNumber,
const QString & newContents,
int newCursorPos,
const QString & prevContents,
int prevCursorPos,
int prevAnchorPos )
: EditTextCommand( newContents, newCursorPos, prevContents, prevCursorPos, prevAnchorPos ),
m_doc ( doc ),
m_form( form ),
m_pageNumber( pageNumber )
{
setText( i18nc( "Edit an form's text contents", "edit form contents" ) );
}
void EditFormTextCommand::undo()
{
m_form->setText( m_prevContents );
m_doc->formTextChangedByUndoRedo( m_pageNumber, m_form, m_prevContents, m_prevCursorPos, m_prevAnchorPos );
}
void EditFormTextCommand::redo()
{
m_form->setText( m_newContents );
m_doc->formTextChangedByUndoRedo( m_pageNumber, m_form, m_newContents, m_newCursorPos, m_newCursorPos );
}
int EditFormTextCommand::id() const
{
return 3;
}
bool EditFormTextCommand::mergeWith(const QUndoCommand* uc)
{
EditFormTextCommand *euc = (EditFormTextCommand*)uc;
// Only attempt merge of euc into this if they modify the same form
if ( m_form == euc->m_form )
{
return EditTextCommand::mergeWith( uc );
}
else
{
return false;
}
}
EditFormListCommand::EditFormListCommand( Okular::Document* doc,
FormFieldChoice* form,
int pageNumber,
const QList< int > & newChoices,
const QList< int > & prevChoices )
: m_doc( doc ),
m_form( form ),
m_pageNumber( pageNumber ),
m_newChoices( newChoices ),
m_prevChoices( prevChoices )
{
setText( i18nc( "Edit a list form's choices", "edit list form choices" ) );
}
void EditFormListCommand::undo()
{
m_form->setCurrentChoices( m_prevChoices );
m_doc->formListChangedByUndoRedo( m_pageNumber, m_form, m_prevChoices );
}
void EditFormListCommand::redo()
{
m_form->setCurrentChoices( m_newChoices );
m_doc->formListChangedByUndoRedo( m_pageNumber, m_form, m_newChoices );
}
EditFormComboCommand::EditFormComboCommand( Okular::Document* doc,
FormFieldChoice* form,
int pageNumber,
const QString & newContents,
int newCursorPos,
const QString & prevContents,
int prevCursorPos,
int prevAnchorPos )
: EditTextCommand( newContents, newCursorPos, prevContents, prevCursorPos, prevAnchorPos ),
m_doc( doc ),
m_form( form ),
m_pageNumber( pageNumber ),
m_newIndex( -1 ),
m_prevIndex( -1 )
{
setText( i18nc( "Edit a combo form's selection", "edit combo form selection" ) );
// Determine new and previous choice indices (if any)
for ( int i = 0; i < m_form->choices().size(); i++ )
{
if ( m_form->choices()[i] == m_prevContents )
{
m_prevIndex = i;
}
if ( m_form->choices()[i] == m_newContents )
{
m_newIndex = i;
}
}
}
void EditFormComboCommand::undo()
{
if ( m_prevIndex != -1 )
{
m_form->setCurrentChoices( QList<int>() << m_prevIndex );
}
else
{
m_form->setEditChoice( m_prevContents );
}
m_doc->formComboChangedByUndoRedo( m_pageNumber, m_form, m_prevContents, m_prevCursorPos, m_prevAnchorPos );
}
void EditFormComboCommand::redo()
{
if ( m_newIndex != -1 )
{
m_form->setCurrentChoices( QList<int>() << m_newIndex );
}
else
{
m_form->setEditChoice( m_newContents );
}
m_doc->formComboChangedByUndoRedo( m_pageNumber, m_form, m_newContents, m_newCursorPos, m_newCursorPos );
}
int EditFormComboCommand::id() const
{
return 4;
}
bool EditFormComboCommand::mergeWith( const QUndoCommand *uc )
{
EditFormComboCommand *euc = (EditFormComboCommand*)uc;
// Only attempt merge of euc into this if they modify the same form
if ( m_form == euc->m_form )
{
bool shouldMerge = EditTextCommand::mergeWith( uc );
if( shouldMerge )
{
m_newIndex = euc->m_newIndex;
}
return shouldMerge;
}
else
{
return false;
}
}
EditFormButtonsCommand::EditFormButtonsCommand( Okular::Document* doc,
int pageNumber,
const QList< FormFieldButton* > & formButtons,
const QList< bool > & newButtonStates )
: m_doc( doc ),
m_pageNumber( pageNumber ),
m_formButtons( formButtons ),
m_newButtonStates( newButtonStates ),
m_prevButtonStates( QList< bool >() )
{
setText( i18nc( "Edit the state of a group of form buttons", "edit form button states" ) );
foreach( FormFieldButton* formButton, m_formButtons )
{
m_prevButtonStates.append( formButton->state() );
}
}
void EditFormButtonsCommand::undo()
{
clearFormButtonStates();
for( int i = 0; i < m_formButtons.size(); i++ )
{
bool checked = m_prevButtonStates.at( i );
if ( checked )
m_formButtons.at( i )->setState( checked );
}
m_doc->formButtonsChangedByUndoRedo( m_pageNumber, m_formButtons );
}
void EditFormButtonsCommand::redo()
{
clearFormButtonStates();
for( int i = 0; i < m_formButtons.size(); i++ )
{
bool checked = m_newButtonStates.at( i );
if ( checked )
m_formButtons.at( i )->setState( checked );
}
m_doc->formButtonsChangedByUndoRedo( m_pageNumber, m_formButtons );
}
void EditFormButtonsCommand::clearFormButtonStates()
{
foreach( FormFieldButton* formButton, m_formButtons )
{
formButton->setState( false );
}
}
}

View file

@ -17,8 +17,12 @@
namespace Okular {
class Document;
class Annotation;
class DocumentPrivate;
class FormFieldText;
class FormFieldButton;
class FormFieldChoice;
class AddAnnotationCommand : public QUndoCommand
{
@ -157,8 +161,98 @@ class EditAnnotationContentsCommand : public EditTextCommand
int m_pageNumber;
};
}
class EditFormTextCommand : public EditTextCommand
{
public:
EditFormTextCommand( Okular::Document* doc,
Okular::FormFieldText* form,
int pageNumber,
const QString & newContents,
int newCursorPos,
const QString & prevContents,
int prevCursorPos,
int prevAnchorPos );
virtual void undo();
virtual void redo();
virtual int id() const;
virtual bool mergeWith( const QUndoCommand *uc );
private:
Okular::Document* m_doc;
Okular::FormFieldText* m_form;
int m_pageNumber;
};
class EditFormListCommand : public QUndoCommand
{
public:
EditFormListCommand( Okular::Document* doc,
FormFieldChoice* form,
int pageNumber,
const QList< int > & newChoices,
const QList< int > & prevChoices
);
virtual void undo();
virtual void redo();
private:
Okular::Document* m_doc;
FormFieldChoice* m_form;
int m_pageNumber;
QList< int > m_newChoices;
QList< int > m_prevChoices;
};
class EditFormComboCommand : public EditTextCommand
{
public:
EditFormComboCommand( Okular::Document* doc,
FormFieldChoice* form,
int pageNumber,
const QString & newText,
int newCursorPos,
const QString & prevText,
int prevCursorPos,
int prevAnchorPos
);
virtual void undo();
virtual void redo();
virtual int id() const;
virtual bool mergeWith( const QUndoCommand *uc );
private:
Okular::Document* m_doc;
FormFieldChoice* m_form;
int m_pageNumber;
int m_newIndex;
int m_prevIndex;
};
class EditFormButtonsCommand : public QUndoCommand
{
public:
EditFormButtonsCommand( Okular::Document* doc,
int pageNumber,
const QList< FormFieldButton* > & formButtons,
const QList< bool > & newButtonStates
);
virtual void undo();
virtual void redo();
private:
void clearFormButtonStates();
private:
Okular::Document* m_doc;
int m_pageNumber;
QList< FormFieldButton* > m_formButtons;
QList< bool > m_newButtonStates;
QList< bool > m_prevButtonStates;
};
}
#endif
/* kate: replace-tabs on; indent-width 4; */

View file

@ -8,56 +8,112 @@
***************************************************************************/
#include "formwidgets.h"
#include "pageviewutils.h"
#include <qbuttongroup.h>
#include <QKeyEvent>
#include <QMenu>
#include <QEvent>
#include <klineedit.h>
#include <klocale.h>
#include <kstandardaction.h>
#include <kaction.h>
// local includes
#include "core/form.h"
#include "core/document.h"
FormWidgetsController::FormWidgetsController( QObject *parent )
: QObject( parent )
FormWidgetsController::FormWidgetsController( Okular::Document *doc )
: QObject( doc ), m_doc( doc )
{
// emit changed signal when a form has changed
connect( this, SIGNAL( formTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ),
this, SIGNAL( changed( int ) ) );
connect( this, SIGNAL( formListChangedByUndoRedo(int, Okular::FormFieldChoice*, QList<int> ) ),
this, SIGNAL( changed( int ) ) );
connect( this, SIGNAL( formComboChangedByUndoRedo(int, Okular::FormFieldChoice*, QString, int, int ) ),
this, SIGNAL( changed( int ) ) );
// connect form modification signals to and from document
connect( this, SIGNAL( formTextChangedByWidget( int, Okular::FormFieldText*, QString, int, int, int ) ),
doc, SLOT( editFormText( int, Okular::FormFieldText*, QString, int, int, int ) ) );
connect( doc, SIGNAL( formTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ),
this, SIGNAL( formTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ) );
connect( this, SIGNAL( formListChangedByWidget( int, Okular::FormFieldChoice*, QList<int> ) ),
doc, SLOT( editFormList( int, Okular::FormFieldChoice*, QList<int> ) ) );
connect( doc, SIGNAL( formListChangedByUndoRedo( int, Okular::FormFieldChoice*, QList<int> ) ),
this, SIGNAL( formListChangedByUndoRedo( int,Okular::FormFieldChoice*, QList<int> ) ) );
connect( this, SIGNAL( formComboChangedByWidget( int, Okular::FormFieldChoice*, QString, int, int, int ) ),
doc, SLOT( editFormCombo( int, Okular::FormFieldChoice*, QString, int, int, int ) ) );
connect( doc, SIGNAL( formComboChangedByUndoRedo( int, Okular::FormFieldChoice*, QString, int, int ) ),
this, SIGNAL( formComboChangedByUndoRedo( int, Okular::FormFieldChoice*, QString, int, int ) ) );
connect( this, SIGNAL( formButtonsChangedByWidget( int, QList<Okular::FormFieldButton*>, QList<bool> ) ),
doc, SLOT( editFormButtons( int, QList<Okular::FormFieldButton*>, QList<bool> ) ) );
connect( doc, SIGNAL( formButtonsChangedByUndoRedo( int, QList<Okular::FormFieldButton*> ) ),
this, SLOT( slotFormButtonsChangedByUndoRedo(int,QList<Okular::FormFieldButton*> ) ) );
// Connect undo/redo signals
connect( this, SIGNAL( requestUndo() ),
doc, SLOT( undo() ) );
connect( this, SIGNAL( requestRedo() ),
doc, SLOT( redo() ) );
connect( doc, SIGNAL( canUndoChanged( bool ) ),
this, SIGNAL( canUndoChanged( bool ) ) );
connect( doc, SIGNAL( canRedoChanged( bool ) ),
this, SIGNAL( canRedoChanged( bool ) ) );
}
FormWidgetsController::~FormWidgetsController()
{
}
void FormWidgetsController::signalChanged( FormWidgetIface *w )
{
emit changed( w );
}
void FormWidgetsController::signalAction( Okular::Action *a )
{
emit action( a );
}
QButtonGroup* FormWidgetsController::registerRadioButton( FormWidgetIface* widget, const QList< int >& siblings )
QButtonGroup* FormWidgetsController::registerRadioButton( QAbstractButton *button, Okular::FormFieldButton *formButton )
{
if ( !widget->button() )
if ( !button )
return 0;
QList< RadioData >::iterator it = m_radios.begin(), itEnd = m_radios.end();
const int id = widget->formField()->id();
const int id = formButton->id();
m_formButtons.insert( id, formButton );
m_buttons.insert( id, button );
for ( ; it != itEnd; ++it )
{
const QList< int >::const_iterator idsIt = qFind( (*it).ids, id );
if ( idsIt != (*it).ids.constEnd() )
{
(*it).group->addButton( widget->button() );
kDebug(4700) << "Adding id" << id << "To group including" << (*it).ids;
(*it).group->addButton( button );
(*it).group->setId( button, id );
return (*it).group;
}
}
const QList< int > siblings = formButton->siblings();
RadioData newdata;
newdata.ids = siblings;
newdata.ids.append( id );
newdata.group = new QButtonGroup();
newdata.group->addButton( widget->button() );
connect( newdata.group, SIGNAL(buttonClicked(QAbstractButton*)),
this, SLOT(slotButtonClicked(QAbstractButton*)) );
newdata.group->addButton( button );
newdata.group->setId( button, id );
// Groups of 1 (like checkboxes) can't be exclusive
if (siblings.isEmpty())
newdata.group->setExclusive( false );
connect( newdata.group, SIGNAL( buttonClicked(QAbstractButton* ) ),
this, SLOT( slotButtonClicked( QAbstractButton* ) ) );
m_radios.append( newdata );
return newdata.group;
}
@ -70,16 +126,60 @@ void FormWidgetsController::dropRadioButtons()
delete (*it).group;
}
m_radios.clear();
m_buttons.clear();
m_formButtons.clear();
}
bool FormWidgetsController::canUndo()
{
return m_doc->canUndo();
}
bool FormWidgetsController::canRedo()
{
return m_doc->canRedo();
}
void FormWidgetsController::slotButtonClicked( QAbstractButton *button )
{
int pageNumber = -1;
if ( CheckBoxEdit *check = qobject_cast< CheckBoxEdit * >( button ) )
emit changed( check );
{
pageNumber = check->pageItem()->pageNumber();
}
else if ( RadioButtonEdit *radio = qobject_cast< RadioButtonEdit * >( button ) )
emit changed( radio );
{
pageNumber = radio->pageItem()->pageNumber();
}
const QList< QAbstractButton* > buttons = button->group()->buttons();
QList< bool > checked;
QList< bool > prevChecked;
QList< Okular::FormFieldButton*> formButtons;
foreach ( QAbstractButton* button, buttons )
{
checked.append( button->isChecked() );
int id = button->group()->id( button );
formButtons.append( m_formButtons[id] );
prevChecked.append( m_formButtons[id]->state() );
}
if (checked != prevChecked)
emit formButtonsChangedByWidget( pageNumber, formButtons, checked );
}
void FormWidgetsController::slotFormButtonsChangedByUndoRedo( int pageNumber, const QList< Okular::FormFieldButton* > & formButtons)
{
foreach ( Okular::FormFieldButton* formButton, formButtons )
{
int id = formButton->id();
QAbstractButton* button = m_buttons[id];
bool checked = formButton->state();
button->setChecked( checked );
button->setFocus();
}
emit changed( pageNumber );
}
FormWidgetIface * FormWidgetFactory::createWidget( Okular::FormField * ff, QWidget * parent )
{
@ -242,13 +342,8 @@ CheckBoxEdit::CheckBoxEdit( Okular::FormFieldButton * button, QWidget * parent )
void CheckBoxEdit::setFormWidgetsController( FormWidgetsController *controller )
{
FormWidgetIface::setFormWidgetsController( controller );
const QList< int > siblings = m_form->siblings();
if ( !siblings.isEmpty() )
m_controller->registerRadioButton( this, siblings );
setCheckState( m_form->state() ? Qt::Checked : Qt::Unchecked );
m_controller->registerRadioButton( button(), m_form );
setChecked( m_form->state() );
connect( this, SIGNAL(stateChanged(int)), this, SLOT(slotStateChanged(int)) );
}
@ -259,11 +354,6 @@ QAbstractButton* CheckBoxEdit::button()
void CheckBoxEdit::slotStateChanged( int state )
{
m_form->setState( state == Qt::Checked );
if ( !group() )
m_controller->signalChanged( this );
if ( state == Qt::Checked && m_form->activationAction() )
m_controller->signalAction( m_form->activationAction() );
}
@ -282,12 +372,8 @@ RadioButtonEdit::RadioButtonEdit( Okular::FormFieldButton * button, QWidget * pa
void RadioButtonEdit::setFormWidgetsController( FormWidgetsController *controller )
{
FormWidgetIface::setFormWidgetsController( controller );
m_controller->registerRadioButton( this, m_form->siblings() );
m_controller->registerRadioButton( button(), m_form );
setChecked( m_form->state() );
connect( this, SIGNAL(toggled(bool)), this, SLOT(slotToggled(bool)) );
}
QAbstractButton* RadioButtonEdit::button()
@ -295,15 +381,6 @@ QAbstractButton* RadioButtonEdit::button()
return this;
}
void RadioButtonEdit::slotToggled( bool checked )
{
m_form->setState( checked );
if ( !group() )
m_controller->signalChanged( this );
}
FormLineEdit::FormLineEdit( Okular::FormFieldText * text, QWidget * parent )
: QLineEdit( parent ), FormWidgetIface( this, text ), m_form( text )
{
@ -316,36 +393,220 @@ FormLineEdit::FormLineEdit( Okular::FormFieldText * text, QWidget * parent )
setEchoMode( QLineEdit::Password );
setReadOnly( m_form->isReadOnly() );
connect( this, SIGNAL(textEdited(QString)), this, SLOT(textEdited(QString)) );
m_prevCursorPos = cursorPosition();
m_prevAnchorPos = cursorPosition();
connect( this, SIGNAL( textEdited( QString ) ), this, SLOT( slotChanged() ) );
connect( this, SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotChanged() ) );
setVisible( m_form->isVisible() );
}
void FormLineEdit::textEdited( const QString& )
void FormLineEdit::setFormWidgetsController(FormWidgetsController* controller)
{
m_form->setText( text() );
m_controller->signalChanged( this );
FormWidgetIface::setFormWidgetsController(controller);
connect( m_controller, SIGNAL( formTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ),
this, SLOT( slotHandleTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ) );
}
bool FormLineEdit::event( QEvent* e )
{
if ( e->type() == QEvent::KeyPress )
{
QKeyEvent *keyEvent = static_cast< QKeyEvent* >( e );
if ( keyEvent == QKeySequence::Undo )
{
emit m_controller->requestUndo();
return true;
}
else if ( keyEvent == QKeySequence::Redo )
{
emit m_controller->requestRedo();
return true;
}
}
return QLineEdit::event( e );
}
void FormLineEdit::contextMenuEvent( QContextMenuEvent* event )
{
QMenu *menu = createStandardContextMenu();
QList<QAction *> actionList = menu->actions();
enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, DeleteAct, SelectAllAct };
KAction *kundo = KStandardAction::create( KStandardAction::Undo, m_controller, SIGNAL( requestUndo() ), menu );
KAction *kredo = KStandardAction::create( KStandardAction::Redo, m_controller, SIGNAL( requestRedo() ), menu );
connect( m_controller, SIGNAL( canUndoChanged( bool ) ), kundo, SLOT( setEnabled( bool ) ) );
connect( m_controller, SIGNAL( canRedoChanged( bool ) ), kredo, SLOT( setEnabled( bool ) ) );
kundo->setEnabled( m_controller->canUndo() );
kredo->setEnabled( m_controller->canRedo() );
QAction *oldUndo, *oldRedo;
oldUndo = actionList[UndoAct];
oldRedo = actionList[RedoAct];
menu->insertAction( oldUndo, kundo );
menu->insertAction( oldRedo, kredo );
menu->removeAction( oldUndo );
menu->removeAction( oldRedo );
menu->exec( event->globalPos() );
delete menu;
}
void FormLineEdit::slotChanged()
{
QString contents = text();
int cursorPos = cursorPosition();
if ( contents != m_form->text() )
{
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
m_form,
contents,
cursorPos,
m_prevCursorPos,
m_prevAnchorPos );
}
m_prevCursorPos = cursorPos;
m_prevAnchorPos = cursorPos;
if ( hasSelectedText() ) {
if ( cursorPos == selectionStart() ) {
m_prevAnchorPos = selectionStart() + selectedText().size();
} else {
m_prevAnchorPos = selectionStart();
}
}
}
void FormLineEdit::slotHandleTextChangedByUndoRedo( int pageNumber,
Okular::FormFieldText* textForm,
const QString & contents,
int cursorPos,
int anchorPos )
{
if ( textForm != m_form || contents == text() )
{
return;
}
disconnect( this, SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotChanged() ) );
setText(contents);
setCursorPosition(anchorPos);
cursorForward( true, cursorPos - anchorPos );
connect( this, SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotChanged() ) );
m_prevCursorPos = cursorPos;
m_prevAnchorPos = anchorPos;
setFocus();
}
TextAreaEdit::TextAreaEdit( Okular::FormFieldText * text, QWidget * parent )
: KTextEdit( parent ), FormWidgetIface( this, text ), m_form( text )
: KTextEdit( parent ), FormWidgetIface( this, text ), m_form( text )
{
setAcceptRichText( m_form->isRichText() );
setCheckSpellingEnabled( m_form->canBeSpellChecked() );
setAlignment( m_form->textAlignment() );
setPlainText( m_form->text() );
setReadOnly( m_form->isReadOnly() );
setUndoRedoEnabled( false );
connect( this, SIGNAL(textChanged()), this, SLOT(slotChanged()) );
connect( this, SIGNAL( textChanged() ), this, SLOT( slotChanged() ) );
connect( this, SIGNAL( cursorPositionChanged() ), this, SLOT( slotChanged() ) );
connect( this, SIGNAL( aboutToShowContextMenu( QMenu* ) ),
this, SLOT( slotUpdateUndoAndRedoInContextMenu( QMenu* ) ) );
m_prevCursorPos = textCursor().position();
m_prevAnchorPos = textCursor().anchor();
setVisible( m_form->isVisible() );
}
bool TextAreaEdit::event( QEvent* e )
{
if ( e->type() == QEvent::KeyPress )
{
QKeyEvent *keyEvent = static_cast< QKeyEvent* >(e);
if ( keyEvent == QKeySequence::Undo )
{
emit m_controller->requestUndo();
return true;
}
else if ( keyEvent == QKeySequence::Redo )
{
emit m_controller->requestRedo();
return true;
}
}
return KTextEdit::event( e );
}
void TextAreaEdit::slotUpdateUndoAndRedoInContextMenu( QMenu* menu )
{
if ( !menu ) return;
QList<QAction *> actionList = menu->actions();
enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, ClearAct, SelectAllAct, NCountActs };
KAction *kundo = KStandardAction::create( KStandardAction::Undo, m_controller, SIGNAL( requestUndo() ), menu );
KAction *kredo = KStandardAction::create( KStandardAction::Redo, m_controller, SIGNAL( requestRedo() ), menu );
connect(m_controller, SIGNAL( canUndoChanged( bool ) ), kundo, SLOT( setEnabled( bool ) ) );
connect(m_controller, SIGNAL( canRedoChanged( bool ) ), kredo, SLOT( setEnabled( bool ) ) );
kundo->setEnabled( m_controller->canUndo() );
kredo->setEnabled( m_controller->canRedo() );
QAction *oldUndo, *oldRedo;
oldUndo = actionList[UndoAct];
oldRedo = actionList[RedoAct];
menu->insertAction( oldUndo, kundo );
menu->insertAction( oldRedo, kredo );
menu->removeAction( oldUndo );
menu->removeAction( oldRedo );
}
void TextAreaEdit::setFormWidgetsController( FormWidgetsController* controller )
{
FormWidgetIface::setFormWidgetsController( controller );
connect( m_controller, SIGNAL( formTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ),
this, SLOT( slotHandleTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ) );
}
void TextAreaEdit::slotHandleTextChangedByUndoRedo( int pageNumber,
Okular::FormFieldText* textForm,
const QString & contents,
int cursorPos,
int anchorPos )
{
if ( textForm != m_form )
{
return;
}
setPlainText( contents );
QTextCursor c = textCursor();
c.setPosition( anchorPos );
c.setPosition( cursorPos,QTextCursor::KeepAnchor );
m_prevCursorPos = cursorPos;
m_prevAnchorPos = anchorPos;
setTextCursor( c );
setFocus();
}
void TextAreaEdit::slotChanged()
{
m_form->setText( toPlainText() );
m_controller->signalChanged( this );
QString contents = toPlainText();
int cursorPos = textCursor().position();
if (contents != m_form->text())
{
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
m_form,
contents,
cursorPos,
m_prevCursorPos,
m_prevAnchorPos );
}
m_prevCursorPos = cursorPos;
m_prevAnchorPos = textCursor().anchor();
}
@ -358,17 +619,120 @@ FileEdit::FileEdit( Okular::FormFieldText * text, QWidget * parent )
lineEdit()->setAlignment( m_form->textAlignment() );
setEnabled( !m_form->isReadOnly() );
connect( this, SIGNAL(textChanged(QString)), this, SLOT(slotChanged(QString)) );
m_prevCursorPos = lineEdit()->cursorPosition();
m_prevAnchorPos = lineEdit()->cursorPosition();
connect( this, SIGNAL( textChanged( QString ) ), this, SLOT( slotChanged() ) );
connect( lineEdit(), SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotChanged() ) );
setVisible( m_form->isVisible() );
}
void FileEdit::slotChanged( const QString& )
void FileEdit::setFormWidgetsController( FormWidgetsController* controller )
{
m_form->setText( url().toLocalFile() );
m_controller->signalChanged( this );
FormWidgetIface::setFormWidgetsController( controller );
connect( m_controller, SIGNAL( formTextChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ),
this, SLOT( slotHandleFileChangedByUndoRedo( int, Okular::FormFieldText*, QString, int, int ) ) );
}
bool FileEdit::eventFilter( QObject* obj, QEvent* event )
{
if ( obj == lineEdit() ) {
if ( event->type() == QEvent::KeyPress )
{
QKeyEvent *keyEvent = static_cast< QKeyEvent* >( event );
if ( keyEvent == QKeySequence::Undo )
{
emit m_controller->requestUndo();
return true;
}
else if ( keyEvent == QKeySequence::Redo )
{
emit m_controller->requestRedo();
return true;
}
}
else if( event->type() == QEvent::ContextMenu )
{
QContextMenuEvent *contextMenuEvent = static_cast< QContextMenuEvent* >( event );
QMenu *menu = ( (QLineEdit*) lineEdit() )->createStandardContextMenu();
QList< QAction* > actionList = menu->actions();
enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, DeleteAct, SelectAllAct };
KAction *kundo = KStandardAction::create( KStandardAction::Undo, m_controller, SIGNAL( requestUndo() ), menu );
KAction *kredo = KStandardAction::create( KStandardAction::Redo, m_controller, SIGNAL( requestRedo() ), menu );
connect(m_controller, SIGNAL( canUndoChanged( bool ) ), kundo, SLOT( setEnabled( bool ) ) );
connect(m_controller, SIGNAL( canRedoChanged( bool ) ), kredo, SLOT( setEnabled( bool ) ) );
kundo->setEnabled( m_controller->canUndo() );
kredo->setEnabled( m_controller->canRedo() );
QAction *oldUndo, *oldRedo;
oldUndo = actionList[UndoAct];
oldRedo = actionList[RedoAct];
menu->insertAction( oldUndo, kundo );
menu->insertAction( oldRedo, kredo );
menu->removeAction( oldUndo );
menu->removeAction( oldRedo );
menu->exec( contextMenuEvent->globalPos() );
delete menu;
return true;
}
}
return KUrlRequester::eventFilter( obj, event );
}
void FileEdit::slotChanged()
{
// Make sure line edit's text matches url expansion
if ( text() != url().toLocalFile() )
this->setText( url().toLocalFile() );
QString contents = text();
int cursorPos = lineEdit()->cursorPosition();
if (contents != m_form->text())
{
m_controller->formTextChangedByWidget( pageItem()->pageNumber(),
m_form,
contents,
cursorPos,
m_prevCursorPos,
m_prevAnchorPos );
}
m_prevCursorPos = cursorPos;
m_prevAnchorPos = cursorPos;
if ( lineEdit()->hasSelectedText() ) {
if ( cursorPos == lineEdit()->selectionStart() ) {
m_prevAnchorPos = lineEdit()->selectionStart() + lineEdit()->selectedText().size();
} else {
m_prevAnchorPos = lineEdit()->selectionStart();
}
}
}
void FileEdit::slotHandleFileChangedByUndoRedo( int pageNumber,
Okular::FormFieldText* form,
const QString & contents,
int cursorPos,
int anchorPos )
{
if ( form != m_form || contents == text() )
{
return;
}
disconnect( this, SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotChanged() ) );
setText( contents );
lineEdit()->setCursorPosition( anchorPos );
lineEdit()->cursorForward( true, cursorPos - anchorPos );
connect( this, SIGNAL(cursorPositionChanged( int, int ) ), this, SLOT( slotChanged() ) );
m_prevCursorPos = cursorPos;
m_prevAnchorPos = anchorPos;
setFocus();
}
ListEdit::ListEdit( Okular::FormFieldChoice * choice, QWidget * parent )
: QListWidget( parent ), FormWidgetIface( this, choice ), m_form( choice )
@ -398,17 +762,44 @@ ListEdit::ListEdit( Okular::FormFieldChoice * choice, QWidget * parent )
setCursor( Qt::ArrowCursor );
}
void ListEdit::setFormWidgetsController( FormWidgetsController* controller )
{
FormWidgetIface::setFormWidgetsController( controller );
connect( m_controller, SIGNAL( formListChangedByUndoRedo(int, Okular::FormFieldChoice*, QList<int> ) ),
this, SLOT( slotHandleFormListChangedByUndoRedo( int, Okular::FormFieldChoice*, QList<int> ) ) );
}
void ListEdit::slotSelectionChanged()
{
QList< QListWidgetItem * > selection = selectedItems();
QList< int > rows;
foreach( const QListWidgetItem * item, selection )
rows.append( row( item ) );
m_form->setCurrentChoices( rows );
m_controller->signalChanged( this );
if ( rows != m_form->currentChoices() ) {
m_controller->formListChangedByWidget( pageItem()->pageNumber(),
m_form,
rows );
}
}
void ListEdit::slotHandleFormListChangedByUndoRedo( int pageNumber,
Okular::FormFieldChoice* listForm,
const QList< int > & choices )
{
if ( m_form != listForm ) {
return;
}
disconnect( this, SIGNAL( itemSelectionChanged() ), this, SLOT( slotSelectionChanged() ) );
for(int i=0; i < count(); i++)
{
item( i )->setSelected( choices.contains(i) );
}
connect( this, SIGNAL( itemSelectionChanged() ), this, SLOT( slotSelectionChanged() ) );
setFocus();
}
ComboEdit::ComboEdit( Okular::FormFieldChoice * choice, QWidget * parent )
: QComboBox( parent ), FormWidgetIface( this, choice ), m_form( choice )
@ -427,27 +818,143 @@ ComboEdit::ComboEdit( Okular::FormFieldChoice * choice, QWidget * parent )
connect( this, SIGNAL(currentIndexChanged(int)), this, SLOT(slotValueChanged()) );
connect( this, SIGNAL(editTextChanged(QString)), this, SLOT(slotValueChanged()) );
connect( lineEdit(), SIGNAL(cursorPositionChanged(int,int)), this, SLOT(slotValueChanged()));
setVisible( m_form->isVisible() );
setCursor( Qt::ArrowCursor );
m_prevCursorPos = lineEdit()->cursorPosition();
m_prevAnchorPos = lineEdit()->cursorPosition();
}
void ComboEdit::setFormWidgetsController(FormWidgetsController* controller)
{
FormWidgetIface::setFormWidgetsController(controller);
connect( m_controller, SIGNAL(formComboChangedByUndoRedo(int,Okular::FormFieldChoice*, QString, int, int )),
this, SLOT(slotHandleFormComboChangedByUndoRedo(int,Okular::FormFieldChoice*, QString, int, int )));
}
void ComboEdit::slotValueChanged()
{
const int index = currentIndex();
const QString text = currentText();
const bool isCustomValue = ( index == -1 || itemText( index ) != text );
const QString text = lineEdit()->text();
if ( isCustomValue )
QString prevText;
if ( m_form->currentChoices().isEmpty() )
{
m_form->setEditChoice( text );
prevText = m_form->editChoice();
}
else
{
m_form->setCurrentChoices( QList< int >() << index );
prevText = m_form->choices()[m_form->currentChoices()[0]];
}
m_controller->signalChanged( this );
int cursorPos = lineEdit()->cursorPosition();
if ( text != prevText )
{
m_controller->formComboChangedByWidget( pageItem()->pageNumber(),
m_form,
currentText(),
cursorPos,
m_prevCursorPos,
m_prevAnchorPos
);
}
prevText = text;
m_prevCursorPos = cursorPos;
m_prevAnchorPos = cursorPos;
if ( lineEdit()->hasSelectedText() ) {
if ( cursorPos == lineEdit()->selectionStart() ) {
m_prevAnchorPos = lineEdit()->selectionStart() + lineEdit()->selectedText().size();
} else {
m_prevAnchorPos = lineEdit()->selectionStart();
}
}
}
void ComboEdit::slotHandleFormComboChangedByUndoRedo( int pageNumber,
Okular::FormFieldChoice* form,
const QString & text,
int cursorPos,
int anchorPos )
{
if ( m_form != form ) {
return;
}
// Determine if text corrisponds to an index choices
int index = -1;
for ( int i = 0; i < count(); i++ )
{
if ( itemText(i) == text )
{
index = i;
}
}
m_prevCursorPos = cursorPos;
m_prevAnchorPos = anchorPos;
disconnect( lineEdit(), SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotValueChanged() ) );
const bool isCustomValue = index == -1;
if ( isCustomValue )
{
setEditText( text );
}
else
{
setCurrentIndex( index );
}
lineEdit()->setCursorPosition( anchorPos );
lineEdit()->cursorForward( true, cursorPos - anchorPos );
connect( lineEdit(), SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( slotValueChanged() ) );
setFocus();
}
void ComboEdit::contextMenuEvent( QContextMenuEvent* event )
{
QMenu *menu = lineEdit()->createStandardContextMenu();
QList<QAction *> actionList = menu->actions();
enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, DeleteAct, SelectAllAct };
KAction *kundo = KStandardAction::create( KStandardAction::Undo, m_controller, SIGNAL( requestUndo() ), menu );
KAction *kredo = KStandardAction::create( KStandardAction::Redo, m_controller, SIGNAL( requestRedo() ), menu );
connect( m_controller, SIGNAL( canUndoChanged( bool ) ), kundo, SLOT( setEnabled( bool ) ) );
connect( m_controller, SIGNAL( canRedoChanged( bool ) ), kredo, SLOT( setEnabled( bool ) ) );
kundo->setEnabled( m_controller->canUndo() );
kredo->setEnabled( m_controller->canRedo() );
QAction *oldUndo, *oldRedo;
oldUndo = actionList[UndoAct];
oldRedo = actionList[RedoAct];
menu->insertAction( oldUndo, kundo );
menu->insertAction( oldRedo, kredo );
menu->removeAction( oldUndo );
menu->removeAction( oldRedo );
menu->exec( event->globalPos() );
delete menu;
}
bool ComboEdit::event( QEvent* e )
{
if ( e->type() == QEvent::KeyPress )
{
QKeyEvent *keyEvent = static_cast< QKeyEvent* >(e);
if ( keyEvent == QKeySequence::Undo )
{
emit m_controller->requestUndo();
return true;
}
else if ( keyEvent == QKeySequence::Redo )
{
emit m_controller->requestRedo();
return true;
}
}
return QComboBox::event( e );
}
#include "formwidgets.moc"

View file

@ -21,10 +21,13 @@
#include <ktextedit.h>
#include <kurlrequester.h>
class ComboEdit;
class QMenu;
class QButtonGroup;
class FormWidgetIface;
class PageViewItem;
class RadioButtonEdit;
class QEvent;
namespace Okular {
class Action;
@ -32,6 +35,7 @@ class FormField;
class FormFieldButton;
class FormFieldChoice;
class FormFieldText;
class Document;
}
struct RadioData
@ -47,24 +51,81 @@ class FormWidgetsController : public QObject
Q_OBJECT
public:
FormWidgetsController( QObject *parent = 0 );
FormWidgetsController( Okular::Document *doc );
virtual ~FormWidgetsController();
void signalChanged( FormWidgetIface *w );
void signalAction( Okular::Action *action );
QButtonGroup* registerRadioButton( FormWidgetIface* widget, const QList< int >& siblings );
QButtonGroup* registerRadioButton( QAbstractButton *button, Okular::FormFieldButton *formButton );
void dropRadioButtons();
bool canUndo();
bool canRedo();
signals:
void changed( FormWidgetIface *w );
void changed( int pageNumber );
void requestUndo();
void requestRedo();
void canUndoChanged( bool undoAvailable );
void canRedoChanged( bool redoAvailable);
void formTextChangedByWidget( int pageNumber,
Okular::FormFieldText *form,
const QString & newContents,
int newCursorPos,
int prevCursorPos,
int prevAnchorPos );
void formTextChangedByUndoRedo( int pageNumber,
Okular::FormFieldText *form,
const QString & contents,
int cursorPos,
int anchorPos );
void formListChangedByWidget( int pageNumber,
Okular::FormFieldChoice *form,
const QList< int > & newChoices );
void formListChangedByUndoRedo( int pageNumber,
Okular::FormFieldChoice *form,
const QList< int > & choices );
void formComboChangedByWidget( int pageNumber,
Okular::FormFieldChoice *form,
const QString & newText,
int newCursorPos,
int prevCursorPos,
int prevAnchorPos
);
void formComboChangedByUndoRedo( int pageNumber,
Okular::FormFieldChoice *form,
const QString & text,
int cursorPos,
int anchorPos
);
void formButtonsChangedByWidget( int pageNumber,
const QList< Okular::FormFieldButton* > & formButtons,
const QList< bool > & newButtonStates );
void action( Okular::Action *action );
private slots:
void slotButtonClicked( QAbstractButton *button );
void slotFormButtonsChangedByUndoRedo( int pageNumber,
const QList< Okular::FormFieldButton* > & formButtons );
private:
friend class TextAreaEdit;
friend class FormLineEdit;
friend class FileEdit;
friend class ListEdit;
friend class ComboEdit;
QList< RadioData > m_radios;
QHash< int, Okular::FormFieldButton* > m_formButtons;
QHash< int, QAbstractButton* > m_buttons;
Okular::Document* m_doc;
};
@ -147,9 +208,6 @@ class RadioButtonEdit : public QRadioButton, public FormWidgetIface
void setFormWidgetsController( FormWidgetsController *controller );
QAbstractButton* button();
private slots:
void slotToggled( bool checked );
private:
Okular::FormFieldButton * m_form;
};
@ -160,12 +218,24 @@ class FormLineEdit : public QLineEdit, public FormWidgetIface
public:
explicit FormLineEdit( Okular::FormFieldText * text, QWidget * parent = 0 );
void setFormWidgetsController( FormWidgetsController *controller );
virtual bool event ( QEvent * e );
virtual void contextMenuEvent( QContextMenuEvent* event );
public slots:
void slotHandleTextChangedByUndoRedo( int pageNumber,
Okular::FormFieldText* textForm,
const QString & contents,
int cursorPos,
int anchorPos );
private slots:
void textEdited( const QString& );
void slotChanged();
private:
Okular::FormFieldText * m_form;
int m_prevCursorPos;
int m_prevAnchorPos;
};
class TextAreaEdit : public KTextEdit, public FormWidgetIface
@ -174,12 +244,25 @@ class TextAreaEdit : public KTextEdit, public FormWidgetIface
public:
explicit TextAreaEdit( Okular::FormFieldText * text, QWidget * parent = 0 );
void setFormWidgetsController( FormWidgetsController *controller );
virtual bool event ( QEvent * e );
public slots:
void slotHandleTextChangedByUndoRedo( int pageNumber,
Okular::FormFieldText * textForm,
const QString & contents,
int cursorPos,
int anchorPos );
void slotUpdateUndoAndRedoInContextMenu( QMenu* menu );
private slots:
void slotChanged();
private:
Okular::FormFieldText * m_form;
int m_prevCursorPos;
int m_prevAnchorPos;
};
@ -189,12 +272,23 @@ class FileEdit : public KUrlRequester, public FormWidgetIface
public:
explicit FileEdit( Okular::FormFieldText * text, QWidget * parent = 0 );
void setFormWidgetsController( FormWidgetsController *controller );
protected:
bool eventFilter( QObject *obj, QEvent *event );
private slots:
void slotChanged( const QString& );
void slotChanged();
void slotHandleFileChangedByUndoRedo( int pageNumber,
Okular::FormFieldText * form,
const QString & contents,
int cursorPos,
int anchorPos );
private:
Okular::FormFieldText * m_form;
int m_prevCursorPos;
int m_prevAnchorPos;
};
@ -204,9 +298,13 @@ class ListEdit : public QListWidget, public FormWidgetIface
public:
explicit ListEdit( Okular::FormFieldChoice * choice, QWidget * parent = 0 );
void setFormWidgetsController( FormWidgetsController *controller );
private slots:
void slotSelectionChanged();
void slotHandleFormListChangedByUndoRedo( int pageNumber,
Okular::FormFieldChoice * listForm,
const QList< int > & choices );
private:
Okular::FormFieldChoice * m_form;
@ -219,13 +317,23 @@ class ComboEdit : public QComboBox, public FormWidgetIface
public:
explicit ComboEdit( Okular::FormFieldChoice * choice, QWidget * parent = 0 );
void setFormWidgetsController( FormWidgetsController *controller );
virtual bool event ( QEvent * e );
virtual void contextMenuEvent( QContextMenuEvent* event );
private slots:
void slotValueChanged();
void slotHandleFormComboChangedByUndoRedo( int pageNumber,
Okular::FormFieldChoice * comboForm,
const QString & text,
int cursorPos,
int anchorPos
);
private:
Okular::FormFieldChoice * m_form;
int m_prevCursorPos;
int m_prevAnchorPos;
};
#endif

View file

@ -223,11 +223,11 @@ FormWidgetsController* PageViewPrivate::formWidgetsController()
{
if ( !formsWidgetController )
{
formsWidgetController = new FormWidgetsController();
QObject::connect( formsWidgetController, SIGNAL(changed(FormWidgetIface*)),
q, SLOT(slotFormWidgetChanged(FormWidgetIface*)) );
QObject::connect( formsWidgetController, SIGNAL(action(Okular::Action*)),
q, SLOT(slotAction(Okular::Action*)) );
formsWidgetController = new FormWidgetsController( document );
QObject::connect( formsWidgetController, SIGNAL( changed( int ) ),
q, SLOT( slotFormChanged( int ) ) );
QObject::connect( formsWidgetController, SIGNAL( action( Okular::Action* ) ),
q, SLOT( slotAction( Okular::Action* ) ) );
}
return formsWidgetController;
@ -4642,17 +4642,22 @@ void PageView::slotToggleForms()
toggleFormWidgets( !d->m_formsVisible );
}
void PageView::slotFormWidgetChanged( FormWidgetIface *w )
void PageView::slotFormChanged( int pageNumber )
{
if ( !d->refreshTimer )
{
d->refreshTimer = new QTimer( this );
d->refreshTimer->setSingleShot( true );
connect( d->refreshTimer, SIGNAL(timeout()),
this, SLOT(slotRefreshPage()) );
connect( d->refreshTimer, SIGNAL( timeout() ),
this, SLOT( slotRefreshPage() ) );
}
d->refreshPage = w->pageItem()->pageNumber();
d->refreshTimer->start( 1000 );
d->refreshPage = pageNumber;
int delay = 0;
if ( d->m_formsVisible )
{
delay = 1000;
}
d->refreshTimer->start( delay );
}
void PageView::slotRefreshPage()

View file

@ -248,7 +248,7 @@ Q_OBJECT
void slotPageSizes( int );
void slotTrimMarginsToggled( bool );
void slotToggleForms();
void slotFormWidgetChanged( FormWidgetIface *w );
void slotFormChanged( int pageNumber );
void slotRefreshPage();
void slotSpeakDocument();
void slotSpeakCurrentPage();