blob: c42aa8b925c57bc9903c6859186e5d169a22d3f6 [file] [log] [blame]
package org.eclipse.rmf.reqif10.search.ui;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.rmf.reqif10.SpecHierarchy;
import org.eclipse.rmf.reqif10.Specification;
import org.eclipse.rmf.reqif10.pror.editor.presentation.SpecificationEditor;
import org.eclipse.search.ui.ISearchResultViewPart;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
public class ResultNavigator implements IEditorActionDelegate, IExecutableExtension {
final static String NEXT_ID = "org.eclipse.rmf.reqif10.search.next";
final static String PREV_ID = "org.eclipse.rmf.reqif10.search.prev";
private Specification spec;
private SpecHierarchy selectedSpecHierarchy;
private SpecificationEditor editor;
@Override
public void run(IAction action) {
editor.setFocus();
SpecHierarchy match = null;
if (action.getId().equals(NEXT_ID)) {
match = next();
} else if (action.getId().equals(PREV_ID)) {
match = prev();
} else {
throw new IllegalStateException(action + "");
}
if (match != null) {
ISelection selection = new StructuredSelection(match);
editor.getSite().getSelectionProvider().setSelection(selection);
} else {
MessageDialog.openInformation(editor.getSite().getShell(),
"No more elements", "No more elements in this direction.");
}
}
@Override
public void selectionChanged(IAction action, ISelection selection) {
if (! (selection instanceof IStructuredSelection)) {
action.setEnabled(false);
return;
}
Object element = ((IStructuredSelection)selection).getFirstElement();
if (! (element instanceof SpecHierarchy)) {
action.setEnabled(false);
return;
}
action.setEnabled(specInSearchResult());
this.selectedSpecHierarchy = (SpecHierarchy) element;
}
@Override
public void setActiveEditor(IAction action, IEditorPart targetEditor) {
if (targetEditor instanceof SpecificationEditor) {
this.editor = (SpecificationEditor)targetEditor;
this.spec = ((SpecificationEditor)targetEditor).getSpecification();
} else {
this.spec = null;
this.editor = null;
}
}
private boolean specInSearchResult() {
for (SpecHierarchy sh : getMatchingSpecsHierarchies()) {
Specification s = getSpecForSpecHierarchy(sh);
if (s == spec) return true;
}
return false;
}
private Set<SpecHierarchy> getMatchingSpecsHierarchies() {
HashSet<SpecHierarchy> set = new HashSet<SpecHierarchy>();
ISearchResultViewPart view = NewSearchUI.getSearchResultView();
if (view != null && view.getActivePage() instanceof ReqIFSearchResultPage) {
ReqIFSearchResultPage page = (ReqIFSearchResultPage)view.getActivePage();
UsageSearchResult result = page.getSearchResult();
Collection<EObject> entries = result.getSearchEntries().get(spec.eResource());
if (entries == null) {
return set;
}
for (EObject entry: entries) {
if (entry instanceof SpecHierarchy) {
set.add((SpecHierarchy) entry);
}
}
}
return set;
}
private Specification getSpecForSpecHierarchy(SpecHierarchy entry) {
while (true) {
if (entry.eContainer() instanceof Specification) {
return (Specification) entry.eContainer();
} else if (entry.eContainer() instanceof SpecHierarchy) {
entry = (SpecHierarchy) entry.eContainer();
} else {
return null;
}
}
}
@Override
public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) throws CoreException {
// Not used, but interface implemented to ensure proper class loading.
}
private SpecHierarchy next() {
Set<SpecHierarchy> bag = getMatchingSpecsHierarchies();
SpecHierarchy next = oneDown(selectedSpecHierarchy);
while (next != null) {
if (bag.contains(next)) return next;
next = oneDown(next);
}
return null;
}
private SpecHierarchy oneDown(SpecHierarchy sh) {
// If there are children, go down the hierarchy.
if (sh.getChildren().size() > 0) {
return sh.getChildren().get(0);
}
EObject element = sh;
while (element instanceof SpecHierarchy) {
EObject container = element.eContainer();
int pos = getSpecHierarchies(container).indexOf(element);
if (pos < getSpecHierarchies(container).size() - 1) {
return (SpecHierarchy) getSpecHierarchies(container).get(pos +1);
} else {
element = container;
}
}
return null;
}
private SpecHierarchy prev() {
Set<SpecHierarchy> bag = getMatchingSpecsHierarchies();
SpecHierarchy next = oneUp(selectedSpecHierarchy);
while (next != null) {
if (bag.contains(next)) return next;
next = oneUp(next);
}
return null;
}
private SpecHierarchy oneUp(SpecHierarchy sh) {
EObject element = sh;
while (element instanceof SpecHierarchy) {
EObject container = element.eContainer();
if (! (container instanceof SpecHierarchy || container instanceof Specification)) {
return null;
}
int pos = getSpecHierarchies(container).indexOf(element);
if (pos > 0) {
sh = (SpecHierarchy) getSpecHierarchies(container).get(pos - 1);
while (sh.getChildren().size() > 0) {
sh = sh.getChildren().get(sh.getChildren().size() - 1);
}
return sh;
} else {
// Go one up, then as deep as possible
if (container instanceof SpecHierarchy) {
return (SpecHierarchy) container;
} else {
return null;
}
}
}
return null;
}
private EList<SpecHierarchy> getSpecHierarchies(EObject eObject) {
if (eObject instanceof SpecHierarchy) {
return ((SpecHierarchy)eObject).getChildren();
}
if (eObject instanceof Specification) {
return ((Specification)eObject).getChildren();
}
return null;
}
}