Form.h 16.2 KB
Newer Older
1 2 3 4
//========================================================================
//
// Form.h
//
5 6 7
// This file is licensed under the GPLv2 or later
//
// Copyright 2006 Julien Rebetez <julienr@svn.gnome.org>
Albert Astals Cid's avatar
Albert Astals Cid committed
8
// Copyright 2007, 2008, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
9
// Copyright 2007-2010, 2012, 2015-2017 Albert Astals Cid <aacid@kde.org>
Albert Astals Cid's avatar
Albert Astals Cid committed
10
// Copyright 2010 Mark Riedesel <mark@klowner.com>
Albert Astals Cid's avatar
Albert Astals Cid committed
11
// Copyright 2011 Pino Toscano <pino@kde.org>
12
// Copyright 2012 Fabio D'Urso <fabiodurso@hotmail.it>
Albert Astals Cid's avatar
Albert Astals Cid committed
13
// Copyright 2013 Adrian Johnson <ajohnson@redneon.com>
14 15
// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
16 17 18 19 20 21 22 23 24 25 26
//
//========================================================================

#ifndef FORM_H
#define FORM_H

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "Object.h"
27
#include "Annot.h"
28

29 30
#include <set>

31 32 33 34
class GooString;
class Array;
class Dict;
class Annot;
35
class AnnotWidget;
36
class Annots;
37
class LinkAction;
38
class GfxResources;
39
class PDFDoc;
40 41
class SignatureInfo;
class SignatureHandler;
42 43 44 45 46 47

enum FormFieldType {
  formButton,
  formText,
  formChoice,
  formSignature,
Albert Astals Cid's avatar
Albert Astals Cid committed
48
  formUndef
49 50 51 52 53 54 55 56
};

enum FormButtonType {
  formButtonCheck,
  formButtonPush,
  formButtonRadio
};

57 58 59 60 61 62
enum VariableTextQuadding {
  quaddingLeftJustified,
  quaddingCentered,
  quaddingRightJustified
};

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
class Form;
class FormField;
class FormFieldButton;
class FormFieldText;
class FormFieldSignature;
class FormFieldChoice;

//------------------------------------------------------------------------
// FormWidget
// A FormWidget represents the graphical part of a field and is "attached"
// to a page.
//------------------------------------------------------------------------

class FormWidget {
public:
  virtual ~FormWidget();

  // Check if point is inside the field bounding rect
81
  GBool inRect(double x, double y) const;
82 83

  // Get the field bounding rect
84
  void getRect(double *x1, double *y1, double *x2, double *y2) const;
85 86 87 88

  unsigned getID () { return ID; }
  void setID (unsigned int i) { ID=i; }

89
  FormField *getField () { return field; }
90 91 92 93 94 95 96 97
  FormFieldType getType() { return type; }

  Object* getObj() { return &obj; }
  Ref getRef() { return ref; }

  void setChildNum (unsigned i) { childNum = i; }
  unsigned getChildNum () { return childNum; }

98
  double getFontSize() const;
99

100
  GooString *getPartialName() const;
101
  void setPartialName(const GooString &name);
102 103
  GooString *getAlternateUiName() const;
  GooString *getMappingName() const;
104 105
  GooString *getFullyQualifiedName();

106
  GBool isModified () const;
107

108
  bool isReadOnly() const;
109

110 111
  LinkAction *getActivationAction(); // The caller should not delete the result
  LinkAction *getAdditionalAction(Annot::FormAdditionalActionsType type); // The caller should delete the result
112

113 114 115 116 117
  // return the unique ID corresponding to pageNum/fieldNum
  static int encodeID (unsigned pageNum, unsigned fieldNum);
  // decode id and retrieve pageNum and fieldNum
  static void decodeID (unsigned id, unsigned* pageNum, unsigned* fieldNum);

118
  void createWidgetAnnotation();
119 120
  AnnotWidget *getWidgetAnnotation() const { return widget; }

121 122
  virtual void updateWidgetAppearance() = 0;

123 124 125 126
#ifdef DEBUG_FORMS
  void print(int indent = 0);
#endif

127
protected:
128
  FormWidget(PDFDoc *docA, Object *aobj, unsigned num, Ref aref, FormField *fieldA);
129

130
  AnnotWidget *widget;
131 132 133 134
  FormField* field;
  FormFieldType type;
  Object obj;
  Ref ref;
135
  PDFDoc *doc;
136
  XRef *xref;
137

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
  //index of this field in the parent's child list
  unsigned childNum;

  /*
  Field ID is an (unsigned) integer, calculated as follow :
  the first sizeof/2 bits are the field number, relative to the page
  the last sizeof/2 bits are the page number
  [page number | field number]
  (encoding) id = (pageNum << 4*sizeof(unsigned)) + fieldNum;
  (decoding) pageNum = id >> 4*sizeof(unsigned); fieldNum = (id << 4*sizeof(unsigned)) >> 4*sizeof(unsigned);
  */
  unsigned ID; 
};

