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.Set;
035: import de.intarsys.pdf.cos.COSBasedObject;
036: import de.intarsys.pdf.cos.COSName;
037: import de.intarsys.pdf.cos.COSNull;
038: import de.intarsys.pdf.cos.COSObject;
039: import de.intarsys.pdf.cos.COSString;
040: import de.intarsys.tools.string.StringTools;
041:
042: /**
043: * A logical button within an AcroForm.
044: *
045: */
046: public class PDAFButtonField extends PDAcroFormField {
047: public static class MetaClass extends PDAcroFormField.MetaClass {
048: protected MetaClass(Class instanceClass) {
049: super (instanceClass);
050: }
051:
052: protected COSBasedObject doCreateCOSBasedObject(COSObject object) {
053: return new PDAFButtonField(object);
054: }
055: }
056:
057: /** The meta class instance */
058: public static final MetaClass META = new MetaClass(MetaClass.class
059: .getDeclaringClass());
060:
061: static public final COSName DK_Opt = COSName.constant("Opt");
062:
063: protected PDAFButtonField(COSObject object) {
064: super (object);
065: }
066:
067: /**
068: * Return true when this is an object with checkbox behavior.
069: *
070: * @return true when this is an object with checkbox behavior.
071: */
072: public boolean isCheckbox() {
073: return !isPushbutton() && !isRadio();
074: }
075:
076: /*
077: * (non-Javadoc)
078: *
079: * @see de.intarsys.pdf.pd.PDAcroFormField#cosGetExpectedFieldType()
080: */
081: public COSName cosGetExpectedFieldType() {
082: return CN_FT_Btn;
083: }
084:
085: /**
086: * Make this a push button.
087: *
088: * @param f
089: */
090: public void setPushbutton(boolean f) {
091: getFieldFlags().setPushbutton(f);
092: }
093:
094: /**
095: * <code>true</code> if this is a pushbutton.
096: *
097: * @return <code>true</code> if this is a pushbutton.
098: */
099: public boolean isPushbutton() {
100: return getFieldFlags().isPushbutton();
101: }
102:
103: /**
104: * <code>true</code> if this is a radio button.
105: *
106: * @return <code>true</code> if this is a radio button.
107: */
108: public boolean isRadio() {
109: return getFieldFlags().isRadio();
110: }
111:
112: /*
113: * (non-Javadoc)
114: *
115: * @see de.intarsys.pdf.pd.PDAcroFormField#isTypeBtn()
116: */
117: public boolean isTypeBtn() {
118: return true;
119: }
120:
121: /*
122: * (non-Javadoc)
123: *
124: * @see de.intarsys.pdf.pd.PDAcroFormField#cosSetValue(de.intarsys.pdf.cos.COSObject)
125: */
126: public COSObject cosSetValue(COSObject state) {
127: if (isCheckbox() || isRadio()) {
128: COSName newState;
129: if (state instanceof COSName) {
130: newState = (COSName) state;
131: } else {
132: if (state == null) {
133: newState = PDWidgetAnnotation.CN_State_Off;
134: } else {
135: newState = COSName.create(state.stringValue());
136: }
137: }
138:
139: for (Iterator i = getAnnotations().iterator(); i.hasNext();) {
140: PDWidgetAnnotation annot = (PDWidgetAnnotation) i
141: .next();
142: Set states = annot.getAppearanceStates();
143: if (states.contains(newState)) {
144: annot.setAppearanceState((COSName) newState
145: .copyOptional());
146: } else {
147: annot
148: .setAppearanceState(PDWidgetAnnotation.CN_State_Off);
149: }
150: }
151: return super .cosSetValue(newState);
152: }
153: return COSNull.NULL;
154: }
155:
156: /*
157: * (non-Javadoc)
158: *
159: * @see de.intarsys.pdf.pd.PDAcroFormField#setValueString(java.lang.String)
160: */
161: public void setValueString(String value) {
162: if (value == null) {
163: super .setValueString(value);
164: }
165: if (isCheckbox() || isRadio()) {
166: COSName state = COSName.create(value);
167: cosSetValue(state);
168: }
169: }
170:
171: /**
172: * set the correct appearance state in a button annotation
173: *
174: * <p>
175: * This code applies to checkboxes only
176: * </p>
177: *
178: * @param annot
179: * the button annotation
180: * @param value
181: * the state to be selected
182: *
183: * @return the name of the state
184: */
185: protected COSName setButtonAppearanceState(PDAnnotation annot,
186: String value) {
187: // TODO 2 refactor location
188: COSName state = COSName.create(value);
189: Set states = annot.getAppearanceStates();
190: if (!states.contains(state)) {
191: COSName offState = COSName.create("Off");
192: state = offState;
193: value = value.toLowerCase().trim();
194: // todo 3 provide property "true" characters
195: if (value.equals("1") || value.startsWith("t") || // true
196: value.startsWith("y") || // yes
197: value.startsWith("w") || // wahr
198: value.startsWith("j") || // ja
199: value.startsWith("x") // ankreuzen
200: ) {
201: for (Iterator i = states.iterator(); i.hasNext();) {
202: COSName aState = (COSName) i.next();
203: if (!aState.equals(offState)) {
204: state = (COSName) aState.copyOptional();
205: break;
206: }
207: }
208: }
209: }
210: annot.setAppearanceState(state);
211: return state;
212: }
213:
214: /**
215: * The {@link Set} of possible states the button can enter.
216: *
217: * @return The {@link Set} of possible states the button can enter.
218: */
219: public Set getAvailableButtonAppearanceStates() {
220: // todo change signature
221: Set availableStates = new HashSet();
222: for (Iterator i = getAnnotations().iterator(); i.hasNext();) {
223: PDAnnotation child = (PDAnnotation) i.next();
224: availableStates.addAll(child.getAppearanceStates());
225: }
226: return availableStates;
227: }
228:
229: /**
230: * The {@link Set} of possible non - off states the button can enter.
231: *
232: * @return The {@link Set} of possible non - off states the button can
233: * enter.
234: */
235: public Set getAvailableButtonAppearanceStatesNoOff() {
236: // todo change signature
237: Set availableStates = getAvailableButtonAppearanceStates();
238: COSName offState = COSName.create("Off");
239: availableStates.remove(offState);
240: return availableStates;
241: }
242:
243: /*
244: * (non-Javadoc)
245: *
246: * @see de.intarsys.pdf.pd.PDAcroFormField#reset()
247: */
248: public void reset() {
249: //
250: COSObject value = cosGetDefaultValue();
251: if (value.isNull()) {
252: value = COSString.create(StringTools.EMPTY);
253: } else {
254: value = value.copyOptional();
255: }
256: cosSetValue(value);
257: }
258:
259: /**
260: * <code>true</code> if this is checked.
261: *
262: * @return <code>true</code> if this is checked.
263: */
264: public boolean isChecked() {
265: if (isCheckbox()) {
266: return !PDWidgetAnnotation.CN_State_Off
267: .equals(getAnyAnnotation().getAppearanceState());
268: }
269: return false;
270: }
271: }
|