001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.javaeditor.selectionactions;
011:
012: import org.eclipse.jdt.core.ISourceRange;
013: import org.eclipse.jdt.core.ISourceReference;
014: import org.eclipse.jdt.core.JavaModelException;
015: import org.eclipse.jdt.core.dom.ASTNode;
016:
017: import org.eclipse.ui.PlatformUI;
018:
019: import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
020: import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
021:
022: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
023: import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
024:
025: public class StructureSelectNextAction extends StructureSelectionAction {
026:
027: private static class NextNodeAnalyzer extends GenericVisitor {
028: private final int fOffset;
029: private ASTNode fNextNode;
030:
031: private NextNodeAnalyzer(int offset) {
032: super (true);
033: fOffset = offset;
034: }
035:
036: public static ASTNode perform(int offset,
037: ASTNode lastCoveringNode) {
038: NextNodeAnalyzer analyzer = new NextNodeAnalyzer(offset);
039: lastCoveringNode.accept(analyzer);
040: return analyzer.fNextNode;
041: }
042:
043: protected boolean visitNode(ASTNode node) {
044: int start = node.getStartPosition();
045: int end = start + node.getLength();
046: if (start == fOffset) {
047: fNextNode = node;
048: return true;
049: } else {
050: return (start < fOffset && fOffset < end);
051: }
052: }
053: }
054:
055: public StructureSelectNextAction(JavaEditor editor,
056: SelectionHistory history) {
057: super (SelectionActionMessages.StructureSelectNext_label,
058: editor, history);
059: setToolTipText(SelectionActionMessages.StructureSelectNext_tooltip);
060: setDescription(SelectionActionMessages.StructureSelectNext_description);
061: PlatformUI.getWorkbench().getHelpSystem().setHelp(this ,
062: IJavaHelpContextIds.STRUCTURED_SELECT_NEXT_ACTION);
063: }
064:
065: /*
066: * This constructor is for testing purpose only.
067: */
068: public StructureSelectNextAction() {
069: }
070:
071: /* non java doc
072: * @see StructureSelectionAction#internalGetNewSelectionRange(ISourceRange, ICompilationUnit, SelectionAnalyzer)
073: */
074: ISourceRange internalGetNewSelectionRange(
075: ISourceRange oldSourceRange, ISourceReference sr,
076: SelectionAnalyzer selAnalyzer) throws JavaModelException {
077: if (oldSourceRange.getLength() == 0
078: && selAnalyzer.getLastCoveringNode() != null) {
079: ASTNode previousNode = NextNodeAnalyzer.perform(
080: oldSourceRange.getOffset(), selAnalyzer
081: .getLastCoveringNode());
082: if (previousNode != null)
083: return getSelectedNodeSourceRange(sr, previousNode);
084: }
085: ASTNode first = selAnalyzer.getFirstSelectedNode();
086: if (first == null)
087: return getLastCoveringNodeRange(oldSourceRange, sr,
088: selAnalyzer);
089:
090: ASTNode parent = first.getParent();
091: if (parent == null)
092: return getLastCoveringNodeRange(oldSourceRange, sr,
093: selAnalyzer);
094:
095: ASTNode lastSelectedNode = selAnalyzer.getSelectedNodes()[selAnalyzer
096: .getSelectedNodes().length - 1];
097: ASTNode nextNode = getNextNode(parent, lastSelectedNode);
098: if (nextNode == parent)
099: return getSelectedNodeSourceRange(sr, first.getParent());
100: int offset = oldSourceRange.getOffset();
101: int end = Math.min(sr.getSourceRange().getLength(), nextNode
102: .getStartPosition()
103: + nextNode.getLength() - 1);
104: return StructureSelectionAction.createSourceRange(offset, end);
105: }
106:
107: private static ASTNode getNextNode(ASTNode parent, ASTNode node) {
108: ASTNode[] siblingNodes = StructureSelectionAction
109: .getSiblingNodes(node);
110: if (siblingNodes == null || siblingNodes.length == 0)
111: return parent;
112: if (node == siblingNodes[siblingNodes.length - 1])
113: return parent;
114: else
115: return siblingNodes[StructureSelectionAction.findIndex(
116: siblingNodes, node) + 1];
117: }
118: }
|