[poppler] Form-Reset and Print [patches]
Guillermo Amaral
gamaral at kdab.com
Fri Jun 25 21:23:59 PDT 2010
On Tue, Jun 15, 2010 at 12:53:53PM +0200, Pino Toscano wrote:
>
> Alle lunedì 14 giugno 2010, Guillermo Amaral ha scritto:
> > Anyway, I added the missing features to the reset form patch today,
> > check it out.
>
> Some more notes other than what Albert and Carlos said already:
>
> > +LinkResetForm::LinkResetForm(Object *obj) {
> > + Object obj1;
> > +
> > + fieldList = new GooList();
> > + flags = 0;
> > +
> > + if (obj->dictLookup("Fields", &obj1)->isArray()) {
> > + for (int i = 0; i < obj1.arrayGetLength(); ++i) {
> > + Object obj2;
> > + obj1.arrayGetNF(i, &obj2);
> > + fieldList->append(obj2.getString()->copy());
> > + obj2.free();
> > + }
> > + } else {
> > + error (-1, "Invalid ResetForm action");
> > + delete fieldList;
> > + fieldList = NULL;
> > + }
> > + obj1.free();
> > [...]
> > + // Was the LinkResetForm create successfully?
> > + virtual GBool isOk() { return fieldList != NULL; }
>
> Basically this code makes the action valid only if Fields is specified
> and valid, while that key is optional.
>
> > +class LinkFormActionPrivate : public LinkPrivate
> > +{
> > + public:
> > + LinkFormActionPrivate( const QRectF &area,
> > LinkFormAction::ActionType actionType );
> > +
> > + LinkFormAction::ActionType type;
>
> + const here
>
> > + bool LinkResetFormAction::isExcludeFieldList() const
> > + {
> > + Q_D( const LinkResetFormAction );
> > + return (1 == (d->flags % 1));
>
> Err, you mean 'd->flags & 1'?
>
> > @@ -182,7 +184,8 @@ class POPPLER_QT4_EXPORT Link
> > Action, ///< A "standard" action to be executed
> > in the viewer
> > Sound, ///< A link representing a sound to be
> > played
> > Movie, ///< An action to be executed on a movie
> > - JavaScript ///< A JavaScript code to be
> > interpreted \since 0.10
> > + JavaScript, ///< A
> > JavaScript code to be interpreted \since 0.10
> > + FormAction ///< A "form" action to be
> > executed in the viewer
>
> + \since 0.16
>
> > @@ -484,6 +487,95 @@ class POPPLER_QT4_EXPORT LinkMovie : public Link
> > };
> > #endif
> >
> > +/**
> > + * \brief "Form" action request.
> > + *
> > + * The LinkFormAction class represents a link that request a "form"
> > action
> > + * to be performed by the viewer on the displayed document.
> > + */
>
> as above, add \since 0.16
>
> > +class POPPLER_QT4_EXPORT LinkFormAction : public Link
> > +{
> > + public:
> > + /**
> > + * The possible types of actions
> > + */
> > + enum ActionType { Submit = 1,
> > + Reset = 2,
> > + ImportData = 3 };
>
> I'd use a slightly better name for the enum, like FormActionType.
>
> > +
> > + /**
> > + * The action of the current LinkFormAction
> > + */
> > + ActionType actionType() const;
>
> likewise for the method naming
>
> > + /**
> > + * Create a new Action link, that executes a
> > specified action + * on the document.
> > + *
> > + * \param linkArea the active area of the link
> > + * \param actionType which action should be executed
> > + */
> > + LinkFormAction( const QRectF &linkArea, ActionType
> > actionType );
>
> I'd make this constructor protected, as LinkFormAction looks more an
> intermediate action type which has no sense used alone.
>
> > +/**
> > + * \brief "Form" action reset request.
> > + *
> > + * The LinkResetFormAction class represents a link that request a
> > "ResetForm" action
> > + * to be performed by the viewer on the displayed document.
> > + */
>
> ... guess what? ;)
>
> > +class POPPLER_QT4_EXPORT LinkResetFormAction : public LinkFormAction
> > +{
> > + public:
> > + typedef QList<QString> FieldList;
>
> Why not just a simple QStringList instead of this typedef?
>
> > + LinkResetFormAction( const QRectF &linkArea, const
> > FieldList &_fieldList, int _flags );
> > [...]
> > + int flags() const;
> > [...]
> > + bool isExcludeFieldList() const;
>
> This looks a bit too "raw"... what I would do is something like:
> enum FormResetType { ResetAll, ResetIncluded, ResetExcluded }
> and then use only this enum in both constructor and method. Maybe
> ResetAll is not needed, stating in the apidox that you should check for
> the emptiness of the field list.
Ok guys,
Let's see if I cought all the details ;-)
Check it out
--
Guillermo Amaral | guillermo.amaral at kdab.com | Software Desperado
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel. Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322)
KDAB - Qt Experts - Platform-independent software solutions
-------------- next part --------------
diff --git a/poppler/Link.cc b/poppler/Link.cc
index b6d7f2d..d2079ea 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -124,6 +124,10 @@ LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) {
} else if (obj2.isName("SetOCGState")) {
action = new LinkOCGState(obj);
+ // ResetForm action
+ } else if (obj2.isName("ResetForm")) {
+ action = new LinkResetForm(obj);
+
// unknown action
} else if (obj2.isName()) {
action = new LinkUnknown(obj2.getName());
@@ -848,6 +852,52 @@ LinkOCGState::StateList::~StateList() {
}
//------------------------------------------------------------------------
+// LinkResetForm
+//------------------------------------------------------------------------
+
+LinkResetForm::LinkResetForm(Object *obj) {
+ Object obj1;
+
+ fieldList = new GooList();
+ flags = 0;
+
+ if (obj->dictLookup("Fields", &obj1)->isArray()) {
+ for (int i = 0; i < obj1.arrayGetLength(); ++i) {
+ Object obj2;
+
+ if (obj1.arrayGetNF(i, &obj2)->isString()) {
+ fieldList->append(obj2.getString()->copy());
+ } else {
+ obj2.free();
+
+ if (obj1.arrayGet(i, &obj2)->isDict()) {
+ Object obj3;
+
+ if (obj2.dictLookup("T", &obj3)->isString())
+ fieldList->append(obj3.getString()->copy());
+
+ obj3.free();
+ }
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ if (obj->dictLookup("Flags", &obj1)->isInt()) {
+ flags = obj1.getInt();
+ }
+ } else {
+ // If no Fields entry is found, reset everything.
+ flags = 1;
+ }
+ obj1.free();
+}
+
+LinkResetForm::~LinkResetForm() {
+ deleteGooList(fieldList, GooString);
+}
+
+//------------------------------------------------------------------------
// LinkUnknown
//------------------------------------------------------------------------
diff --git a/poppler/Link.h b/poppler/Link.h
index ea10375..3df61ae 100644
--- a/poppler/Link.h
+++ b/poppler/Link.h
@@ -53,6 +53,7 @@ enum LinkActionKind {
actionSound, // sound action
actionJavaScript, // JavaScript action
actionOCGState, // Set-OCG-State action
+ actionResetForm, // Reset form action
actionUnknown // anything else
};
@@ -429,6 +430,34 @@ private:
};
//------------------------------------------------------------------------
+// LinkResetForm
+//------------------------------------------------------------------------
+
+class LinkResetForm: public LinkAction {
+public:
+
+ // Build a LinkResetForm with the specified action type.
+ LinkResetForm(Object *obj);
+
+ // Destructor.
+ virtual ~LinkResetForm();
+
+ // Was the LinkResetForm create successfully?
+ virtual GBool isOk() { return fieldList != NULL; }
+
+ // Accessors.
+ virtual LinkActionKind getKind() { return actionResetForm; }
+
+ GooList *getFieldList() { return fieldList; }
+ int getFlags() { return flags; }
+
+private:
+
+ GooList *fieldList;
+ int flags;
+};
+
+//------------------------------------------------------------------------
// LinkUnknown
//------------------------------------------------------------------------
diff --git a/qt4/src/poppler-link.cc b/qt4/src/poppler-link.cc
index de06242..a3261de 100644
--- a/qt4/src/poppler-link.cc
+++ b/qt4/src/poppler-link.cc
@@ -179,6 +179,41 @@ class LinkMoviePrivate : public LinkPrivate
}
#endif
+class LinkFormActionPrivate : public LinkPrivate
+{
+ public:
+ LinkFormActionPrivate( const QRectF &area, LinkFormAction::FormActionType formActionType );
+
+ const LinkFormAction::FormActionType type;
+};
+
+ LinkFormActionPrivate::LinkFormActionPrivate( const QRectF &area, LinkFormAction::FormActionType formActionType )
+ : LinkPrivate( area ), type( formActionType )
+ {
+ }
+
+class LinkResetFormActionPrivate : public LinkFormActionPrivate
+{
+ public:
+ LinkResetFormActionPrivate( const QRectF &area,
+ const QStringList &_fieldList, int _flags );
+
+ const QStringList fieldList;
+ LinkResetFormAction::FormResetFlags flags;
+
+};
+
+ LinkResetFormActionPrivate::LinkResetFormActionPrivate( const QRectF &area,
+ const QStringList &_fieldList, int _flags )
+ : LinkFormActionPrivate( area, LinkFormAction::Reset ), fieldList( _fieldList )
+ {
+ // Check for Exclude Field List flag
+ if (_flags & 1)
+ flags.insert(LinkResetFormAction::ExcludeFieldList);
+ else
+ flags.insert(LinkResetFormAction::IncludeFieldList);
+ }
+
static void cvtUserToDev(::Page *page, double xu, double yu, int *xd, int *yd) {
double ctm[6];
@@ -581,4 +616,52 @@ class LinkMoviePrivate : public LinkPrivate
}
#endif
+ // LinkFormAction
+ LinkFormAction::LinkFormAction( const QRectF &linkArea, FormActionType formActionType )
+ : Link( *new LinkFormActionPrivate( linkArea, formActionType ) )
+ {
+ }
+
+ LinkFormAction::LinkFormAction( LinkFormActionPrivate &dd )
+ : Link( dd )
+ {
+ }
+
+ LinkFormAction::~LinkFormAction()
+ {
+ }
+
+ LinkFormAction::FormActionType LinkFormAction::formActionType() const
+ {
+ Q_D( const LinkFormAction );
+ return d->type;
+ }
+
+ Link::LinkType LinkFormAction::linkType() const
+ {
+ return FormAction;
+ }
+
+ // LinkResetFormAction
+ LinkResetFormAction::LinkResetFormAction( const QRectF &linkArea, const QStringList &_fieldList, int _flags )
+ : LinkFormAction( *new LinkResetFormActionPrivate( linkArea, _fieldList, _flags ) )
+ {
+ }
+
+ LinkResetFormAction::~LinkResetFormAction()
+ {
+ }
+
+ QStringList LinkResetFormAction::fieldList() const
+ {
+ Q_D( const LinkResetFormAction );
+ return d->fieldList;
+ }
+
+ LinkResetFormAction::FormResetFlags LinkResetFormAction::flags() const
+ {
+ Q_D( const LinkResetFormAction );
+ return d->flags;
+ }
+
}
diff --git a/qt4/src/poppler-link.h b/qt4/src/poppler-link.h
index 1aa6d78..93fbb16 100644
--- a/qt4/src/poppler-link.h
+++ b/qt4/src/poppler-link.h
@@ -40,6 +40,8 @@ class LinkJavaScriptPrivate;
class LinkMoviePrivate;
class LinkDestinationData;
class LinkDestinationPrivate;
+class LinkFormActionPrivate;
+class LinkResetFormActionPrivate;
class SoundObject;
/**
@@ -183,7 +185,8 @@ class POPPLER_QT4_EXPORT Link
Action, ///< A "standard" action to be executed in the viewer
Sound, ///< A link representing a sound to be played
Movie, ///< An action to be executed on a movie
- JavaScript ///< A JavaScript code to be interpreted \since 0.10
+ JavaScript, ///< A JavaScript code to be interpreted \since 0.10
+ FormAction ///< A "form" action to be executed in the viewer \since 0.16
};
/**
@@ -487,6 +490,100 @@ class POPPLER_QT4_EXPORT LinkMovie : public Link
};
#endif
+/**
+ * \brief "Form" action request.
+ *
+ * The LinkFormAction class represents a link that request a "form" action
+ * to be performed by the viewer on the displayed document. \since 0.16
+ */
+class POPPLER_QT4_EXPORT LinkFormAction : public Link
+{
+ public:
+ /**
+ * The possible types of actions
+ */
+ enum FormActionType { Submit = 1,
+ Reset = 2,
+ ImportData = 3 };
+
+ /**
+ * The action of the current LinkFormAction
+ */
+ FormActionType formActionType() const;
+
+ /**
+ * Destructor.
+ */
+ ~LinkFormAction();
+
+ LinkType linkType() const;
+
+ protected:
+ /**
+ * Create a new Action link, that executes a specified action
+ * on the document.
+ *
+ * \param linkArea the active area of the link
+ * \param formActionType which action should be executed
+ */
+ LinkFormAction( const QRectF &linkArea, FormActionType formActionType );
+
+ LinkFormAction( LinkFormActionPrivate &dd );
+
+ private:
+ Q_DECLARE_PRIVATE( LinkFormAction )
+ Q_DISABLE_COPY( LinkFormAction )
+};
+
+/**
+ * \brief "Form" action reset request.
+ *
+ * The LinkResetFormAction class represents a link that request a "ResetForm" action
+ * to be performed by the viewer on the displayed document.
+ */
+class POPPLER_QT4_EXPORT LinkResetFormAction : public LinkFormAction
+{
+ public:
+ /**
+ * Flags specifying how the reset should be performed by the
+ * viewer.
+ *
+ * Reset all fields usually includes the ExcludeFieldList
+ * flag with an empty field list.
+ */
+ enum FormResetFlag { IncludeFieldList, ExcludeFieldList };
+ typedef QSet<FormResetFlag> FormResetFlags;
+
+ /**
+ * Create a new LinkResetFormAction link, that
+ * resets form fields on document.
+ *
+ * \param linkArea the active area of the link
+ * \param fieldList list of field names
+ * \param flags action flags
+ */
+ LinkResetFormAction( const QRectF &linkArea, const QStringList &_fieldList, int _flags );
+
+ /**
+ * Destructor.
+ */
+ ~LinkResetFormAction();
+
+ /**
+ * The list of fields to either reset or ignore.
+ */
+ QStringList fieldList() const;
+
+ /**
+ * Reset Flags.
+ */
+ FormResetFlags flags() const;
+
+ private:
+ Q_DECLARE_PRIVATE( LinkResetFormAction )
+ Q_DISABLE_COPY( LinkResetFormAction )
+};
+
}
#endif
diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index ae67b11..2b4ee62 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -177,6 +177,23 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo
copyString( m_uri, m->getTitle()->getCString() );
*/ break;
+ case actionResetForm:
+ {
+ QStringList fieldList;
+ LinkResetForm * g = (LinkResetForm *) a;
+ GooList *gfieldList = g->getFieldList();
+
+ /* Convert GooString field list to FieldList */
+ const int c = gfieldList->getLength();
+ for ( int i = 0; i < c; ++i ) {
+ GooString *str = (GooString *) gfieldList->get( i );
+ fieldList.append( str->getCString() );
+ }
+
+ popplerLink = new LinkResetFormAction( linkArea, fieldList, g->getFlags() );
+ }
+ break;
+
case actionUnknown:
break;
}
More information about the poppler
mailing list