/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.modeling.ui.modelBrowser.handlers; import java.lang.reflect.InvocationTargetException; import java.util.Set; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.handlers.HandlerUtil; import org.simantics.browsing.ui.NodeContext; import org.simantics.browsing.ui.common.node.DeleteException; import org.simantics.browsing.ui.common.node.IDeletable; import org.simantics.browsing.ui.common.node.IDeletableNode; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.exception.CannotRemoveException; import org.simantics.db.layer0.util.RemoverUtil; import org.simantics.modeling.ui.Activator; import org.simantics.modeling.ui.modelBrowser.model.INode; import org.simantics.modeling.ui.modelBrowser.model.INode2; import org.simantics.ui.SimanticsUI; import org.simantics.utils.logging.TimeLogger; import org.simantics.utils.ui.ErrorLogger; import org.simantics.utils.ui.ISelectionUtils; import org.simantics.utils.ui.dialogs.ShowMessage; /** * @author Tuukka Lehtonen */ public class DeleteNodeHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { TimeLogger.resetTimeAndLog(getClass(), "execute"); Shell shell = HandlerUtil.getActiveShellChecked(event); ISelection sel = HandlerUtil.getCurrentSelection(event); Set ctxs = ISelectionUtils.filterSetSelection(sel, NodeContext.class); if (ctxs.isEmpty()) return null; if (ctxs.size() == 1 && handleLegacyDelete(ctxs.iterator().next())) { return null; } // If all selected nodes are IDeletableNodes, delete them. final Set deletableNodes = ISelectionUtils.filterSetSelection(ctxs, IDeletableNode.class); if (!deletableNodes.isEmpty()) { // Only delete if all selected nodes are IDeletableNodes if (deletableNodes.size() == ctxs.size()) { inJob(shell, new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("Delete selected nodes", IProgressMonitor.UNKNOWN); try { for (IDeletableNode deletableNode : deletableNodes) { deletableNode.delete(); } } catch (DeleteException e) { throw new InvocationTargetException(e); } } }); } } else { final Set rs = ISelectionUtils.filterSetSelection(ctxs, Resource.class); if (rs.size() == ctxs.size()) { inJob(shell, new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("Delete selected nodes", IProgressMonitor.UNKNOWN); try { RemoverUtil.tryCollectionRemover(rs); } catch (CannotRemoveException e) { ShowMessage.showInformation("Delete Selection Was Denied", e.getLocalizedMessage()); } catch (DatabaseException e) { throw new InvocationTargetException(e); } } }); } } TimeLogger.log("Node deleted"); return null; } private void inJob(Shell shell, final IRunnableWithProgress runnable) { ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell); try { dialog.run(true, false, runnable); } catch (InvocationTargetException e) { Activator.getDefault().getLog().log( new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Delete failed, see exception for details.", e.getCause()) ); } catch (InterruptedException e) { Activator.getDefault().getLog().log( new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Delete failed, see exception for details.", e.getCause()) ); } // Job job = new Job("Delete selection") { // @Override // protected IStatus run(IProgressMonitor monitor) { // monitor.beginTask("Delete selected nodes", IProgressMonitor.UNKNOWN); // try { // runnable.run(monitor); // return Status.OK_STATUS; // } catch (InvocationTargetException e) { // return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Delete failed, see exception for details.", e.getCause()); // } catch (Exception e) { // return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Delete failed, see exception for details.", e); // } finally { // monitor.done(); // } // } // }; // job.setUser(true); // job.setRule(new ObjectIdentitySchedulingRule(schedulingObject)); // job.schedule(); } /** * @param ctx * @return */ private boolean handleLegacyDelete(NodeContext ctx) { if (ctx.getAdapter(IDeletable.class) == null) { return false; } final INode node = (INode) ctx.getAdapter(INode.class); if (node != null) { SimanticsUI.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { node.handleDelete(graph); } }); return true; } INode2 node2 = (INode2) ctx.getAdapter(INode2.class); if (node2 != null) { try { node2.handleDelete(); } catch (DeleteException e) { ShowMessage.showError("Delete failed", e.getMessage()); ErrorLogger.defaultLogError(e); } return true; } // Could not handle with legacy logic. return false; } }