//
// This file is part of the Prose Development Tools for Eclipse package.
//
// The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Prose Development Tools for Eclipse.
//
// The Initial Developer of the Original Code is Angela Nicoara. Portions
// created by Angela Nicoara are Copyright (C) 2006 Angela Nicoara.
// All Rights Reserved.
//
// Contributor(s):
// $Id: ProseRunView.java,v 1.1 2008/11/18 12:23:02 anicoara Exp $
// ==============================================================================
//
package ch.ethz.prose.eclipse.internal.run;
import java.util.ArrayList;
import org.eclipse.jface.action.Action;
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.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
import ch.ethz.prose.eclipse.internal.core.ProsePlugin;
import ch.ethz.prose.eclipse.internal.run.dnd.RunNodeDragAdapter;
import ch.ethz.prose.eclipse.internal.run.dnd.RunNodeDropAdapter;
/**
* View which displays Prose applications.
*
* @author Angela Nicoara
* @author Johann Gyger
* @version $Id: ProseRunView.java,v 1.1 2008/11/18 12:23:02 anicoara Exp $
*/
public class ProseRunView extends ViewPart {
/**
* Tree viewer containing the prose runs.
*/
protected TreeViewer viewer;
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
Tree tree = new Tree(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
viewer = new TreeViewer(tree);
viewer.setLabelProvider(new ProseRunLabelProvider());
viewer.setContentProvider(new ProseRunContentProvider());
viewer.setInput(new ArrayList());
createContextMenu();
initDragAndDrop();
IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager();
configureToolBar(tbm);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
public void setFocus() {
viewer.getControl().setFocus();
}
/**
* @return Tree viewer containing the prose runs
*/
public TreeViewer getTreeViewer() {
return viewer;
}
/**
* Drag and drop support for this view.
*/
protected void initDragAndDrop() {
// Drag support
int ops = DND.DROP_COPY | DND.DROP_MOVE;
Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getInstance() };
viewer.addDragSupport(ops, transfers, new RunNodeDragAdapter(viewer));
// Drop support
ops = DND.DROP_COPY | DND.DROP_MOVE;
viewer.addDropSupport(ops, transfers, new RunNodeDropAdapter(viewer));
}
/**
* Create the context menu for this view.
*/
protected void createContextMenu() {
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
fillContextMenu(manager);
}
});
Control control = viewer.getControl();
Menu menu = menuMgr.createContextMenu(control);
control.setMenu(menu);
getSite().registerContextMenu(menuMgr, getSite().getSelectionProvider());
}
/**
* Fill context menu depending on selected item. Invoked when the menu is
* about to be shown.
*
* @param menu Menu manager
*/
protected void fillContextMenu(IMenuManager menu) {
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
IRunNode node = (IRunNode) selection.getFirstElement();
if (node instanceof AspectNode) {
menu.add(new WithdrawAspectAction((AspectNode) node));
} else if (node instanceof AspectManagerNode) {
menu.add(new StartTransactionAction((AspectManagerNode) node));
menu.add(new CommitTransactionAction((AspectManagerNode) node));
menu.add(new AbortTransactionAction((AspectManagerNode) node));
}
menu.add(new Separator("ProseRun"));
menu.add(new AddProseRunAction());
menu.add(new RemoveProseRunAction(node));
menu.add(new RemoveAllUnreachableAction());
menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS + "-end"));
menu.add(new Separator("Refresh"));
menu.add(new RefreshAction(node));
}
/**
* Configure the tool bar of this view.
*
* @param mgr Tool bar manager
*/
protected void configureToolBar(IToolBarManager mgr) {
mgr.add(new RemoveAllUnreachableAction());
}
protected class WithdrawAspectAction extends Action {
protected AspectNode aspectNode;
protected WithdrawAspectAction(AspectNode node) {
aspectNode = node;
setText("Withdraw Aspect");
}
public void run() {
try {
aspectNode.withdraw();
} catch (UnreachableException e) {
ProsePlugin.log(e);
ProsePlugin.openErrorDialog("Aspect withdrawal failed",
"Could not withdraw aspect because the Prose application is not reachable.");
}
}
}
protected class RefreshAction extends Action {
protected ProseRunNode run;
protected RefreshAction(IRunNode node) {
if (node == null) {
setEnabled(false);
} else {
this.run = (ProseRunNode) node.getRoot();
setEnabled(run.isReachable());
}
setText("Refresh");
setImageDescriptor(ProsePlugin.getDefault().createImageDescriptor("icons/refresh.gif"));
}
public void run() {
Control ctrl = viewer.getControl();
if (ctrl == null || ctrl.isDisposed()) return;
ctrl.getDisplay().syncExec(new Runnable() {
public void run() {
if (!viewer.getControl().isDisposed()) {
viewer.refresh(run);
}
}
});
}
}
protected class RemoveProseRunAction extends Action {
protected ProseRunNode run;
protected RemoveProseRunAction(IRunNode node) {
if (node == null)
setEnabled(false);
else
this.run = (ProseRunNode) node.getRoot();
setText("Remove Prose Application");
setImageDescriptor(ProsePlugin.getDefault().createImageDescriptor("icons/remove.gif"));
}
public void run() {
Control ctrl = viewer.getControl();
if (ctrl == null || ctrl.isDisposed()) return;
ctrl.getDisplay().syncExec(new Runnable() {
public void run() {
ProsePlugin.getDefault().removeRun(run);
}
});
}
}
protected class RemoveAllUnreachableAction extends Action {
protected RemoveAllUnreachableAction() {
setToolTipText("Remove all unreachable Prose applications.");
setText("Remove All Unreachable");
setImageDescriptor(ProsePlugin.getDefault().createImageDescriptor("icons/remove_all.gif"));
}
public void run() {
Control ctrl = viewer.getControl();
if (ctrl == null || ctrl.isDisposed()) return;
ctrl.getDisplay().syncExec(new Runnable() {
public void run() {
Object[] runs = ProsePlugin.getDefault().getRuns();
for (int i = 0; i < runs.length; i++) {
ProseRunNode run = (ProseRunNode) runs[i];
if (!run.isReachable()) ProsePlugin.getDefault().removeRun((ProseRunNode) runs[i]);
}
}
});
}
}
protected class AddProseRunAction extends Action {
protected AddProseRunAction() {
setText("Add Prose Application...");
}
public void run() {
AddProseRunDialog dialog = new AddProseRunDialog(ProsePlugin.getShell());
dialog.open();
}
}
protected class StartTransactionAction extends Action {
protected AspectManagerNode aspectManager;
protected StartTransactionAction(AspectManagerNode aspectManager) {
this.aspectManager = aspectManager;
setEnabled(aspectManager.getTransactionId() == null);
setText("Start Transaction");
}
public void run() {
aspectManager.startTransaction();
}
}
protected class CommitTransactionAction extends Action {
protected AspectManagerNode aspectManager;
protected CommitTransactionAction(AspectManagerNode aspectManager) {
this.aspectManager = aspectManager;
setEnabled(aspectManager.getTransactionId() != null);
setText("Commit Transaction");
}
public void run() {
try {
aspectManager.commitTransaction();
Control ctrl = viewer.getControl();
if (ctrl == null || ctrl.isDisposed()) return;
ctrl.getDisplay().syncExec(new Runnable() {
public void run() {
if (!viewer.getControl().isDisposed()) {
viewer.refresh(aspectManager);
}
}
});
} catch (UnreachableException e) {
ProsePlugin.openErrorDialog("Commit failed", "Could not commit because the Prose application is not reachable.");
}
}
}
protected class AbortTransactionAction extends Action {
protected AspectManagerNode aspectManager;
protected AbortTransactionAction(AspectManagerNode aspectManager) {
this.aspectManager = aspectManager;
setEnabled(aspectManager.getTransactionId() != null);
setText("Abort Transaction");
}
public void run() {
try {
aspectManager.abortTransaction();
Control ctrl = viewer.getControl();
if (ctrl == null || ctrl.isDisposed()) return;
ctrl.getDisplay().syncExec(new Runnable() {
public void run() {
if (!viewer.getControl().isDisposed()) {
viewer.refresh(aspectManager);
}
}
});
} catch (UnreachableException e) {
ProsePlugin.openErrorDialog("Abort failed", "Could not commit because the Prose application is not reachable.");
}
}
}
}