diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/GoToNextPreviousMemberAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/GoToNextPreviousMemberAction.java index 6775facb559..6c931267ed9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/GoToNextPreviousMemberAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/GoToNextPreviousMemberAction.java @@ -8,12 +8,11 @@ * Contributors: * P.Tomaszewski * Anton Leherbauer (Wind River Systems) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.actions; -import java.util.LinkedList; -import java.util.List; import java.util.ResourceBundle; import org.eclipse.jface.text.ITextSelection; @@ -23,6 +22,8 @@ import org.eclipse.ui.texteditor.TextEditorAction; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IParent; +import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.ui.CUIPlugin; @@ -89,91 +90,64 @@ public class GoToNextPreviousMemberAction extends TextEditorAction { return; } try { - final ICElement[] elements = workingCopy.getChildren(); - final Integer[] elementOffsets = createSourceIndexes(elements); - final ICElement selectedElement = workingCopy.getElementAtOffset(selection.getOffset()); - if (selectedElement != null && selectedElement instanceof ISourceReference) { - final int offset = ((ISourceReference) selectedElement).getSourceRange().getStartPos(); - final int offsetToSelect = fGotoNext ? getNextOffset(elementOffsets, offset) : getPreviousOffset(elementOffsets, offset); - editor.selectAndReveal(offsetToSelect, 0); - } else if (selectedElement == null) { - final int offset = selection.getOffset(); - final int offsetToSelect = fGotoNext ? getNextOffset(elementOffsets, offset) : getPreviousOffset(elementOffsets, offset); - editor.selectAndReveal(offsetToSelect, 0); - } else { - //System.out.println("Selected element class:" + selectedElement.getClass()); //$NON-NLS-1$ - } + ISourceReference next= fGotoNext ? + getNextElement(workingCopy, selection.getOffset()) : + getPrevElement(workingCopy, selection.getOffset()); + if (next != null) { + editor.selectAndReveal(next.getSourceRange().getIdStartPos(), 0); + } } catch (CModelException e) { CUIPlugin.getDefault().log(e); - //System.out.println("Exception:" + e.getMessage()); //$NON-NLS-1$ } } - /** - * Searches for next offset within array of offsets. - * @param offsets Offsets to search. - * @param actualOffset Actual offsets. - * @return Found offset or actual. - */ - private static int getNextOffset(Integer[] offsets, int actualOffset) { - if (offsets.length > 0) { - if (actualOffset < offsets[0].intValue()) - { - return offsets[0].intValue(); - } - } - for (int i = 0; i < offsets.length - 1; i++) { - if (offsets[i].intValue() == actualOffset) { - return offsets[i + 1].intValue(); - } else if ((actualOffset > offsets[i].intValue()) - && (actualOffset < offsets[i + 1].intValue())) { - return offsets[i + 1].intValue(); - } - } - return actualOffset; - } + private ISourceReference getNextElement(IParent parent, int offset) throws CModelException { + ICElement[] children= parent.getChildren(); + for (int i = 0; i < children.length; i++) { + ICElement element = children[i]; + if (element instanceof ISourceReference) { + final ISourceReference candidate1= (ISourceReference) element; + final ISourceRange range= candidate1.getSourceRange(); + final int idpos1= range.getIdStartPos(); + if (element instanceof IParent && range.getStartPos() + range.getLength() > offset) { + ISourceReference candidate2= getNextElement((IParent) element, offset); + if (candidate2 != null) { + final int idpos2= candidate2.getSourceRange().getIdStartPos(); + if (idpos1 <= offset || idpos1 > idpos2) { + return candidate2; + } + } + } + if (idpos1 > offset) { + return candidate1; + } + } + } + return null; + } - /** - * Searches for previous offset within array of offsets. - * @param offsets Offsets to search. - * @param actualOffset Actual offset. - * @return Found offset or actual. - */ - private static int getPreviousOffset(Integer[] offsets, int actualOffset) { - if (offsets.length > 0) { - if (actualOffset > offsets[offsets.length - 1].intValue()) - { - return offsets[offsets.length - 1].intValue(); - } - } - for (int i = 1; i < offsets.length; i++) { - if (offsets[i].intValue() == actualOffset) { - return offsets[i - 1].intValue(); - } else if ((actualOffset > offsets[i - 1].intValue()) - && (actualOffset < offsets[i].intValue())) { - return offsets[i - 1].intValue(); - } - } - return actualOffset; - } - - /** - * Creates array in indexes from ICElements. - * @param elements Elements to retrieve needed data. - * @return indexes. - * @throws CModelException Thrown if source range not found. - */ - private static Integer[] createSourceIndexes(ICElement[] elements) throws CModelException - { - final List indexesList = new LinkedList(); - for (int i = 0; i < elements.length; i++) { - if (elements[i] instanceof ISourceReference) { - indexesList.add(new Integer(((ISourceReference) elements[i]).getSourceRange().getStartPos())); - } - } - //System.out.println("Indexes list:" + indexesList); //$NON-NLS-1$ - final Integer[] indexes = new Integer[indexesList.size()]; - indexesList.toArray(indexes); - return indexes; - } + private ISourceReference getPrevElement(IParent parent, int offset) throws CModelException { + ICElement[] children= parent.getChildren(); + for (int i= children.length-1; i >= 0; i--) { + ICElement element = children[i]; + if (element instanceof ISourceReference) { + final ISourceReference candidate1= (ISourceReference) element; + final ISourceRange range= candidate1.getSourceRange(); + final int idpos1= range.getIdStartPos(); + if (element instanceof IParent && range.getStartPos() < offset) { + ISourceReference candidate2= getPrevElement((IParent) element, offset); + if (candidate2 != null) { + final int idpos2= candidate2.getSourceRange().getIdStartPos(); + if (idpos1 >= offset || idpos1 < idpos2) { + return candidate2; + } + } + } + if (idpos1 < offset) { + return candidate1; + } + } + } + return null; + } }