/* * Lokomo OneCMDB - An Open Source Software for Configuration * Management of Datacenter Resources * * Copyright (C) 2006 Lokomo Systems AB * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via * paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33 * Danderyd, Sweden. * */ package org.onecmdb.ui.gwt.desktop.client.widget.grid; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.onecmdb.ui.gwt.desktop.client.service.model.CMDBPermissions; import org.onecmdb.ui.gwt.desktop.client.service.model.ValueListModel; import org.onecmdb.ui.gwt.desktop.client.service.model.ValueModel; import org.onecmdb.ui.gwt.desktop.client.service.model.grid.AttributeColumnConfig; import org.onecmdb.ui.gwt.desktop.client.service.model.grid.GridModelConfig; import org.onecmdb.ui.gwt.desktop.client.utils.ExpressionHandler; import com.extjs.gxt.ui.client.Events; import com.extjs.gxt.ui.client.Style.SortDir; import com.extjs.gxt.ui.client.core.XTemplate; import com.extjs.gxt.ui.client.data.BaseModel; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.store.GroupingStore; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.ComponentPlugin; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.form.TextField; import com.extjs.gxt.ui.client.widget.grid.CellEditor; import com.extjs.gxt.ui.client.widget.grid.CellSelectionModel; 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.ColumnModel; import com.extjs.gxt.ui.client.widget.grid.EditorGrid; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer; import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel; import com.extjs.gxt.ui.client.widget.grid.GroupColumnData; import com.extjs.gxt.ui.client.widget.grid.GroupingView; import com.extjs.gxt.ui.client.widget.grid.RowExpander; import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel.CellSelection; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import com.extjs.gxt.ui.client.widget.menu.Menu; import com.extjs.gxt.ui.client.widget.menu.MenuItem; import com.google.gwt.user.client.Element; public class CIPropertyGrid extends LayoutContainer { private BaseModel instance; private GridModelConfig gridConfig; private HashMap<String, AttributeColumnConfig> colId2AttrConfig = new HashMap<String, AttributeColumnConfig>(); //private boolean readonly; private GroupingStore<ValueWrapper> store; private CMDBPermissions permissions; public CIPropertyGrid(GridModelConfig gridConfig, BaseModel instance) { this.gridConfig = gridConfig; for (AttributeColumnConfig aCfg : gridConfig.getColumnConfig()) { colId2AttrConfig.put(aCfg.getId(), aCfg); } this.instance = instance; //this.readonly = readonly; } public void setPermissions(CMDBPermissions perm) { this.permissions = (perm == null ? perm : perm.copy()); } class MyColumnModel extends ColumnModel { public MyColumnModel(List<ColumnConfig> columns) { super(columns); } public void bind(Grid grid) { this.grid = grid; } @Override public CellEditor getEditor(int colIndex) { if (grid.getSelectionModel() instanceof CellSelectionModel) { CellSelectionModel selModel = (CellSelectionModel) grid.getSelectionModel(); if (selModel.getSelectCell() != null) { ValueWrapper wr = (ValueWrapper) selModel.getSelectCell().model; return(wr.col.getEditor()); } } return super.getEditor(colIndex); } @Override public GridCellRenderer getRenderer(int colIndex) { ColumnConfig cfg = config.get(colIndex); if (cfg instanceof RowExpander) { return(cfg.getRenderer()); } return(new GridCellRenderer<ModelData>() { public String render(ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ModelData> store) { if (property.equals("value")) { if (model instanceof ValueWrapper) { ValueWrapper wrapper = (ValueWrapper)model; GridCellRenderer<ModelData> r = wrapper.col.getRenderer(); if (r != null) { return(r.render(wrapper.m, wrapper.col.getId(), config, rowIndex, colIndex, store)); } } } Object o = model.get(property); if (o == null) { return(""); } return("<b>" + o.toString() + "</b>"); } }); } } public class ValueWrapper extends BaseModel { private ColumnConfig col; private BaseModel m; private AttributeColumnConfig aCfg; public ValueWrapper(ColumnConfig col, BaseModel m, AttributeColumnConfig aCfg) { this.col = col; this.m = m; this.aCfg = aCfg; if (aCfg != null) { set("description", aCfg.getDescription()); set("id", col.getId()); set("type", aCfg.getType()); set("refType", aCfg.getRefType()); if (aCfg.isInternal()) { set("group", "Internal"); } else { set("group", "User Defined"); } } else { set("group", "Unknown"); } } public <X> X set(String name, X value) { if (name.equals("value")) { m.set(col.getId(), value); return(value); } return(super.set(name, value)); } @Override public <X> X get(String property) { if (property.equals("name")) { return((X)col.getHeader()); } if (property.equals("value")) { if (m == null) { return((X)""); } return((X)m.get(col.getId())); } return((X)super.get(property)); } public AttributeColumnConfig getAttributeConfig() { return(aCfg); } public BaseModel getModel() { return(m); } } @Override protected void onRender(Element parent, int index) { super.onRender(parent, index); initUI(); } protected void initUI() { List<ValueWrapper> demoModels = new ArrayList<ValueWrapper>(); for (ColumnConfig m : gridConfig.getColumns()) { //Object v = instance.get(m.getId()); demoModels.add(new ValueWrapper(m, instance, colId2AttrConfig.get(m.getId()))); } setLayout(new FitLayout()); List<ColumnConfig> configs = new ArrayList<ColumnConfig>(); XTemplate tpl = XTemplate.create("<p><b>Description:</b> <br/> {description}<br/><b>Column ID:</b> {id}</p>"); RowExpander expander = new RowExpander(); expander.setTemplate(tpl); configs.add(expander); ColumnConfig column = new ColumnConfig(); column = new ColumnConfig(); column.setId("group"); column.setHeader("Group"); column.setWidth(70); column.setHidden(true); configs.add(column); column = new ColumnConfig(); column.setId("alias"); column.setHeader("Alias"); column.setWidth(130); column.setHidden(true); //column.setEditor(editor); configs.add(column); column = new ColumnConfig(); column.setId("name"); column.setHeader("Name"); column.setWidth(130); //column.setEditor(editor); configs.add(column); column = new ColumnConfig(); column.setId("type"); column.setHeader("Type"); column.setWidth(100); column.setHidden(true); //column.setEditor(editor); configs.add(column); column = new ColumnConfig(); column.setId("refType"); column.setHeader("Reference Type"); column.setWidth(100); //column.setEditor(editor); column.setHidden(true); configs.add(column); column = new ColumnConfig(); column.setId("value"); column.setHeader("Value"); column.setWidth(250); column.setEditor(new CellEditor(new TextField())); configs.add(column); //final ListStore<ValueWrapper> store = new ListStore<ValueWrapper>(); store = new GroupingStore<ValueWrapper>(); store.groupBy("group"); store.sort("group", SortDir.DESC); store.add(demoModels); final MyColumnModel cm = new MyColumnModel(configs); ContentPanel cp = new ContentPanel(); cp.setLayout(new FitLayout()); cp.setHeaderVisible(false); //cp.setFrame(true); Grid<ValueWrapper> grid = null; if (permissions.getCurrentState().equals(CMDBPermissions.PermissionState.READONLY)) { grid = new Grid<ValueWrapper>(store, cm); grid.setSelectionModel(new CellSelectionModel<ValueWrapper>()); } else { grid = new EditorGrid<ValueWrapper>(store, cm); } grid.setStripeRows(true); GroupingView view = new GroupingView(); view.setGroupRenderer(new GridGroupRenderer() { public String render(GroupColumnData data) { String f = cm.getColumnById(data.field).getHeader(); String l = data.models.size() == 1 ? "Item" : "Items"; return f + ": " + data.group + " (" + data.models.size() + " " + l + ")"; } }); //view.setForceFit(true); grid.setView(view); // Bind Column Model. cm.bind(grid); // Defualt plugin to handle mouse events. grid.addPlugin(expander); // Add other ComponentPlugins. for (ColumnConfig col : gridConfig.getColumns()) { CellEditor editor = col.getEditor(); if (editor instanceof ComponentPlugin) { grid.addPlugin((ComponentPlugin)editor); } // Check this for checkbox editors! if (col instanceof ComponentPlugin) { grid.addPlugin((ComponentPlugin)col); } } grid.setContextMenu(getGridContextMenu(grid)); //grid.setAutoExpandColumn("name"); grid.setBorders(true); cp.add(grid); add(cp); //layout(); //view.refresh(false); } private Menu getGridContextMenu(final Grid<ValueWrapper> grid) { Menu menu = new Menu(); final MenuItem open = new MenuItem("Open in Browser", "open-icon"); open.addSelectionListener(new SelectionListener<ComponentEvent>() { @Override public void componentSelected(ComponentEvent ce) { String url = open.getData("url"); com.google.gwt.user.client.Window.open(url,"OneCMDB_URL", ""); } }); open.setVisible(false); menu.add(open); menu.addListener(Events.BeforeShow, new Listener<BaseEvent>() { public void handleEvent(BaseEvent be) { open.setVisible(false); GridSelectionModel<ValueWrapper> selectionModel = (GridSelectionModel<ValueWrapper>) grid.getSelectionModel(); if (!(selectionModel instanceof CellSelectionModel)) { return; } CellSelection cell = ((CellSelectionModel)selectionModel).getSelectCell(); if (cell == null) { return; } if (!(cell.model instanceof ValueWrapper)) { return; } ValueWrapper wr = (ValueWrapper) cell.model; if (wr == null) { return; } AttributeColumnConfig aCfg = wr.getAttributeConfig(); if (aCfg == null) { return; } if ("xs:anyURI".equals(aCfg.getType())) { open.setVisible(true); Object value = wr.get("value"); String url = ""; if (value != null) { url = value.toString(); } if (value instanceof ValueModel) { url = ((ValueModel)value).getValue(); url = ExpressionHandler.replaceURL(url); } open.setData("url", url); } } }); return(menu); } public boolean commit() { store.commitChanges(); return(true); } public void restore() { store.rejectChanges(); } }