KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > rtf > rtflib > rtfdoc > RtfTextrun


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: RtfTextrun.java 426576 2006-07-28 15:44:37Z jeremias $ */
19
20 package org.apache.fop.render.rtf.rtflib.rtfdoc;
21
22 // Java
23
import java.io.IOException JavaDoc;
24 import java.io.Writer JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.ListIterator JavaDoc;
28
29 // FOP
30
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic;
31
32 /**
33  * Class which contains a linear text run. It has methods to add attributes,
34  * text, paragraph breaks....
35  * @author Peter Herweg, pherweg@web.de
36  */

37 public class RtfTextrun extends RtfContainer {
38     private boolean bSuppressLastPar = false;
39     private RtfListItem rtfListItem;
40     
41     /** Manager for handling space-* property. */
42     private RtfSpaceManager rtfSpaceManager = new RtfSpaceManager();
43     
44     /** Class which represents the opening of a RTF group mark.*/
45     private class RtfOpenGroupMark extends RtfElement {
46                 
47         RtfOpenGroupMark(RtfContainer parent, Writer JavaDoc w, RtfAttributes attr)
48                 throws IOException JavaDoc {
49             super(parent, w, attr);
50         }
51         
52         /**
53          * @return true if this element would generate no "useful" RTF content
54          */

55         public boolean isEmpty() {
56             return false;
57         }
58         
59         /**
60          * write RTF code of all our children
61          * @throws IOException for I/O problems
62          */

63         protected void writeRtfContent() throws IOException JavaDoc {
64             writeGroupMark(true);
65             writeAttributes(getRtfAttributes(), null);
66         }
67     }
68     
69     /** Class which represents the closing of a RTF group mark.*/
70     private class RtfCloseGroupMark extends RtfElement {
71         
72         RtfCloseGroupMark(RtfContainer parent, Writer JavaDoc w)
73                 throws IOException JavaDoc {
74             super(parent, w);
75         }
76         
77         /**
78          * @return true if this element would generate no "useful" RTF content
79          */

80         public boolean isEmpty() {
81             return false;
82         }
83         
84         /**
85          * write RTF code of all our children
86          * @throws IOException for I/O problems
87          */

88         protected void writeRtfContent() throws IOException JavaDoc {
89             writeGroupMark(false);
90         }
91     }
92
93     /** Class which represents a paragraph break.*/
94     private class RtfParagraphBreak extends RtfElement {
95         
96         RtfParagraphBreak(RtfContainer parent, Writer JavaDoc w)
97                 throws IOException JavaDoc {
98             super(parent, w);
99         }
100     
101         /**
102          * @return true if this element would generate no "useful" RTF content
103          */

104         public boolean isEmpty() {
105             return false;
106         }
107     
108         /**
109          * write RTF code of all our children
110          * @throws IOException for I/O problems
111          */

112         protected void writeRtfContent() throws IOException JavaDoc {
113             writeControlWord("par");
114         }
115     }
116               
117     /** Create an RTF container as a child of given container */
118     RtfTextrun(RtfContainer parent, Writer JavaDoc w, RtfAttributes attrs) throws IOException JavaDoc {
119         super(parent, w, attrs);
120     }
121     
122     
123     /**
124      * Adds instance of <code>OpenGroupMark</code> as a child with attributes.
125      *
126      * @param attrs attributes to add
127      * @throws IOException for I/O problems
128      */

129     private void addOpenGroupMark(RtfAttributes attrs) throws IOException JavaDoc {
130         RtfOpenGroupMark r = new RtfOpenGroupMark(this, writer, attrs);
131     }
132
133     /**
134      * Adds instance of <code>CloseGroupMark</code> as a child.
135      *
136      * @throws IOException for I/O problems
137      */

138     private void addCloseGroupMark() throws IOException JavaDoc {
139         RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer);
140     }
141     
142     /**
143      * Pushes block attributes, notifies all opened blocks about pushing block
144      * attributes, adds <code>OpenGroupMark</code> as a child.
145      *
146      * @param attrs the block attributes to push
147      * @throws IOException for I/O problems
148      */

149     public void pushBlockAttributes(RtfAttributes attrs) throws IOException JavaDoc {
150         rtfSpaceManager.stopUpdatingSpaceBefore();
151         RtfSpaceSplitter splitter = rtfSpaceManager.pushRtfSpaceSplitter(attrs);
152         addOpenGroupMark(splitter.getCommonAttributes());
153     }
154     
155     /**
156      * Pops block attributes, notifies all opened blocks about pushing block
157      * attributes, adds <code>CloseGroupMark</code> as a child.
158      *
159      * @throws IOException for I/O problems
160      */

