blob: 3abf3686c1c36b85317d21de94c9f09a392fadba [file] [log] [blame]
/*
* Copyright (c) 2007-2012, 2014, 2015 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
* Simon McDuff - maintenance
* Victor Roldan Betancort - maintenance
*/
package org.eclipse.emf.cdo.ui;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.internal.ui.ItemsProcessor;
import org.eclipse.emf.cdo.internal.ui.bundle.OM;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent;
import org.eclipse.emf.cdo.view.CDOObjectHandler;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
import org.eclipse.net4j.util.container.IContainerDelta;
import org.eclipse.net4j.util.container.IContainerEvent;
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.om.pref.OMPreferencesChangeEvent;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
import java.util.List;
import java.util.Set;
/**
* A class that handles {@link org.eclipse.net4j.util.event.IEvent events} on
* {@link org.eclipse.jface.viewers.TreeViewer TreeViewer}-based editors or views.
*
* @author Eike Stepper
* @see org.eclipse.net4j.util.event.IEvent
* @see org.eclipse.jface.viewers.TreeViewer
*/
public class CDOEventHandler
{
private CDOView view;
private TreeViewer treeViewer;
private IListener sessionListener = new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof IContainerEvent<?>)
{
IContainerEvent<?> e = (IContainerEvent<?>)event;
if (e.getDeltaElement() == view && e.getDeltaKind() == IContainerDelta.Kind.REMOVED)
{
viewClosed();
}
}
else if (event instanceof ILifecycleEvent)
{
ILifecycleEvent e = (ILifecycleEvent)event;
if (e.getKind() == ILifecycleEvent.Kind.DEACTIVATED)
{
viewClosed();
}
}
}
};
private IListener viewListener = new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof CDOViewInvalidationEvent)
{
CDOViewInvalidationEvent e = (CDOViewInvalidationEvent)event;
// Remove detached object from selection, could incur into unwanted exceptions
checkDetachedSelection(e.getDetachedObjects());
viewInvalidated(e.getDirtyObjects());
}
else if (event instanceof CDOViewLocksChangedEvent)
{
CDOViewLocksChangedEvent e = (CDOViewLocksChangedEvent)event;
EObject[] objects = e.getAffectedObjects();
if (objects.length != 0)
{
updateElement(objects);
}
}
else if (event instanceof CDOTransactionFinishedEvent)
{
// CDOTransactionFinishedEvent e = (CDOTransactionFinishedEvent)event;
// if (e.getType() == CDOTransactionFinishedEvent.Type.COMMITTED)
// {
// Map<CDOID, CDOID> idMappings = e.getIDMappings();
// HashSet<CDOID> newOIDs = new HashSet<CDOID>(idMappings.values());
// new ItemsProcessor(view)
// {
// @Override
// protected void processCDOObject(TreeViewer viewer, InternalCDOObject cdoObject)
// {
// viewer.update(cdoObject.cdoInternalInstance(), null);
// }
// }.processCDOObjects(treeViewer, newOIDs);
// }
// else
{
refreshTreeViewer();
}
viewDirtyStateChanged();
}
else if (event instanceof CDOTransactionStartedEvent)
{
viewDirtyStateChanged();
}
else if (event instanceof CDOTransactionConflictEvent)
{
CDOTransactionConflictEvent e = (CDOTransactionConflictEvent)event;
viewConflict(e.getConflictingObject(), e.isFirstConflict());
}
}
};
private CDOObjectHandler objectHandler = new CDOObjectHandler()
{
public void objectStateChanged(CDOView view, CDOObject object, CDOState oldState, CDOState newState)
{
CDOEventHandler.this.objectStateChanged(object);
}
};
private IListener preferenceListener = new IListener()
{
public void notifyEvent(IEvent event)
{
@SuppressWarnings("unchecked")
OMPreferencesChangeEvent<Boolean> preferenceChangeEvent = (OMPreferencesChangeEvent<Boolean>)event;
if (OM.PREF_EDITOR_AUTO_RELOAD.getName().equals(preferenceChangeEvent.getPreference().getName()))
{
if (preferenceChangeEvent.getNewValue().booleanValue())
{
refreshTreeViewer();
}
}
else if (OM.PREF_LABEL_DECORATION.getName().equals(preferenceChangeEvent.getPreference().getName()))
{
// Fire a LabelProviderChangedEvent in case user changed decoration pattern
try
{
treeViewer.getControl().getDisplay().asyncExec(new Runnable()
{
public void run()
{
try
{
PlatformUI.getWorkbench().getDecoratorManager().update(CDOLabelDecorator.DECORATOR_ID);
}
catch (Exception ignore)
{
}
}
});
}
catch (Exception ignore)
{
}
}
}
};
private void checkDetachedSelection(final Set<?> detachedObjects)
{
UIUtil.getDisplay().asyncExec(new Runnable()
{
public void run()
{
try
{
IStructuredSelection selection = (IStructuredSelection)treeViewer.getSelection();
List<?> selectedElements = selection.toList();
for (Object object : selectedElements)
{
if (detachedObjects.contains(object))
{
treeViewer.setSelection(StructuredSelection.EMPTY);
}
}
}
catch (Exception ignore)
{
}
}
});
}
/**
* @since 2.0
*/
public CDOEventHandler(CDOView view, TreeViewer treeViewer)
{
this.view = view;
this.treeViewer = treeViewer;
wirePreferences();
view.getSession().addListener(sessionListener);
view.addListener(viewListener);
view.addObjectHandler(objectHandler);
}
/**
* @since 2.0
*/
public void dispose()
{
if (view != null)
{
view.removeObjectHandler(objectHandler);
view.removeListener(viewListener);
CDOSession session = view.getSession();
if (session != null)
{
session.removeListener(sessionListener);
}
}
unwirePreferences();
view = null;
treeViewer = null;
}
/**
* @since 2.0
*/
public CDOView getView()
{
return view;
}
public TreeViewer getTreeViewer()
{
return treeViewer;
}
/**
* @since 2.0
*/
public void setTreeViewer(TreeViewer viewer)
{
treeViewer = viewer;
}
/**
* @since 2.0
*/
public void refreshTreeViewer()
{
try
{
Control control = treeViewer.getControl();
if (!control.isDisposed())
{
control.getDisplay().asyncExec(new Runnable()
{
public void run()
{
try
{
treeViewer.refresh(true);
}
catch (Exception ignore)
{
}
}
});
}
}
catch (Exception ignore)
{
}
}
/**
* @since 4.4
*/
public void updateElement(final Object element)
{
UIUtil.updateElements(treeViewer, element);
}
/**
* @since 2.0
*/
public boolean isAutoReloadEnabled()
{
return OM.PREF_EDITOR_AUTO_RELOAD.getValue();
}
/**
* @since 2.0
*/
protected void wirePreferences()
{
OM.PREFS.addListener(preferenceListener);
}
/**
* @since 2.0
*/
protected void unwirePreferences()
{
OM.PREFS.removeListener(preferenceListener);
}
/**
* @since 4.3
*/
protected void objectStateChanged(CDOObject cdoObject)
{
updateElement(cdoObject);
}
/**
* @since 2.0
*/
protected void objectInvalidated(InternalCDOObject cdoObject)
{
}
/**
* @since 2.0
*/
protected void viewInvalidated(Set<? extends CDOObject> dirtyObjects)
{
new ItemsProcessor(view)
{
@Override
protected void processCDOObject(TreeViewer viewer, InternalCDOObject cdoObject)
{
objectInvalidated(cdoObject);
if (isAutoReloadEnabled())
{
viewer.refresh(cdoObject.cdoInternalInstance(), true);
}
}
}.processCDOObjects(treeViewer, dirtyObjects);
}
protected void viewDirtyStateChanged()
{
}
protected void viewConflict(CDOObject conflictingObject, boolean firstConflict)
{
}
protected void viewClosed()
{
}
}