| /* |
| * Copyright (c) 2004-2014 Eike Stepper (Berlin, Germany) 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.ui; |
| |
| import org.eclipse.emf.cdo.CDOElement; |
| import org.eclipse.emf.cdo.CDOObject; |
| import org.eclipse.emf.cdo.common.id.CDOID; |
| import org.eclipse.emf.cdo.internal.ui.bundle.OM; |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| import org.eclipse.emf.cdo.view.CDOView; |
| import org.eclipse.emf.cdo.view.CDOViewTargetChangedEvent; |
| |
| import org.eclipse.net4j.util.CheckUtil; |
| import org.eclipse.net4j.util.event.IEvent; |
| import org.eclipse.net4j.util.event.IListener; |
| import org.eclipse.net4j.util.lifecycle.ILifecycleEvent; |
| import org.eclipse.net4j.util.lifecycle.ILifecycleEvent.Kind; |
| |
| import org.eclipse.emf.ecore.EObject; |
| |
| import org.eclipse.jface.viewers.ITreeViewerListener; |
| import org.eclipse.jface.viewers.TreeExpansionEvent; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.widgets.Tree; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * @author Eike Stepper |
| * @since 4.4 |
| */ |
| public class CDOTreeExpansionAgent |
| { |
| private final Listener listener = new Listener(); |
| |
| private final Set<CDOID> expandedIDs = new HashSet<CDOID>(); |
| |
| private final Set<CDOID> expandedWrappers = new HashSet<CDOID>(); |
| |
| private final CDOView view; |
| |
| private final TreeViewer viewer; |
| |
| public CDOTreeExpansionAgent(final CDOView view, final TreeViewer viewer) |
| { |
| CheckUtil.checkArg(view, "view"); |
| CheckUtil.checkArg(viewer, "viewer"); |
| |
| this.view = view; |
| this.viewer = viewer; |
| |
| final Tree tree = viewer.getTree(); |
| if (!tree.isDisposed()) |
| { |
| tree.getDisplay().syncExec(new Runnable() |
| { |
| public void run() |
| { |
| for (Object element : viewer.getExpandedElements()) |
| { |
| addExpandedElement(element); |
| } |
| |
| view.addListener(listener); |
| viewer.addTreeListener(listener); |
| viewer.getTree().addDisposeListener(listener); |
| } |
| }); |
| } |
| } |
| |
| public final CDOView getView() |
| { |
| return view; |
| } |
| |
| public final TreeViewer getViewer() |
| { |
| return viewer; |
| } |
| |
| public void setExpandedStates() |
| { |
| for (CDOID id : expandedIDs) |
| { |
| try |
| { |
| CDOObject object = view.getObject(id); |
| if (object != null) |
| { |
| EObject eObject = CDOUtil.getEObject(object); |
| viewer.setExpandedState(eObject, true); |
| } |
| } |
| catch (Exception ex) |
| { |
| // Ignore. |
| } |
| } |
| |
| for (CDOID id : expandedWrappers) |
| { |
| try |
| { |
| CDOObject object = view.getObject(id); |
| if (object != null) |
| { |
| CDOElement wrapper = CDOElement.getFor(object); |
| if (wrapper != null) |
| { |
| viewer.setExpandedState(wrapper, true); |
| } |
| } |
| } |
| catch (Exception ex) |
| { |
| // Ignore. |
| } |
| } |
| } |
| |
| public void dispose() |
| { |
| try |
| { |
| final Tree tree = viewer.getTree(); |
| if (!tree.isDisposed()) |
| { |
| tree.getDisplay().syncExec(new Runnable() |
| { |
| public void run() |
| { |
| tree.removeDisposeListener(listener); |
| } |
| }); |
| } |
| |
| viewer.removeTreeListener(listener); |
| view.removeListener(listener); |
| expandedIDs.clear(); |
| expandedWrappers.clear(); |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| } |
| } |
| |
| private CDOID getID(Object element) |
| { |
| if (element instanceof EObject) |
| { |
| CDOObject object = CDOUtil.getCDOObject((EObject)element, false); |
| if (object != null && object.cdoView() == view) |
| { |
| return object.cdoID(); |
| } |
| } |
| |
| return null; |
| } |
| |
| private void addExpandedElement(Object element) |
| { |
| if (element instanceof CDOElement) |
| { |
| CDOElement wrapper = (CDOElement)element; |
| |
| CDOID id = getID(wrapper.getDelegate()); |
| if (id != null) |
| { |
| expandedWrappers.add(id); |
| } |
| } |
| else |
| { |
| CDOID id = getID(element); |
| if (id != null) |
| { |
| expandedIDs.add(id); |
| } |
| } |
| } |
| |
| private void removeExpandedElement(Object element) |
| { |
| if (element instanceof CDOElement) |
| { |
| CDOElement wrapper = (CDOElement)element; |
| |
| CDOID id = getID(wrapper.getDelegate()); |
| if (id != null) |
| { |
| expandedWrappers.remove(id); |
| } |
| } |
| else |
| { |
| CDOID id = getID(element); |
| if (id != null) |
| { |
| expandedIDs.remove(id); |
| } |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| private final class Listener implements IListener, ITreeViewerListener, DisposeListener |
| { |
| public void notifyEvent(IEvent event) |
| { |
| if (event instanceof CDOViewTargetChangedEvent) |
| { |
| final Tree tree = viewer.getTree(); |
| if (!tree.isDisposed()) |
| { |
| tree.getDisplay().asyncExec(new Runnable() |
| { |
| public void run() |
| { |
| if (!tree.isDisposed() && !view.isClosed()) |
| { |
| setExpandedStates(); |
| } |
| } |
| }); |
| } |
| } |
| else if (event instanceof ILifecycleEvent) |
| { |
| ILifecycleEvent e = (ILifecycleEvent)event; |
| if (e.getKind() == Kind.ABOUT_TO_DEACTIVATE) |
| { |
| dispose(); |
| } |
| } |
| } |
| |
| public void treeExpanded(TreeExpansionEvent event) |
| { |
| Object element = event.getElement(); |
| addExpandedElement(element); |
| } |
| |
| public void treeCollapsed(TreeExpansionEvent event) |
| { |
| Object element = event.getElement(); |
| removeExpandedElement(element); |
| } |
| |
| public void widgetDisposed(DisposeEvent e) |
| { |
| dispose(); |
| } |
| } |
| } |