1package autotest.common.table;
2
3import autotest.common.DomUtils;
4import autotest.common.spreadsheet.Spreadsheet.CellInfo;
5
6import com.google.gwt.core.client.GWT;
7import com.google.gwt.dom.client.Element;
8import com.google.gwt.user.client.DOM;
9import com.google.gwt.user.client.ui.HTMLTable;
10
11
12public class TableRenderer {
13    // min-width/min-height aren't supported in the hosted mode browser
14    public static final String SIZE_PREFIX = GWT.isScript() ? "min-" : "";
15    private static final String NONCLICKABLE_CLASS = "spreadsheet-cell-nonclickable";
16
17    protected String attributeString(String attribute, String value) {
18        if (value.equals(""))
19            return "";
20        return " " + attribute + "=\"" + value + "\"";
21    }
22
23    public void renderRowsAndAppend(HTMLTable tableObject, CellInfo[][] rows,
24                                    int startRow, int maxRows, boolean renderNull) {
25        StringBuffer htmlBuffer= new StringBuffer();
26        htmlBuffer.append("<table><tbody>");
27        for (int rowIndex = startRow; rowIndex < startRow + maxRows && rowIndex < rows.length;
28             rowIndex++) {
29            CellInfo[] row = rows[rowIndex];
30            htmlBuffer.append("<tr>");
31            for (CellInfo cell : row) {
32                if (cell == null && renderNull) {
33                    htmlBuffer.append("<td> </td>");
34                } else if (cell != null) {
35                    String tdAttributes = "", divAttributes = "", divStyle = "";
36                    if (cell.cssClass != null) {
37                        tdAttributes += attributeString("class", cell.cssClass);
38                    }
39                    if (cell.rowSpan > 1) {
40                        tdAttributes += attributeString("rowspan", Integer.toString(cell.rowSpan));
41                    }
42                    if (cell.colSpan > 1) {
43                        tdAttributes += attributeString("colspan", Integer.toString(cell.colSpan));
44                    }
45
46                    if (cell.widthPx != null) {
47                        divStyle += SIZE_PREFIX + "width: " + cell.widthPx + "px; ";
48                    }
49                    if (cell.heightPx != null) {
50                        divStyle += SIZE_PREFIX + "height: " + cell.heightPx + "px; ";
51                    }
52                    if (!divStyle.equals("")) {
53                        divAttributes += attributeString("style", divStyle);
54                    }
55                    if (cell.isEmpty()) {
56                        divAttributes += attributeString("class", NONCLICKABLE_CLASS);
57                    }
58
59                    htmlBuffer.append("<td " + tdAttributes + ">");
60                    htmlBuffer.append("<div " + divAttributes + ">");
61                    htmlBuffer.append(cell.contents);
62                    htmlBuffer.append("</div></td>");
63                }
64            }
65            htmlBuffer.append("</tr>");
66        }
67        htmlBuffer.append("</tbody></table>");
68
69        renderBody(tableObject, htmlBuffer.toString());
70    }
71
72    public void renderRows(HTMLTable tableObject, CellInfo[][] rows, boolean renderNull) {
73        DomUtils.clearDomChildren(tableObject.getElement()); // remove existing tbodies
74        renderRowsAndAppend(tableObject, rows, 0, rows.length, renderNull);
75    }
76
77    public void renderRows(HTMLTable tableObject, CellInfo[][] rows) {
78        renderRows(tableObject, rows, true);
79    }
80
81    private void renderBody(HTMLTable tableObject, String html) {
82        // render the table within a DIV
83        Element tempDiv = DOM.createDiv();
84        tempDiv.setInnerHTML(html);
85
86        // inject the new tbody into the existing table
87        Element newTable = tempDiv.getFirstChildElement();
88        Element newBody = newTable.getFirstChildElement();
89        tableObject.getElement().appendChild(newBody);
90
91        setBodyElement(tableObject, newBody);
92    }
93
94    /**
95     * A little hack to set the private member variable bodyElem of an HTMLTable.
96     */
97    protected native void setBodyElement(HTMLTable table, Element newBody) /*-{
98        table.@com.google.gwt.user.client.ui.HTMLTable::bodyElem = newBody;
99    }-*/;
100
101}
102