/*******************************************************************************
* Copyright (c) 2011 Sebastian Benz.
* 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:
* Sebastian Benz - initial API and implementation
******************************************************************************/
package de.sebastianbenz.task.ui.views;
import java.util.Stack;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.IViewerNotification;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.NotifyChangedToViewerRefresh;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.XMLMemento;
import org.eclipse.xtext.ui.InjectableAdapterFactory;
import com.google.inject.Inject;
public class ContentProvider extends AdapterFactoryContentProvider {
public class ExpandingViewerRefresh extends ViewerRefresh {
public ExpandingViewerRefresh(Viewer viewer) {
super(viewer);
}
@Override
public void run() {
if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()){
IMemento memento = XMLMemento.createWriteRoot("TMP");
treeState.saveExpandedElements(expandedElements(), memento );
super.run();
Object[] expandedElements = treeState.restoreExpandedElements(memento, globalStateManager);
for (Object object : expandedElements) {
treeViewer().reveal(treePath(object));
}
treeViewer().setExpandedElements(expandedElements);
}
}
private TreePath treePath(Object object) {
if (object instanceof EObject) {
EObject eObject = (EObject) object;
Stack<Object> path = new Stack<Object>();
while(eObject != null){
path.push(eObject);
eObject = eObject.eContainer();
}
Object[] segments = new Object[path.size()];
for(int i = 0; !path.isEmpty(); i++){
segments[i] = path.pop();
}
return new TreePath(segments);
}
return null;
}
private TreeViewer treeViewer() {
return (TreeViewer)viewer;
}
private Object[] expandedElements() {
if (viewer instanceof TreeViewer) {
TreeViewer treeViewer = (TreeViewer) viewer;
return treeViewer.getExpandedElements();
}
return new Object[0];
}
}
private final TreeState treeState;
private GlobalStateManager globalStateManager;
@Inject
public ContentProvider(InjectableAdapterFactory adapterFactory,
TreeState treeState) {
super(adapterFactory);
this.treeState = treeState;
}
public void init(GlobalStateManager globalStateManager){
this.globalStateManager = globalStateManager;
}
public void notifyChanged(Notification notification) {
if (viewer != null && viewer.getControl() != null
&& !viewer.getControl().isDisposed()) {
// If the notification is an IViewerNotification, it specifies how
// ViewerRefresh should behave. Otherwise fall
// back to NotifyChangedToViewerRefresh, which determines how to
// refresh the viewer directly from the model
// notification.
//
if (notification instanceof IViewerNotification) {
if (viewerRefresh == null) {
viewerRefresh = new ExpandingViewerRefresh(viewer);
}
if (viewerRefresh
.addNotification((IViewerNotification) notification)) {
viewer.getControl().getDisplay().asyncExec(viewerRefresh);
}
} else {
NotifyChangedToViewerRefresh.handleNotifyChanged(viewer,
notification.getNotifier(),
notification.getEventType(), notification.getFeature(),
notification.getOldValue(), notification.getNewValue(),
notification.getPosition());
}
}
}
}