001: /*
002: * Copyright 2002 by Paulo Soares.
003: *
004: * The contents of this file are subject to the Mozilla Public License Version 1.1
005: * (the "License"); you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the License.
011: *
012: * The Original Code is 'iText, a free JAVA-PDF library'.
013: *
014: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
015: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
016: * All Rights Reserved.
017: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
018: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
019: *
020: * Contributor(s): all the names of the contributors are added in the source code
021: * where applicable.
022: *
023: * Alternatively, the contents of this file may be used under the terms of the
024: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
025: * provisions of LGPL are applicable instead of those above. If you wish to
026: * allow use of your version of this file only under the terms of the LGPL
027: * License and not to allow others to use your version of this file under
028: * the MPL, indicate your decision by deleting the provisions above and
029: * replace them with the notice and other provisions required by the LGPL.
030: * If you do not delete the provisions above, a recipient may use your version
031: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
032: *
033: * This library is free software; you can redistribute it and/or modify it
034: * under the terms of the MPL as stated above or under the terms of the GNU
035: * Library General Public License as published by the Free Software Foundation;
036: * either version 2 of the License, or any later version.
037: *
038: * This library is distributed in the hope that it will be useful, but WITHOUT
039: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
040: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
041: * details.
042: *
043: * If you didn't download this code from the following link, you should check if
044: * you aren't using an obsolete version:
045: * http://www.lowagie.com/iText/
046: */
047:
048: package com.lowagie.text.pdf;
049:
050: import java.util.ArrayList;
051: import java.util.Iterator;
052:
053: import com.lowagie.text.Rectangle;
054:
055: /** Implements form fields.
056: *
057: * @author Paulo Soares (psoares@consiste.pt)
058: */
059: public class PdfFormField extends PdfAnnotation {
060:
061: public static final int FF_READ_ONLY = 1;
062: public static final int FF_REQUIRED = 2;
063: public static final int FF_NO_EXPORT = 4;
064: public static final int FF_NO_TOGGLE_TO_OFF = 16384;
065: public static final int FF_RADIO = 32768;
066: public static final int FF_PUSHBUTTON = 65536;
067: public static final int FF_MULTILINE = 4096;
068: public static final int FF_PASSWORD = 8192;
069: public static final int FF_COMBO = 131072;
070: public static final int FF_EDIT = 262144;
071: public static final int FF_FILESELECT = 1048576;
072: public static final int FF_MULTISELECT = 2097152;
073: public static final int FF_DONOTSPELLCHECK = 4194304;
074: public static final int FF_DONOTSCROLL = 8388608;
075: public static final int FF_COMB = 16777216;
076: public static final int FF_RADIOSINUNISON = 1 << 25;
077: public static final int Q_LEFT = 0;
078: public static final int Q_CENTER = 1;
079: public static final int Q_RIGHT = 2;
080: public static final int MK_NO_ICON = 0;
081: public static final int MK_NO_CAPTION = 1;
082: public static final int MK_CAPTION_BELOW = 2;
083: public static final int MK_CAPTION_ABOVE = 3;
084: public static final int MK_CAPTION_RIGHT = 4;
085: public static final int MK_CAPTION_LEFT = 5;
086: public static final int MK_CAPTION_OVERLAID = 6;
087: public static final PdfName IF_SCALE_ALWAYS = PdfName.A;
088: public static final PdfName IF_SCALE_BIGGER = PdfName.B;
089: public static final PdfName IF_SCALE_SMALLER = PdfName.S;
090: public static final PdfName IF_SCALE_NEVER = PdfName.N;
091: public static final PdfName IF_SCALE_ANAMORPHIC = PdfName.A;
092: public static final PdfName IF_SCALE_PROPORTIONAL = PdfName.P;
093: public static final boolean MULTILINE = true;
094: public static final boolean SINGLELINE = false;
095: public static final boolean PLAINTEXT = false;
096: public static final boolean PASSWORD = true;
097: static PdfName mergeTarget[] = { PdfName.FONT, PdfName.XOBJECT,
098: PdfName.COLORSPACE, PdfName.PATTERN };
099:
100: /** Holds value of property parent. */
101: protected PdfFormField parent;
102:
103: protected ArrayList kids;
104:
105: /**
106: * Constructs a new <CODE>PdfAnnotation</CODE> of subtype link (Action).
107: */
108:
109: public PdfFormField(PdfWriter writer, float llx, float lly,
110: float urx, float ury, PdfAction action) {
111: super (writer, llx, lly, urx, ury, action);
112: put(PdfName.TYPE, PdfName.ANNOT);
113: put(PdfName.SUBTYPE, PdfName.WIDGET);
114: annotation = true;
115: }
116:
117: /** Creates new PdfFormField */
118: protected PdfFormField(PdfWriter writer) {
119: super (writer, null);
120: form = true;
121: annotation = false;
122: }
123:
124: public void setWidget(Rectangle rect, PdfName highlight) {
125: put(PdfName.TYPE, PdfName.ANNOT);
126: put(PdfName.SUBTYPE, PdfName.WIDGET);
127: put(PdfName.RECT, new PdfRectangle(rect));
128: annotation = true;
129: if (highlight != null && !highlight.equals(HIGHLIGHT_INVERT))
130: put(PdfName.H, highlight);
131: }
132:
133: public static PdfFormField createEmpty(PdfWriter writer) {
134: PdfFormField field = new PdfFormField(writer);
135: return field;
136: }
137:
138: public void setButton(int flags) {
139: put(PdfName.FT, PdfName.BTN);
140: if (flags != 0)
141: put(PdfName.FF, new PdfNumber(flags));
142: }
143:
144: protected static PdfFormField createButton(PdfWriter writer,
145: int flags) {
146: PdfFormField field = new PdfFormField(writer);
147: field.setButton(flags);
148: return field;
149: }
150:
151: public static PdfFormField createPushButton(PdfWriter writer) {
152: return createButton(writer, FF_PUSHBUTTON);
153: }
154:
155: public static PdfFormField createCheckBox(PdfWriter writer) {
156: return createButton(writer, 0);
157: }
158:
159: public static PdfFormField createRadioButton(PdfWriter writer,
160: boolean noToggleToOff) {
161: return createButton(writer, FF_RADIO
162: + (noToggleToOff ? FF_NO_TOGGLE_TO_OFF : 0));
163: }
164:
165: public static PdfFormField createTextField(PdfWriter writer,
166: boolean multiline, boolean password, int maxLen) {
167: PdfFormField field = new PdfFormField(writer);
168: field.put(PdfName.FT, PdfName.TX);
169: int flags = (multiline ? FF_MULTILINE : 0);
170: flags += (password ? FF_PASSWORD : 0);
171: field.put(PdfName.FF, new PdfNumber(flags));
172: if (maxLen > 0)
173: field.put(PdfName.MAXLEN, new PdfNumber(maxLen));
174: return field;
175: }
176:
177: protected static PdfFormField createChoice(PdfWriter writer,
178: int flags, PdfArray options, int topIndex) {
179: PdfFormField field = new PdfFormField(writer);
180: field.put(PdfName.FT, PdfName.CH);
181: field.put(PdfName.FF, new PdfNumber(flags));
182: field.put(PdfName.OPT, options);
183: if (topIndex > 0)
184: field.put(PdfName.TI, new PdfNumber(topIndex));
185: return field;
186: }
187:
188: public static PdfFormField createList(PdfWriter writer,
189: String options[], int topIndex) {
190: return createChoice(writer, 0, processOptions(options),
191: topIndex);
192: }
193:
194: public static PdfFormField createList(PdfWriter writer,
195: String options[][], int topIndex) {
196: return createChoice(writer, 0, processOptions(options),
197: topIndex);
198: }
199:
200: public static PdfFormField createCombo(PdfWriter writer,
201: boolean edit, String options[], int topIndex) {
202: return createChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0),
203: processOptions(options), topIndex);
204: }
205:
206: public static PdfFormField createCombo(PdfWriter writer,
207: boolean edit, String options[][], int topIndex) {
208: return createChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0),
209: processOptions(options), topIndex);
210: }
211:
212: protected static PdfArray processOptions(String options[]) {
213: PdfArray array = new PdfArray();
214: for (int k = 0; k < options.length; ++k) {
215: array
216: .add(new PdfString(options[k],
217: PdfObject.TEXT_UNICODE));
218: }
219: return array;
220: }
221:
222: protected static PdfArray processOptions(String options[][]) {
223: PdfArray array = new PdfArray();
224: for (int k = 0; k < options.length; ++k) {
225: String subOption[] = options[k];
226: PdfArray ar2 = new PdfArray(new PdfString(subOption[0],
227: PdfObject.TEXT_UNICODE));
228: ar2
229: .add(new PdfString(subOption[1],
230: PdfObject.TEXT_UNICODE));
231: array.add(ar2);
232: }
233: return array;
234: }
235:
236: public static PdfFormField createSignature(PdfWriter writer) {
237: PdfFormField field = new PdfFormField(writer);
238: field.put(PdfName.FT, PdfName.SIG);
239: return field;
240: }
241:
242: /** Getter for property parent.
243: * @return Value of property parent.
244: */
245: public PdfFormField getParent() {
246: return parent;
247: }
248:
249: public void addKid(PdfFormField field) {
250: field.parent = this ;
251: if (kids == null)
252: kids = new ArrayList();
253: kids.add(field);
254: }
255:
256: public ArrayList getKids() {
257: return kids;
258: }
259:
260: public int setFieldFlags(int flags) {
261: PdfNumber obj = (PdfNumber) get(PdfName.FF);
262: int old;
263: if (obj == null)
264: old = 0;
265: else
266: old = obj.intValue();
267: int v = old | flags;
268: put(PdfName.FF, new PdfNumber(v));
269: return old;
270: }
271:
272: public void setValueAsString(String s) {
273: put(PdfName.V, new PdfString(s, PdfObject.TEXT_UNICODE));
274: }
275:
276: public void setValueAsName(String s) {
277: put(PdfName.V, new PdfName(s));
278: }
279:
280: public void setValue(PdfSignature sig) {
281: put(PdfName.V, sig);
282: }
283:
284: public void setDefaultValueAsString(String s) {
285: put(PdfName.DV, new PdfString(s, PdfObject.TEXT_UNICODE));
286: }
287:
288: public void setDefaultValueAsName(String s) {
289: put(PdfName.DV, new PdfName(s));
290: }
291:
292: public void setFieldName(String s) {
293: if (s != null)
294: put(PdfName.T, new PdfString(s, PdfObject.TEXT_UNICODE));
295: }
296:
297: public void setUserName(String s) {
298: put(PdfName.TU, new PdfString(s, PdfObject.TEXT_UNICODE));
299: }
300:
301: public void setMappingName(String s) {
302: put(PdfName.TM, new PdfString(s, PdfObject.TEXT_UNICODE));
303: }
304:
305: public void setQuadding(int v) {
306: put(PdfName.Q, new PdfNumber(v));
307: }
308:
309: static void mergeResources(PdfDictionary result,
310: PdfDictionary source, PdfStamperImp writer) {
311: PdfDictionary dic = null;
312: PdfDictionary res = null;
313: PdfName target = null;
314: for (int k = 0; k < mergeTarget.length; ++k) {
315: target = mergeTarget[k];
316: PdfDictionary pdfDict = (PdfDictionary) PdfReader
317: .getPdfObject(source.get(target));
318: if ((dic = pdfDict) != null) {
319: if ((res = (PdfDictionary) PdfReader.getPdfObject(
320: result.get(target), result)) == null) {
321: res = new PdfDictionary();
322: }
323: res.mergeDifferent(dic);
324: result.put(target, res);
325: if (writer != null)
326: writer.markUsed(res);
327: }
328: }
329: }
330:
331: static void mergeResources(PdfDictionary result,
332: PdfDictionary source) {
333: mergeResources(result, source, null);
334: }
335:
336: public void setUsed() {
337: used = true;
338: if (parent != null)
339: put(PdfName.PARENT, parent.getIndirectReference());
340: if (kids != null) {
341: PdfArray array = new PdfArray();
342: for (int k = 0; k < kids.size(); ++k)
343: array.add(((PdfFormField) kids.get(k))
344: .getIndirectReference());
345: put(PdfName.KIDS, array);
346: }
347: if (templates == null)
348: return;
349: PdfDictionary dic = new PdfDictionary();
350: for (Iterator it = templates.keySet().iterator(); it.hasNext();) {
351: PdfTemplate template = (PdfTemplate) it.next();
352: mergeResources(dic, (PdfDictionary) template.getResources());
353: }
354: put(PdfName.DR, dic);
355: }
356:
357: public static PdfAnnotation shallowDuplicate(PdfAnnotation annot) {
358: PdfAnnotation dup;
359: if (annot.isForm()) {
360: dup = new PdfFormField(annot.writer);
361: PdfFormField dupField = (PdfFormField) dup;
362: PdfFormField srcField = (PdfFormField) annot;
363: dupField.parent = srcField.parent;
364: dupField.kids = srcField.kids;
365: } else
366: dup = new PdfAnnotation(annot.writer, null);
367: dup.merge(annot);
368: dup.form = annot.form;
369: dup.annotation = annot.annotation;
370: dup.templates = annot.templates;
371: return dup;
372: }
373: }
|