001: /* Row.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Tue Oct 25 16:02:43 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zul;
020:
021: import java.util.List;
022: import java.util.LinkedList;
023: import java.util.Iterator;
024: import java.io.IOException;
025:
026: import org.zkoss.lang.JVMs;
027: import org.zkoss.lang.Objects;
028: import org.zkoss.xml.HTMLs;
029:
030: import org.zkoss.zk.ui.Component;
031: import org.zkoss.zk.ui.UiException;
032: import org.zkoss.zk.ui.WrongValueException;
033: import org.zkoss.zul.impl.XulElement;
034: import org.zkoss.zul.impl.Utils;
035:
036: /**
037: * A single row in a {@link Rows} element.
038: * Each child of the {@link Row} element is placed in each successive cell
039: * of the grid. The row with the most child elements determines the number
040: * of columns in each row.
041: *
042: * <p>Default {@link #getSclass}: the same as grid's sclass.
043: *
044: * @author tomyeh
045: */
046: public class Row extends XulElement {
047: private Object _value;
048: private String _align, _valign;
049: private int[] _spans;
050: /** Used only to generate {@link #getChildAttrs}. */
051: private transient int _rsflags;
052: private boolean _nowrap;
053: /** whether the content of this row is loaded; used if
054: * the grid owning this row is using a list model.
055: */
056: private boolean _loaded;
057:
058: /** Returns the grid that contains this row. */
059: public Grid getGrid() {
060: final Component parent = getParent();
061: return parent != null ? (Grid) parent.getParent() : null;
062: }
063:
064: /** Returns the horizontal alignment of the whole row.
065: * <p>Default: null (system default: left unless CSS specified).
066: */
067: public String getAlign() {
068: return _align;
069: }
070:
071: /** Sets the horizontal alignment of the whole row.
072: */
073: public void setAlign(String align) {
074: if (!Objects.equals(_align, align)) {
075: _align = align;
076: smartUpdate("align", _align);
077: }
078: }
079:
080: /** Returns the nowrap.
081: * <p>Default: null (system default: wrap).
082: */
083: public boolean isNowrap() {
084: return _nowrap;
085: }
086:
087: /** Sets the nowrap.
088: */
089: public void setNowrap(boolean nowrap) {
090: if (_nowrap != nowrap) {
091: _nowrap = nowrap;
092: smartUpdate("nowrap", _nowrap);
093: }
094: }
095:
096: /** Returns the vertical alignment of the whole row.
097: * <p>Default: null (system default: top).
098: */
099: public String getValign() {
100: return _valign;
101: }
102:
103: /** Sets the vertical alignment of the whole row.
104: */
105: public void setValign(String valign) {
106: if (!Objects.equals(_valign, valign)) {
107: _valign = valign;
108: smartUpdate("valign", _valign);
109: }
110: }
111:
112: /** Returns the value.
113: * <p>Default: null.
114: * <p>Note: the value is application dependent, you can place
115: * whatever value you want.
116: */
117: public Object getValue() {
118: return _value;
119: }
120:
121: /** Sets the value.
122: * @param value the value.
123: * <p>Note: the value is application dependent, you can place
124: * whatever value you want.
125: */
126: public void setValue(Object value) {
127: _value = value;
128: }
129:
130: /** Returns the spans, which is a list of numbers separated by comma.
131: *
132: * <p>Default: empty.
133: */
134: public String getSpans() {
135: return Utils.intsToString(_spans);
136: }
137:
138: /** Sets the spans, which is a list of numbers separated by comma.
139: *
140: * <p>For example, "1,2,3" means the second column will span two columns
141: * and the following column span three columns, while others occupies
142: * one column.
143: */
144: public void setSpans(String spans) throws WrongValueException {
145: final int[] ispans = Utils.stringToInts(spans, 1);
146: if (!Objects.equals(ispans, _spans)) {
147: _spans = ispans;
148: invalidate();
149: }
150: }
151:
152: /** Sets whether the content of this row is loaded; used if
153: * the grid owning this row is using a list model.
154: */
155: /*package*/final void setLoaded(boolean loaded) {
156: if (loaded != _loaded) {
157: _loaded = loaded;
158:
159: final Grid grid = getGrid();
160: if (grid != null && grid.getModel() != null)
161: if (_loaded && !grid.inPagingMold())
162: invalidate();
163: //reason: the client doesn't init (for better performance)
164: //i.e., z.skipsib is specified for unloaded items
165: else
166: smartUpdate("z.loaded", _loaded);
167: }
168: }
169:
170: /** Returns whether the content of this row is loaded; used if
171: * the grid owning this row is using a list model.
172: */
173: /*package*/final boolean isLoaded() {
174: return _loaded;
175: }
176:
177: /** Returns the index of the specified row.
178: * The current implementation is stupid, so not public it yet.
179: */
180: /*package*/int getIndex() {
181: int j = 0;
182: for (Iterator it = getParent().getChildren().iterator(); it
183: .hasNext(); ++j) {
184: if (it.next() == this )
185: break;
186: }
187: return j;
188: }
189:
190: protected String getRealSclass() {
191: final String sclx = (String) getParent().getAttribute(
192: Attributes.STRIPE_STATE);
193: return super .getRealSclass() + (sclx != null ? " " + sclx : "");
194: }
195:
196: /** Returns the HTML attributes for the child of the specified index.
197: */
198: public String getChildAttrs(int index) {
199: int realIndex = index, span = 1;
200: if (_spans != null) {
201: for (int j = 0; j < _spans.length; ++j) {
202: if (j == index) {
203: span = _spans[j];
204: break;
205: }
206: realIndex += _spans[j] - 1;
207: }
208: }
209:
210: String colattrs = null, wd = null, hgh = null;
211: final Grid grid = getGrid();
212: if (grid != null) {
213: final Columns cols = grid.getColumns();
214: if (cols != null) {
215: final List colchds = cols.getChildren();
216: if (realIndex < colchds.size()) {
217: final Column col = (Column) colchds.get(realIndex);
218: colattrs = col.getColAttrs();
219: //if (span == 1) wd = col.getWidth();
220: //Bug 1633982: don't generate width if span > 1
221: //Side effect: the width might not be the same as specified
222: hgh = col.getHeight();
223: }
224: }
225: }
226:
227: String style;
228: _rsflags = RS_NO_WIDTH | RS_NO_HEIGHT | RS_NO_DISPLAY;
229: try {
230: style = getRealStyle();
231: } finally {
232: _rsflags = 0;
233: }
234:
235: if (wd != null || hgh != null) {
236: final StringBuffer sb = new StringBuffer(80).append(style);
237: //HTMLs.appendStyle(sb, "width", wd);
238: HTMLs.appendStyle(sb, "height", hgh);
239: style = sb.toString();
240: }
241:
242: if (colattrs == null && style.length() == 0 && span == 1)
243: return " class=\"gc\"";
244:
245: final StringBuffer sb = new StringBuffer(100);
246: if (colattrs != null)
247: sb.append(colattrs);
248: if (span != 1)
249: sb.append(" colspan=\"").append(span).append('"');
250: HTMLs.appendAttribute(sb, "style", style);
251:
252: return sb.append(" class=\"gc\"").toString();
253: }
254:
255: //-- super --//
256: protected int getRealStyleFlags() {
257: return super .getRealStyleFlags() | _rsflags;
258: }
259:
260: public String getOuterAttrs() {
261: final StringBuffer sb = new StringBuffer(64).append(super
262: .getOuterAttrs());
263: final String clkattrs = getAllOnClickAttrs(false);
264: if (clkattrs != null)
265: sb.append(clkattrs);
266:
267: HTMLs.appendAttribute(sb, "z.rid", getGrid().getUuid());
268: HTMLs.appendAttribute(sb, "align", _align);
269: HTMLs.appendAttribute(sb, "valign", _valign);
270: if (_nowrap)
271: HTMLs.appendAttribute(sb, "nowrap", "nowrap");
272:
273: final Grid grid = getGrid();
274: if (grid != null && grid.getModel() != null) {
275: HTMLs.appendAttribute(sb, "z.loaded", _loaded);
276: if (getAttribute(Attributes.SKIP_SIBLING) != null) {
277: HTMLs.appendAttribute(sb, "z.skipsib", "true");
278: removeAttribute(Attributes.SKIP_SIBLING);
279: }
280: }
281: return sb.toString();
282: }
283:
284: public void setStyle(String style) {
285: if (style != null && style.length() == 0)
286: style = null;
287:
288: final String s = getStyle();
289: if (!Objects.equals(s, style)) {
290: super .setStyle(style);
291: invalidate(); //yes, invalidate
292: }
293: }
294:
295: public void setSclass(String sclass) {
296: if (sclass != null && sclass.length() == 0)
297: sclass = null;
298:
299: final String s = getSclass();
300: if (!Objects.equals(s, sclass)) {
301: super .setSclass(sclass);
302: invalidate(); //yes, invalidate
303: }
304: }
305:
306: /** Returns the style class.
307: * By default, it is the same as grid's stye class, unless
308: * {@link #setSclass} is called with non-empty value.
309: */
310: public String getSclass() {
311: final String sclass = super .getSclass();
312: if (sclass != null)
313: return sclass;
314:
315: final Grid grid = getGrid();
316: return grid != null ? grid.getSclass() : sclass;
317: }
318:
319: //-- Component --//
320: public void setParent(Component parent) {
321: if (parent != null && !(parent instanceof Rows))
322: throw new UiException("Unsupported parent for row: "
323: + parent);
324: super .setParent(parent);
325: }
326:
327: public void onDrawNewChild(Component child, StringBuffer out)
328: throws IOException {
329: final StringBuffer sb = new StringBuffer(128).append(
330: "<td z.type=\"Gcl\" id=\"").append(child.getUuid())
331: .append("!chdextr\"");
332:
333: final Grid grid = getGrid();
334: if (grid != null) {
335: int j = 0;
336: for (Iterator it = getChildren().iterator(); it.hasNext(); ++j)
337: if (child == it.next())
338: break;
339: sb.append(getChildAttrs(j));
340: }
341: sb.append("><div id=\"").append(child.getUuid()).append(
342: "!cell\"").append(" class=\"gc cell-inner\">");
343: if (JVMs.isJava5())
344: out.insert(0, sb); //Bug 1682844
345: else
346: out.insert(0, sb.toString());
347: out.append("</div></td>");
348: }
349: }
|