//------------------------------------------------------------------------
// FormWidgetButton
//------------------------------------------------------------------------

class FormWidgetButton: public FormWidget {
public:
158
  FormWidgetButton(PDFDoc *docA, Object *dict, unsigned num, Ref ref, FormField *p);
159 160
  ~FormWidgetButton ();

161 162
  FormButtonType getButtonType() const;
  
163
  void setState (GBool state);
164 165
  GBool getState ();

166
  char* getOnStr();
167
  void setAppearanceState(const char *state);
Albert Astals Cid's avatar
Albert Astals Cid committed
168
  void updateWidgetAppearance() override;
169 170

protected:
171
  FormFieldButton *parent() const;
172
  GooString *onStr;
173 174 175 176 177 178 179 180
};

//------------------------------------------------------------------------
// FormWidgetText
//------------------------------------------------------------------------

class FormWidgetText: public FormWidget {
public:
181
  FormWidgetText(PDFDoc *docA, Object *dict, unsigned num, Ref ref, FormField *p);
182 183 184 185 186 187 188 189
  //return the field's content (UTF16BE)
  GooString* getContent() ;
  //return a copy of the field's content (UTF16BE)
  GooString* getContentCopy();

  //except a UTF16BE string
  void setContent(GooString* new_content);

Albert Astals Cid's avatar
Albert Astals Cid committed
190
  void updateWidgetAppearance() override;
191

192 193 194 195 196 197 198
  bool isMultiline () const; 
  bool isPassword () const; 
  bool isFileSelect () const; 
  bool noSpellCheck () const; 
  bool noScroll () const; 
  bool isComb () const; 
  bool isRichText () const;
199
  int getMaxLen () const;
200
protected:
201
  FormFieldText *parent() const;
202 203 204 205 206 207 208 209
};

//------------------------------------------------------------------------
// FormWidgetChoice
//------------------------------------------------------------------------

class FormWidgetChoice: public FormWidget {
public:
210
  FormWidgetChoice(PDFDoc *docA, Object *dict, unsigned num, Ref ref, FormField *p);
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
  ~FormWidgetChoice();

  int getNumChoices();
  //return the display name of the i-th choice (UTF16BE)
  GooString* getChoice(int i);
  //select the i-th choice
  void select (int i); 

  //toggle selection of the i-th choice
  void toggle (int i);

  //deselect everything
  void deselectAll ();

  //except a UTF16BE string
  //only work for editable combo box, set the user-entered text as the current choice
  void setEditChoice(GooString* new_content);

  GooString* getEditChoice ();

Albert Astals Cid's avatar
Albert Astals Cid committed
231
  void updateWidgetAppearance() override;
232 233 234 235 236 237 238 239 240 241
  bool isSelected (int i);

  bool isCombo () const; 
  bool hasEdit () const; 
  bool isMultiSelect () const; 
  bool noSpellCheck () const; 
  bool commitOnSelChange () const; 
  bool isListBox () const;
protected:
  bool _checkRange (int i);
242
  FormFieldChoice *parent() const;
243 244 245 246 247 248 249 250
};

//------------------------------------------------------------------------
// FormWidgetSignature
//------------------------------------------------------------------------

class FormWidgetSignature: public FormWidget {
public:
251
  FormWidgetSignature(PDFDoc *docA, Object *dict, unsigned num, Ref ref, FormField *p);
Albert Astals Cid's avatar
Albert Astals Cid committed
252
  void updateWidgetAppearance() override;
253 254

  SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation);
255 256 257 258 259 260 261 262 263 264 265
};

//------------------------------------------------------------------------
// FormField
// A FormField implements the logical side of a field and is "attached" to
// the Catalog. This is an internal class and client applications should
// only interact with FormWidgets.
//------------------------------------------------------------------------

class FormField {
public:
266
  FormField(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parent, std::set<int> *usedParents, FormFieldType t=formUndef);
267 268 269 270 271 272 273 274 275 276 277

  virtual ~FormField();

  // Accessors.
  FormFieldType getType() { return type; }
  Object* getObj() { return &obj; }
  Ref getRef() { return ref; }

  void setReadOnly (bool b) { readOnly = b; }
  bool isReadOnly () const { return readOnly; }

278 279 280 281
  GooString* getDefaultAppearance() const { return defaultAppearance; }
  GBool hasTextQuadding() const { return hasQuadding; }
  VariableTextQuadding getTextQuadding() const { return quadding; }

282
  GooString *getPartialName() const { return partialName; }
283
  void setPartialName(const GooString &name);
284 285 286 287
  GooString *getAlternateUiName() const { return alternateUiName; }
  GooString *getMappingName() const { return mappingName; }
  GooString *getFullyQualifiedName();

288
  FormWidget* findWidgetByRef (Ref aref);
289
  int getNumWidgets() { return terminal ? numChildren : 0; }
290
  FormWidget *getWidget(int i) { return terminal ? widgets[i] : NULL; }
291 292 293 294

