/* * 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); } } } }