/*
* Copyright (c) 2004-2011 Marco Maccaferri 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:
* Marco Maccaferri - initial API and implementation
*/
package org.eclipsetrader.ui.internal.ats.explorer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;
import org.eclipsetrader.core.IScript;
import org.eclipsetrader.core.ats.IStrategy;
import org.eclipsetrader.core.ats.ScriptStrategy;
import org.eclipsetrader.core.instruments.ISecurity;
import org.eclipsetrader.core.repositories.IRepositoryRunnable;
import org.eclipsetrader.core.repositories.IRepositoryService;
import org.eclipsetrader.ui.UIConstants;
import org.eclipsetrader.ui.internal.UIActivator;
import org.eclipsetrader.ui.internal.ats.explorer.ExplorerViewModel.InstrumentRootItem;
import org.eclipsetrader.ui.internal.ats.explorer.ExplorerViewModel.ScriptRootItem;
import org.eclipsetrader.ui.navigator.RepositoryObjectTransfer;
import org.eclipsetrader.ui.navigator.SecurityObjectTransfer;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class ExplorerViewPart extends ViewPart {
public static final String VIEW_ID = "org.eclipsetrader.ui.ats.views.explorer";
private IRepositoryService repositoryService;
private TreeViewer viewer;
private ExplorerViewModel model;
private Action collapseAllAction;
private Action expandAllAction;
private Action deleteAction;
private Action removeAction;
public ExplorerViewPart() {
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
*/
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
BundleContext bundleContext = UIActivator.getDefault().getBundle().getBundleContext();
ServiceReference<IRepositoryService> serviceReference = bundleContext.getServiceReference(IRepositoryService.class);
repositoryService = bundleContext.getService(serviceReference);
ImageRegistry imageRegistry = UIActivator.getDefault().getImageRegistry();
collapseAllAction = new Action("Collapse All", imageRegistry.getDescriptor(UIConstants.COLLAPSEALL_ICON)) {
@Override
public void run() {
viewer.collapseAll();
}
};
expandAllAction = new Action("Expand All", imageRegistry.getDescriptor(UIConstants.EXPANDALL_ICON)) {
@Override
public void run() {
viewer.expandAll();
}
};
deleteAction = new Action("Delete") {
@Override
public void run() {
if (viewer.getSelection().isEmpty()) {
return;
}
if (!MessageDialog.openConfirm(getViewSite().getShell(), getPartName(), "Do you really want to delete the selected item(s) ?")) {
return;
}
doDeleteAction();
}
};
deleteAction.setImageDescriptor(imageRegistry.getDescriptor(UIActivator.IMG_DELETE_ICON));
deleteAction.setDisabledImageDescriptor(imageRegistry.getDescriptor(UIActivator.IMG_DELETE_DISABLED_ICON));
deleteAction.setId(ActionFactory.DELETE.getId());
deleteAction.setActionDefinitionId("org.eclipse.ui.edit.delete"); //$NON-NLS-1$
deleteAction.setEnabled(false);
removeAction = new Action("Remove") {
@Override
public void run() {
if (viewer.getSelection().isEmpty()) {
return;
}
if (!MessageDialog.openConfirm(getViewSite().getShell(), getPartName(), "Do you really want to remove the selected item(s) ?")) {
return;
}
doRemoveAction();
}
};
removeAction.setImageDescriptor(imageRegistry.getDescriptor(UIActivator.IMG_REMOVE_ICON));
removeAction.setDisabledImageDescriptor(imageRegistry.getDescriptor(UIActivator.IMG_REMOVE_DISABLED_ICON));
removeAction.setEnabled(false);
IToolBarManager toolBarManager = site.getActionBars().getToolBarManager();
toolBarManager.add(expandAllAction);
toolBarManager.add(collapseAllAction);
site.getActionBars().setGlobalActionHandler(deleteAction.getId(), deleteAction);
site.getActionBars().updateActionBars();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent) {
viewer = new TreeViewer(parent, SWT.FULL_SELECTION | SWT.MULTI);
viewer.getTree().setHeaderVisible(false);
viewer.getTree().setLinesVisible(false);
getSite().setSelectionProvider(viewer);
createContextMenu();
model = new ExplorerViewModel(repositoryService);
viewer.setContentProvider(new ObservableListTreeContentProvider(model, model));
viewer.setLabelProvider(new LabelProvider() {
@Override
public Image getImage(Object element) {
if ((element instanceof StrategyItem) || (element instanceof InstrumentRootItem)) {
return UIActivator.getImageFromRegistry(UIActivator.IMG_FOLDER);
}
if (element instanceof InstrumentItem) {
return UIActivator.getImageFromRegistry(UIActivator.IMG_INSTRUMENT);
}
if (element instanceof ScriptRootItem) {
return UIActivator.getImageFromRegistry(UIActivator.IMG_SCRIPT_FOLDER);
}
if (element instanceof ScriptItem) {
return UIActivator.getImageFromRegistry(UIActivator.IMG_SCRIPT_INCLUDE);
}
if (element instanceof MainScriptItem) {
return UIActivator.getImageFromRegistry(UIActivator.IMG_MAIN_SCRIPT);
}
return super.getImage(element);
}
});
viewer.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
if ((e1 instanceof ScriptItem) && (e2 instanceof ScriptItem)) {
return 0;
}
return super.compare(viewer, e1, e2);
}
});
viewer.setInput(model);
viewer.expandAll();
viewer.addOpenListener(new IOpenListener() {
@Override
public void open(OpenEvent event) {
try {
IHandlerService service = (IHandlerService) getSite().getService(IHandlerService.class);
service.executeCommand("org.eclipse.ui.file.open", null);
} catch (Exception e) {
e.printStackTrace();
}
}
});
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
deleteAction.setEnabled(canEnableDeleteAction(selection));
removeAction.setEnabled(canEnableRemoveAction(selection));
}
});
viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, new Transfer[] {
SecurityObjectTransfer.getInstance(),
RepositoryObjectTransfer.getInstance(),
}, new ViewerDropAdapter(viewer) {
@Override
public boolean validateDrop(Object target, int operation, TransferData transferType) {
return SecurityObjectTransfer.getInstance().isSupportedType(transferType) || RepositoryObjectTransfer.getInstance().isSupportedType(transferType);
}
@Override
public boolean performDrop(Object data) {
ScriptStrategy strategy = null;
ExplorerViewItem target = (ExplorerViewItem) getCurrentTarget();
while (strategy == null && target != null) {
strategy = (ScriptStrategy) target.getAdapter(ScriptStrategy.class);
if (strategy == null) {
target = target.getParent();
}
}
if (strategy != null) {
final ScriptStrategy repositoryObject = strategy;
final IAdaptable[] contents = (IAdaptable[]) data;
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
doAddDroppedObjects(repositoryObject, contents);
}
});
}
return true;
}
});
}
private void createContextMenu() {
MenuManager menuMgr = new MenuManager("#popupMenu", "popupMenu"); //$NON-NLS-1$ //$NON-NLS-2$
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager menuManager) {
menuManager.add(new Separator("group.new"));
menuManager.add(new GroupMarker("group.goto"));
menuManager.add(new Separator("group.open"));
menuManager.add(new GroupMarker("group.openWith"));
menuManager.add(new Separator("group.trade"));
menuManager.add(new GroupMarker("group.tradeWith"));
menuManager.add(new Separator("group.show"));
menuManager.add(new Separator("group.edit"));
menuManager.add(new GroupMarker("group.reorganize"));
menuManager.add(new GroupMarker("group.port"));
menuManager.add(new Separator("group.generate"));
menuManager.add(new Separator("group.search"));
menuManager.add(new Separator("group.build"));
menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
menuManager.add(new Separator("group.properties"));
menuManager.appendToGroup("group.show", new Action("Expand All") {
@Override
public void run() {
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
for (Iterator<?> iter = selection.iterator(); iter.hasNext();) {
viewer.expandToLevel(iter.next(), AbstractTreeViewer.ALL_LEVELS);
}
}
});
menuManager.appendToGroup("group.reorganize", removeAction);
menuManager.appendToGroup("group.reorganize", deleteAction);
}
});
viewer.getControl().setMenu(menuMgr.createContextMenu(viewer.getControl()));
getSite().registerContextMenu(menuMgr, getSite().getSelectionProvider());
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
@Override
public void setFocus() {
viewer.getControl().setFocus();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose() {
BundleContext bundleContext = UIActivator.getDefault().getBundle().getBundleContext();
ServiceReference<IRepositoryService> serviceReference = bundleContext.getServiceReference(IRepositoryService.class);
if (serviceReference != null && repositoryService != null) {
bundleContext.ungetService(serviceReference);
}
model.dispose();
super.dispose();
}
private void doDeleteAction() {
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
for (final Object object : selection.toList()) {
if (object instanceof StrategyItem) {
final IStrategy repositoryObject = ((StrategyItem) object).getStrategy();
repositoryService.runInService(new IRepositoryRunnable() {
@Override
public IStatus run(IProgressMonitor monitor) throws Exception {
repositoryService.deleteAdaptable(new IAdaptable[] {
repositoryObject
});
return Status.OK_STATUS;
}
}, null);
}
}
}
private void doRemoveAction() {
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
for (final Object object : selection.toList()) {
if (object instanceof InstrumentItem) {
InstrumentItem instrumentItem = (InstrumentItem) object;
final ScriptStrategy repositoryObject = (ScriptStrategy) instrumentItem.getAdapter(ScriptStrategy.class);
if (repositoryObject != null) {
List<ISecurity> list = new ArrayList<ISecurity>(Arrays.asList(repositoryObject.getInstruments()));
list.remove(instrumentItem.getInstrument());
repositoryObject.setInstruments(list.toArray(new ISecurity[list.size()]));
repositoryService.runInService(new IRepositoryRunnable() {
@Override
public IStatus run(IProgressMonitor monitor) throws Exception {
repositoryService.saveAdaptable(new IAdaptable[] {
repositoryObject
});
return Status.OK_STATUS;
}
}, null);
}
}
else if (object instanceof ScriptItem) {
ScriptItem instrumentItem = (ScriptItem) object;
final ScriptStrategy repositoryObject = (ScriptStrategy) instrumentItem.getAdapter(ScriptStrategy.class);
if (repositoryObject != null) {
List<IScript> list = new ArrayList<IScript>(Arrays.asList(repositoryObject.getIncludes()));
list.remove(instrumentItem.getScript());
repositoryObject.setIncludes(list.toArray(new IScript[list.size()]));
repositoryService.runInService(new IRepositoryRunnable() {
@Override
public IStatus run(IProgressMonitor monitor) throws Exception {
repositoryService.saveAdaptable(new IAdaptable[] {
repositoryObject
});
return Status.OK_STATUS;
}
}, null);
}
}
}
}
private boolean canEnableDeleteAction(IStructuredSelection selection) {
if (selection.isEmpty()) {
return false;
}
for (final Object object : selection.toList()) {
if (!(object instanceof StrategyItem)) {
return false;
}
}
return true;
}
private boolean canEnableRemoveAction(IStructuredSelection selection) {
if (selection.isEmpty()) {
return false;
}
for (final Object object : selection.toList()) {
if (!(object instanceof ScriptItem) && !(object instanceof InstrumentItem)) {
return false;
}
}
return true;
}
private void doAddDroppedObjects(ScriptStrategy strategy, IAdaptable[] contents) {
boolean dirty = false;
List<ISecurity> instruments = new ArrayList<ISecurity>(Arrays.asList(strategy.getInstruments()));
List<IScript> scripts = new ArrayList<IScript>(Arrays.asList(strategy.getIncludes()));
for (int i = 0; i < contents.length; i++) {
ISecurity security = (ISecurity) contents[i].getAdapter(ISecurity.class);
if (security != null && !instruments.contains(security)) {
instruments.add(security);
dirty = true;
}
IScript script = (IScript) contents[i].getAdapter(IScript.class);
if (script != null && !scripts.contains(script)) {
scripts.add(script);
dirty = true;
}
}
if (dirty) {
strategy.setInstruments(instruments.toArray(new ISecurity[instruments.size()]));
strategy.setIncludes(scripts.toArray(new IScript[scripts.size()]));
final IAdaptable repositoryObject = strategy;
repositoryService.runInService(new IRepositoryRunnable() {
@Override
public IStatus run(IProgressMonitor monitor) throws Exception {
repositoryService.saveAdaptable(new IAdaptable[] {
repositoryObject
});
return Status.OK_STATUS;
}
}, null);
}
}
}