KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > fo > flow > AbstractTableBody


1 /*
2  * $Id: AbstractTableBody.java,v 1.1.2.9 2003/04/11 00:24:38 pietsch Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.fo.flow;
52
53 // FOP
54
import org.apache.fop.fo.*;
55 import org.apache.fop.fo.properties.*;
56 import org.apache.fop.datatypes.*;
57 import org.apache.fop.layout.*;
58 import org.apache.fop.apps.FOPException;
59
60 // Java
61
import java.util.ArrayList JavaDoc;
62
63 public abstract class AbstractTableBody extends FObj {
64
65     int spaceBefore;
66     int spaceAfter;
67     String JavaDoc id;
68
69     ArrayList JavaDoc columns;
70     RowSpanMgr rowSpanMgr; // manage information about spanning rows
71

72     AreaContainer areaContainer;
73
74     public AbstractTableBody(FObj parent, PropertyList propertyList,
75                              String JavaDoc systemId, int line, int column)
76         throws FOPException {
77         super(parent, propertyList, systemId, line, column);
78         if (!(parent instanceof Table)) {
79           throw new FOPException("A table body must be child of fo:table,"
80                                    + " not " + parent.getName(),
81                                  systemId, line, column);
82         }
83     }
84
85     public void setColumns(ArrayList JavaDoc columns) {
86         this.columns = columns;
87     }
88
89     public void setYPosition(int value) {
90         areaContainer.setYPosition(value);
91     }
92
93     public int getYPosition() {
94         return areaContainer.getCurrentYPosition();
95     }
96
97     public int getHeight() {
98         return areaContainer.getHeight() + spaceBefore + spaceAfter;
99     }
100
101     public int layout(Area area) throws FOPException {
102         if (this.marker == BREAK_AFTER) {
103             return Status.OK;
104         }
105
106         if (this.marker == START) {
107
108             // Common Accessibility Properties
109
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();
110
111             // Common Aural Properties
112
AuralProps mAurProps = propMgr.getAuralProps();
113
114             // Common Border, Padding, and Background Properties
115
BorderAndPadding bap = propMgr.getBorderAndPadding();
116             BackgroundProps bProps = propMgr.getBackgroundProps();
117
118             // Common Relative Position Properties
119
RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
120         
121             // this.properties.get("id");
122

123             this.spaceBefore =
124                 this.properties.get("space-before.optimum").getLength().mvalue();
125             this.spaceAfter =
126                 this.properties.get("space-after.optimum").getLength().mvalue();
127             this.id = this.properties.get("id").getString();
128
129             try {
130                 area.getIDReferences().createID(id);
131             }
132             catch(FOPException e) {
133                 if (!e.isLocationSet()) {
134                     e.setLocation(systemId, line, column);
135                 }
136                 throw e;
137             }
138
139             if (area instanceof BlockArea) {
140                 area.end();
141             }
142
143             if (rowSpanMgr == null) {
144                 rowSpanMgr = new RowSpanMgr(columns.size());
145             }
146
147             // if (this.isInListBody) {
148
// startIndent += bodyIndent + distanceBetweenStarts;
149
// }
150

151             this.marker = 0;
152
153         }
154
155         if ((spaceBefore != 0) && (this.marker == 0)) {
156             area.increaseHeight(spaceBefore);
157         }
158
159         if (marker == 0) {
160             // configure id
161
area.getIDReferences().configureID(id, area);
162         }
163
164         int spaceLeft = area.spaceLeft();
165
166         /*
167          * Note: the parent FO must be a Table. The parent Area is the Block
168          * type area created by the Table, which is also a reference area.
169          * The content "width" (IPD) of the TableBody is the same as that
170          * of the containing table area, and its relative position is 0,0.
171          * Strictly speaking (CR), this FO should generate no areas!
172          */

