/*******************************************************************************
* MontiCore Language Workbench
* Copyright (c) 2015, 2016, MontiCore, All rights reserved.
*
* This project 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.0 of the License, or (at your option) any later version.
* This library 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 this project. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package de.monticore.genericgraphics.controller.selection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.SelectionManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
/**
* <p>
* A selection manager that only selects parent figures and not its children.
* </p>
* Example:<br>
* User selects a class of a class diagram which has several child figures.
* Independent of which child figure the user clicked on only the parent, the
* outermost figure, is selected only.
*
* @author Tim Enger
*/
public class OnlyParentSelectionManager extends SelectionManager {
private final GraphicalViewer viewer;
/**
* Constructor
*
* @param viewer
*/
public OnlyParentSelectionManager(GraphicalViewer viewer) {
this.viewer = viewer;
}
@Override
public void setSelection(ISelection selection) {
// build a collection of originally selection parts
List<?> oldSelection = ((IStructuredSelection) selection).toList();
// and a collection from which nested parts are removed
List<Object> newSelection = new ArrayList<Object>(oldSelection);
// cycle through all selected parts and remove nested parts
// which have a parent or grandparent part that is selected
Iterator<Object> iter = newSelection.iterator();
while (iter.hasNext()) {
if (containsAncestor(newSelection, (EditPart) iter.next())) {
iter.remove();
}
}
// pass the new selection to the superclass implementation
// to perform the actual selection
super.setSelection(new StructuredSelection(newSelection));
}
// don't select inner children
// e.g. don't select every attribute, when the class is already selected
@Override
public void appendSelection(EditPart editpart) {
List<?> selection = ((IStructuredSelection) getSelection()).toList();
// if "nothing" is selected then getSelection() returns
// the viewer's primary edit part in which case the
// specified part should be selected
if (selection.size() == 1 && selection.get(0) == viewer.getContents()) {
super.appendSelection(editpart);
return;
}
// if the selection already contains an ancestor
// of the specified part then don't selection the part
if (containsAncestor(selection, editpart)) {
return;
}
// deselect any currently selection parts
// which have the new part as an ancestor
Iterator<?> iter = new ArrayList<Object>(selection).iterator();
while (iter.hasNext()) {
EditPart each = (EditPart) iter.next();
if (isAncestor(editpart, each)) {
deselect(each);
}
}
// call the supercalls implementation to select the part
super.appendSelection(editpart);
}
private boolean isAncestor(EditPart ancestor, EditPart part) {
while (part != null) {
part = part.getParent();
if (part == ancestor) {
return true;
}
}
return false;
}
private boolean containsAncestor(List<?> list, EditPart part) {
while (part != null) {
part = part.getParent();
if (list.contains(part)) {
return true;
}
}
return false;
}
}