[poppler] Form-Reset and Print [patches]

Guillermo Amaral gamaral at kdab.com
Sun Jun 13 20:37:16 PDT 2010


On Sun, Jun 13, 2010 at 11:02:56PM +0100, Albert Astals Cid wrote:
> A Diumenge, 13 de juny de 2010, Guillermo Amaral va escriure:
> > On Sun, Jun 13, 2010 at 10:21:35AM +0200, Carlos Garcia Campos wrote:
> > > Excerpts from Guillermo Amaral's message of dom jun 13 04:40:44 +0200 
> 2010:
> > > > Albert Astals Cid <aacid at kde.org> wrote:
> > > > > A Dissabte, 12 de juny de 2010, Guillermo Amaral va escriure:
> > > > >> I wanted to send in these patches, they allow handling of reset-form
> > > > >> and print actions respectably.
> > > > >> 
> > > > >> Please check them out, and if you have any questions please don't
> > > > >> hesitate to ask.
> > > > > 
> > > > > Do you have a document that uses them?
> > > > > 
> > > >   I do, but I dunno if I can share them ATM, looking into it.
> > > >   But I did make a test pdf that uses both features. :-)
> > > >   
> > > > > Also what is the point of
> > > > > 
> > > > > +  } else if (obj2.isName("ResetForm")) {
> > > > > +    action = new LinkResetForm(obj2.getName());
> > > > > 
> > > >   As usual, you are right aacid :) I try a little to hard not to break
> > > >   the flow of other programs, I think I went to far lol (fixed)
> > > >   
> > > > > And
> > > > > if (obj->dictLookup("AA", &tmp)->isDict())
> > > > > seems like an unrelated fix, can you please explain it too?
> > > > > 
> > > >   Mixed them up, that one should be in the print patch (moved).
> > > >   Sometimes the AA dict is used to hold a ref to the named object. I
> > > >   have seen it in two docs so far, it seems to happen when people set
> > > >   an action to happen on mouse down instead of mouse up. It should not
> > > >   break anything else (as far as I can see).
> > > 
> > > We should definitely add support for additional actions properly in
> > > poppler.
> > > 
> > > > diff --git a/poppler/Link.cc b/poppler/Link.cc
> > > > index 5d7b779..e3d6ce7 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();
> > > > +
> > > > 
> > > >    // unknown action
> > > >    } else if (obj2.isName()) {
> > > >    
> > > >      action = new LinkUnknown(obj2.getName());
> > > > 
> > > > @@ -856,6 +860,18 @@ LinkOCGState::StateList::~StateList() {
> > > > 
> > > >  }
> > > >  
> > > >  //--------------------------------------------------------------------
> > > >  ----
> > > > 
> > > > +// LinkFormClear
> > > > +//--------------------------------------------------------------------
> > > > ---- +
> > > > +LinkResetForm::LinkResetForm() {
> > > > +  action = new GooString("ResetForm");
> > > 
> > > this is redundant, you already know it's a LinkResetForm object. You
> > > should parse Fields and Flags here.
> > 
> >   Yeah it's a partial patch, it allows the client to know it has to reset..
> >   I guess I could make it reset the fields in the fieldlist here and just
> >   notify the client the form values have changed or something? what do you
> >   guys think?
> > 
> >   As far as it being redundant T_T yep totally. but I do see that
> >   the getAction() accessor returns said action GooString ptr, as I said
> > before I don't want to rock the boat; I'm guessing that method is used
> > some place else so I don't want to take it out willy nilly. But I do want
> > to make it clear (if it's not totally obvious already) that I'm not
> > completely familiar with the popplers code. ;-)
> 
> getAction() used somewhere? It's not virtual and you don't use it anywhere, so 
> where is it going to be used?
> 

  Mmm thought it was lol, dammit.
  Anyway, I added the missing features to the reset form patch today, check it out.

  Cheers,
  GA

-- 
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 5d7b779..abb17b6 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());
@@ -856,6 +860,40 @@ 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;
+      obj1.arrayGetNF(i, &obj2);
+      fieldList->append(obj2.getString()->copy());
+      obj2.free();
+    }
+  } else {
+    error (-1, "Invalid ResetForm action");
+    delete fieldList;
+    fieldList = NULL;
+  }
+  obj1.free();
+
+  if (obj->dictLookup("Flags", &obj1)->isNum()) {
+    flags = obj1.getInt();
+  }
+  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..d460c94 100644
--- a/qt4/src/poppler-link.cc
+++ b/qt4/src/poppler-link.cc
@@ -179,6 +179,36 @@ class LinkMoviePrivate : public LinkPrivate
 	}
 #endif
 