161     public void popBlockAttributes() throws IOException JavaDoc {
162         rtfSpaceManager.popRtfSpaceSplitter();
163         rtfSpaceManager.stopUpdatingSpaceBefore();
164         addCloseGroupMark();
165     }
166
167     /**
168      * Pushes inline attributes.
169      *
170      * @param attrs the inline attributes to push
171      * @throws IOException for I/O problems
172      */

173     public void pushInlineAttributes(RtfAttributes attrs) throws IOException JavaDoc {
174         rtfSpaceManager.pushInlineAttributes(attrs);
175         addOpenGroupMark(attrs);
176     }
177
178     /**
179      * Pop inline attributes.
180      *
181      * @throws IOException for I/O problems
182      */

183     public void popInlineAttributes() throws IOException JavaDoc {
184         rtfSpaceManager.popInlineAttributes();
185         addCloseGroupMark();
186     }
187     
188     /**
189      * Add string to children list.
190      *
191      * @param s string to add
192      * @throws IOException for I/O problems
193      */

194     public void addString(String JavaDoc s) throws IOException JavaDoc {
195         if (s.equals("")) {
196             return;
197         }
198         RtfAttributes attrs = rtfSpaceManager.getLastInlineAttribute();
199         //add RtfSpaceSplitter to inherit accumulated space
200
rtfSpaceManager.pushRtfSpaceSplitter(attrs);
201         rtfSpaceManager.setCandidate(attrs);
202         RtfString r = new RtfString(this, writer, s);
203         rtfSpaceManager.popRtfSpaceSplitter();
204     }
205     
206     /**
207      * Inserts a footnote.
208      *
209      * @return inserted footnote
210      * @throws IOException for I/O problems
211      */

212     public RtfFootnote addFootnote() throws IOException JavaDoc {
213         return new RtfFootnote(this, writer);
214     }
215     
216     /**
217      * Inserts paragraph break before all close group marks.
218      *
219      * @throws IOException for I/O problems
220      */

221     public void addParagraphBreak() throws IOException JavaDoc {
222         // get copy of children list
223
List JavaDoc children = getChildren();
224
225         // delete all previous CloseGroupMark
226
int deletedCloseGroupCount = 0;
227
228         ListIterator JavaDoc lit = children.listIterator(children.size());
229         while (lit.hasPrevious()
230                 && (lit.previous() instanceof RtfCloseGroupMark)) {
231             lit.remove();
232             deletedCloseGroupCount++;
233         }
234
235         if (children.size() != 0) {
236             // add paragraph break and restore all deleted close group marks
237
setChildren(children);
238             new RtfParagraphBreak(this, writer);
239             for (int i = 0; i < deletedCloseGroupCount; i++) {
240                 addCloseGroupMark();
241             }
242         }
243     }
244     
245     /**
246      * Inserts a page number.
247      * @param attr Attributes for the page number to insert.
248      * @throws IOException for I/O problems
249      */

250     public void addPageNumber(RtfAttributes attr) throws IOException JavaDoc {
251         RtfPageNumber r = new RtfPageNumber(this, writer, attr);
252     }
253     
254     /**
255      * Inserts a hyperlink.
256      * @param attr Attributes for the hyperlink to insert.
257      * @return inserted hyperlink
258      * @throws IOException for I/O problems
259      */

260     public RtfHyperLink addHyperlink(RtfAttributes attr) throws IOException JavaDoc {
261         return new RtfHyperLink(this, writer, attr);
262     }
263     
264     /**
265      * Inserts a bookmark.
266      * @param id Id for the inserted bookmark
267      * @throws IOException for I/O problems
268      */

269     public void addBookmark(String JavaDoc id) throws IOException JavaDoc {
270        if (id != "") {
271             // if id is not empty, add boormark
272
new RtfBookmark(this, writer, id);
273        }
274     }
275
276     /**
277      * Inserts an image.
278      * @return inserted image
279      * @throws IOException for I/O problems
280      */

281     public RtfExternalGraphic newImage() throws IOException JavaDoc {
282         return new RtfExternalGraphic(this, writer);
283     }
284
285     /**
286      * Adds a new RtfTextrun to the given container if necessary, and returns it.
287      * @param container RtfContainer, which is the parent of the returned RtfTextrun
288      * @param writer Writer of the given RtfContainer
289      * @param attrs RtfAttributes which are to write at the beginning of the RtfTextrun
290      * @return new or existing RtfTextrun object.
291      * @throws IOException for I/O problems
292      */

293     public static RtfTextrun getTextrun(RtfContainer container, Writer JavaDoc writer, RtfAttributes attrs)
294             throws IOException JavaDoc {
295
296         List JavaDoc list = container.getChildren();
297                 
298         if (list.size() == 0) {
299             //add a new RtfTextrun
300
RtfTextrun textrun = new RtfTextrun(container, writer, attrs);
301             list.add(textrun);
302
303             return textrun;
304         }
305         
306         Object JavaDoc obj = list.get(list.size() - 1);
307
308         if (obj instanceof RtfTextrun) {
309             //if the last child is a RtfTextrun, return it
310
return (RtfTextrun) obj;
311         }
312
313         //add a new RtfTextrun as the last child
314
RtfTextrun textrun = new RtfTextrun(container, writer, attrs);
315         list.add(textrun);
316         
317         return textrun;
318     }
319    
320     /**
321      * specify, if the last paragraph control word (\par) should be suppressed.
322      * @param bSuppress true, if the last \par should be suppressed
323      */

