/***************************************************************************** * Copyright (c) 2012 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.infra.gmfdiag.properties.databinding.custom; import java.util.Collection; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.list.WritableList; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.databinding.EMFProperties; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.gmf.runtime.notation.NamedStyle; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.infra.emf.databinding.EMFObservableList; import org.eclipse.papyrus.infra.gmfdiag.common.listener.CustomStyleListener; import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor; public class CustomStyleObservableList extends EMFObservableList implements IChangeListener { protected EClass eClass; protected EStructuralFeature feature; protected String styleName; protected View view; protected EditingDomain domain; protected CustomStyleListener listener; protected boolean styleExists; protected boolean changing = false; //Equals to concreteList protected IObservableList observableConcreteList; // protected final List<?> transientList; public CustomStyleObservableList(View view, String styleName, EditingDomain domain, EClass eClass, EStructuralFeature feature) { super(getWrappedList(view, styleName, eClass, feature), domain, null, null); this.eClass = eClass; this.feature = feature; this.styleName = styleName; this.view = view; this.domain = domain; observableConcreteList = (IObservableList)concreteList; styleExists = isStyleCreated(); view.eAdapters().add(listener = new CustomStyleListener(view, feature, this, styleName)); } @Override public void commit(AbstractEditor editor) { changing = true; super.commit(editor); changing = false; } private boolean isStyleCreated() { return view.getNamedStyle(eClass, styleName) != null; } private static IObservableList getWrappedList(View view, String styleName, EClass eClass, EStructuralFeature feature) { NamedStyle style = view.getNamedStyle(eClass, styleName); if(style != null) { return EMFProperties.list(feature).observe(style); } //The style doesn't exist yet, we need to simulate it //(With an empty list) return new WritableList(); } @Override public Command getAddCommand(int index, Object value) { return new AddCustomStyleListValueCommand(domain, view, styleName, eClass, feature, value, index); } @Override public Command getAddCommand(Object value) { return new AddCustomStyleListValueCommand(domain, view, styleName, eClass, feature, value); } @Override public Command getAddAllCommand(Collection<?> values) { return new AddAllCustomStyleListValueCommand(domain, view, styleName, eClass, feature, values); } @Override public Command getAddAllCommand(int index, Collection<?> values) { return new AddCustomStyleListValueCommand(domain, view, styleName, eClass, feature, values, index); } @Override public Command getRemoveCommand(Object value) { return new RemoveCustomStyleListValueCommand(domain, view, styleName, eClass, feature, value); } @Override public Command getRemoveAllCommand(Collection<?> values) { return new RemoveAllCustomStyleListValueCommand(domain, view, styleName, eClass, feature, values); } @Override public Command getSetCommand(int index, Object value) { return new SetCustomStyleListValueCommand(domain, view, styleName, eClass, feature, index, value); } public void handleChange(ChangeEvent event) { //If the ListValueStyle has been created or removed, we need to resync //the concrete list with it if(styleExists != (styleExists = isStyleCreated())) { observableConcreteList.dispose(); concreteList = observableConcreteList = getWrappedList(view, styleName, eClass, feature); } //If this observable is not the source of the change, the wrapped //list should also be refreshed. if(!changing) { refreshCacheList(); } } @Override public void dispose() { view.eAdapters().remove(listener); listener.dispose(); listener = null; observableConcreteList.dispose(); super.dispose(); } }