package org.marketcetera.photon.internal.strategy.engine.ui.workbench;
import org.eclipse.core.databinding.observable.DisposeEvent;
import org.eclipse.core.databinding.observable.IDisposeListener;
import org.eclipse.core.databinding.observable.Observables;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.navigator.CommonNavigator;
import org.marketcetera.photon.commons.osgi.HighestRankedTracker;
import org.marketcetera.photon.commons.osgi.HighestRankedTracker.IHighestRankedTrackerListener;
import org.marketcetera.photon.commons.ui.IdentityComparer;
import org.marketcetera.photon.commons.ui.workbench.WorkaroundGuiceExtensionFactory;
import org.marketcetera.photon.strategy.engine.IStrategyEngines;
import org.marketcetera.photon.strategy.engine.model.core.StrategyEngine;
import org.marketcetera.photon.strategy.engine.ui.StrategyEngineColors;
import org.marketcetera.photon.strategy.engine.ui.workbench.StrategyEngineWorkbenchUI;
import org.marketcetera.util.except.ExceptUtils;
import org.marketcetera.util.misc.ClassVersion;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.google.inject.Inject;
/* $License$ */
/**
* A view for strategy engines. It uses for input the {@link IStrategyEngines}
* model service. It is {@link CommonNavigator} view, supporting dynamic
* extensions.
* <p>
* This view requires a {@link BundleContext} to be injected and thus must be
* created with the {@link WorkaroundGuiceExtensionFactory}.
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: StrategyEnginesView.java 16154 2012-07-14 16:34:05Z colin $
* @since 2.0.0
*/
@ClassVersion("$Id: StrategyEnginesView.java 16154 2012-07-14 16:34:05Z colin $")
public class StrategyEnginesView extends CommonNavigator implements
IStrategyEngines {
/**
* The id of the Eclipse properties command. Used to execute the command
* programmatically.
*/
private static final String PROPERTIES_COMMAND_ID = "org.eclipse.ui.file.properties"; //$NON-NLS-1$
/**
* Tracks the model.
*/
private final ServiceTracker mEnginesTracker;
/**
* Input to the common viewer, confined to the UI thread.
*/
private IObservableList mInput;
/**
* Indicates that the view has been disposed.
*/
private volatile boolean mDisposed;
/**
* Caches the current service being used.
*/
private volatile IStrategyEngines mService;
/**
* Caches the {@link IContextActivation} token that is used to deactivate
* the context.
*/
private IContextActivation mViewReadyContextToken;
@Inject
public StrategyEnginesView(BundleContext context) {
mEnginesTracker = new HighestRankedTracker(context,
IStrategyEngines.class.getName(),
new IHighestRankedTrackerListener() {
@Override
public void highestRankedServiceChanged(Object newService) {
mService = (IStrategyEngines) newService;
if (mService != null) {
setInput(mService.getStrategyEngines());
} else {
setInput(null);
}
}
});
}
@Override
public void createPartControl(Composite parent) {
// ensure colors are loaded
StrategyEngineColors.init();
super.createPartControl(parent);
// required per StrategyEngineContentProvider
getCommonViewer().setComparer(new IdentityComparer());
getCommonViewer().setComparator(null);
mEnginesTracker.open();
hookContextMenu();
getCommonViewer().addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
IHandlerService service = (IHandlerService) getViewSite()
.getService(IHandlerService.class);
try {
service.executeCommand(PROPERTIES_COMMAND_ID, null);
} catch (Exception e) {
ExceptUtils
.swallow(
e,
StrategyEnginesView.this,
Messages.STRATEGY_ENGINES_VIEW_FAILED_TO_OPEN_PROPERTIES);
}
}
});
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuMgr.setRemoveAllWhenShown(true);
Menu menu = menuMgr.createContextMenu(getCommonViewer().getControl());
getCommonViewer().getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, getCommonViewer());
}
@Override
public void dispose() {
mDisposed = true;
mEnginesTracker.close();
super.dispose();
if (mInput != null) {
mInput.dispose();
mInput = null;
}
}
@Override
protected Object getInitialInput() {
return null;
}
@Override
public IObservableList getStrategyEngines() {
return Observables.unmodifiableObservableList(mInput);
}
@Override
public StrategyEngine addEngine(StrategyEngine engine) {
if (mService != null) {
return mService.addEngine(engine);
}
return null;
}
@Override
public void removeEngine(StrategyEngine engine) {
if (mService != null) {
mService.removeEngine(engine);
}
}
private void setInput(final IObservableList input) {
getViewSite().getShell().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
if (mInput != null) {
mInput.dispose();
mInput = null;
}
if (!mDisposed) {
if (input == null) {
if (mViewReadyContextToken != null) {
mViewReadyContextToken.getContextService()
.deactivateContext(mViewReadyContextToken);
}
} else {
mInput = Observables.unmodifiableObservableList(input);
mInput.addDisposeListener(new IDisposeListener() {
@Override
public void handleDispose(DisposeEvent staleEvent) {
setInput(null);
}
});
mViewReadyContextToken = ((IContextService) PlatformUI
.getWorkbench().getService(
IContextService.class))
.activateContext(StrategyEngineWorkbenchUI.STRATEGY_ENGINES_VIEW_READY_CONTEXT_ID);
}
getCommonViewer().setInput(mInput);
getCommonViewer().expandAll();
}
}
});
}
}