blob: 3e7045494385dcb7bd36aa2b8bc888accd2098df [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.search2.internal.ui.basic.views;
import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
public class TreeViewerNavigator implements INavigate {
private TreeViewer fViewer;
private AbstractTextSearchViewPage fPage;
public TreeViewerNavigator(AbstractTextSearchViewPage page, TreeViewer viewer) {
fViewer= viewer;
fPage= page;
}
public void navigateNext(boolean forward) {
TreeItem currentItem= getCurrentItem(forward);
if (currentItem == null)
return;
TreeItem nextItem= null;
if (forward) {
nextItem= getNextItemForward(currentItem);
if (nextItem == null)
nextItem= getFirstItem();
} else {
nextItem= getNextItemBackward(currentItem);
if (nextItem == null)
nextItem= getLastItem();
}
if (nextItem != null) {
internalSetSelection(nextItem);
}
}
private TreeItem getFirstItem() {
TreeItem[] roots= fViewer.getTree().getItems();
if (roots.length == 0)
return null;
for (int i = 0; i < roots.length; i++) {
if (hasMatches(roots[i]))
return roots[i];
TreeItem firstChild= getFirstChildWithMatches(roots[0]);
if (firstChild != null)
return firstChild;
}
return null;
}
private TreeItem getLastItem() {
TreeItem[] roots= fViewer.getTree().getItems();
if (roots.length == 0)
return null;
return getLastChildWithMatches(roots[roots.length-1]);
}
private TreeItem getNextItemBackward(TreeItem currentItem) {
TreeItem previousSibling= getNextSibling(currentItem, false);
if (previousSibling != null) {
TreeItem lastChild= getLastChildWithMatches(previousSibling);
if (lastChild != null)
return lastChild;
if (hasMatches(previousSibling))
return previousSibling;
return null;
}
TreeItem parent= currentItem.getParentItem();
if (parent != null) {
if (hasMatches(parent))
return parent;
return getNextItemBackward(parent);
}
return null;
}
private TreeItem getLastChildWithMatches(TreeItem currentItem) {
TreeItem[] children= getChildren(currentItem);
if (children.length == 0)
return null;
TreeItem recursiveChild= getLastChildWithMatches(children[children.length-1]);
if (recursiveChild == null)
return children[children.length-1];
return recursiveChild;
}
private TreeItem getNextItemForward(TreeItem currentItem) {
TreeItem child= getFirstChildWithMatches(currentItem);
if (child != null)
return child;
TreeItem nextSibling= getNextSibling(currentItem, true);
if (nextSibling != null) {
if (hasMatches(nextSibling))
return nextSibling;
return getFirstChildWithMatches(nextSibling);
}
TreeItem parent= currentItem.getParentItem();
while (parent != null) {
nextSibling= getNextSibling(parent, true);
if (nextSibling != null) {
if (hasMatches(nextSibling))
return nextSibling;
return getFirstChildWithMatches(nextSibling);
}
parent= parent.getParentItem();
}
return null;
}
private TreeItem getFirstChildWithMatches(TreeItem item) {
TreeItem[] children= getChildren(item);
if (children.length == 0)
return null;
TreeItem child= children[0];
if (hasMatches(child))
return child;
return getFirstChildWithMatches(child);
}
private TreeItem[] getChildren(TreeItem item) {
fViewer.setExpandedState(item.getData(), true);
return item.getItems();
}
private TreeItem getNextSibling(TreeItem currentItem, boolean forward) {
TreeItem[] siblings= getSiblings(currentItem);
if (siblings.length < 2)
return null;
int index= -1;
for (int i= 0; i <siblings.length; i++) {
if (siblings[i] == currentItem) {
index= i;
break;
}
}
if (forward && index == siblings.length-1) {
return null;
} else if (!forward && index == 0) {
return null;
}
return forward?siblings[index+1]:siblings[index-1];
}
private TreeItem[] getSiblings(TreeItem currentItem) {
Tree tree= fViewer.getTree();
TreeItem parentItem= currentItem.getParentItem();
if (parentItem != null)
return parentItem.getItems();
return tree.getItems();
}
private boolean hasMatches(TreeItem item) {
Object element= item.getData();
if (element == null)
return false;
return fPage.getDisplayedMatchCount(element) > 0;
}
private TreeItem getCurrentItem(boolean forward) {
Tree tree= fViewer.getTree();
TreeItem[] selection= tree.getSelection();
if (selection.length == 0) {
selection= tree.getItems();
}
TreeItem nextItem= null;
if (selection.length > 0) {
nextItem= forward?selection[0]:selection[selection.length-1];
}
return nextItem;
}
private void internalSetSelection(TreeItem ti) {
if (ti != null) {
Object data= ti.getData();
if (data != null) {
ISelection selection= new StructuredSelection(data);
fViewer.setSelection(selection, true);
}
}
}
}