blob: 189c8559b6638e98451057f1fb44e9d8e2f52de7 [file] [log] [blame]
/*
* Copyright (c) 2015, 2016, 2019 Eike Stepper (Loehne, 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
*/
package org.eclipse.emf.cdo.explorer.ui.handlers;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.ui.ObjectListController;
import org.eclipse.emf.cdo.explorer.ui.bundle.OM;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;
import java.util.List;
/**
* @author Eike Stepper
*/
public class ObjectDeleteHandler extends AbstractObjectHandler
{
public ObjectDeleteHandler()
{
super(null);
}
@Override
protected void preRun(ExecutionEvent event) throws Exception
{
Shell shell = HandlerUtil.getActiveShell(event);
DeleteObjectsDialog dialog = new DeleteObjectsDialog(shell, getCheckout(), elements);
if (dialog.open() != DeleteObjectsDialog.OK)
{
cancel();
}
}
@Override
protected boolean doExecute(ExecutionEvent event, List<EObject> transactionalElements, IProgressMonitor monitor)
{
try
{
for (EObject eObject : transactionalElements)
{
EcoreUtil.remove(eObject);
}
}
catch (Throwable ex)
{
// TODO Exceptions due to deleting children of already deleted parents are expected, but hard to detect.
// It would be better to determine the set of top-most objects plus all their transitive children.
// This should happen in a ProgressRunnable before the DeleteObjectsDialog is even shown.
Shell shell = HandlerUtil.getActiveShell(event);
if (!shell.isDisposed())
{
shell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
try
{
if (!shell.isDisposed())
{
MessageDialog.openError(shell, "Error", ex.getMessage());
}
}
catch (Exception ex)
{
OM.LOG.error(ex);
}
}
});
}
return false;
}
return true;
}
/**
* @author Eike Stepper
*/
private static class DeleteObjectsDialog extends TitleAreaDialog
{
private final CDOCheckout checkout;
private final List<EObject> objects;
public DeleteObjectsDialog(Shell parentShell, CDOCheckout checkout, List<EObject> objects)
{
super(parentShell);
this.checkout = checkout;
this.objects = objects;
setShellStyle(SWT.CLOSE | SWT.RESIZE | SWT.TITLE | SWT.APPLICATION_MODAL);
}
@Override
protected Control createDialogArea(Composite parent)
{
Composite area = (Composite)super.createDialogArea(parent);
int size = objects.size();
if (size != 0)
{
String title = "Delete " + (size == 1 ? "Object" : "Objects");
getShell().setText(title);
setTitle(title);
setTitleImage(OM.getImage("icons/wiz/delete.gif"));
updateMessage(size);
Composite container = new Composite(area, SWT.NONE);
container.setLayoutData(new GridData(GridData.FILL_BOTH));
GridLayout containerGridLayout = new GridLayout();
containerGridLayout.marginWidth = 10;
containerGridLayout.marginHeight = 10;
container.setLayout(containerGridLayout);
final ObjectListController objectListController = new ObjectListController(checkout);
for (EObject object : objects)
{
objectListController.addObject(object, true);
}
final CheckboxTreeViewer treeViewer = new CheckboxTreeViewer(container);
treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
objectListController.configure(treeViewer);
treeViewer.addCheckStateListener(new ICheckStateListener()
{
@Override
public void checkStateChanged(CheckStateChangedEvent event)
{
EObject object = objectListController.getObject(event.getElement());
if (event.getChecked())
{
objects.add(object);
}
else
{
objects.remove(object);
}
int size = objects.size();
updateMessage(size);
if (size <= 1)
{
Button button = getButton(OK);
button.setEnabled(size != 0);
}
}
});
}
return area;
}
@Override
protected Point getInitialSize()
{
return new Point(500, 400);
}
private void updateMessage(int size)
{
if (size == 0)
{
setMessage("No objects to delete.");
}
else
{
setMessage("Are you sure you want to delete " + (size == 1 ? "this" : "these") + " " + size + " " + (size == 1 ? "object" : "objects") + "?");
}
}
}
}