  // only implemented in FormFieldButton
  virtual void fillChildrenSiblingsID ();

295
  void createWidgetAnnotations();
296

297 298 299 300 301
#ifdef DEBUG_FORMS
  void printTree(int indent = 0);
  virtual void print(int indent = 0);
#endif

302 303 304

 protected:
  void _createWidget (Object *obj, Ref aref);
305
  void createChildren(std::set<int> *usedParents);
306
  void updateChildrenAppearance();
307 308 309 310 311

  FormFieldType type;           // field type
  Ref ref;
  bool terminal;
  Object obj;
312
  PDFDoc *doc;
313 314
  XRef *xref;
  FormField **children;
315
  FormField *parent;
316 317 318 319
  int numChildren;
  FormWidget **widgets;
  bool readOnly;

320 321 322 323 324
  GooString *partialName; // T field
  GooString *alternateUiName; // TU field
  GooString *mappingName; // TM field
  GooString *fullyQualifiedName;

325 326 327 328 329
  // Variable Text
  GooString *defaultAppearance;
  GBool hasQuadding;
  VariableTextQuadding quadding;

330 331 332 333 334 335 336 337 338 339 340
private:
  FormField() {}
};


//------------------------------------------------------------------------
// FormFieldButton
//------------------------------------------------------------------------

class FormFieldButton: public FormField {
public:
341
  FormFieldButton(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
342 343 344 345 346 347

  FormButtonType getButtonType () { return btype; }

  bool noToggleToOff () const { return noAllOff; }

  // returns gTrue if the state modification is accepted
348
  GBool setState (char *state);
349
  GBool getState(char *state);
350 351

  char *getAppearanceState() { return appearanceState.isName() ? appearanceState.getName() : NULL; }
352

Albert Astals Cid's avatar
Albert Astals Cid committed
353
  void fillChildrenSiblingsID () override;
354 355 356 357 358 359 360
  
  void setNumSiblings (int num);
  void setSibling (int i, FormFieldButton *id) { siblings[i] = id; }

  //For radio buttons, return the fields of the other radio buttons in the same group
  FormFieldButton* getSibling (int i) const { return siblings[i]; }
  int getNumSiblings () const { return numSiblings; }
361

362 363 364 365
#ifdef DEBUG_FORMS
  void print(int indent = 0);
#endif

Albert Astals Cid's avatar
Albert Astals Cid committed
366
  ~FormFieldButton();
367
protected:
368 369
  void updateState(char *state);

370 371 372 373
  FormFieldButton** siblings; // IDs of dependent buttons (each button of a radio field has all the others buttons
                               // of the same field in this array)
  int numSiblings;

374 375 376 377
  FormButtonType btype;
  int size;
  int active_child; //only used for combo box
  bool noAllOff;
378
  Object appearanceState; // V
379 380 381 382 383 384 385 386
};

//------------------------------------------------------------------------
// FormFieldText
//------------------------------------------------------------------------

class FormFieldText: public FormField {
public:
387
  FormFieldText(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
388 389 390 391
  
  GooString* getContent () { return content; }
  GooString* getContentCopy ();
  void setContentCopy (GooString* new_content);
Albert Astals Cid's avatar
Albert Astals Cid committed
392
  ~FormFieldText();
393 394 395 396 397 398 399 400

  bool isMultiline () const { return multiline; }
  bool isPassword () const { return password; }
  bool isFileSelect () const { return fileSelect; }
  bool noSpellCheck () const { return doNotSpellCheck; }
  bool noScroll () const { return doNotScroll; }
  bool isComb () const { return comb; }
  bool isRichText () const { return richText; }
401 402

  int getMaxLen () const { return maxLen; }
403 404 405 406

#ifdef DEBUG_FORMS
  void print(int indent = 0);
#endif
407 408 409 410 411 412 413 414 415
protected:
  GooString* content;
  bool multiline;
  bool password;
  bool fileSelect;
  bool doNotSpellCheck;
  bool doNotScroll;
  bool comb;
  bool richText;
416
  int maxLen;
417 418 419 420 421 422 423 424
};

//------------------------------------------------------------------------
// FormFieldChoice
//------------------------------------------------------------------------

class FormFieldChoice: public FormField {
public:
425
  FormFieldChoice(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents);
426

Albert Astals Cid's avatar
Albert Astals Cid committed
427
  ~FormFieldChoice();
428 429

