blob: 4615b2dd2efdbe987e9a9c08ad8315d88662a81e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.internal.databinding;
import org.eclipse.jface.databinding.ChangeEvent;
import org.eclipse.jface.databinding.IChangeListener;
import org.eclipse.jface.databinding.IDataBindingContext;
import org.eclipse.jface.databinding.IUpdatable;
import org.eclipse.jface.databinding.IUpdatableCollection;
import org.eclipse.jface.databinding.IUpdatableTree;
import org.eclipse.jface.databinding.IUpdatableValue;
import org.eclipse.jface.databinding.TreeModelDescription;
import org.eclipse.jface.databinding.Updatable;
import org.eclipse.jface.util.Assert;
/**
* @since 3.2
*
*/
public class NestedUpdatableTree extends Updatable implements IUpdatableTree {
private IDataBindingContext databindingContext;
private TreeModelDescription originalDescription;
private IUpdatableTree innerUpdatableTree;
private boolean updating = false;
private IChangeListener innerChangeListener = new IChangeListener() {
public void handleChange(ChangeEvent changeEvent) {
if (!updating) {
ChangeEvent nestedEvent = fireChangeEvent(changeEvent.getChangeType(), changeEvent
.getOldValue(), changeEvent.getNewValue(), changeEvent.getParent(), changeEvent.getPosition());
if(nestedEvent.getVeto()) {
changeEvent.setVeto(true);
}
}
}
};
/**
* @param databindingContext
* @param description
*/
public NestedUpdatableTree(IDataBindingContext databindingContext, TreeModelDescription description) {
this.databindingContext=databindingContext;
this.originalDescription=description;
Assert.isTrue(description.getRoot() instanceof IUpdatable);
final IUpdatable outerUpdatableValue = (IUpdatable) description.getRoot();
updateInnerUpdatableValue(outerUpdatableValue);
IChangeListener outerChangeListener = new IChangeListener() {
public void handleChange(ChangeEvent changeEvent) {
Object[] old = getElements(null);
updateInnerUpdatableValue(outerUpdatableValue);
fireChangeEvent(ChangeEvent.REPLACE, old, getElements(null), null, -1);
}
};
outerUpdatableValue.addChangeListener(outerChangeListener);
}
private void updateInnerUpdatableValue(IUpdatable outerUpdatableValue) {
updating=true;
try {
if (innerUpdatableTree != null) {
innerUpdatableTree.removeChangeListener(innerChangeListener);
innerUpdatableTree.dispose();
}
Object currentOuterValue;
if (outerUpdatableValue instanceof IUpdatableValue)
currentOuterValue = ((IUpdatableValue)outerUpdatableValue).getValue();
else {
IUpdatableCollection collection = (IUpdatableCollection)outerUpdatableValue;
Object[] elements = new Object[collection.getSize()];
for (int i = 0; i < elements.length; i++)
elements[i]=collection.getElement(i);
currentOuterValue=elements;
}
// Construct a new description
TreeModelDescription newDescriptor = new TreeModelDescription(currentOuterValue);
Class[] types = originalDescription.getTypes();
for (int i = 0; i < types.length; i++) {
String[] properties = originalDescription.getChildrenProperties(types[i]);
for (int j = 0; j < properties.length; j++)
newDescriptor.addChildrenProperty(types[i], properties[j]);
}
innerUpdatableTree = (IUpdatableTree) databindingContext.createUpdatable(newDescriptor);
innerUpdatableTree.addChangeListener(innerChangeListener);
}
finally {
updating=false;
}
}
public int addElement(Object parentElement, int index, Object value) {
return innerUpdatableTree.addElement(parentElement, index, value);
}
public void removeElement(Object parentElement, int index) {
innerUpdatableTree.removeElement(parentElement, index);
}
public void setElement(Object parentElement, int index, Object value) {
innerUpdatableTree.setElement(parentElement, index, value);
}
public void setElements(Object parentElement, Object[] values) {
innerUpdatableTree.setElements(parentElement, values);
}
public Object getElement(Object parentElement, int index) {
return innerUpdatableTree.getElement(parentElement, index);
}
public Object[] getElements(Object parentElement) {
return innerUpdatableTree.getElements(parentElement);
}
public Class[] getTypes() {
return innerUpdatableTree.getTypes();
}
}