/******************************************************************************* * Copyright (c) 2010 Tomasz Wesolowski and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Tomasz Wesolowski - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.ui.actions; import java.util.ResourceBundle; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.ITextSelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.TextEditorAction; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.ui.CDTUITools; import org.eclipse.cdt.ui.text.SharedASTJob; import org.eclipse.cdt.internal.core.model.ext.SourceRange; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.SelectionHistory; public abstract class StructureSelectionAction extends TextEditorAction { protected final SelectionHistory history; protected StructureSelectionAction(ResourceBundle bundle, String prefix, ITextEditor editor, SelectionHistory history) { super(bundle, prefix, editor); this.history = history; } private final class ExpandSelectionJob extends SharedASTJob { public ISourceRange newSourceRange; private SourceRange currentSourceRange; private ExpandSelectionJob(String name, ITranslationUnit tUnit, CEditor cEditor, SourceRange range) { super(name, tUnit); currentSourceRange = range; newSourceRange = null; } @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException { newSourceRange = doExpand(ast,currentSourceRange); return Status.OK_STATUS; } } public static final String ENCLOSING = "StructureSelectEnclosing"; //$NON-NLS-1$ public static final String NEXT = "StructureSelectNext"; //$NON-NLS-1$ public static final String PREVIOUS = "StructureSelectPrevious"; //$NON-NLS-1$ public static final String HISTORY = "StructureSelectHistory"; //$NON-NLS-1$ @Override public void run() { IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); if (!(editorPart instanceof CEditor)) { return; } final CEditor cEditor = (CEditor) editorPart; ITranslationUnit tu = (ITranslationUnit) CDTUITools.getEditorInputCElement(cEditor.getEditorInput()); ITextSelection selection; try { selection = (ITextSelection) cEditor.getSelectionProvider().getSelection(); } catch (ClassCastException e) { return; } final int offset = selection.getOffset(); final int length = selection.getLength(); ExpandSelectionJob expandSelectionJob = new ExpandSelectionJob("expand selection", tu, cEditor, new SourceRange(offset, length)); //$NON-NLS-1$ expandSelectionJob.schedule(); try { expandSelectionJob.join(); } catch (InterruptedException e) { return; } if (expandSelectionJob.newSourceRange != null) { history.ignoreSelectionChanges(); cEditor.setSelection(expandSelectionJob.newSourceRange, true); history.listenToSelectionChanges(); } } protected abstract ISourceRange doExpand(IASTTranslationUnit ast, SourceRange currentSourceRange); protected boolean nodeContains(IASTNode node, int position) { IASTFileLocation fl = node.getFileLocation(); return position >= fl.getNodeOffset() && position <= fl.getNodeOffset() + fl.getNodeLength(); } protected boolean samePosition(IASTNode node, SourceRange current) { IASTFileLocation fl = node.getFileLocation(); return fl.getNodeOffset() == current.getStartPos() && fl.getNodeLength() == current.getLength(); } }