/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.ui.viewers;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.gef.LightweightEditDomain;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
/**
* @author Enrico Persiani
*/
public class EntityEditDomain extends LightweightEditDomain implements ISchedulingRule {
@Override
public void addViewer(EditPartViewer viewer) {
boolean isFirstViewer = getViewers().isEmpty();
super.addViewer(viewer);
// configures a new command stack
if (isFirstViewer)
setCommandStack(new HistoryCommandStack((IEntityPartViewer) viewer));
// disables system specific drag detect strategy
if (viewer.getControl() != null)
viewer.getControl().setDragDetect(false);
}
@Override
public void mouseDrag(MouseEvent mouseEvent, EditPartViewer viewer) {
// performs whole specific drag detect strategy
if (isDragDetect(mouseEvent, viewer)) {
abortDragTracker(viewer);
mouseEvent.button = 1;
mouseEvent.count = 1;
viewer.getControl().dragDetect(mouseEvent);
} else
super.mouseDrag(mouseEvent, viewer);
}
protected boolean isDragDetect(MouseEvent mouseEvent, EditPartViewer viewer) {
//FIXME workaround for MacOS X ?
if (!(viewer.getControl() instanceof FigureCanvas))
return false;
FigureCanvas figureCanvas = (FigureCanvas) viewer.getControl();
if (!figureCanvas.getClientArea().contains(mouseEvent.x, mouseEvent.y))
return true;
Shell canvasShell = figureCanvas.getShell();
Set<Shell> canvasShellDescendants = new HashSet<>(Arrays.asList(canvasShell.getShells()));
Point absolutePoint = figureCanvas.toDisplay(mouseEvent.x, mouseEvent.y);
for (Shell shell : figureCanvas.getDisplay().getShells()) {
if (shell == canvasShell || !shell.isVisible() || !canvasShellDescendants.contains(shell))
continue;
if (shell.getBounds().contains(absolutePoint))
return true;
}
return false;
}
protected void abortDragTracker(EditPartViewer viewer) {
// hack: send a synthetic ESC key-press to interrupt GEF drag
Event event = new Event();
event.display = viewer.getControl().getDisplay();
event.widget = viewer.getControl();
event.character = 27;
event.keyCode = SWT.ESC;
event.stateMask = SWT.NONE;
event.doit = true;
getActiveTool().keyDown(new KeyEvent(event),viewer);
}
@Override
public boolean contains(ISchedulingRule rule) {
if (rule instanceof MultiRule) {
for (ISchedulingRule childRule : ((MultiRule) rule).getChildren())
if (!contains(childRule))
return false;
return true;
} else
return this == rule || rule instanceof IResource;
}
@Override
public boolean isConflicting(ISchedulingRule rule) {
return contains(rule);
}
}