[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