blob: 0020ece4d17db27dcde4fb2968cdd60e2f02bcbf [file] [log] [blame]
/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.tools.search2.internal.ui.basic.views;
import com.google.dart.tools.search.ui.text.AbstractTextSearchViewPage;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
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);
}
}
}
}