/* * Copyright (C) 2000-2012 InfoChamp System Corporation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.gk.engine.client.build.grid.field; import java.util.Iterator; import java.util.Map; import org.gk.engine.client.Engine; import org.gk.engine.client.build.field.XField; import org.gk.engine.client.build.grid.XGridField; import org.gk.engine.client.utils.NodeUtils; import org.gk.ui.client.com.IC; import org.gk.ui.client.com.grid.column.gkICColumnConfig; import org.gk.ui.client.com.panel.gkFormPanelIC; import com.extjs.gxt.ui.client.core.XDOM; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnData; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; import com.google.gwt.xml.client.Document; import com.google.gwt.xml.client.Element; import com.google.gwt.xml.client.Node; import com.google.gwt.xml.client.NodeList; /** * 清單中的column放入一個Form,當清單的column可以放Form後,應該沒有甚麼做不到的了... * * @author I21890 * @since 2010/11/15 */ public class GAdaptFieldBuilder extends GridFieldBuilder { public GAdaptFieldBuilder(String fieldType) { super(fieldType); } @Override public ColumnConfig create() { final XGridField x = (XGridField) getField().clone(); ColumnConfig cc = new gkICColumnConfig(x) { @Override public GridCellRenderer<ModelData> createCellRender() { GridCellRenderer<ModelData> render = new GridCellRenderer<ModelData>() { @Override public Object render(ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ModelData> store, Grid<ModelData> grid) { config.cellAttr = getColumnAlign(); return createCell(model, rowIndex, colIndex, grid, x); } }; return render; } }; return cc; } /** * 建立IC元件的Cell,IC資訊統一使用Info * * @param model * @param rowIndex * @param colIndex * @param grid * @param x * @return Object */ private Object createCell(ModelData model, int rowIndex, int colIndex, Grid<ModelData> grid, XField x) { Component c = createIC(rowIndex, colIndex, grid, x); // 初始從Form的info取得欄位資訊 Map info = (Map) ((IC) c).getInfo(); Iterator it = info.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); // 不需要dirtyField if (!key.equals(gkFormPanelIC.Event.DIRTY_FIELD)) { if (model.get(key) == null) { model.set(key, info.get(key)); } } } ((IC) c).setInfo(model); ((IC) c).linkInfo(model); return c; } private Component createIC(int rowIndex, int colIndex, Grid<ModelData> grid, XField x) { String gul = x.getContent(); String vertical = x.getAttribute("vertical", "false"); String space = x.getAttribute("space", "0"); String readonly = x.getReadOnly(); String enable = x.getEnable(); StringBuffer form = new StringBuffer("<form"); form.append(" hideLabels='true' id='").append(x.getId()).append("_") .append(rowIndex).append("'>"); form.append("<field type='adapt' "); form.append("id='").append(x.getId()).append("_").append(rowIndex) .append("_").append(colIndex).append("' "); form.append("vertical='").append(vertical).append("' "); form.append("space='").append(space).append("' "); form.append("adaptingrid='true' "); // 給AdaptFieldBuilder判斷是否在Grid中 form.append("readonly='").append(readonly).append("' "); form.append("enable='").append(enable).append("' ").append(">"); form.append(gul); form.append("</field>"); form.append("</form>"); // 將gul裡面field's id 改為 id_rowIndex,自動增列才能正常使用 gul = setFieldIdAndVerify(form.toString(), rowIndex); String id = rowIndex + "_" + colIndex; LayoutContainer lc = new LayoutContainer(); lc.setId(id); Engine.get().renderPanel(gul, lc); Component c = lc.getItem(0); if (c instanceof ContentPanel) { ((ContentPanel) c).setHeaderVisible(false); ((ContentPanel) c).setFrame(false); } return c; } /** * <pre> * 判斷adapt裡面的gul程式碼有沒有符合下列規範,並建立所有field的id (加入rowIdx) * (1) 只能放 <field ...> * (2) <field 不包含 type='adapt' 的欄位 * </pre> * * @param gul * @param rowIdx * @return String */ private String setFieldIdAndVerify(String gul, int rowIdx) { Document doc = NodeUtils.parseGUL(gul); // 拿 <form><field type='adapt'> ...</field></form> 裡面的fields NodeList childList = doc.getFirstChild().getFirstChild() .getChildNodes(); int fields = childList.getLength(); for (int i = 0; i < fields; i++) { Node field = childList.item(i); String tagName = field.getNodeName(); Node type = field.getAttributes().getNamedItem("type"); Node id = field.getAttributes().getNamedItem("id"); // 只能使用 field 的元件 if (!tagName.equals("field")) { throw new RuntimeException("tagName error:" + tagName); } // 不能使用type='adapt' if (type == null || type.getNodeValue().equals("adapt")) { throw new RuntimeException("attribute error:" + type); } // 沒有設定id就幫忙設定,以便detach後,Engine可以刪除 if (id == null) { ((Element) field).setAttribute("id", XDOM.getUniqueId() + "_" + rowIdx); } else { id.setNodeValue(id.getNodeValue() + "_" + rowIdx); } } return doc + ""; } }