/******************************************************************************* * 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.attribute; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.jboss.tools.common.model.ui.attribute.adapter.AdapterFactory; import org.jboss.tools.common.model.ui.attribute.adapter.DefaultValueAdapter; import org.jboss.tools.common.model.ui.attribute.adapter.IModelPropertyEditorAdapter; import org.jboss.tools.common.model.ui.attribute.editor.ExtendedFieldEditor; import org.jboss.tools.common.model.ui.attribute.editor.IFieldEditor; import org.jboss.tools.common.model.ui.attribute.editor.IPropertyEditor; import org.jboss.tools.common.model.ui.attribute.editor.NoteEditor; import org.jboss.tools.common.model.ui.attribute.editor.NoteFieldEditor; import org.jboss.tools.common.model.ui.attribute.editor.PropertyEditor; import org.jboss.tools.common.model.ui.attribute.editor.PropertyEditorFactory; import org.jboss.tools.common.model.ui.attribute.editor.StringButtonFieldEditorEx; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.swt.SWT; 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.Layout; import org.eclipse.ui.actions.ActionFactory; import org.jboss.tools.common.meta.XAttribute; import org.jboss.tools.common.meta.XModelEntity; import org.jboss.tools.common.meta.action.XAttributeData; import org.jboss.tools.common.meta.action.XEntityData; import org.jboss.tools.common.meta.key.WizardKeys; import org.jboss.tools.common.model.XModelFactory; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.ui.ModelUIPlugin; import org.jboss.tools.common.model.ui.widgets.DefaultSettings; import org.jboss.tools.common.model.ui.widgets.IWidgetSettings; import org.jboss.tools.common.model.util.ModelFeatureFactory; /** * @author eskimo */ public class XAttributeSupport { public static interface IAttributeDependency extends java.beans.PropertyChangeListener { public void setSupport(XAttributeSupport support); } boolean isDebugging = ModelUIPlugin.getDefault().isDebugging(); private ArrayList<IModelPropertyEditorAdapter> adapters = new ArrayList<IModelPropertyEditorAdapter>(); private ArrayList<PropertyEditor> editors = new ArrayList<PropertyEditor>(); private Map<String,FieldEditor> fieldEditors = new HashMap<String,FieldEditor>(); protected Set<String> alwaysGreedy = new HashSet<String>(); private XModelObject xmo; private XEntityData data; private Layout layout; private IWidgetSettings settings = DefaultSettings.getDefault(); public XAttributeSupport() { } public XAttributeSupport(IWidgetSettings settings) { this.settings = settings; } public XAttributeSupport(XModelObject xmo) { if(xmo==null) throw new IllegalArgumentException("XModelObject cannot be null."); //$NON-NLS-1$ init(xmo); } public XAttributeSupport(XModelObject xmo, XEntityData data) { this(xmo, data, false); } public XAttributeSupport(XModelObject xmo, XEntityData data, boolean useObject) { if(data==null) throw new IllegalArgumentException("XEntityData cannot be null."); //$NON-NLS-1$ init(xmo, data, useObject); } public XEntityData getEntityData() { return data; } public void init(XModelObject xmo, XEntityData data) { init(xmo, data, false); } public void init(XModelObject xmo) { this.xmo = xmo; XAttribute[] attribute = xmo.getModelEntity().getAttributes(); adapters.clear(); editors.clear(); for (int i = 0; i < attribute.length; i++) { if(!attribute[i].isVisible()) continue; IModelPropertyEditorAdapter adapter = createAdapter(xmo, attribute[i]); PropertyEditor editor = createEditor(adapter, xmo, attribute[i]); adapters.add(adapter); editors.add(editor); if("always".equals(attribute[i].getProperty("greedy"))) { //$NON-NLS-1$ //$NON-NLS-2$ alwaysGreedy.add(attribute[i].getName()); } } initDependencies(xmo.getModelEntity()); } public void init(XModelObject xmo, XEntityData data, boolean useObject) { this.data = data; this.xmo = xmo; XAttributeData ads[] = data.getAttributeData(); adapters.clear(); editors.clear(); for (int i = 0; i < ads.length; i++) { //if(!ads[i].getAttribute().isVisible()) continue; XAttribute attr = ads[i].getAttribute(); IModelPropertyEditorAdapter adapter = (useObject) ? createAdapter(xmo, attr) : createAdapter(xmo, ads[i]); PropertyEditor editor = (useObject) ? createEditor(adapter, xmo, attr) : createEditor(adapter, xmo, ads[i]); if(editor.getLabelText() == null) { String labelText = WizardKeys.getAttributeDisplayName(ads[i]); if (labelText!=null) { labelText = labelText + ((ads[i].getMandatoryFlag()) ? "*" : ""); //$NON-NLS-1$ //$NON-NLS-2$ editor.setLabelText(labelText); } } adapters.add(adapter); editors.add(editor); if("always".equals(attr.getProperty("greedy"))) { //$NON-NLS-1$ //$NON-NLS-2$ alwaysGreedy.add(attr.getName()); } } initDependencies(data.getModelEntity()); } void initDependencies(XModelEntity entity) { String dependencies = entity.getProperty("formDependencies"); if(dependencies == null || dependencies.length() == 0) return; IAttributeDependency d = (IAttributeDependency)ModelFeatureFactory.getInstance().createFeatureInstance(dependencies); if(d == null) return; d.setSupport(this); addPropertyChangeListener(d); } public void dispose() { if (editors!=null) { Iterator i = editors.iterator(); Object object; while (i.hasNext()) { object = i.next(); if (object instanceof FieldEditor) ((FieldEditor)object).dispose(); } editors.clear(); editors = null; } if (adapters!=null) { Iterator i = adapters.iterator(); Object object; while (i.hasNext()) { object = i.next(); if (object instanceof DefaultValueAdapter) ((DefaultValueAdapter)object).dispose(); } adapters.clear(); adapters = null; } if (fieldEditors!=null) { fieldEditors.clear(); fieldEditors = null; } if (alwaysGreedy!=null) { alwaysGreedy.clear(); alwaysGreedy = null; } xmo = null; settings = null; } private IModelPropertyEditorAdapter createAdapter(XModelObject o, XAttribute a) { return AdapterFactory.getAdapter(a, o, o.getModel()); } private IModelPropertyEditorAdapter createAdapter(XModelObject o, XAttributeData a) { return AdapterFactory.getAdapter(a.getAttribute(), o, a, o.getModel()); } private PropertyEditor createEditor(Object adapter, XModelObject o, XAttribute a) { return PropertyEditorFactory.createPropertyEditor(adapter, a, o, settings); } private PropertyEditor createEditor(Object adapter, XModelObject o, XAttributeData a) { return PropertyEditorFactory.createPropertyEditor(adapter, a.getAttribute(), a, settings); } public void setAutoStore(boolean set) { for (Iterator iter = adapters.iterator(); iter.hasNext();) { IModelPropertyEditorAdapter element = (IModelPropertyEditorAdapter) iter.next(); element.setAutoStore(set); } } // private static final int COLUMN_1_WIDTH = 100; public Control[] fillComposite(Composite composite, PropertyEditor editor, StringButtonFieldEditorEx sb) { composite.setBackgroundMode(SWT.INHERIT_DEFAULT); ExtendedFieldEditor fieldEditor = null; boolean greedy = editor.isGreedyEditor(); if(!greedy) { fieldEditor = editor.getFieldEditor(composite); } else { if(sb == null) sb = new StringButtonFieldEditorEx(settings); sb.setLabelText(editor.getLabelText()); sb.setPropertyEditor(editor); String changeButtonName = editor.getChangeButtonName(); if(changeButtonName != null) { sb.setChangeButtonText(changeButtonName); } fieldEditor = sb; greedy = false; } registerFieldEditor(editor.getAttributeName(), fieldEditor); if (!enabled) { fieldEditor.setEnabled(enabled); } Control[] controls = fillComposite(composite, fieldEditor, greedy); if(fieldEditor instanceof StringButtonFieldEditorEx) { ((StringButtonFieldEditorEx)fieldEditor).setStringValue("" + editor.getValue()); //$NON-NLS-1$ } return controls; } public Control[] fillComposite(Composite composite, FieldEditor fieldEditor, boolean greedy) { composite.setBackgroundMode(SWT.INHERIT_DEFAULT); if (fieldEditor instanceof IFieldEditor) { Control control; GridData gd; Control[] controls = ((IFieldEditor)fieldEditor).getControls(composite); if (controls.length==2) { // layout 2 element control = controls[0]; gd = new GridData(); control.setLayoutData(gd); control = controls[1]; if(greedy) { gd.verticalAlignment = GridData.BEGINNING; if(editors.size() == 1) gd.horizontalSpan = 2; gd = new GridData(GridData.FILL_BOTH); if(editors.size() == 1) gd.horizontalSpan = 2; } else { gd = new GridData(GridData.FILL_HORIZONTAL); } if(greedy) { int h = control.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; if(h > 300) gd.heightHint = 300; if (fieldEditor instanceof NoteFieldEditor) { gd.heightHint = 100; } } control.setLayoutData(gd); } else if (controls.length==1) { // layout 1st element control = controls[0]; gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 2; control.setLayoutData(gd); } return controls; } else { fieldEditor.fillIntoGrid(composite, 2); return null; } } public void fillComposite(Composite composite) { composite.setBackgroundMode(SWT.INHERIT_DEFAULT); int greedyCount = 0; sortEditors(); for (int i = 0; i < editors.size(); i++) { PropertyEditor editor = (PropertyEditor)editors.get(i); if(editor.isGreedyEditor()) ++greedyCount; } for (int i = 0; i < editors.size(); i++) { PropertyEditor editor = (PropertyEditor)editors.get(i); //editor.setLabelText(support.getAttributeMessage(id, ads[i].getAttribute().getName())); ExtendedFieldEditor fieldEditor = null; boolean greedy = editor.isGreedyEditor(); if(!greedy || keepGreedy(editor.getAttributeName(), i, greedyCount) || editor instanceof NoteEditor) { fieldEditor = editor.getFieldEditor(composite); } else { StringButtonFieldEditorEx sb; sb = new StringButtonFieldEditorEx(settings); sb.setLabelText(editor.getLabelText()); sb.setPropertyEditor(editor); String changeButtonName = editor.getChangeButtonName(); if(changeButtonName != null) { sb.setChangeButtonText(changeButtonName); } fieldEditor = sb; greedy = false; } registerFieldEditor(editor.getAttributeName(), fieldEditor); if (!enabled) { fieldEditor.setEnabled(enabled); } fillComposite(composite, fieldEditor, greedy); if(fieldEditor instanceof StringButtonFieldEditorEx) { ((StringButtonFieldEditorEx)fieldEditor).setStringValue("" + editor.getValue()); //$NON-NLS-1$ } } } private void sortEditors(){ PropertyEditor editor = null; for (int i = 0; i < editors.size(); i++) { editor = editors.get(i); if ("description".equalsIgnoreCase(editor.getAttributeName())) { editors.remove(editor); editors.add(editor); return; } } } public Composite createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); // composite.setBackgroundMode(SWT.INHERIT_DEFAULT); // composite.setBackground(parent.getBackground()); composite.setLayout(getLayout()); fillComposite(composite); // int greedyCount = 0; // sortEditors(); // for (int i = 0; i < editors.size(); i++) { // PropertyEditor editor = (PropertyEditor)editors.get(i); // if(editor.isGreedyEditor()) ++greedyCount; // } // // for (int i = 0; i < editors.size(); i++) { // PropertyEditor editor = (PropertyEditor)editors.get(i); // //editor.setLabelText(support.getAttributeMessage(id, ads[i].getAttribute().getName())); // ExtendedFieldEditor fieldEditor = null; // boolean greedy = editor.isGreedyEditor(); // if(!greedy || keepGreedy(editor.getAttributeName(), i, greedyCount) || editor instanceof NoteEditor) { // fieldEditor = editor.getFieldEditor(composite); // } else { // StringButtonFieldEditorEx sb = null; // // sb = new StringButtonFieldEditorEx(settings); // // sb.setLabelText(editor.getLabelText()); // String changeButtonName = editor.getChangeButtonName(); // if(changeButtonName != null) { // sb.setChangeButtonText(changeButtonName); // } // sb.setPropertyEditor(editor); // fieldEditor = sb; // greedy = false; // } // registerFieldEditor(editor.getAttributeName(), fieldEditor); // if (!enabled) { // fieldEditor.setEnabled(enabled); // } // fillComposite(composite, fieldEditor, greedy); // if(fieldEditor instanceof StringButtonFieldEditorEx) { // ((StringButtonFieldEditorEx)fieldEditor).setStringValue("" + editor.getValue()); //$NON-NLS-1$ // } // } return composite; } protected boolean keepGreedy(String name, int index, int greedyCount) { return greedyCount < 1 || (greedyCount == 1 && editors.size() < 2) || alwaysGreedy.contains(name); } public void store() { for (int i = 0; i < editors.size(); i++) ((IModelPropertyEditorAdapter)adapters.get(i)).store(); } public void load() { if(xmo == null) throw new IllegalArgumentException("" + //$NON-NLS-1$ "Init support with XModelObject before saving"); //$NON-NLS-1$ for (int i = 0; i < editors.size(); i++) ((IModelPropertyEditorAdapter)adapters.get(i)).load(); } public void save() { if(xmo == null) throw new IllegalArgumentException("" + //$NON-NLS-1$ "Init support with XModelObject before saving"); //$NON-NLS-1$ if(xmo.getModel()==null) throw new IllegalArgumentException("Cannot store deleted or removed XModel object"); //$NON-NLS-1$ xmo.getModel().saveOptions(); } public List getAdapterList() { return Collections.unmodifiableList(adapters); } public List<FieldEditor> getVisibleFieldEditors() { ArrayList<FieldEditor> visibleEditors = new ArrayList<FieldEditor>(); Set keySet = fieldEditors.keySet(); Iterator i = keySet.iterator(); while (i.hasNext()) visibleEditors.add(fieldEditors.get(i.next())); return visibleEditors; } public List getEditorList() { return Collections.unmodifiableList(editors); } public String getTitle() { return xmo.getPresentationString(); } public IPropertyEditor getPropertyEditorByName(String attributeName) { IPropertyEditor result = null; if (attributeName != null && !"".equals(attributeName)) { //$NON-NLS-1$ Iterator iterator = editors.iterator(); while (iterator.hasNext() && result == null) { IPropertyEditor editor = (IPropertyEditor)iterator.next(); if (attributeName.equals(editor.getAttributeName())) result = editor; } } return result; } public FieldEditor getFieldEditorByName(String attributeName) { return (FieldEditor)fieldEditors.get(attributeName); } public void registerFieldEditor(String attributeName, FieldEditor f) { if(f != null) fieldEditors.put(attributeName, f); } public IModelPropertyEditorAdapter getPropertyEditorAdapterByName(String attributeName) { IModelPropertyEditorAdapter result = null; if (attributeName != null && !"".equals(attributeName)) { //$NON-NLS-1$ Iterator iterator = adapters.iterator(); while (iterator.hasNext() && result == null) { IModelPropertyEditorAdapter adapter = (IModelPropertyEditorAdapter)iterator.next(); if (attributeName.equals(adapter.getAttribute().getName())) result = adapter; } } return result; } public Layout getLayout() { if (layout == null) { layout = getDefaultLayout(); } return layout; } public void setLayout(Layout layout) { this.layout = layout; } protected Layout getDefaultLayout() { GridLayout gridLayout = new GridLayout(2, false); return gridLayout; } public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) { for (int i = 0; i < adapters.size(); i++) { IModelPropertyEditorAdapter a = (IModelPropertyEditorAdapter)adapters.get(i); a.addValueChangeListener(listener); } } public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) { for (int i = 0; i < adapters.size(); i++) { IModelPropertyEditorAdapter a = (IModelPropertyEditorAdapter)adapters.get(i); a.removeValueChangeListener(listener); } } public Properties getValues() { Properties p = new Properties(); if(data == null) return p; XAttributeData ads[] = data.getAttributeData(); for (int i = 0; i < adapters.size(); i++) { IModelPropertyEditorAdapter a = (IModelPropertyEditorAdapter)adapters.get(i); Object v = a.getValue(); if(v == null) continue; XAttribute att = ads[i].getAttribute(); String value = v.toString(); if(att.isTrimmable()) value = value.trim(); p.setProperty(att.getName(), value); } return p; } /** * @return */ public IWidgetSettings getSettings() { return settings; } /** * @param settings */ public void setSettings(IWidgetSettings settings) { this.settings = settings; } /* * enabled */ private boolean enabled = Boolean.TRUE.booleanValue(); public boolean isEnabled() { return enabled; } public void setEnabled(boolean b) { enabled = b; doSetEnabled(); } protected void doSetEnabled() { if (this.fieldEditors!=null) { Collection fieldEditros = this.fieldEditors.values(); Iterator i = fieldEditros.iterator(); while (i.hasNext()) { ((ExtendedFieldEditor)i.next()).setEnabled(enabled); } } } public void updateEnablementByModelObject() { Iterator it = fieldEditors.keySet().iterator(); while(it.hasNext()) { String n = it.next().toString(); ExtendedFieldEditor f = (ExtendedFieldEditor)fieldEditors.get(n); f.setEnabled(xmo.isAttributeEditable(n)); } } public boolean doGlobalAction(String actionId) { if (getVisibleFieldEditors()==null) return false; Iterator i = getVisibleFieldEditors().iterator(); ExtendedFieldEditor fieldEditor; while (i.hasNext()) { fieldEditor = (ExtendedFieldEditor)i.next(); if (ActionFactory.CUT.getId().equals(actionId)) { fieldEditor.cut(); } else if (ActionFactory.COPY.getId().equals(actionId)) { fieldEditor.copy(); } else if (ActionFactory.PASTE.getId().equals(actionId)) { fieldEditor.paste(); } else if (ActionFactory.DELETE.getId().equals(actionId)) { fieldEditor.delete(); } } return false; } }