+class LinkFormActionPrivate : public LinkPrivate
+{
+	public:
+		LinkFormActionPrivate( const QRectF &area, LinkFormAction::ActionType actionType );
+
+		LinkFormAction::ActionType type;
+};
+
+	LinkFormActionPrivate::LinkFormActionPrivate( const QRectF &area, LinkFormAction::ActionType actionType )
+		: LinkPrivate( area ), type( actionType )
+	{
+	}
+
+class LinkResetFormActionPrivate : public LinkFormActionPrivate
+{
+	public:
+		LinkResetFormActionPrivate( const QRectF &area,
+			const LinkResetFormAction::FieldList &_fieldList, int _flags );
+
+		LinkResetFormAction::FieldList fieldList;
+		int flags;
+		
+};
+
+	LinkResetFormActionPrivate::LinkResetFormActionPrivate( const QRectF &area,
+		const LinkResetFormAction::FieldList &_fieldList, int _flags )
+		: LinkFormActionPrivate( area, LinkFormAction::Reset ), fieldList( _fieldList ), flags( _flags )
+	{
+	}
+
 	static void cvtUserToDev(::Page *page, double xu, double yu, int *xd, int *yd) {
 		double ctm[6];
 		
@@ -581,4 +611,58 @@ class LinkMoviePrivate : public LinkPrivate
 	}
 #endif
 
+	// LinkFormAction
+	LinkFormAction::LinkFormAction( const QRectF &linkArea, ActionType actionType )
+		: Link( *new LinkFormActionPrivate( linkArea, actionType ) )
+	{
+	}
+
+	LinkFormAction::LinkFormAction( LinkFormActionPrivate &dd )
+		: Link( dd )
+	{
+	}
+		
+	LinkFormAction::~LinkFormAction()
+	{
+	}
+	
+	LinkFormAction::ActionType LinkFormAction::actionType() const
+	{
+		Q_D( const LinkFormAction );
+		return d->type;
+	}
+
+	Link::LinkType LinkFormAction::linkType() const
+	{
+		return FormAction;
+	}
+
+	// LinkResetFormAction
+	LinkResetFormAction::LinkResetFormAction( const QRectF &linkArea, const FieldList &_fieldList, int _flags )
+		: LinkFormAction( *new LinkResetFormActionPrivate( linkArea, _fieldList, _flags ) )
+	{
+	}
+		
+	LinkResetFormAction::~LinkResetFormAction()
+	{
+	}
+	
+	LinkResetFormAction::FieldList LinkResetFormAction::fieldList() const
+	{
+		Q_D( const LinkResetFormAction );
+		return d->fieldList;
+	}
+
+	int LinkResetFormAction::flags() const
+	{
+		Q_D( const LinkResetFormAction );
+		return d->flags;
+	}
+
+	bool LinkResetFormAction::isExcludeFieldList() const
+	{
+		Q_D( const LinkResetFormAction );
+		return (1 == (d->flags % 1));
+	}
+
 }
diff --git a/qt4/src/poppler-link.h b/qt4/src/poppler-link.h
index 6d42cbe..ba401b9 100644
--- a/qt4/src/poppler-link.h
+++ b/qt4/src/poppler-link.h
@@ -39,6 +39,8 @@ class LinkJavaScriptPrivate;
 class LinkMoviePrivate;
 class LinkDestinationData;
 class LinkDestinationPrivate;
+class LinkFormActionPrivate;
+class LinkResetFormActionPrivate;
 class SoundObject;
 
 /**
@@ -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
 		};
 
 		/**
@@ -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.
+ */
+class POPPLER_QT4_EXPORT LinkFormAction : public Link
+{
+	public:
+		/**
+		 * The possible types of actions
+		 */
+		enum ActionType { Submit = 1,
+		                  Reset = 2,
+		                  ImportData = 3 };
+
+		/**
+		 * The action of the current LinkFormAction
+		 */
+		ActionType actionType() const;
+
+		/**
+		 * 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 );
+		/**
+		 * Destructor.
+		 */
+		~LinkFormAction();
+		LinkType linkType() const;
+
+	protected:
+		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:
+		typedef QList<QString> FieldList;
+
+		/**
+		 * 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 FieldList &_fieldList, int _flags );
+
+		/**
+		 * Destructor.
+		 */
+		~LinkResetFormAction();
+
+		/**
+		 * The list of fields to either reset or ignore.
+		 */
+		FieldList fieldList() const;
+
+		/**
+		 * Return raw flags.
+		 */
+		int flags() const;
+
+		/**
+		 * Whether the field list should be excluded from the reset.
+		 */
+		bool isExcludeFieldList() 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 6dbf50f..ca9de3b 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -174,6 +174,23 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo
           copyString( m_uri, m->getTitle()->getCString() );
 */  break;
 
+    case actionResetForm:
+    {
+      LinkResetFormAction::FieldList 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