|
1 /* |
|
2 * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 package javax.swing.text.rtf; |
|
26 |
|
27 import javax.swing.text.StyleConstants; |
|
28 import javax.swing.text.AttributeSet; |
|
29 import javax.swing.text.MutableAttributeSet; |
|
30 import javax.swing.text.TabStop; |
|
31 import java.util.*; |
|
32 import java.io.IOException; |
|
33 |
|
34 class RTFAttributes |
|
35 { |
|
36 static RTFAttribute attributes[]; |
|
37 |
|
38 static { |
|
39 Vector a = new Vector(); |
|
40 int CHR = RTFAttribute.D_CHARACTER; |
|
41 int PGF = RTFAttribute.D_PARAGRAPH; |
|
42 int SEC = RTFAttribute.D_SECTION; |
|
43 int DOC = RTFAttribute.D_DOCUMENT; |
|
44 int PST = RTFAttribute.D_META; |
|
45 Boolean True = Boolean.valueOf(true); |
|
46 Boolean False = Boolean.valueOf(false); |
|
47 |
|
48 a.addElement(new BooleanAttribute(CHR, StyleConstants.Italic, "i")); |
|
49 a.addElement(new BooleanAttribute(CHR, StyleConstants.Bold, "b")); |
|
50 a.addElement(new BooleanAttribute(CHR, StyleConstants.Underline, "ul")); |
|
51 a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.LeftIndent, "li", |
|
52 0f, 0)); |
|
53 a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.RightIndent, "ri", |
|
54 0f, 0)); |
|
55 a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.FirstLineIndent, "fi", |
|
56 0f, 0)); |
|
57 |
|
58 a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment, |
|
59 "ql", StyleConstants.ALIGN_LEFT)); |
|
60 a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment, |
|
61 "qr", StyleConstants.ALIGN_RIGHT)); |
|
62 a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment, |
|
63 "qc", StyleConstants.ALIGN_CENTER)); |
|
64 a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment, |
|
65 "qj", StyleConstants.ALIGN_JUSTIFIED)); |
|
66 a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.SpaceAbove, |
|
67 "sa", 0)); |
|
68 a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.SpaceBelow, |
|
69 "sb", 0)); |
|
70 |
|
71 a.addElement(new AssertiveAttribute(PST, RTFReader.TabAlignmentKey, |
|
72 "tqr", TabStop.ALIGN_RIGHT)); |
|
73 a.addElement(new AssertiveAttribute(PST, RTFReader.TabAlignmentKey, |
|
74 "tqc", TabStop.ALIGN_CENTER)); |
|
75 a.addElement(new AssertiveAttribute(PST, RTFReader.TabAlignmentKey, |
|
76 "tqdec", TabStop.ALIGN_DECIMAL)); |
|
77 |
|
78 |
|
79 a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey, |
|
80 "tldot", TabStop.LEAD_DOTS)); |
|
81 a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey, |
|
82 "tlhyph", TabStop.LEAD_HYPHENS)); |
|
83 a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey, |
|
84 "tlul", TabStop.LEAD_UNDERLINE)); |
|
85 a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey, |
|
86 "tlth", TabStop.LEAD_THICKLINE)); |
|
87 a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey, |
|
88 "tleq", TabStop.LEAD_EQUALS)); |
|
89 |
|
90 /* The following aren't actually recognized by Swing */ |
|
91 a.addElement(new BooleanAttribute(CHR, Constants.Caps, "caps")); |
|
92 a.addElement(new BooleanAttribute(CHR, Constants.Outline, "outl")); |
|
93 a.addElement(new BooleanAttribute(CHR, Constants.SmallCaps, "scaps")); |
|
94 a.addElement(new BooleanAttribute(CHR, Constants.Shadow, "shad")); |
|
95 a.addElement(new BooleanAttribute(CHR, Constants.Hidden, "v")); |
|
96 a.addElement(new BooleanAttribute(CHR, Constants.Strikethrough, |
|
97 "strike")); |
|
98 a.addElement(new BooleanAttribute(CHR, Constants.Deleted, |
|
99 "deleted")); |
|
100 |
|
101 |
|
102 |
|
103 a.addElement(new AssertiveAttribute(DOC, "saveformat", "defformat", "RTF")); |
|
104 a.addElement(new AssertiveAttribute(DOC, "landscape", "landscape")); |
|
105 |
|
106 a.addElement(NumericAttribute.NewTwips(DOC, Constants.PaperWidth, |
|
107 "paperw", 12240)); |
|
108 a.addElement(NumericAttribute.NewTwips(DOC, Constants.PaperHeight, |
|
109 "paperh", 15840)); |
|
110 a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginLeft, |
|
111 "margl", 1800)); |
|
112 a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginRight, |
|
113 "margr", 1800)); |
|
114 a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginTop, |
|
115 "margt", 1440)); |
|
116 a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginBottom, |
|
117 "margb", 1440)); |
|
118 a.addElement(NumericAttribute.NewTwips(DOC, Constants.GutterWidth, |
|
119 "gutter", 0)); |
|
120 |
|
121 a.addElement(new AssertiveAttribute(PGF, Constants.WidowControl, |
|
122 "nowidctlpar", False)); |
|
123 a.addElement(new AssertiveAttribute(PGF, Constants.WidowControl, |
|
124 "widctlpar", True)); |
|
125 a.addElement(new AssertiveAttribute(DOC, Constants.WidowControl, |
|
126 "widowctrl", True)); |
|
127 |
|
128 |
|
129 RTFAttribute[] attrs = new RTFAttribute[a.size()]; |
|
130 a.copyInto(attrs); |
|
131 attributes = attrs; |
|
132 } |
|
133 |
|
134 static Dictionary attributesByKeyword() |
|
135 { |
|
136 Dictionary d = new Hashtable(attributes.length); |
|
137 int i, m; |
|
138 |
|
139 m = attributes.length; |
|
140 for(i = 0; i < m; i++) |
|
141 d.put(attributes[i].rtfName(), attributes[i]); |
|
142 |
|
143 return d; |
|
144 } |
|
145 |
|
146 /************************************************************************/ |
|
147 /************************************************************************/ |
|
148 |
|
149 static abstract class GenericAttribute |
|
150 { |
|
151 int domain; |
|
152 Object swingName; |
|
153 String rtfName; |
|
154 |
|
155 protected GenericAttribute(int d,Object s, String r) |
|
156 { |
|
157 domain = d; |
|
158 swingName = s; |
|
159 rtfName = r; |
|
160 } |
|
161 |
|
162 public int domain() { return domain; } |
|
163 public Object swingName() { return swingName; } |
|
164 public String rtfName() { return rtfName; } |
|
165 |
|
166 abstract boolean set(MutableAttributeSet target); |
|
167 abstract boolean set(MutableAttributeSet target, int parameter); |
|
168 abstract boolean setDefault(MutableAttributeSet target); |
|
169 |
|
170 public boolean write(AttributeSet source, |
|
171 RTFGenerator target, |
|
172 boolean force) |
|
173 throws IOException |
|
174 { |
|
175 return writeValue(source.getAttribute(swingName), target, force); |
|
176 } |
|
177 |
|
178 public boolean writeValue(Object value, RTFGenerator target, |
|
179 boolean force) |
|
180 throws IOException |
|
181 { |
|
182 return false; |
|
183 } |
|
184 } |
|
185 |
|
186 static class BooleanAttribute |
|
187 extends GenericAttribute |
|
188 implements RTFAttribute |
|
189 { |
|
190 boolean rtfDefault; |
|
191 boolean swingDefault; |
|
192 |
|
193 protected static final Boolean True = Boolean.valueOf(true); |
|
194 protected static final Boolean False = Boolean.valueOf(false); |
|
195 |
|
196 public BooleanAttribute(int d, Object s, |
|
197 String r, boolean ds, boolean dr) |
|
198 { |
|
199 super(d, s, r); |
|
200 swingDefault = ds; |
|
201 rtfDefault = dr; |
|
202 } |
|
203 |
|
204 public BooleanAttribute(int d, Object s, String r) |
|
205 { |
|
206 super(d, s, r); |
|
207 |
|
208 swingDefault = false; |
|
209 rtfDefault = false; |
|
210 } |
|
211 |
|
212 public boolean set(MutableAttributeSet target) |
|
213 { |
|
214 /* TODO: There's some ambiguity about whether this should |
|
215 *set* or *toggle* the attribute. */ |
|
216 target.addAttribute(swingName, True); |
|
217 |
|
218 return true; /* true indicates we were successful */ |
|
219 } |
|
220 |
|
221 public boolean set(MutableAttributeSet target, int parameter) |
|
222 { |
|
223 /* See above note in the case that parameter==1 */ |
|
224 Boolean value = ( parameter != 0 ? True : False ); |
|
225 |
|
226 target.addAttribute(swingName, value); |
|
227 |
|
228 return true; /* true indicates we were successful */ |
|
229 } |
|
230 |
|
231 public boolean setDefault(MutableAttributeSet target) |
|
232 { |
|
233 if (swingDefault != rtfDefault || |
|
234 ( target.getAttribute(swingName) != null ) ) |
|
235 target.addAttribute(swingName, Boolean.valueOf(rtfDefault)); |
|
236 return true; |
|
237 } |
|
238 |
|
239 public boolean writeValue(Object o_value, |
|
240 RTFGenerator target, |
|
241 boolean force) |
|
242 throws IOException |
|
243 { |
|
244 Boolean val; |
|
245 |
|
246 if (o_value == null) |
|
247 val = Boolean.valueOf(swingDefault); |
|
248 else |
|
249 val = (Boolean)o_value; |
|
250 |
|
251 if (force || (val.booleanValue() != rtfDefault)) { |
|
252 if (val.booleanValue()) { |
|
253 target.writeControlWord(rtfName); |
|
254 } else { |
|
255 target.writeControlWord(rtfName, 0); |
|
256 } |
|
257 } |
|
258 return true; |
|
259 } |
|
260 } |
|
261 |
|
262 |
|
263 static class AssertiveAttribute |
|
264 extends GenericAttribute |
|
265 implements RTFAttribute |
|
266 { |
|
267 Object swingValue; |
|
268 |
|
269 public AssertiveAttribute(int d, Object s, String r) |
|
270 { |
|
271 super(d, s, r); |
|
272 swingValue = Boolean.valueOf(true); |
|
273 } |
|
274 |
|
275 public AssertiveAttribute(int d, Object s, String r, Object v) |
|
276 { |
|
277 super(d, s, r); |
|
278 swingValue = v; |
|
279 } |
|
280 |
|
281 public AssertiveAttribute(int d, Object s, String r, int v) |
|
282 { |
|
283 super(d, s, r); |
|
284 swingValue = new Integer(v); |
|
285 } |
|
286 |
|
287 public boolean set(MutableAttributeSet target) |
|
288 { |
|
289 if (swingValue == null) |
|
290 target.removeAttribute(swingName); |
|
291 else |
|
292 target.addAttribute(swingName, swingValue); |
|
293 |
|
294 return true; |
|
295 } |
|
296 |
|
297 public boolean set(MutableAttributeSet target, int parameter) |
|
298 { |
|
299 return false; |
|
300 } |
|
301 |
|
302 public boolean setDefault(MutableAttributeSet target) |
|
303 { |
|
304 target.removeAttribute(swingName); |
|
305 return true; |
|
306 } |
|
307 |
|
308 public boolean writeValue(Object value, |
|
309 RTFGenerator target, |
|
310 boolean force) |
|
311 throws IOException |
|
312 { |
|
313 if (value == null) { |
|
314 return ! force; |
|
315 } |
|
316 |
|
317 if (value.equals(swingValue)) { |
|
318 target.writeControlWord(rtfName); |
|
319 return true; |
|
320 } |
|
321 |
|
322 return ! force; |
|
323 } |
|
324 } |
|
325 |
|
326 |
|
327 static class NumericAttribute |
|
328 extends GenericAttribute |
|
329 implements RTFAttribute |
|
330 { |
|
331 int rtfDefault; |
|
332 Number swingDefault; |
|
333 float scale; |
|
334 |
|
335 protected NumericAttribute(int d, Object s, String r) |
|
336 { |
|
337 super(d, s, r); |
|
338 rtfDefault = 0; |
|
339 swingDefault = null; |
|
340 scale = 1f; |
|
341 } |
|
342 |
|
343 public NumericAttribute(int d, Object s, |
|
344 String r, int ds, int dr) |
|
345 { |
|
346 this(d, s, r, new Integer(ds), dr, 1f); |
|
347 } |
|
348 |
|
349 public NumericAttribute(int d, Object s, |
|
350 String r, Number ds, int dr, float sc) |
|
351 { |
|
352 super(d, s, r); |
|
353 swingDefault = ds; |
|
354 rtfDefault = dr; |
|
355 scale = sc; |
|
356 } |
|
357 |
|
358 public static NumericAttribute NewTwips(int d, Object s, String r, |
|
359 float ds, int dr) |
|
360 { |
|
361 return new NumericAttribute(d, s, r, new Float(ds), dr, 20f); |
|
362 } |
|
363 |
|
364 public static NumericAttribute NewTwips(int d, Object s, String r, |
|
365 int dr) |
|
366 { |
|
367 return new NumericAttribute(d, s, r, null, dr, 20f); |
|
368 } |
|
369 |
|
370 public boolean set(MutableAttributeSet target) |
|
371 { |
|
372 return false; |
|
373 } |
|
374 |
|
375 public boolean set(MutableAttributeSet target, int parameter) |
|
376 { |
|
377 Number swingValue; |
|
378 |
|
379 if (scale == 1f) |
|
380 swingValue = new Integer(parameter); |
|
381 else |
|
382 swingValue = new Float(parameter / scale); |
|
383 target.addAttribute(swingName, swingValue); |
|
384 return true; |
|
385 } |
|
386 |
|
387 public boolean setDefault(MutableAttributeSet target) |
|
388 { |
|
389 Number old = (Number)target.getAttribute(swingName); |
|
390 if (old == null) |
|
391 old = swingDefault; |
|
392 if (old != null && ( |
|
393 (scale == 1f && old.intValue() == rtfDefault) || |
|
394 (Math.round(old.floatValue() * scale) == rtfDefault) |
|
395 )) |
|
396 return true; |
|
397 set(target, rtfDefault); |
|
398 return true; |
|
399 } |
|
400 |
|
401 public boolean writeValue(Object o_value, |
|
402 RTFGenerator target, |
|
403 boolean force) |
|
404 throws IOException |
|
405 { |
|
406 Number value = (Number)o_value; |
|
407 if (value == null) |
|
408 value = swingDefault; |
|
409 if (value == null) { |
|
410 /* TODO: What is the proper behavior if the Swing object does |
|
411 not specify a value, and we don't know its default value? |
|
412 Currently we pretend that the RTF default value is |
|
413 equivalent (probably a workable assumption) */ |
|
414 return true; |
|
415 } |
|
416 int int_value = Math.round(value.floatValue() * scale); |
|
417 if (force || (int_value != rtfDefault)) |
|
418 target.writeControlWord(rtfName, int_value); |
|
419 return true; |
|
420 } |
|
421 } |
|
422 } |