diff --git a/core/form.h b/core/form.h index 65f946869..a9bac7ba6 100644 --- a/core/form.h +++ b/core/form.h @@ -1,457 +1,465 @@ /*************************************************************************** * Copyright (C) 2007 by Pino Toscano * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef _OKULAR_FORM_H_ #define _OKULAR_FORM_H_ #include "okularcore_export.h" #include "area.h" #include "annotations.h" #include "signatureutils.h" #include #include namespace Okular { class Action; class Page; class PagePrivate; class FormFieldPrivate; class FormFieldButtonPrivate; class FormFieldTextPrivate; class FormFieldChoicePrivate; class FormFieldSignaturePrivate; /** * @short The base interface of a form field. * * This is the very basic interface to represent a field in a form. * * This is not meant to be used as a direct base for the form fields in a * document, but its abstract subclasses are. */ class OKULARCORE_EXPORT FormField { /// @cond PRIVATE friend class Page; friend class PagePrivate; /// @endcond public: /** * The types of form field. */ enum FieldType { FormButton, ///< A "button". See @ref FormFieldButton::ButtonType. FormText, ///< A field of variable text. See @ref FormFieldText::TextType. FormChoice, ///< A choice field. See @ref FormFieldChoice::ChoiceType. FormSignature ///< A signature. }; virtual ~FormField(); /** * The type of the field. */ FieldType type() const; /** * The bounding rect of the field, in normalized coordinates. */ virtual NormalizedRect rect() const = 0; /** * The ID of the field. */ virtual int id() const = 0; /** * The internal name of the field, to be used when referring to the * field in eg scripts. */ virtual QString name() const = 0; /** * The visible name of the field, to be used in the user interface * (eg in error messages, etc). */ virtual QString uiName() const = 0; + /** + * The fully qualified name of the field, is used in the JavaScript + * scripts. + * + * @since 1.9 + */ + virtual QString fullyQualifiedName() const = 0; + /** * Whether the field is read-only. */ virtual bool isReadOnly() const; /** * Whether the field is read-only. * * @since 1.4 */ virtual void setReadOnly( bool value ); /** * Whether this form field is visible. */ virtual bool isVisible() const; /** * Whether the field is visible. * * @since 1.5 */ virtual void setVisible( bool value ); /** Whether this field is printable. @since 1.9 */ virtual bool isPrintable() const; /** Set this field printable @since 1.9 */ virtual void setPrintable( bool value ); Action* activationAction() const; /** * Describes the type of form additional action. * * @since 1.1 */ enum AdditionalActionType { FieldModified, ///< An action to be performed when the user modifies the field FormatField, ///< An action to be performed before the field is formatted to display its value ValidateField, ///< An action to be performed when the field value changes CalculateField, ///< An action to be performed when the field needs to be recalculated }; /** * Returns the additional action of the given @p type or @c nullptr if no action has been defined. * * @since 1.1 */ Action* additionalAction( AdditionalActionType type ) const; /* Returns the additional action of the given @p type or @c nullptr if no action has been defined. * * This is for actions of annotation widgets associated with the FormField * * @since 1.5 */ Action* additionalAction( Annotation::AdditionalActionType type ) const; protected: /// @cond PRIVATE FormField( FormFieldPrivate &dd ); Q_DECLARE_PRIVATE( FormField ) FormFieldPrivate *d_ptr; /// @endcond void setActivationAction( Action *action ); void setAdditionalAction( AdditionalActionType type, Action *action ); void setAdditionalAction( Annotation::AdditionalActionType type, Action *action ); private: Q_DISABLE_COPY( FormField ) }; /** * @short Interface of a button form field. * * This is the base interface to reimplement to represent a button field, like * a push button, a check box or a radio button. * * @since 0.7 (KDE 4.1) */ class OKULARCORE_EXPORT FormFieldButton : public FormField { public: /** * The types of button field. */ enum ButtonType { Push, ///< A simple push button. CheckBox, ///< A check box. Radio ///< A radio button. }; virtual ~FormFieldButton(); /** The particular type of the button field. */ virtual ButtonType buttonType() const = 0; /** * The caption to be used for the button. */ virtual QString caption() const = 0; /** * The state of the button. */ virtual bool state() const = 0; /** * Sets the state of the button to the new \p state . */ virtual void setState( bool state ); /** * The list with the IDs of siblings (ie, buttons belonging to the same * group as the current one. * * Valid only for \ref Radio buttons, an empty list otherwise. */ virtual QList< int > siblings() const = 0; /** * Sets the icon of the Button to the Icon of the field parameter. * * @since 1.9 */ virtual void setIcon( Okular::FormField *field ); protected: FormFieldButton(); private: Q_DECLARE_PRIVATE( FormFieldButton ) Q_DISABLE_COPY( FormFieldButton ) }; /** * @short Interface of a text form field. * * This is the base interface to reimplement to represent a text field, ie a * field where the user insert text. */ class OKULARCORE_EXPORT FormFieldText : public FormField { public: /** * The types of text field. */ enum TextType { Normal, ///< A simple singleline text field. Multiline, ///< A multiline text field. FileSelect ///< An input field to select the path of a file on disk. }; virtual ~FormFieldText(); /** * The particular type of the text field. */ virtual TextType textType() const = 0; /** * The text of text field. */ virtual QString text() const = 0; /** * Sets the new @p text in the text field. * * The default implementation does nothing. * * Reimplemented only if the setting of new text is supported. */ virtual void setText( const QString& text ); /** * Whether this text field is a password input, eg its text @b must be * replaced with asterisks. * * Always false for @ref FileSelect text fields. */ virtual bool isPassword() const; /** * Whether this text field should allow rich text. */ virtual bool isRichText() const; /** * The maximum length allowed for the text of text field, or -1 if * there is no limitation for the text. */ virtual int maximumLength() const; /** * The alignment of the text within the field. */ virtual Qt::Alignment textAlignment() const; /** * Whether the text inserted manually in the field (where possible) * can be spell-checked. * * @note meaningful only if the field is editable. */ virtual bool canBeSpellChecked() const; protected: FormFieldText(); private: Q_DECLARE_PRIVATE( FormFieldText ) Q_DISABLE_COPY( FormFieldText ) }; /** * @short Interface of a choice form field. * * This is the base interface to reimplement to represent a choice field, ie a * field where the user can select one (of more) element(s) among a set of * choices. */ class OKULARCORE_EXPORT FormFieldChoice : public FormField { public: /** * The types of choice field. */ enum ChoiceType { ComboBox, ///< A combo box choice field. ListBox ///< A list box choice field. }; virtual ~FormFieldChoice(); /** * The particular type of the choice field. */ virtual ChoiceType choiceType() const = 0; /** * The possible choices of the choice field. */ virtual QStringList choices() const = 0; /** * Whether this ComboBox is editable, ie the user can type in a custom * value. * * Always false for the other types of choices. */ virtual bool isEditable() const; /** * Whether more than one choice of this ListBox can be selected at the * same time. * * Always false for the other types of choices. */ virtual bool multiSelect() const; /** * The currently selected choices. * * Always one element in the list in case of single choice elements. */ virtual QList< int > currentChoices() const = 0; /** * Sets the selected choices to @p choices . */ virtual void setCurrentChoices( const QList< int >& choices ); /** The text entered into an editable combo box choice field @since 0.16 (KDE 4.10) */ virtual QString editChoice() const; /** Sets the text entered into an editable combo box choice field @since 0.16 (KDE 4.10) */ virtual void setEditChoice( const QString& text ); /** * The alignment of the text within the field. */ virtual Qt::Alignment textAlignment() const; /** * Whether the text inserted manually in the field (where possible) * can be spell-checked. * * @note meaningful only if the field is editable. */ virtual bool canBeSpellChecked() const; protected: FormFieldChoice(); private: Q_DECLARE_PRIVATE( FormFieldChoice ) Q_DISABLE_COPY( FormFieldChoice ) }; /** * @short Interface of a signature form field. * * This is the base interface to reimplement to represent a signature field. */ class OKULARCORE_EXPORT FormFieldSignature : public FormField { public: /** * The types of signature. */ enum SignatureType { AdbePkcs7sha1, AdbePkcs7detached, EtsiCAdESdetached, UnknownType }; ~FormFieldSignature(); /** * The signature type */ virtual SignatureType signatureType() const = 0; /** * The signature info */ virtual const SignatureInfo &signatureInfo() const = 0; protected: FormFieldSignature(); private: Q_DECLARE_PRIVATE( FormFieldSignature ) Q_DISABLE_COPY( FormFieldSignature ) }; } Q_DECLARE_METATYPE(const Okular::FormFieldSignature *); #endif diff --git a/core/script/kjs_document.cpp b/core/script/kjs_document.cpp index deb95103b..9b5796e67 100644 --- a/core/script/kjs_document.cpp +++ b/core/script/kjs_document.cpp @@ -1,359 +1,359 @@ /*************************************************************************** * Copyright (C) 2008 by Pino Toscano * * Copyright (C) 2008 by Harri Porten * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "kjs_document_p.h" #include #include #include #include #include #include #include "../document_p.h" #include "../page.h" #include "../form.h" #include "kjs_data_p.h" #include "kjs_field_p.h" #include "kjs_ocg_p.h" using namespace Okular; static KJSPrototype *g_docProto; // Document.numPages static KJSObject docGetNumPages( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); return KJSNumber( doc->m_pagesVector.count() ); } // Document.pageNum (getter) static KJSObject docGetPageNum( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); return KJSNumber( doc->m_parent->currentPage() ); } // Document.pageNum (setter) static void docSetPageNum( KJSContext* ctx, void* object, KJSObject value ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); int page = value.toInt32( ctx ); if ( page == (int)doc->m_parent->currentPage() ) return; doc->m_parent->setViewportPage( page ); } // Document.documentFileName static KJSObject docGetDocumentFileName( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); return KJSString( doc->m_url.fileName() ); } // Document.filesize static KJSObject docGetFilesize( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); return KJSNumber( doc->m_docSize ); } // Document.path static KJSObject docGetPath( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); return KJSString( doc->m_url.toDisplayString(QUrl::PreferLocalFile) ); } // Document.URL static KJSObject docGetURL( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); return KJSString( doc->m_url.toDisplayString() ); } // Document.permStatusReady static KJSObject docGetPermStatusReady( KJSContext *, void * ) { return KJSBoolean( true ); } // Document.dataObjects static KJSObject docGetDataObjects( KJSContext *ctx, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); const QList< EmbeddedFile * > *files = doc->m_generator->embeddedFiles(); KJSArray dataObjects( ctx, files ? files->count() : 0 ); if ( files ) { QList< EmbeddedFile * >::ConstIterator it = files->begin(), itEnd = files->end(); for ( int i = 0; it != itEnd; ++it, ++i ) { KJSObject newdata = JSData::wrapFile( ctx, *it ); dataObjects.setProperty( ctx, QString::number( i ), newdata ); } } return dataObjects; } // Document.external static KJSObject docGetExternal( KJSContext *, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); QWidget *widget = doc->m_widget; const bool isShell = ( widget && widget->parentWidget() && widget->parentWidget()->objectName().startsWith( QLatin1String( "okular::Shell" ) ) ); return KJSBoolean( !isShell ); } // Document.numFields static KJSObject docGetNumFields( KJSContext *, void *object ) { const DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); unsigned int numFields = 0; for ( const Page * pIt : qAsConst(doc->m_pagesVector) ) { numFields += pIt->formFields().size(); } return KJSNumber( numFields ); } static KJSObject docGetInfo( KJSContext *ctx, void *object ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); KJSObject obj; QSet keys; keys << DocumentInfo::Title << DocumentInfo::Author << DocumentInfo::Subject << DocumentInfo::Keywords << DocumentInfo::Creator << DocumentInfo::Producer; const DocumentInfo docinfo = doc->m_parent->documentInfo( keys ); #define KEY_GET( key, property ) \ do { \ const QString data = docinfo.get( key ); \ if ( !data.isEmpty() ) \ { \ const KJSString newval( data ); \ obj.setProperty( ctx, QStringLiteral(property), newval ); \ obj.setProperty( ctx, QStringLiteral( property ).toLower(), newval ); \ } \ } while ( 0 ); KEY_GET( DocumentInfo::Title, "Title" ); KEY_GET( DocumentInfo::Author, "Author" ); KEY_GET( DocumentInfo::Subject, "Subject" ); KEY_GET( DocumentInfo::Keywords, "Keywords" ); KEY_GET( DocumentInfo::Creator, "Creator" ); KEY_GET( DocumentInfo::Producer, "Producer" ); #undef KEY_GET return obj; } #define DOCINFO_GET_METHOD( key, name ) \ static KJSObject docGet ## name( KJSContext *, void *object ) \ { \ DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); \ const DocumentInfo docinfo = doc->m_parent->documentInfo(QSet() << key ); \ return KJSString( docinfo.get( key ) ); \ } DOCINFO_GET_METHOD( DocumentInfo::Author, Author ) DOCINFO_GET_METHOD( DocumentInfo::Creator, Creator ) DOCINFO_GET_METHOD( DocumentInfo::Keywords, Keywords ) DOCINFO_GET_METHOD( DocumentInfo::Producer, Producer ) DOCINFO_GET_METHOD( DocumentInfo::Title, Title ) DOCINFO_GET_METHOD( DocumentInfo::Subject, Subject ) #undef DOCINFO_GET_METHOD // Document.getField() static KJSObject docGetField( KJSContext *context, void *object, const KJSArguments &arguments ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); QString cName = arguments.at( 0 ).toString( context ); QVector< Page * >::const_iterator pIt = doc->m_pagesVector.constBegin(), pEnd = doc->m_pagesVector.constEnd(); for ( ; pIt != pEnd; ++pIt ) { const QLinkedList< Okular::FormField * > pageFields = (*pIt)->formFields(); QLinkedList< Okular::FormField * >::const_iterator ffIt = pageFields.constBegin(), ffEnd = pageFields.constEnd(); for ( ; ffIt != ffEnd; ++ffIt ) { - if ( (*ffIt)->name() == cName ) + if ( (*ffIt)->fullyQualifiedName() == cName ) { return JSField::wrapField( context, *ffIt, *pIt ); } } } return KJSUndefined(); } // Document.getPageLabel() static KJSObject docGetPageLabel( KJSContext *ctx,void *object, const KJSArguments &arguments ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); int nPage = arguments.at( 0 ).toInt32( ctx ); Page *p = doc->m_pagesVector.value( nPage ); return KJSString( p ? p->label() : QString() ); } // Document.getPageRotation() static KJSObject docGetPageRotation( KJSContext *ctx, void *object, const KJSArguments &arguments ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); int nPage = arguments.at( 0 ).toInt32( ctx ); Page *p = doc->m_pagesVector.value( nPage ); return KJSNumber( p ? p->orientation() * 90 : 0 ); } // Document.gotoNamedDest() static KJSObject docGotoNamedDest( KJSContext *ctx, void *object, const KJSArguments &arguments ) { DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); QString dest = arguments.at( 0 ).toString( ctx ); DocumentViewport viewport( doc->m_generator->metaData( QStringLiteral("NamedViewport"), dest ).toString() ); if ( !viewport.isValid() ) return KJSUndefined(); doc->m_parent->setViewport( viewport ); return KJSUndefined(); } // Document.syncAnnotScan() static KJSObject docSyncAnnotScan( KJSContext *, void *, const KJSArguments & ) { return KJSUndefined(); } // Document.getNthFieldName static KJSObject docGetNthFieldName( KJSContext *ctx, void *object, const KJSArguments &arguments ) { const DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); int numField = arguments.at( 0 ).toInt32( ctx ); for ( const Page * pIt : qAsConst(doc->m_pagesVector) ) { const QLinkedList< Okular::FormField * > pageFields = pIt->formFields(); if(numField < pageFields.size()) { const auto ffIt = pageFields.begin() + numField; - return KJSString( (*ffIt)->name() ); + return KJSString( (*ffIt)->fullyQualifiedName() ); } numField -= pageFields.size(); } return KJSUndefined(); } static KJSObject docGetOCGs( KJSContext *ctx, void *object, const KJSArguments & ) { const DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); QAbstractItemModel * model = doc->m_parent->layersModel(); KJSArray array( ctx, model->rowCount() ); for(int i = 0;i < model->rowCount();++i){ for(int j = 0;j < model->columnCount();++j){ const QModelIndex index = model->index( i, j ); KJSObject item = JSOCG::wrapOCGObject( ctx, model, i, j ); item.setProperty( ctx, QStringLiteral("name"), model->data( index , Qt::DisplayRole ).toString() ); item.setProperty( ctx, QStringLiteral("initState"), model->data( index , Qt::CheckStateRole ).toBool() ); array.setProperty( ctx, QString::number( i ), item ); } } return array; } void JSDocument::initType( KJSContext *ctx ) { assert( g_docProto ); static bool initialized = false; if ( initialized ) return; initialized = true; g_docProto->defineProperty( ctx, QStringLiteral("numPages"), docGetNumPages ); g_docProto->defineProperty( ctx, QStringLiteral("pageNum"), docGetPageNum, docSetPageNum ); g_docProto->defineProperty( ctx, QStringLiteral("documentFileName"), docGetDocumentFileName ); g_docProto->defineProperty( ctx, QStringLiteral("filesize"), docGetFilesize ); g_docProto->defineProperty( ctx, QStringLiteral("path"), docGetPath ); g_docProto->defineProperty( ctx, QStringLiteral("URL"), docGetURL ); g_docProto->defineProperty( ctx, QStringLiteral("permStatusReady"), docGetPermStatusReady ); g_docProto->defineProperty( ctx, QStringLiteral("dataObjects"), docGetDataObjects ); g_docProto->defineProperty( ctx, QStringLiteral("external"), docGetExternal ); g_docProto->defineProperty( ctx, QStringLiteral("numFields"), docGetNumFields ); // info properties g_docProto->defineProperty( ctx, QStringLiteral("info"), docGetInfo ); g_docProto->defineProperty( ctx, QStringLiteral("author"), docGetAuthor ); g_docProto->defineProperty( ctx, QStringLiteral("creator"), docGetCreator ); g_docProto->defineProperty( ctx, QStringLiteral("keywords"), docGetKeywords ); g_docProto->defineProperty( ctx, QStringLiteral("producer"), docGetProducer ); g_docProto->defineProperty( ctx, QStringLiteral("title"), docGetTitle ); g_docProto->defineProperty( ctx, QStringLiteral("subject"), docGetSubject ); g_docProto->defineFunction( ctx, QStringLiteral("getField"), docGetField ); g_docProto->defineFunction( ctx, QStringLiteral("getPageLabel"), docGetPageLabel ); g_docProto->defineFunction( ctx, QStringLiteral("getPageRotation"), docGetPageRotation ); g_docProto->defineFunction( ctx, QStringLiteral("gotoNamedDest"), docGotoNamedDest ); g_docProto->defineFunction( ctx, QStringLiteral("syncAnnotScan"), docSyncAnnotScan ); g_docProto->defineFunction( ctx, QStringLiteral("getNthFieldName"), docGetNthFieldName ); g_docProto->defineFunction( ctx, QStringLiteral("getOCGs"), docGetOCGs ); } KJSGlobalObject JSDocument::wrapDocument( DocumentPrivate *doc ) { if ( !g_docProto ) g_docProto = new KJSPrototype(); return g_docProto->constructGlobalObject( doc ); } diff --git a/core/script/kjs_field.cpp b/core/script/kjs_field.cpp index bb7b6b5d9..ff96ba015 100644 --- a/core/script/kjs_field.cpp +++ b/core/script/kjs_field.cpp @@ -1,344 +1,344 @@ /*************************************************************************** * Copyright (C) 2008 by Pino Toscano * * Copyright (C) 2008 by Harri Porten * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "kjs_field_p.h" #include #include #include #include #include #include "../debug_p.h" #include "../document_p.h" #include "../form.h" #include "../page.h" #include "../page_p.h" #include "kjs_display_p.h" using namespace Okular; #define OKULAR_NAME QStringLiteral("okular_name") static KJSPrototype *g_fieldProto; typedef QHash< FormField *, Page * > FormCache; Q_GLOBAL_STATIC( FormCache, g_fieldCache ) typedef QHash< QString, FormField * > ButtonCache; Q_GLOBAL_STATIC( ButtonCache, g_buttonCache ) // Helper for modified fields static void updateField( FormField *field ) { Page *page = g_fieldCache->value( field ); if (page) { 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 { qWarning() << "Could not get page of field" << field; } } // Field.doc static KJSObject fieldGetDoc( KJSContext *context, void * ) { return context->interpreter().globalObject(); } // Field.name static KJSObject fieldGetName( KJSContext *, void *object ) { const FormField *field = reinterpret_cast< FormField * >( object ); - return KJSString( field->name() ); + return KJSString( field->fullyQualifiedName() ); } // Field.readonly (getter) static KJSObject fieldGetReadOnly( KJSContext *, void *object ) { const FormField *field = reinterpret_cast< FormField * >( object ); return KJSBoolean( field->isReadOnly() ); } // Field.readonly (setter) static void fieldSetReadOnly( KJSContext *context, void *object, KJSObject value ) { FormField *field = reinterpret_cast< FormField * >( object ); bool b = value.toBoolean( context ); field->setReadOnly( b ); updateField( field ); } static QString fieldGetTypeHelper( const FormField *field ) { switch ( field->type() ) { case FormField::FormButton: { const FormFieldButton *button = static_cast< const FormFieldButton * >( field ); switch ( button->buttonType() ) { case FormFieldButton::Push: return QStringLiteral("button"); case FormFieldButton::CheckBox: return QStringLiteral("checkbox"); case FormFieldButton::Radio: return QStringLiteral("radiobutton"); } break; } case FormField::FormText: return QStringLiteral("text"); case FormField::FormChoice: { const FormFieldChoice *choice = static_cast< const FormFieldChoice * >( field ); switch ( choice->choiceType() ) { case FormFieldChoice::ComboBox: return QStringLiteral("combobox"); case FormFieldChoice::ListBox: return QStringLiteral("listbox"); } break; } case FormField::FormSignature: return QStringLiteral("signature"); } return QString(); } // Field.type static KJSObject fieldGetType( KJSContext *, void *object ) { const FormField *field = reinterpret_cast< FormField * >( object ); return KJSString( fieldGetTypeHelper( field ) ); } // Field.value (getter) static KJSObject fieldGetValue( KJSContext */*context*/, void *object ) { FormField *field = reinterpret_cast< FormField * >( object ); switch ( field->type() ) { case FormField::FormButton: { const FormFieldButton *button = static_cast< const FormFieldButton * >( field ); if ( button->state() ) { return KJSString( QStringLiteral( "Yes" ) ); } return KJSString( QStringLiteral( "Off" ) ); } case FormField::FormText: { const FormFieldText *text = static_cast< const FormFieldText * >( field ); return KJSString( text->text() ); } case FormField::FormChoice: { const FormFieldChoice *choice = static_cast< const FormFieldChoice * >( field ); Q_UNUSED( choice ); // ### break; } case FormField::FormSignature: { break; } } return KJSUndefined(); } // Field.value (setter) static void fieldSetValue( KJSContext *context, void *object, KJSObject value ) { FormField *field = reinterpret_cast< FormField * >( object ); switch ( field->type() ) { case FormField::FormButton: { FormFieldButton *button = static_cast< FormFieldButton * >( field ); const QString text = value.toString( context ); if ( text == QStringLiteral( "Yes" ) ) { button->setState( true ); updateField( field ); } else if ( text == QStringLiteral( "Off" ) ) { button->setState( false ); updateField( field ); } break; } case FormField::FormText: { FormFieldText *textField = static_cast< FormFieldText * >( field ); const QString text = value.toString( context ); if ( text != textField->text() ) { textField->setText( text ); updateField( field ); } break; } case FormField::FormChoice: { FormFieldChoice *choice = static_cast< FormFieldChoice * >( field ); Q_UNUSED( choice ); // ### break; } case FormField::FormSignature: { break; } } } // Field.hidden (getter) static KJSObject fieldGetHidden( KJSContext *, void *object ) { const FormField *field = reinterpret_cast< FormField * >( object ); return KJSBoolean( !field->isVisible() ); } // Field.hidden (setter) static void fieldSetHidden( KJSContext *context, void *object, KJSObject value ) { FormField *field = reinterpret_cast< FormField * >( object ); bool b = value.toBoolean( context ); field->setVisible( !b ); updateField( field ); } // Field.display (getter) static KJSObject fieldGetDisplay( KJSContext *, void *object ) { const FormField *field = reinterpret_cast< FormField * >( object ); bool visible = field->isVisible(); if( visible ) { return KJSNumber( field->isPrintable() ? FormDisplay::FormVisible : FormDisplay::FormNoPrint ); } return KJSNumber( field->isPrintable() ? FormDisplay::FormNoView : FormDisplay::FormHidden ); } // Field.display (setter) static void fieldSetDisplay( KJSContext *context, void *object, KJSObject value ) { FormField *field = reinterpret_cast< FormField * >( object ); const unsigned int b = value.toInt32( context ); switch( b ) { case FormDisplay::FormVisible: field->setVisible( true ); field->setPrintable( true ); break; case FormDisplay::FormHidden: field->setVisible( false ); field->setPrintable( false ); break; case FormDisplay::FormNoPrint: field->setVisible( true ); field->setPrintable( false ); break; case FormDisplay::FormNoView: field->setVisible( false ); field->setPrintable( true ); break; } updateField( field ); } // Instead of getting the Icon, we pick the field. static KJSObject fieldButtonGetIcon( KJSContext *ctx, void *object, const KJSArguments & ) { FormField *field = reinterpret_cast< FormField * >( object ); KJSObject fieldObject; - fieldObject.setProperty( ctx, OKULAR_NAME, field->name() ); - g_buttonCache->insert( field->name(), field ); + fieldObject.setProperty( ctx, OKULAR_NAME, field->fullyQualifiedName() ); + g_buttonCache->insert( field->fullyQualifiedName(), field ); return fieldObject; } /* * Now we send to the button what Icon should be drawn on it */ static KJSObject fieldButtonSetIcon( KJSContext *ctx, void *object, const KJSArguments &arguments ) { FormField *field = reinterpret_cast< FormField * >( object ); const QString fieldName = arguments.at( 0 ).property( ctx, OKULAR_NAME ).toString( ctx ); if( field->type() == Okular::FormField::FormButton ) { FormFieldButton *button = static_cast< FormFieldButton * >( field ); button->setIcon( g_buttonCache->value( fieldName ) ); } updateField( field ); return KJSUndefined(); } void JSField::initType( KJSContext *ctx ) { static bool initialized = false; if ( initialized ) return; initialized = true; if ( !g_fieldProto ) g_fieldProto = new KJSPrototype(); g_fieldProto->defineProperty( ctx, QStringLiteral("doc"), fieldGetDoc ); g_fieldProto->defineProperty( ctx, QStringLiteral("name"), fieldGetName ); g_fieldProto->defineProperty( ctx, QStringLiteral("readonly"), fieldGetReadOnly, fieldSetReadOnly ); g_fieldProto->defineProperty( ctx, QStringLiteral("type"), fieldGetType ); g_fieldProto->defineProperty( ctx, QStringLiteral("value"), fieldGetValue, fieldSetValue ); g_fieldProto->defineProperty( ctx, QStringLiteral("hidden"), fieldGetHidden, fieldSetHidden ); g_fieldProto->defineProperty( ctx, QStringLiteral("display"), fieldGetDisplay, fieldSetDisplay ); g_fieldProto->defineFunction( ctx, QStringLiteral("buttonGetIcon"), fieldButtonGetIcon ); g_fieldProto->defineFunction( ctx, QStringLiteral("buttonSetIcon"), fieldButtonSetIcon ); } KJSObject JSField::wrapField( KJSContext *ctx, FormField *field, Page *page ) { // ### cache unique wrapper KJSObject f = g_fieldProto->constructObject( ctx, field ); f.setProperty( ctx, QStringLiteral("page"), page->number() ); g_fieldCache->insert( field, page ); return f; } void JSField::clearCachedFields() { if ( g_fieldCache.exists() ) g_fieldCache->clear(); if( g_buttonCache.exists() ) g_buttonCache->clear(); } diff --git a/generators/poppler/formfields.cpp b/generators/poppler/formfields.cpp index 2092c5220..2dedce58b 100644 --- a/generators/poppler/formfields.cpp +++ b/generators/poppler/formfields.cpp @@ -1,527 +1,547 @@ /*************************************************************************** * Copyright (C) 2007 by Pino Toscano * * Copyright (C) 2018 by Intevation GmbH * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "formfields.h" #include "core/action.h" #include "pdfsignatureutils.h" #include #include extern Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink, bool deletePopplerLink = true); #ifdef HAVE_POPPLER_0_65 # define SET_ANNOT_ACTIONS \ setAdditionalAction( Okular::Annotation::CursorEntering, createLinkFromPopplerLink( field->additionalAction( Poppler::Annotation::CursorEnteringAction ) ) ); \ setAdditionalAction( Okular::Annotation::CursorLeaving, createLinkFromPopplerLink( field->additionalAction( Poppler::Annotation::CursorLeavingAction ) ) ); \ setAdditionalAction( Okular::Annotation::MousePressed, createLinkFromPopplerLink( field->additionalAction( Poppler::Annotation::MousePressedAction ) ) ); \ setAdditionalAction( Okular::Annotation::MouseReleased, createLinkFromPopplerLink( field->additionalAction( Poppler::Annotation::MouseReleasedAction ) ) ); \ setAdditionalAction( Okular::Annotation::FocusIn, createLinkFromPopplerLink( field->additionalAction( Poppler::Annotation::FocusInAction ) ) ); \ setAdditionalAction( Okular::Annotation::FocusOut, createLinkFromPopplerLink( field->additionalAction( Poppler::Annotation::FocusOutAction ) ) ); #else # define SET_ANNOT_ACTIONS #endif #ifdef HAVE_POPPLER_0_53 #define SET_ACTIONS \ setActivationAction( createLinkFromPopplerLink( field->activationAction() ) ); \ setAdditionalAction( Okular::FormField::FieldModified, createLinkFromPopplerLink( field->additionalAction( Poppler::FormField::FieldModified ) ) ); \ setAdditionalAction( Okular::FormField::FormatField, createLinkFromPopplerLink( field->additionalAction( Poppler::FormField::FormatField ) ) ); \ setAdditionalAction( Okular::FormField::ValidateField, createLinkFromPopplerLink( field->additionalAction( Poppler::FormField::ValidateField ) ) ); \ setAdditionalAction( Okular::FormField::CalculateField, createLinkFromPopplerLink( field->additionalAction( Poppler::FormField::CalculateField ) ) ); \ SET_ANNOT_ACTIONS #else #define SET_ACTIONS \ setActivationAction( createLinkFromPopplerLink( field->activationAction() ) ); #endif PopplerFormFieldButton::PopplerFormFieldButton( Poppler::FormFieldButton * field ) : Okular::FormFieldButton(), m_field( field ) { m_rect = Okular::NormalizedRect::fromQRectF( m_field->rect() ); m_id = m_field->id(); SET_ACTIONS } PopplerFormFieldButton::~PopplerFormFieldButton() { delete m_field; } Okular::NormalizedRect PopplerFormFieldButton::rect() const { return m_rect; } int PopplerFormFieldButton::id() const { return m_id; } QString PopplerFormFieldButton::name() const { return m_field->name(); } QString PopplerFormFieldButton::uiName() const { return m_field->uiName(); } +QString PopplerFormFieldButton::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + bool PopplerFormFieldButton::isReadOnly() const { return m_field->isReadOnly(); } void PopplerFormFieldButton::setReadOnly( bool value ) { #ifdef HAVE_POPPLER_0_64 m_field->setReadOnly( value ); #else Q_UNUSED( value ); #endif } bool PopplerFormFieldButton::isVisible() const { return m_field->isVisible(); } void PopplerFormFieldButton::setVisible( bool value ) { #ifdef HAVE_POPPLER_0_64 m_field->setVisible( value ); #else Q_UNUSED( value ); #endif } bool PopplerFormFieldButton::isPrintable() const { #ifdef HAVE_POPPLER_0_79 return m_field->isPrintable(); #else return true; #endif } void PopplerFormFieldButton::setPrintable( bool value ) { #ifdef HAVE_POPPLER_0_79 m_field->setPrintable( value ); #else Q_UNUSED( value ); #endif } Okular::FormFieldButton::ButtonType PopplerFormFieldButton::buttonType() const { switch ( m_field->buttonType() ) { case Poppler::FormFieldButton::Push: return Okular::FormFieldButton::Push; case Poppler::FormFieldButton::CheckBox: return Okular::FormFieldButton::CheckBox; case Poppler::FormFieldButton::Radio: return Okular::FormFieldButton::Radio; } return Okular::FormFieldButton::Push; } QString PopplerFormFieldButton::caption() const { return m_field->caption(); } bool PopplerFormFieldButton::state() const { return m_field->state(); } void PopplerFormFieldButton::setState( bool state ) { m_field->setState( state ); } QList< int > PopplerFormFieldButton::siblings() const { return m_field->siblings(); } #ifdef HAVE_POPPLER_0_79 Poppler::FormFieldIcon PopplerFormFieldButton::icon() const { return m_field->icon(); } #endif void PopplerFormFieldButton::setIcon( Okular::FormField *field ) { #ifdef HAVE_POPPLER_0_79 if( field->type() == Okular::FormField::FormButton ) { PopplerFormFieldButton *button = static_cast< PopplerFormFieldButton * >( field ); m_field->setIcon( button->icon() ); } #else Q_UNUSED( field ); #endif } PopplerFormFieldText::PopplerFormFieldText( Poppler::FormFieldText * field ) : Okular::FormFieldText(), m_field( field ) { m_rect = Okular::NormalizedRect::fromQRectF( m_field->rect() ); m_id = m_field->id(); SET_ACTIONS } PopplerFormFieldText::~PopplerFormFieldText() { delete m_field; } Okular::NormalizedRect PopplerFormFieldText::rect() const { return m_rect; } int PopplerFormFieldText::id() const { return m_id; } QString PopplerFormFieldText::name() const { return m_field->name(); } QString PopplerFormFieldText::uiName() const { return m_field->uiName(); } +QString PopplerFormFieldText::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + bool PopplerFormFieldText::isReadOnly() const { return m_field->isReadOnly(); } void PopplerFormFieldText::setReadOnly( bool value ) { #ifdef HAVE_POPPLER_0_64 m_field->setReadOnly( value ); #else Q_UNUSED( value ); #endif } bool PopplerFormFieldText::isVisible() const { return m_field->isVisible(); } void PopplerFormFieldText::setVisible( bool value ) { #ifdef HAVE_POPPLER_0_64 m_field->setVisible( value ); #else Q_UNUSED( value ); #endif } bool PopplerFormFieldText::isPrintable() const { #ifdef HAVE_POPPLER_0_79 return m_field->isPrintable(); #else return true; #endif } void PopplerFormFieldText::setPrintable( bool value ) { #ifdef HAVE_POPPLER_0_79 m_field->setPrintable( value ); #else Q_UNUSED( value ); #endif } Okular::FormFieldText::TextType PopplerFormFieldText::textType() const { switch ( m_field->textType() ) { case Poppler::FormFieldText::Normal: return Okular::FormFieldText::Normal; case Poppler::FormFieldText::Multiline: return Okular::FormFieldText::Multiline; case Poppler::FormFieldText::FileSelect: return Okular::FormFieldText::FileSelect; } return Okular::FormFieldText::Normal; } QString PopplerFormFieldText::text() const { return m_field->text(); } void PopplerFormFieldText::setText( const QString& text ) { m_field->setText( text ); } bool PopplerFormFieldText::isPassword() const { return m_field->isPassword(); } bool PopplerFormFieldText::isRichText() const { return m_field->isRichText(); } int PopplerFormFieldText::maximumLength() const { return m_field->maximumLength(); } Qt::Alignment PopplerFormFieldText::textAlignment() const { return Qt::AlignTop | m_field->textAlignment(); } bool PopplerFormFieldText::canBeSpellChecked() const { return m_field->canBeSpellChecked(); } PopplerFormFieldChoice::PopplerFormFieldChoice( Poppler::FormFieldChoice * field ) : Okular::FormFieldChoice(), m_field( field ) { m_rect = Okular::NormalizedRect::fromQRectF( m_field->rect() ); m_id = m_field->id(); SET_ACTIONS } PopplerFormFieldChoice::~PopplerFormFieldChoice() { delete m_field; } Okular::NormalizedRect PopplerFormFieldChoice::rect() const { return m_rect; } int PopplerFormFieldChoice::id() const { return m_id; } QString PopplerFormFieldChoice::name() const { return m_field->name(); } QString PopplerFormFieldChoice::uiName() const { return m_field->uiName(); } +QString PopplerFormFieldChoice::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + bool PopplerFormFieldChoice::isReadOnly() const { return m_field->isReadOnly(); } void PopplerFormFieldChoice::setReadOnly( bool value ) { #ifdef HAVE_POPPLER_0_64 m_field->setReadOnly( value ); #else Q_UNUSED( value ); #endif } bool PopplerFormFieldChoice::isVisible() const { return m_field->isVisible(); } void PopplerFormFieldChoice::setVisible( bool value ) { #ifdef HAVE_POPPLER_0_64 m_field->setVisible( value ); #else Q_UNUSED( value ); #endif } bool PopplerFormFieldChoice::isPrintable() const { #ifdef HAVE_POPPLER_0_79 return m_field->isPrintable(); #else return true; #endif } void PopplerFormFieldChoice::setPrintable( bool value ) { #ifdef HAVE_POPPLER_0_79 m_field->setPrintable( value ); #else Q_UNUSED( value ); #endif } Okular::FormFieldChoice::ChoiceType PopplerFormFieldChoice::choiceType() const { switch ( m_field->choiceType() ) { case Poppler::FormFieldChoice::ComboBox: return Okular::FormFieldChoice::ComboBox; case Poppler::FormFieldChoice::ListBox: return Okular::FormFieldChoice::ListBox; } return Okular::FormFieldChoice::ListBox; } QStringList PopplerFormFieldChoice::choices() const { return m_field->choices(); } bool PopplerFormFieldChoice::isEditable() const { return m_field->isEditable(); } bool PopplerFormFieldChoice::multiSelect() const { return m_field->multiSelect(); } QList PopplerFormFieldChoice::currentChoices() const { return m_field->currentChoices(); } void PopplerFormFieldChoice::setCurrentChoices( const QList& choices ) { m_field->setCurrentChoices( choices ); } QString PopplerFormFieldChoice::editChoice() const { return m_field->editChoice(); } void PopplerFormFieldChoice::setEditChoice( const QString& text ) { m_field->setEditChoice( text ); } Qt::Alignment PopplerFormFieldChoice::textAlignment() const { return Qt::AlignTop | m_field->textAlignment(); } bool PopplerFormFieldChoice::canBeSpellChecked() const { return m_field->canBeSpellChecked(); } #ifndef HAVE_POPPLER_0_51 class DummySignatureInfo : public Okular::SignatureInfo { }; #endif PopplerFormFieldSignature::PopplerFormFieldSignature( Poppler::FormFieldSignature * field ) : Okular::FormFieldSignature(), m_field( field ) { m_rect = Okular::NormalizedRect::fromQRectF( m_field->rect() ); m_id = m_field->id(); #ifdef HAVE_POPPLER_0_51 m_info = new PopplerSignatureInfo( m_field->validate( Poppler::FormFieldSignature::ValidateVerifyCertificate ) ); #else m_info = new DummySignatureInfo(); #endif SET_ACTIONS } PopplerFormFieldSignature::~PopplerFormFieldSignature() { delete m_field; delete m_info; } Okular::NormalizedRect PopplerFormFieldSignature::rect() const { return m_rect; } int PopplerFormFieldSignature::id() const { return m_id; } QString PopplerFormFieldSignature::name() const { return m_field->name(); } QString PopplerFormFieldSignature::uiName() const { return m_field->uiName(); } +QString PopplerFormFieldSignature::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + bool PopplerFormFieldSignature::isReadOnly() const { return m_field->isReadOnly(); } bool PopplerFormFieldSignature::isVisible() const { return m_field->isVisible(); } PopplerFormFieldSignature::SignatureType PopplerFormFieldSignature::signatureType() const { #ifdef HAVE_POPPLER_0_58 switch ( m_field->signatureType() ) { case Poppler::FormFieldSignature::AdbePkcs7sha1: return Okular::FormFieldSignature::AdbePkcs7sha1; case Poppler::FormFieldSignature::AdbePkcs7detached: return Okular::FormFieldSignature::AdbePkcs7detached; case Poppler::FormFieldSignature::EtsiCAdESdetached: return Okular::FormFieldSignature::EtsiCAdESdetached; default: return Okular::FormFieldSignature::UnknownType; } #else return Okular::FormFieldSignature::UnknownType; #endif } const Okular::SignatureInfo &PopplerFormFieldSignature::signatureInfo() const { return *m_info; } diff --git a/generators/poppler/formfields.h b/generators/poppler/formfields.h index fab0e1393..849ca4279 100644 --- a/generators/poppler/formfields.h +++ b/generators/poppler/formfields.h @@ -1,155 +1,159 @@ /*************************************************************************** * Copyright (C) 2007 by Pino Toscano * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef _OKULAR_GENERATOR_PDF_FORMFIELDS_H_ #define _OKULAR_GENERATOR_PDF_FORMFIELDS_H_ #include #include #include "core/form.h" class PopplerFormFieldButton : public Okular::FormFieldButton { public: explicit PopplerFormFieldButton( Poppler::FormFieldButton * field ); virtual ~PopplerFormFieldButton(); // inherited from Okular::FormField Okular::NormalizedRect rect() const override; int id() const override; QString name() const override; QString uiName() const override; + QString fullyQualifiedName() const override; bool isReadOnly() const override; void setReadOnly( bool value ) override; bool isVisible() const override; void setVisible( bool value ) override; bool isPrintable() const override; void setPrintable( bool value ) override; // inherited from Okular::FormFieldButton ButtonType buttonType() const override; QString caption() const override; bool state() const override; void setState( bool state ) override; QList< int > siblings() const override; void setIcon( Okular::FormField *field ) override; #ifdef HAVE_POPPLER_0_79 /* * Supported only in newer versions of Poppler library. * * @since 1.9 */ Poppler::FormFieldIcon icon() const; #endif private: Poppler::FormFieldButton * m_field; Okular::NormalizedRect m_rect; int m_id; }; class PopplerFormFieldText : public Okular::FormFieldText { public: explicit PopplerFormFieldText( Poppler::FormFieldText * field ); virtual ~PopplerFormFieldText(); // inherited from Okular::FormField Okular::NormalizedRect rect() const override; int id() const override; QString name() const override; QString uiName() const override; + QString fullyQualifiedName() const override; bool isReadOnly() const override; void setReadOnly( bool value ) override; bool isVisible() const override; void setVisible( bool value ) override; bool isPrintable() const override; void setPrintable( bool value ) override; // inherited from Okular::FormFieldText Okular::FormFieldText::TextType textType() const override; QString text() const override; void setText( const QString& text ) override; bool isPassword() const override; bool isRichText() const override; int maximumLength() const override; Qt::Alignment textAlignment() const override; bool canBeSpellChecked() const override; private: Poppler::FormFieldText * m_field; Okular::NormalizedRect m_rect; int m_id; }; class PopplerFormFieldChoice : public Okular::FormFieldChoice { public: explicit PopplerFormFieldChoice( Poppler::FormFieldChoice * field ); virtual ~PopplerFormFieldChoice(); // inherited from Okular::FormField Okular::NormalizedRect rect() const override; int id() const override; QString name() const override; QString uiName() const override; + QString fullyQualifiedName() const override; bool isReadOnly() const override; void setReadOnly( bool value ) override; bool isVisible() const override; void setVisible( bool value ) override; bool isPrintable() const override; void setPrintable( bool value ) override; // inherited from Okular::FormFieldChoice ChoiceType choiceType() const override; QStringList choices() const override; bool isEditable() const override; bool multiSelect() const override; QList currentChoices() const override; void setCurrentChoices( const QList& choices ) override; QString editChoice() const override; void setEditChoice( const QString& text ) override; Qt::Alignment textAlignment() const override; bool canBeSpellChecked() const override; private: Poppler::FormFieldChoice * m_field; Okular::NormalizedRect m_rect; int m_id; }; class PopplerFormFieldSignature : public Okular::FormFieldSignature { public: PopplerFormFieldSignature( Poppler::FormFieldSignature * field ); virtual ~PopplerFormFieldSignature(); // inherited from Okular::FormField Okular::NormalizedRect rect() const override; int id() const override; QString name() const override; QString uiName() const override; + QString fullyQualifiedName() const override; bool isReadOnly() const override; bool isVisible() const override; // inherited from Okular::FormFieldSignature SignatureType signatureType() const override; const Okular::SignatureInfo &signatureInfo() const override; private: Poppler::FormFieldSignature * m_field; Okular::SignatureInfo *m_info; Okular::NormalizedRect m_rect; int m_id; }; #endif