324     public void setSuppressLastPar(boolean bSuppress) {
325         bSuppressLastPar = bSuppress;
326     }
327    
328     /**
329      * write RTF code of all our children
330      * @throws IOException for I/O problems
331      */

332     protected void writeRtfContent() throws IOException JavaDoc {
333         /**
334          *TODO: The textrun's children are iterated twice:
335          * 1. To determine the last RtfParagraphBreak
336          * 2. To write the children
337          * Maybe this can be done more efficient.
338          */

339         
340         boolean bHasTableCellParent =
341             this.getParentOfClass(RtfTableCell.class) != null;
342         RtfAttributes attrBlockLevel = new RtfAttributes();
343
344         //determine, if this RtfTextrun is the last child of its parent
345
boolean bLast = false;
346         for (Iterator JavaDoc it = parent.getChildren().iterator(); it.hasNext();) {
347             if (it.next() == this) {
348                 bLast = !it.hasNext();
349                 break;
350             }
351         }
352         
353         //get last RtfParagraphBreak, which is not followed by any visible child
354
RtfParagraphBreak lastParagraphBreak = null;
355         if (bLast) {
356             for (Iterator JavaDoc it = getChildren().iterator(); it.hasNext();) {
357                 final RtfElement e = (RtfElement)it.next();
358                 if (e instanceof RtfParagraphBreak) {
359                     lastParagraphBreak = (RtfParagraphBreak)e;
360                 } else {
361                     if (!(e instanceof RtfOpenGroupMark)
362                             && !(e instanceof RtfCloseGroupMark)
363                             && e.isEmpty()) {
364                         lastParagraphBreak = null;
365                     }
366                 }
367             }
368         }
369         
370         //may contain for example \intbl
371
writeAttributes(attrib, null);
372         
373         if (rtfListItem != null) {
374             rtfListItem.getRtfListStyle().writeParagraphPrefix(this);
375         }
376
377         //write all children
378
boolean bPrevPar = false;
379         boolean bFirst = true;
380         for (Iterator JavaDoc it = getChildren().iterator(); it.hasNext();) {
381             final RtfElement e = (RtfElement)it.next();
382             final boolean bRtfParagraphBreak = (e instanceof RtfParagraphBreak);
383
384             if (bHasTableCellParent) {
385                 attrBlockLevel.set(e.getRtfAttributes());
386             }
387             
388             
389             /**
390              * -Write RtfParagraphBreak only, if the previous visible child
391              * was't also a RtfParagraphBreak.
392              * -Write RtfParagraphBreak only, if it is not the first visible
393              * child.
394              * -If the RtfTextrun is the last child of its parent, write a
395              * RtfParagraphBreak only, if it is not the last child.
396              */

397             boolean bHide = false;
398             bHide = bRtfParagraphBreak;
399             bHide = bHide
400                 && (bPrevPar
401                     || bFirst
402                     || (bSuppressLastPar && bLast && lastParagraphBreak != null
403                         && e == lastParagraphBreak));
404                 
405             if (!bHide) {
406                 newLine();
407                 e.writeRtf();
408                 
409                 if (rtfListItem != null && e instanceof RtfParagraphBreak) {
410                     rtfListItem.getRtfListStyle().writeParagraphPrefix(this);
411                 }
412             }
413             
414             if (e instanceof RtfParagraphBreak) {
415                 bPrevPar = true;
416             } else if (e instanceof RtfCloseGroupMark) {
417                 //do nothing
418
} else if (e instanceof RtfOpenGroupMark) {
419                 //do nothing
420
} else {
421                 bPrevPar = bPrevPar && e.isEmpty();
422                 bFirst = bFirst && e.isEmpty();
423             }
424         } //for (Iterator it = ...)
425

426         //
427
if (bHasTableCellParent) {
428             writeAttributes(attrBlockLevel, null);
429         }
430         
431     }
432     
433     /**
434      * Set the parent list-item of the textrun.
435      *
436      * @param listItem parent list-item of the textrun
437      */

438     public void setRtfListItem(RtfListItem listItem) {
439         rtfListItem = listItem;
440     }
441     
442     /**
443      * Gets the parent list-item of the textrun.
444      *
445      * @return parent list-item of the textrun
446      */

447     public RtfListItem getRtfListItem() {
448         return rtfListItem;
449     }
450 }
451
452
Popular Tags