/*******************************************************************************
* Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Exadel, Inc. and Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.model.ui.forms;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.StringTokenizer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableItem;
import org.jboss.tools.common.meta.action.XActionInvoker;
import org.jboss.tools.common.model.ServiceDialog;
import org.jboss.tools.common.model.XModelException;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.impl.AnyElementObjectImpl;
import org.jboss.tools.common.model.ui.ModelUIPlugin;
import org.jboss.tools.common.model.ui.action.CommandBar;
import org.jboss.tools.common.model.ui.action.CommandBarListener;
import org.jboss.tools.common.model.ui.objecteditor.XChildrenEditor;
import org.jboss.tools.common.model.ui.objecteditor.XTable;
import org.jboss.tools.common.model.ui.objecteditor.XTableProvider;
import org.jboss.tools.common.model.ui.widgets.IWidgetSettings;
import org.jboss.tools.common.model.ui.widgets.WhiteSettings;
public class AnyElementForm extends ExpandableForm {
private XModelObject xmo;
private XTable tableEditor = new XTable();
TableProviderImpl tableProvider = new TableProviderImpl();
CommandBar bar = new CommandBar();
private IWidgetSettings settings = WhiteSettings.getWhite();
public AnyElementForm() {
this.setCollapsable(Boolean.TRUE.booleanValue());
tableEditor.setTableProvider(tableProvider);
bar.setCommands(new String[]{XChildrenEditor.ADD, XChildrenEditor.EDIT, XChildrenEditor.DELETE});
bar.addCommandBarListener(new CommandBarListenerImpl());
bar.getLayout().direction = SWT.VERTICAL;
bar.setWidgetSettings(settings);
bar.getLayout().buttonWidth = 80;
}
public void dispose() {
super.dispose();
if (tableEditor != null) {
tableEditor.dispose();
tableEditor = null;
}
if(tableProvider != null) {
tableProvider.dispose();
tableProvider = null;
}
}
protected Control createClientArea(Composite parent, IWidgetSettings settings) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackgroundMode(SWT.INHERIT_DEFAULT);
settings.setupControl(composite);
GridLayout layout = new GridLayout(2, Boolean.FALSE.booleanValue());
layout.horizontalSpacing = 5;
layout.verticalSpacing = 5;
layout.marginHeight = 5;
layout.marginWidth = 5;
composite.setLayout(layout);
if(xmo == null) return composite;
String description = ""; //$NON-NLS-1$
if(description != null && description.length() > 0) {
Label label = new Label(composite, SWT.WRAP);
settings.setupControl(label);
label.setText(description);
GridData gd = new GridData();
gd.horizontalSpan = 2;
label.setLayoutData(gd);
}
Composite c = new Composite(composite, SWT.NONE);
settings.setupControl(c);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.horizontalSpan = 2;
c.setLayoutData(gd);
GridLayout layout2 = new GridLayout(2,false);
layout2.marginHeight = 0;
layout2.marginWidth = 0;
c.setLayout(layout2);
Control control = tableEditor.createControl(c);
gd = new GridData(GridData.FILL_BOTH);
control.setLayoutData(gd);
control = bar.createControl(c);
gd = new GridData(GridData.FILL_VERTICAL);
control.setLayoutData(gd);
tableEditor.update();
tableEditor.getViewer().setColumnProperties(tableProvider.header);
tableEditor.getViewer().setCellEditors(new CellEditor[]{new TextCellEditor(tableEditor.getTable()), new TextCellEditor(tableEditor.getTable())});
tableEditor.getViewer().setCellModifier(new CellModifier());
tableEditor.getViewer().addSelectionChangedListener(new SCL());
updateCommandBar();
return composite;
}
/*
private void putFieldEditorInToComposit(Composite composite, IPropertyEditor propertyEditor) {
if (propertyEditor != null) {
propertyEditor.getFieldEditor(composite).fillIntoGrid(composite, 2);
// support.registerFieldEditor(propertyEditor.getAttributeName(), propertyEditor.getFieldEditor(composite));
}
}
*/
public void initialize(Object model) {
String heading = "Attributes";
this.setHeadingText(heading);
if(!(model instanceof XModelObject)) {
ModelUIPlugin.getPluginLog().logInfo( "Error to create form " + heading + ". Model object cannot be null.", new Exception()); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
this.xmo = (XModelObject)model;
updateAttributes();
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
}
private long timeStamp = -1;
public void update() {
long ts = (xmo == null) ? -1 : xmo.getTimeStamp();
if(ts == timeStamp) return;
timeStamp = ts;
updateAttributes();
tableEditor.update();
}
void updateAttributes() {
if(tableProvider == null) return;
if(xmo == null) {
tableProvider.attributes = null;
} else {
String attrs = xmo.getAttributeValue("attributes"); //$NON-NLS-1$
StringTokenizer st = new StringTokenizer(attrs, ";"); //$NON-NLS-1$
int length = st.countTokens();
String[][] as = new String[length][2];
for (int i = 0; i < length; i++) {
String t = st.nextToken();
int k = t.indexOf('=');
String n = k < 0 ? "" : t.substring(0, k); //$NON-NLS-1$
String v = t.substring(k + 1);
as[i][0] = n;
as[i][1] = v;
}
tableProvider.attributes = as;
}
}
class TableProviderImpl implements XTableProvider {
String[] header = new String[]{"Name", "Value"};
String[][] attributes = null;
public int getColumnCount() {
return 2;
}
public int getRowCount() {
return attributes == null ? 0 : attributes.length;
}
public String getColumnName(int c) {
return header[c];
}
public String getValueAt(int r, int c) {
return attributes == null ? null : attributes[r][c];
}
public Object getDataAt(int r) {
return Integer.valueOf(r);
}
public Color getColor(int r) {
return null;
}
public int getWidthHint(int c) {
return 10;
}
public void dispose() {
}
}
class CellModifier implements ICellModifier {
public boolean canModify(Object element, String property) {
if(!"value".equals(property)) return false; //$NON-NLS-1$
return xmo != null && xmo.isObjectEditable() && getColumn(property) >= 0;
}
public Object getValue(Object element, String property) {
int r = ((Integer)element).intValue();
int c = getColumn(property);
return (c < 0) ? "" : tableProvider.getValueAt(r, c); //$NON-NLS-1$
}
int getColumn(String property) {
for (int c = 0; c < tableProvider.header.length; c++) {
if(property.equals(tableProvider.header[c])) return c;
}
return -1;
}
public void modify(Object element, String property, Object value) {
int r = ((Integer)((TableItem)element).getData()).intValue();
int c = getColumn(property);
if(c < 0) return;
String oldValue = tableProvider.getValueAt(r, c);
if(oldValue != null && oldValue.equals(value)) return;
tableProvider.attributes[r][c] = "" + value; //$NON-NLS-1$
try {
commitAttributes();
} catch (XModelException e) {
throw new IllegalArgumentException(e);
}
}
}
void commitAttributes() throws XModelException {
if(xmo == null || tableProvider == null || tableProvider.attributes == null) return;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < tableProvider.attributes.length; i++) {
String n = tableProvider.attributes[i][0].trim();
if(n.length() == 0) continue;
String v = tableProvider.attributes[i][1].trim();
if(sb.length() > 0) sb.append(AnyElementObjectImpl.SEPARATOR);
sb.append(n).append('=').append(v);
}
String v = sb.toString();
xmo.getModel().editObjectAttribute(xmo, "attributes", v); //$NON-NLS-1$
}
class CommandBarListenerImpl implements CommandBarListener {
public void action(String command) throws XModelException {
if(XChildrenEditor.ADD.equals(command)) {
add();
} else if(XChildrenEditor.EDIT.equals(command)) {
edit();
} else if(XChildrenEditor.DELETE.equals(command)) {
delete();
}
}
}
void updateCommandBar() {
boolean enabled = xmo != null && xmo.isObjectEditable();
int[] is = tableEditor.getTable().getSelectionIndices();
int selected = (is == null) ? 0 : is.length;
bar.setEnabled(XChildrenEditor.EDIT, enabled && selected == 1);
bar.setEnabled(XChildrenEditor.DELETE, enabled && selected > 0);
bar.setEnabled(XChildrenEditor.ADD, enabled);
}
class SCL implements ISelectionChangedListener {
public void selectionChanged(SelectionChangedEvent event) {
updateCommandBar();
}
}
void add() {
XActionInvoker.invoke("CreateActions.CreateAttribute", xmo, new Properties()); //$NON-NLS-1$
}
void edit() {
if(tableEditor.getTable() == null || tableEditor.getTable().isDisposed()) return;
int i = tableEditor.getTable().getSelectionIndex();
if(i < 0) return;
String name = tableProvider.getValueAt(i, 0);
Properties p = new Properties();
p.setProperty("name", name); //$NON-NLS-1$
XActionInvoker.invoke("AnyElementNew", "EditActions.EditAttribute", xmo, p); //$NON-NLS-1$ //$NON-NLS-2$
}
void delete() throws XModelException {
if(tableEditor.getTable() == null || tableEditor.getTable().isDisposed()) return;
int[] is = tableEditor.getTable().getSelectionIndices();
if(is == null || is.length == 0) return;
String name = tableProvider.getValueAt(is[0], 0);
ServiceDialog d = xmo.getModel().getService();
String message = null;
if(is.length == 1) {
message = MessageFormat.format("Delete attribute {0}?", name);
} else {
message = MessageFormat.format("Delete {0} attributes?", is.length);
}
int q = d.showDialog("Delete", message, new String[]{"OK", "Cancel"}, null, ServiceDialog.QUESTION);
if(q != 0) return;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < tableProvider.attributes.length; i++) {
boolean a = true;
for (int j = 0; j < is.length && a; j++) if(is[j] == i) a = false;
if(!a) continue;
String n = tableProvider.attributes[i][0].trim();
if(n.length() == 0) continue;
String v = tableProvider.attributes[i][1].trim();
if(sb.length() > 0) sb.append(AnyElementObjectImpl.SEPARATOR);
sb.append(n).append('=').append(v);
}
String v = sb.toString();
xmo.getModel().editObjectAttribute(xmo, "attributes", v); //$NON-NLS-1$
}
}