  int getNumChoices() { return numChoices; }
430 431 432 433
  GooString* getChoice(int i) { return choices ? choices[i].optionName : NULL; }
  GooString* getExportVal (int i) { return choices ? choices[i].exportVal : NULL; }
  // For multi-select choices it returns the first one
  GooString* getSelectedChoice();
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459

  //select the i-th choice
  void select (int i); 

  //toggle selection of the i-th choice
  void toggle (int i);

  //deselect everything
  void deselectAll ();

  //only work for editable combo box, set the user-entered text as the current choice
  void setEditChoice(GooString* new_content);

  GooString* getEditChoice ();

  bool isSelected (int i) { return choices[i].selected; }

  int getNumSelected ();

  bool isCombo () const { return combo; }
  bool hasEdit () const { return edit; }
  bool isMultiSelect () const { return multiselect; }
  bool noSpellCheck () const { return doNotSpellCheck; }
  bool commitOnSelChange () const { return doCommitOnSelChange; }
  bool isListBox () const { return !combo; }

460 461
  int getTopIndex() const { return topIdx; }

462 463 464 465
#ifdef DEBUG_FORMS
  void print(int indent = 0);
#endif

466
protected:
467 468 469
  void unselectAll();
  void updateSelection();

470 471 472 473 474 475 476 477 478 479 480 481 482 483
  bool combo;
  bool edit;
  bool multiselect;
  bool doNotSpellCheck;
  bool doCommitOnSelChange;

  struct ChoiceOpt {
    GooString* exportVal; //the export value ("internal" name)
    GooString* optionName; //displayed name
    bool selected; //if this choice is selected
  };

  int numChoices;
  ChoiceOpt* choices;
484 485
  GooString* editedChoice;
  int topIdx; // TI
486 487 488 489 490 491 492 493
};

//------------------------------------------------------------------------
// FormFieldSignature
//------------------------------------------------------------------------

class FormFieldSignature: public FormField {
public:
494
  FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
495

496 497
  SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation);

Albert Astals Cid's avatar
Albert Astals Cid committed
498
  ~FormFieldSignature();
499

500 501
private:
  void parseInfo();
502
  void hashSignedDataBlock(SignatureHandler *handler, Goffset block_len);
503
  Object byte_range;
504
  GooString *signature;
505 506
  SignatureInfo *signature_info;

507 508 509
#ifdef DEBUG_FORMS
  void print(int indent = 0);
#endif
510 511 512 513 514 515 516 517 518 519
};

//------------------------------------------------------------------------
// Form
// This class handle the document-wide part of Form (things in the acroForm
// Catalog entry).
//------------------------------------------------------------------------

class Form {
public:
520
  Form(PDFDoc *docA, Object* acroForm);
521 522 523

  ~Form();

524
  // Look up an inheritable field dictionary entry.
525
  static Object *fieldLookup(Dict *field, const char *key, Object *obj);
526
  
527 528
  /* Creates a new Field of the type specified in obj's dict.
     used in Form::Form and FormField::FormField */
529
  static FormField *createFieldFromDict (Object* obj, PDFDoc *docA, const Ref& aref, FormField *parent, std::set<int> *usedParents);
530 531

  Object *getObj () const { return acroForm; }
532
  GBool getNeedAppearances () const { return needAppearances; }
533 534
  int getNumFields() const { return numFields; }
  FormField* getRootField(int i) const { return rootFields[i]; }
535 536
  GooString* getDefaultAppearance() const { return defaultAppearance; }
  VariableTextQuadding getTextQuadding() const { return quadding; }
537 538
  GfxResources* getDefaultResources() const { return defaultResources; }
  Object* getDefaultResourcesObj() { return &resDict; }
539 540 541

  FormWidget* findWidgetByRef (Ref aref);

542
  void postWidgetsLoad();
543 544 545

  const std::vector<Ref> &getCalculateOrder() const { return calculateOrder; }

546 547 548 549
private:
  FormField** rootFields;
  int numFields;
  int size;
550
  PDFDoc *doc;
551
  XRef* xref;
552
  Object *acroForm;
553
  GBool needAppearances;
554 555
  GfxResources *defaultResources;
  Object resDict;
556
  std::vector<Ref> calculateOrder;
557 558 559 560

  // Variable Text
  GooString *defaultAppearance;
  VariableTextQuadding quadding;
561 562 563 564 565 566 567 568
};

//------------------------------------------------------------------------
// FormPageWidgets
//------------------------------------------------------------------------

class FormPageWidgets {
public:
569
  FormPageWidgets (Annots* annots, unsigned int page, Form *form);
570 571 572 573 574 575 576 577 578 579 580 581 582
  ~FormPageWidgets();
  
  int getNumWidgets() const { return numWidgets; }
  FormWidget* getWidget(int i) const { return widgets[i]; }

private:
  FormWidget** widgets;
  int numWidgets;
  int size;
};

#endif