001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.pd;
031:
032: import java.util.HashSet;
033: import java.util.Iterator;
034: import java.util.Map;
035: import java.util.Set;
036:
037: import de.intarsys.pdf.cds.CDSDate;
038: import de.intarsys.pdf.cds.CDSRectangle;
039: import de.intarsys.pdf.cos.COSArray;
040: import de.intarsys.pdf.cos.COSBasedObject;
041: import de.intarsys.pdf.cos.COSDictionary;
042: import de.intarsys.pdf.cos.COSInteger;
043: import de.intarsys.pdf.cos.COSName;
044: import de.intarsys.pdf.cos.COSObject;
045: import de.intarsys.pdf.cos.COSStream;
046:
047: /**
048: * An Annotation is an abstract object that allows a PDF document to be changed
049: * and extended in a variety of ways. Annotations are recorded with a page in
050: * the PDF document. The behavior of an annotation depends on the subtype.
051: */
052: public abstract class PDAnnotation extends PDObject implements
053: IAdditionalActionSupport {
054: /**
055: * The meta class implementation
056: */
057: public static class MetaClass extends PDObject.MetaClass {
058: protected MetaClass(Class instanceClass) {
059: super (instanceClass);
060: }
061:
062: /*
063: * (non-Javadoc)
064: *
065: * @see de.intarsys.pdf.cos.COSBasedObject.MetaClass#doDetermineClass(de.intarsys.pdf.cos.COSObject)
066: */
067: protected COSBasedObject.MetaClass doDetermineClass(
068: COSObject object) {
069: if (!(object instanceof COSDictionary)) {
070: return null;
071: }
072: COSName type = ((COSDictionary) object).get(DK_Subtype)
073: .asName();
074: if (PDWidgetAnnotation.CN_Subtype_Widget.equals(type)) {
075: return PDWidgetAnnotation.META;
076: }
077: if (PDLinkAnnotation.CN_Subtype_Link.equals(type)) {
078: return PDLinkAnnotation.META;
079: }
080: if (PDMarkupAnnotation.CN_Subtype_Ink.equals(type)) {
081: return PDMarkupAnnotation.META;
082: }
083: if (PDMarkupAnnotation.CN_Subtype_Square.equals(type)) {
084: return PDMarkupAnnotation.META;
085: }
086: if (PDMarkupAnnotation.CN_Subtype_Circle.equals(type)) {
087: return PDMarkupAnnotation.META;
088: }
089: if (PDMarkupAnnotation.CN_Subtype_Line.equals(type)) {
090: return PDMarkupAnnotation.META;
091: }
092: if (PDMarkupAnnotation.CN_Subtype_Polygon.equals(type)) {
093: return PDMarkupAnnotation.META;
094: }
095: if (PDMarkupAnnotation.CN_Subtype_PolyLine.equals(type)) {
096: return PDMarkupAnnotation.META;
097: }
098: if (PDTextMarkupAnnotation.CN_Subtype_Highlight
099: .equals(type)) {
100: return PDTextMarkupAnnotation.META;
101: }
102: if (PDTextMarkupAnnotation.CN_Subtype_Underline
103: .equals(type)) {
104: return PDTextMarkupAnnotation.META;
105: }
106: if (PDTextMarkupAnnotation.CN_Subtype_Squiggly.equals(type)) {
107: return PDTextMarkupAnnotation.META;
108: }
109: if (PDTextMarkupAnnotation.CN_Subtype_StrikeOut
110: .equals(type)) {
111: return PDTextMarkupAnnotation.META;
112: }
113: if (PDPopupAnnotation.CN_Subtype_Popup.equals(type)) {
114: return PDPopupAnnotation.META;
115: }
116: if (PDTextAnnotation.CN_Subtype_Text.equals(type)) {
117: return PDTextAnnotation.META;
118: }
119: if (PDFileAttachmentAnnotation.CN_Subtype_FileAttachment
120: .equals(type)) {
121: return PDFileAttachmentAnnotation.META;
122: }
123: if (PDStampAnnotation.CN_Subtype_Stamp.equals(type)) {
124: return PDStampAnnotation.META;
125: }
126: return PDAnyAnnotation.META;
127: }
128:
129: public Class getRootClass() {
130: return PDAnnotation.class;
131: }
132: }
133:
134: /** The meta class instance */
135: public static final MetaClass META = new MetaClass(MetaClass.class
136: .getDeclaringClass());
137:
138: public static final COSName DK_Contents = COSName
139: .constant("Contents"); //$NON-NLS-1$
140:
141: public static final COSName DK_P = COSName.constant("P"); //$NON-NLS-1$
142:
143: public static final COSName DK_Rect = COSName.constant("Rect"); //$NON-NLS-1$
144:
145: public static final COSName DK_NM = COSName.constant("NM"); //$NON-NLS-1$
146:
147: public static final COSName DK_M = COSName.constant("M"); //$NON-NLS-1$
148:
149: /**
150: * The name for the F entry.
151: * <p>
152: * Currently:
153: * </p>
154: * <ul>
155: * <li>Bit 1: Invisible
156: * <li>Bit 2: Hidden
157: * <li>Bit 3: Print
158: * <li>Bit 4: NoZoom
159: * <li>Bit 5: NoRotate
160: * <li>Bit 6: NoView
161: * <li>Bit 7: ReadOnly
162: * <li>Bit 8: Locked
163: * <li>Bit 9: ToggleNoView
164: * </ul>
165: */
166: public static final COSName DK_F = COSName.constant("F"); //$NON-NLS-1$
167:
168: public static final COSName DK_BS = COSName.constant("BS"); //$NON-NLS-1$
169:
170: public static final COSName DK_Border = COSName.constant("Border"); //$NON-NLS-1$
171:
172: public static final COSName DK_AP = COSName.constant("AP"); //$NON-NLS-1$
173:
174: public static final COSName DK_AS = COSName.constant("AS"); //$NON-NLS-1$
175:
176: public static final COSName DK_C = COSName.constant("C"); //$NON-NLS-1$
177:
178: public static final COSName DK_CA = COSName.constant("CA"); //$NON-NLS-1$//PDF v1.4
179:
180: public static final COSName DK_IC = COSName.constant("IC"); //$NON-NLS-1$//PDF v1.4
181:
182: public static final COSName DK_A = COSName.constant("A"); //$NON-NLS-1$
183:
184: public static final COSName DK_StructParent = COSName
185: .constant("StructParent"); //$NON-NLS-1$
186:
187: public static final COSName DK_OC = COSName.constant("OC"); //$NON-NLS-1$
188:
189: public static final COSName CN_Type_Annot = COSName
190: .constant("Annot"); //$NON-NLS-1$
191:
192: /** supported additional action triggers */
193: public static final Set ANNOTATION_ACTION_TRIGGERS;
194:
195: static {
196: ANNOTATION_ACTION_TRIGGERS = new HashSet(11);
197: ANNOTATION_ACTION_TRIGGERS.add("E"); //$NON-NLS-1$
198: ANNOTATION_ACTION_TRIGGERS.add("X"); //$NON-NLS-1$
199: ANNOTATION_ACTION_TRIGGERS.add("D"); //$NON-NLS-1$
200: ANNOTATION_ACTION_TRIGGERS.add("U"); //$NON-NLS-1$
201: ANNOTATION_ACTION_TRIGGERS.add("Fo"); //$NON-NLS-1$
202: ANNOTATION_ACTION_TRIGGERS.add("BI"); //$NON-NLS-1$
203: ANNOTATION_ACTION_TRIGGERS.add("PO"); //$NON-NLS-1$
204: ANNOTATION_ACTION_TRIGGERS.add("PC"); //$NON-NLS-1$
205: ANNOTATION_ACTION_TRIGGERS.add("PV"); //$NON-NLS-1$
206: ANNOTATION_ACTION_TRIGGERS.add("PI"); //$NON-NLS-1$
207: }
208:
209: /**
210: * Copy the receivers appearance dictionary.
211: *
212: * @param appDict
213: * THe appearance dictionary.
214: *
215: * @return A copy of the appearance dictionary.
216: */
217: protected static COSDictionary copyAppearanceDict(
218: COSDictionary appDict) {
219: if (appDict == null) {
220: return null;
221: }
222: COSDictionary result = COSDictionary.create();
223: for (Iterator i = appDict.entryIterator(); i.hasNext();) {
224: Map.Entry entry = (Map.Entry) i.next();
225: COSName key = (COSName) entry.getKey();
226: COSObject value = (COSObject) entry.getValue();
227: if (value instanceof COSDictionary) {
228: COSDictionary oldDict = (COSDictionary) value;
229: value = copyAppearanceDictInner(oldDict);
230: } else {
231: if (value instanceof COSStream) {
232: value = value.copyShallow();
233: }
234: }
235: result.put(key, value);
236: }
237: return result;
238: }
239:
240: /**
241: * When the appearance dictionary has multiple states, this methos copies
242: * the inner appearance dictionaries.
243: *
244: * @param stateDict
245: * An inner appearance dictionary.
246: *
247: * @return A copy of the inner appearance dict.
248: */
249: protected static COSDictionary copyAppearanceDictInner(
250: COSDictionary stateDict) {
251: COSDictionary result = COSDictionary.create();
252: for (Iterator i = stateDict.entryIterator(); i.hasNext();) {
253: Map.Entry entry = (Map.Entry) i.next();
254: COSName key = (COSName) entry.getKey();
255: COSObject value = (COSObject) entry.getValue();
256: if (value instanceof COSStream) {
257: value = value.copyShallow();
258: }
259: result.put(key, value);
260: }
261: return result;
262: }
263:
264: private AnnotationFlags flags;
265:
266: private PDBorderStyle cachedBorderStyle;
267:
268: private CDSRectangle cachedRectangle;
269:
270: /**
271: * Create the receiver class from an already defined {@link COSDictionary}.
272: * NEVER use the constructor directly.
273: *
274: * @param object
275: * the PDDocument containing the new object
276: */
277: protected PDAnnotation(COSObject object) {
278: super (object);
279: }
280:
281: /**
282: * Add a {@link PDAction} to be executed when this is "activated".
283: *
284: * @param newAction
285: * The {@link PDAction} to be executed.
286: */
287: public void addAction(PDAction newAction) {
288: if (newAction != null) {
289: if (getAction() == null) {
290: setAction(newAction);
291: } else {
292: getAction().addNext(newAction);
293: }
294: }
295: }
296:
297: /**
298: * The annotation flags in its integer representation.
299: *
300: * @return The annotation flags in its integer representation.
301: */
302: public int basicGetFlags() {
303: return getFieldInt(DK_F, 0);
304: }
305:
306: /**
307: * Assign the annotation flags in integer representation.
308: *
309: * @param newFlags
310: * The new annotation flags.
311: */
312: public void basicSetFlags(int newFlags) {
313: if (newFlags != 0) { // default
314: cosSetField(DK_F, COSInteger.create(newFlags));
315: } else {
316: cosRemoveField(DK_F);
317: }
318: }
319:
320: /**
321: * <code>true</code> if this can receive the focus in an interactive
322: * viewer.
323: *
324: * @return <code>true</code> if this can receive the focus in an
325: * interactive viewer.
326: */
327: public boolean canReceiveFocus() {
328: return !isReadOnly() && !isHidden() && !isNoView()
329: && !isInvisible() && !isLocked();
330: }
331:
332: /**
333: * Create a copy of the receiver.
334: *
335: * @return A copy of the receiver.
336: */
337: public PDAnnotation copy() {
338: // can not use copyNet as there are backward references.
339: COSDictionary dict = (COSDictionary) cosGetDict().copyShallow();
340: PDAnnotation copy = (PDAnnotation) PDAnnotation.META
341: .createFromCos(dict);
342:
343: // kill page parent
344: copy.cosRemoveField(DK_P);
345: // kill form parent
346: copy.cosRemoveField(PDAcroFormField.DK_Parent);
347: //
348: copy.cosRemoveField(PDAcroFormField.DK_T);
349: //
350: copy.cosRemoveField(PDAcroFormField.DK_TU);
351: // kill modification
352: copy.cosRemoveField(DK_M);
353: // kill value from form field
354: copy.cosRemoveField(PDAcroFormField.DK_V);
355:
356: // create new appearance
357: COSDictionary newAppearance = copyAppearanceDict(cosGetField(
358: DK_AP).asDictionary());
359: copy.cosSetField(DK_AP, newAppearance);
360: return copy;
361: }
362:
363: /*
364: * (non-Javadoc)
365: *
366: * @see de.intarsys.pdf.pd.PDObject#cosGetExpectedType()
367: */
368: protected COSName cosGetExpectedType() {
369: return CN_Type_Annot;
370: }
371:
372: /**
373: * @deprecated
374: */
375: public void dispose() {
376: PDPage page = PDAnnotationTools.getPage(this );
377: if (page != null) {
378: page.removeAnnotation(this );
379: }
380: }
381:
382: /**
383: * The {@link PDAction} to be executed when this is "activated".
384: *
385: * @return The {@link PDAction} to be executed when this is "activated".
386: */
387: public PDAction getAction() {
388: COSObject cosObject = cosGetField(DK_A);
389: if (cosObject.isNull()) {
390: return null;
391: }
392: return (PDAction) PDAction.META.createFromCos(cosObject);
393: }
394:
395: /*
396: * (non-Javadoc)
397: *
398: * @see de.intarsys.pdf.pd.IAdditionalActionSupport#getAdditionalActions()
399: */
400: public PDAdditionalActions getAdditionalActions() {
401: COSDictionary field = cosGetField(DK_AA).asDictionary();
402: return (PDAdditionalActions) PDAdditionalActions.META
403: .createFromCos(field);
404: }
405:
406: /**
407: * The visual appearance of this.
408: *
409: * @return The {@link PDAction} to be executed when this is "activated".
410: */
411: public PDAppearance getAppearance() {
412: COSObject cosObject = cosGetField(DK_AP);
413: if (cosObject.isNull()) {
414: return null;
415: }
416: return (PDAppearance) PDAppearance.META
417: .createFromCos(cosObject);
418: }
419:
420: /**
421: * The visual appearance state of this. This state selects an appearance
422: * within its {@link PDAppearance}.
423: *
424: * @return The visual appearance state of this.
425: */
426: public COSName getAppearanceState() {
427: return cosGetField(DK_AS).asName();
428: }
429:
430: /**
431: * All defined appearance states in this.
432: *
433: * @return All defined appearance states in this.
434: */
435: public Set getAppearanceStates() {
436: Set result = new HashSet();
437: COSDictionary ap = cosGetField(DK_AP).asDictionary();
438: if (ap != null) {
439: COSDictionary states;
440: states = ap.get(PDAppearance.DK_N).asDictionary();
441: if (states != null) {
442: result.addAll(states.keySet());
443: }
444: states = ap.get(PDAppearance.DK_D).asDictionary();
445: if (states != null) {
446: result.addAll(states.keySet());
447: }
448: states = ap.get(PDAppearance.DK_N).asDictionary();
449: if (states != null) {
450: result.addAll(states.keySet());
451: }
452: }
453: return result;
454: }
455:
456: /**
457: * The annotations border style.
458: *
459: * @return The annotations border style.
460: */
461: public PDBorderStyle getBorderStyle() {
462: if (cachedBorderStyle == null) {
463: COSObject cosObject = cosGetField(DK_BS);
464: if (!cosObject.isNull()) {
465: cachedBorderStyle = (PDBorderStyle) PDBorderStyle.META
466: .createFromCos(cosObject);
467: }
468: }
469: return cachedBorderStyle;
470: }
471:
472: /**
473: * The name of the border style.
474: *
475: * @return The name of the border style.
476: */
477: public COSName getBorderStyleName() {
478: PDBorderStyle bs = getBorderStyle();
479: if (bs == null) {
480: return PDBorderStyle.DK_S;
481: }
482: return bs.getStyle();
483: }
484:
485: /**
486: * The width of the annotations border.
487: *
488: * @return The width of the annotations border.
489: */
490: public float getBorderStyleWidth() {
491: PDBorderStyle bs = getBorderStyle();
492: if (bs == null) {
493: return 1;
494: }
495: return bs.getWidth();
496: }
497:
498: /**
499: * The color values for this.
500: *
501: * @return The color values for this.
502: */
503: public float[] getColor() {
504: return getFieldFixedArray(DK_C, null);
505: }
506:
507: /**
508: * The contents {@link String} for this.
509: *
510: * @return The contents {@link String} for this.
511: */
512: public String getContents() {
513: return getFieldMLString(DK_Contents, ""); //$NON-NLS-1$
514: }
515:
516: /**
517: * The annotation flags.
518: *
519: * @return The annotation flags.
520: */
521: public AnnotationFlags getFlags() {
522: if (flags == null) {
523: flags = new AnnotationFlags(this );
524: }
525: return flags;
526: }
527:
528: /**
529: * The last modification date.
530: *
531: * @return The last modification date.
532: */
533: public CDSDate getModified() {
534: return CDSDate.createFromCOS(cosGetField(DK_M).asString());
535: }
536:
537: /**
538: * The annotations name.
539: *
540: * @return The annotations name.
541: */
542: public String getName() {
543: return getFieldString(DK_NM, null);
544: }
545:
546: /**
547: * Convenience method to access a normalized copy of the receivers
548: * rectangle.
549: *
550: */
551: public CDSRectangle getNormalizedRectangle() {
552: return getRectangle().copy().normalize();
553: }
554:
555: /**
556: * Try to access the {@link PDPage} we are on. This may return null, as this
557: * reference is not required by the spec.
558: *
559: * @return Try to access the {@link PDPage} we are on.
560: */
561: public PDPage getPage() {
562: COSObject cosObject = cosGetField(DK_P);
563: return (PDPage) PDPageNode.META.createFromCos(cosObject);
564: }
565:
566: /**
567: * The {@link CDSRectangle} for the visual appearance of this.
568: *
569: * @return The {@link CDSRectangle} for the visual appearance of this.
570: */
571: public CDSRectangle getRectangle() {
572: if (cachedRectangle == null) {
573: COSArray array = cosGetField(DK_Rect).asArray();
574: if (array == null) {
575: return null;
576: }
577: cachedRectangle = CDSRectangle.createFromCOS(array);
578: }
579: return cachedRectangle;
580: }
581:
582: protected Integer getStructParent() {
583: COSInteger cosObject = cosGetField(DK_StructParent).asInteger();
584: if (cosObject != null) {
585: new Integer(cosObject.intValue());
586: }
587: return null;
588: }
589:
590: /**
591: * A {@link String} representation of this.
592: *
593: * @return A {@link String} representation of this.
594: */
595: abstract public String getSubtypeLabel();
596:
597: /*
598: * (non-Javadoc)
599: *
600: * @see de.intarsys.pdf.pd.IAdditionalActionSupport#getSupportedTriggerEvents()
601: */
602: public Set getSupportedTriggerEvents() {
603: return ANNOTATION_ACTION_TRIGGERS;
604: }
605:
606: /*
607: * (non-Javadoc)
608: *
609: * @see de.intarsys.pdf.pd.PDObject#initializeFromScratch()
610: */
611: protected void initializeFromScratch() {
612: super .initializeFromScratch();
613: CDSRectangle initialRect = new CDSRectangle(0, 0, 0, 0);
614: setRectangle(initialRect);
615: }
616:
617: /*
618: * (non-Javadoc)
619: *
620: * @see de.intarsys.pdf.cos.COSBasedObject#invalidateCaches()
621: */
622: public void invalidateCaches() {
623: super .invalidateCaches();
624: cachedBorderStyle = null;
625: cachedRectangle = null;
626: }
627:
628: /**
629: * Convenience method to access "Hidden" flag.
630: */
631: public boolean isHidden() {
632: return getFlags().isHidden();
633: }
634:
635: /**
636: * Convenience method to access "Invisible" flag.
637: */
638: public boolean isInvisible() {
639: return getFlags().isInvisible();
640: }
641:
642: /**
643: * Convenience method to access "Locked" flag.
644: */
645: public boolean isLocked() {
646: return getFlags().isLocked();
647: }
648:
649: /**
650: * <code>true</code> if this is a {@link PDMarkupAnnotation}.
651: *
652: * @return <code>true</code> if this is a {@link PDMarkupAnnotation}.
653: */
654: public boolean isMarkupAnnotation() {
655: return false;
656: }
657:
658: /**
659: * Convenience method to access "NoRotate" flag.
660: */
661: public boolean isNoRotate() {
662: return getFlags().isNoRotate();
663: }
664:
665: /**
666: * Convenience method to access "NoView" flag.
667: */
668: public boolean isNoView() {
669: return getFlags().isNoView();
670: }
671:
672: /**
673: * Convenience method to access "NoZoom" flag.
674: */
675: public boolean isNoZoom() {
676: return getFlags().isNoZoom();
677: }
678:
679: /**
680: * Convenience method to access "Print" flag.
681: */
682: public boolean isPrint() {
683: return getFlags().isPrint();
684: }
685:
686: /**
687: * <code>true</code> if print flag can be selected/changed for this kind
688: * of annotation.
689: *
690: * @return <code>true</code> if print flag can be selected/changed for
691: * this kind of annotation.
692: */
693: public boolean supportsPrint() {
694: return true;
695: }
696:
697: /**
698: * Convenience method to access "ReadOnly" flag.
699: */
700: public boolean isReadOnly() {
701: return getFlags().isReadOnly();
702: }
703:
704: /**
705: * Convenience method to access "ToggleNoView" flag.
706: */
707: public boolean isToggleNoView() {
708: return getFlags().isToggleNoView();
709: }
710:
711: /**
712: * <code>true</code> if this is a {@link PDWidgetAnnotation}.
713: *
714: * @return <code>true</code> if this is a {@link PDWidgetAnnotation}.
715: */
716: public boolean isWidgetAnnotation() {
717: return false;
718: }
719:
720: /**
721: * Set the {@link PDAction} for the "activation" of this.
722: *
723: * @param newAction
724: * Set the {@link PDAction} for the "activation" of this.
725: */
726: public void setAction(PDAction newAction) {
727: setFieldObject(DK_A, newAction);
728: }
729:
730: /*
731: * (non-Javadoc)
732: *
733: * @see de.intarsys.pdf.pd.IAdditionalActionSupport#setActions(de.intarsys.pdf.pd.PDAdditionalActions)
734: */
735: public void setAdditionalActions(PDAdditionalActions actions) {
736: setFieldObject(DK_AA, actions);
737: }
738:
739: /**
740: * Assign a {@link PDAppearance} to this.
741: *
742: * @param newAppearance
743: * The new {@link PDAppearance}.
744: */
745: public void setAppearance(PDAppearance newAppearance) {
746: setFieldObject(DK_AP, newAppearance);
747: }
748:
749: /**
750: * Select a concrete {@link PDForm} from the {@link PDAppearance}.
751: *
752: * @param newAppearanceState
753: * The new state name.
754: */
755: public void setAppearanceState(COSName newAppearanceState) {
756: cosSetField(DK_AS, newAppearanceState);
757: }
758:
759: /**
760: * Assign a {@link PDBorderStyle}.
761: *
762: * @param newBorderStyle
763: * The new {@link PDBorderStyle}
764: */
765: public void setBorderStyle(PDBorderStyle newBorderStyle) {
766: setFieldObject(DK_BS, newBorderStyle);
767: }
768:
769: /**
770: * Assign a border style name.
771: *
772: * @param newStyle
773: * The new border style name.
774: */
775: public void setBorderStyleName(COSName newStyle) {
776: PDBorderStyle bs = getBorderStyle();
777: if (bs == null) {
778: bs = (PDBorderStyle) PDBorderStyle.META.createNew();
779: setBorderStyle(bs);
780: }
781: bs.setStyle(newStyle);
782: }
783:
784: /**
785: * Assign a border width.
786: *
787: * @param newWidth
788: * The new Border width.
789: */
790: public void setBorderStyleWidth(float newWidth) {
791: PDBorderStyle bs = getBorderStyle();
792: if (bs == null) {
793: bs = (PDBorderStyle) PDBorderStyle.META.createNew();
794: setBorderStyle(bs);
795: }
796: bs.setWidth(newWidth);
797: }
798:
799: /**
800: * Assign a color.
801: *
802: * @param color
803: * The new color values.
804: */
805: public void setColor(float[] color) {
806: setFieldFixedArray(DK_C, color);
807: }
808:
809: /**
810: * Assign a content {@link String}.
811: *
812: * @param newContents
813: * The new content {@link String}.
814: */
815: public void setContents(String newContents) {
816: setFieldString(DK_Contents, newContents);
817: }
818:
819: /**
820: * Convenience method to access "Hidden" flag.
821: */
822: public void setHidden(boolean f) {
823: getFlags().setHidden(f);
824: }
825:
826: /**
827: * Convenience method to access "Invisible" flag.
828: */
829: public void setInvisible(boolean f) {
830: getFlags().setInvisible(f);
831: }
832:
833: /**
834: * Convenience method to access "Locked" flag.
835: */
836: public void setLocked(boolean f) {
837: getFlags().setLocked(f);
838: }
839:
840: protected void setModified(String newModified) {
841: setFieldString(DK_M, newModified);
842: }
843:
844: /**
845: * Assign a name.
846: *
847: * @param newName
848: * The new name.
849: */
850: public void setName(String newName) {
851: setFieldString(DK_NM, newName);
852: }
853:
854: /**
855: * Convenience method to access "NoRotate" flag.
856: */
857: public void setNoRotate(boolean f) {
858: getFlags().setNoRotate(f);
859: }
860:
861: /**
862: * Convenience method to access "NoView" flag.
863: */
864: public void setNoView(boolean f) {
865: getFlags().setNoView(f);
866: }
867:
868: /**
869: * Convenience method to access "NoZoom" flag.
870: */
871: public void setNoZoom(boolean f) {
872: getFlags().setNoZoom(f);
873: }
874:
875: protected void setPage(PDPage newPage) {
876: setFieldObject(DK_P, newPage);
877: }
878:
879: /**
880: * Convenience method to access "Print" flag.
881: */
882: public void setPrint(boolean f) {
883: getFlags().setPrint(f);
884: }
885:
886: /**
887: * Convenience method to access "ReadOnly" flag.
888: */
889: public void setReadOnly(boolean readOnly) {
890: getFlags().setReadOnly(readOnly);
891: }
892:
893: /**
894: * Assign a {@link CDSRectangle} for the visual appearance of this.
895: *
896: * @param newRectangle
897: * Assign a {@link CDSRectangle} for the visual appearance of
898: * this.
899: */
900: public void setRectangle(CDSRectangle newRectangle) {
901: setFieldObject(DK_Rect, newRectangle);
902: }
903:
904: protected void setStructParent(Integer newStructParent) {
905: if (newStructParent != null) {
906: setFieldInt(DK_StructParent, newStructParent.intValue());
907: } else {
908: cosRemoveField(DK_StructParent);
909: }
910: }
911:
912: /**
913: * Convenience method to access "ToggleNoView" flag.
914: */
915: public void setToggleNoView(boolean f) {
916: getFlags().setToggleNoView(f);
917: }
918:
919: /*
920: * (non-Javadoc)
921: *
922: * @see de.intarsys.pdf.pd.PDObject#toString()
923: */
924: public String toString() {
925: StringBuilder sb = new StringBuilder();
926: sb.append("Annotation: "); //$NON-NLS-1$
927: sb.append(cosGetSubtype());
928: sb.append(" "); //$NON-NLS-1$
929: if (isWidgetAnnotation()) {
930: PDAcroFormField field = (PDAcroFormField) PDAcroFormField.META
931: .createFromCos(cosGetDict());
932: sb.append(field.getQualifiedName());
933: sb.append(" "); //$NON-NLS-1$
934: }
935: sb.append(super .toString());
936: return sb.toString();
937: }
938:
939: /**
940: * Assign the current date as the date of last modification.
941: */
942: public void touch() {
943: setFieldObject(PDAnnotation.DK_M, new CDSDate());
944: }
945: }
|