173         this.areaContainer =
174             new AreaContainer(propMgr.getFontState(area.getFontInfo()), 0,
175                               area.getContentHeight(),
176                               area.getContentWidth(), // IPD
177
area.spaceLeft(), Position.RELATIVE);
178         areaContainer.foCreator = this; // G Seshadri
179
areaContainer.setPage(area.getPage());
180         areaContainer.setParent(area);
181         areaContainer.setBackground(propMgr.getBackgroundProps());
182         areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding());
183         areaContainer.start();
184
185         areaContainer.setAbsoluteHeight(area.getAbsoluteHeight());
186         areaContainer.setIDReferences(area.getIDReferences());
187
188         ArrayList JavaDoc keepWith = new ArrayList JavaDoc();
189         int numChildren = this.children.size();
190         TableRow lastRow = null;
191         boolean endKeepGroup = true;
192         for (int i = this.marker; i < numChildren; i++) {
193             Object JavaDoc child = children.get(i);
194             if (child instanceof Marker) {
195                 ((Marker)child).layout(area);
196                 continue;
197             }
198             if (!(child instanceof TableRow)) {
199                 throw new FOPException("Currently only Table Rows are supported in table body, header and footer", systemId, line, column);
200             }
201             TableRow row = (TableRow)child;
202
203             row.setRowSpanMgr(rowSpanMgr);
204             row.setColumns(columns);
205             row.doSetup(areaContainer);
206             if (row.getKeepWithPrevious().getType()
207                     != KeepValue.KEEP_WITH_AUTO && lastRow != null
208                                                 && keepWith.indexOf(lastRow)
209                                                    == -1) {
210                 keepWith.add(lastRow);
211             } else {
212                 /* This row has no keep-with-previous, or it is the first
213                  * row in this area.
214                  */

215                 if (endKeepGroup && keepWith.size() > 0) {
216                     keepWith = new ArrayList JavaDoc();
217                 }
218                 // If we have composed at least one complete row which is not part
219
// of a keep set, we can take following keeps into account again
220
if (endKeepGroup && i > this.marker) {
221                    rowSpanMgr.setIgnoreKeeps(false);
222                 }
223             }
224             
225             /* Tell the row whether it is at the top of this area: if so, the row
226              * should not honor keep-together.
227              */

228             boolean bRowStartsArea = (i == this.marker);
229             if (bRowStartsArea == false && keepWith.size() > 0) {
230                 if (children.indexOf(keepWith.get(0)) == this.marker) {
231                    bRowStartsArea = true;
232                 }
233             }
234             row.setIgnoreKeepTogether(bRowStartsArea && startsAC(area));
235             int status;
236             if (Status.isIncomplete((status = row.layout(areaContainer)))) {
237                 // BUG!!! don't distinguish between break-before and after!
238
if (Status.isPageBreak(status)) {
239                     this.marker = i;
240                     area.addChild(areaContainer);
241                     // areaContainer.end();
242

243                     area.increaseHeight(areaContainer.getHeight());
244                     if (i == numChildren - 1) {
245                         this.marker = BREAK_AFTER;
246                         if (spaceAfter != 0) {
247                             area.increaseHeight(spaceAfter);
248                         }
249                     }
250                     return status;
251                 }
252                 if ((keepWith.size() > 0)
253                     && (!rowSpanMgr.ignoreKeeps())) {
254                     // && status.getCode() == Status.AREA_FULL_NONE
255
// FIXME!!! Handle rows spans!!!
256
row.removeLayout(areaContainer);
257                     for (int j = 0; j < keepWith.size(); j++) {
258                         TableRow tr = (TableRow)keepWith.get(j);
259                         tr.removeLayout(areaContainer);
260                         i--;
261                     }
262                     if (i == 0) {
263                         resetMarker();
264
265                         // Fix for infinite loop bug if keeps are too big for page
266
rowSpanMgr.setIgnoreKeeps(true);
267
268                         return Status.AREA_FULL_NONE;
269                     }
270                 }
271                 this.marker = i;
272                 if ((i != 0) && (status == Status.AREA_FULL_NONE)) {
273                     status = Status.AREA_FULL_SOME;
274                 }
275                 if (!((i == 0) && (areaContainer.getContentHeight() <= 0))) {
276                     area.addChild(areaContainer);
277                     // areaContainer.end();
278

279                     area.increaseHeight(areaContainer.getHeight());
280                 }
281
282                 // Fix for infinite loop bug if spanned rows are too big for page
283
rowSpanMgr.setIgnoreKeeps(true);
284
285                 return status;
286             } else if (status == Status.KEEP_WITH_NEXT
287                        || rowSpanMgr.hasUnfinishedSpans()) {
288                 keepWith.add(row);
289                 endKeepGroup = false;
290             } else {
291                 endKeepGroup = true;
292             }
293             lastRow = row;
294             area.setMaxHeight(area.getMaxHeight() - spaceLeft
295                               + this.areaContainer.getMaxHeight());
296             spaceLeft = area.spaceLeft();
297         }
298         area.addChild(areaContainer);
299         areaContainer.end();
300
301         area.increaseHeight(areaContainer.getHeight());
302
303         if (spaceAfter != 0) {
304             area.increaseHeight(spaceAfter);
305             area.setMaxHeight(area.getMaxHeight() - spaceAfter);
306         }
307
308         if (area instanceof BlockArea) {
309             area.start();
310         }
311
312         return Status.OK;
313     }
314
315     public void removeLayout(Area area) {
316         if (areaContainer != null) {
317             area.removeChild(areaContainer);
318         }
319         if (spaceBefore != 0) {
320             area.increaseHeight(-spaceBefore);
321         }
322         if (spaceAfter != 0) {
323             area.increaseHeight(-spaceAfter);
324         }
325         this.resetMarker();
326         this.removeID(area.getIDReferences());
327     }
328     
329     /**
330      * Return true if the passed area is on the left edge of its nearest
331      * absolute AreaContainer (generally a page column).
332      */

333     private boolean startsAC(Area area) {
334         Area parent=null;
335         
336         while ((parent = area.getParent()) != null &&
337                parent.hasNonSpaceChildren() == false) {
338             // The area will be the first non-space child in its parent
339
// Note: it's not added yet!
340
if (parent instanceof AreaContainer &&
341                 ((AreaContainer)parent).getPosition() == Position.ABSOLUTE) {
342                 return true;
343             }
344             area = parent;
345         }
346         return false;
347     }
348 }
349
Popular Tags