/******************************************************************************* * Copyright (c) 2013 Ericsson AB 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: * Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup; import org.eclipse.cdt.core.model.IFunctionDeclaration; import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.SelectionToDeclarationJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.texteditor.ITextEditor; public class DsfSourceSelectionResolver implements Runnable { private ITextEditor fEditorPage = null; private ITextSelection fSelection = null; private LineLocation fLineLocation = new LineLocation(); private IFunctionDeclaration fFunction = null; private boolean fSuccessful = false; public class LineLocation { private String fileName = null; private int lineNumber = 0; public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public int getLineNumber() { return lineNumber; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } } private interface ResolveEditorRunnable extends Runnable { TextEditor getEditor(); } public DsfSourceSelectionResolver() { } public DsfSourceSelectionResolver(ITextEditor editor, ITextSelection selection) { fEditorPage = editor; fSelection = selection; } /* (non-Javadoc) * @see org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup.IDsfSourceSelectionResolver#run() */ @Override public void run() { fEditorPage = resolveEditor(); if (fEditorPage != null) { ITextSelection selection = resolveSelection(); if (selection != null) { IFunctionDeclaration[] selectedFunctions = resolveSelectedFunction(selection); IFunctionDeclaration selFunction = null; if (selectedFunctions == null || selectedFunctions.length != 1 || selectedFunctions[0] == null) { //Unable to resolve selection to a function return; } else { // Continue as expected selFunction = selectedFunctions[0]; } LineLocation selectedLine = resolveSelectedLine(); if (selectedLine == null) { // Unable to resolve the selected line return; } fLineLocation = selectedLine; fFunction = selFunction; fSuccessful = true; } } } public ITextEditor resolveEditor() { if (fEditorPage != null) { return fEditorPage; } final IWorkbench wb = DsfUIPlugin.getDefault().getWorkbench(); // Run in UI thread to access UI resources ResolveEditorRunnable reditorRunnable = new ResolveEditorRunnable() { TextEditor result = null; @Override public void run() { IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); if (win == null || win.getActivePage() == null || win.getActivePage().getActiveEditor() == null) { result = null; } else { IEditorPart editorPart = win.getActivePage().getActiveEditor(); if (editorPart instanceof CEditor) { result = (TextEditor) win.getActivePage().getActiveEditor(); } } } @Override public TextEditor getEditor() { return result; } }; Display.getDefault().syncExec(reditorRunnable); return reditorRunnable.getEditor(); } private LineLocation resolveSelectedLine() { String errorMessage = ""; //$NON-NLS-1$ IEditorInput input = fEditorPage.getEditorInput(); if (input == null) { errorMessage = "Invalid Editor input on selection"; //$NON-NLS-1$ } else { IDocument document = fEditorPage.getDocumentProvider().getDocument(input); if (document == null) { errorMessage = "Invalid Editor Document input on selection"; //$NON-NLS-1$ } else { ITextSelection selection = resolveSelection(); if (selection == null) { errorMessage = "Invalid selection. Only textual selections are supported"; //$NON-NLS-1$ } else { String fileName = null; try { fileName = CDebugUIUtils.getEditorFilePath(input); } catch (CoreException e) { // unable to resolve the path DsfUIPlugin.log(e); return null; } if (fileName == null) { errorMessage = "Unable to resolve fileName from selection"; //$NON-NLS-1$ DsfUIPlugin.logErrorMessage(errorMessage); } else { // Resolve the values LineLocation lineLocation = new LineLocation(); lineLocation.setFileName(fileName); lineLocation.setLineNumber(selection.getStartLine() + 1); return lineLocation; } } } } DsfUIPlugin.logErrorMessage(errorMessage); return null; } public ITextSelection resolveSelection() { if (fSelection != null) { //Value received at construction time return fSelection; } ISelection selection = fEditorPage.getEditorSite().getSelectionProvider().getSelection(); if (selection instanceof ITextSelection) { return (ITextSelection) selection; } return null; } private IFunctionDeclaration[] resolveSelectedFunction(ITextSelection textSelection) { if (textSelection != null) { SelectionToDeclarationJob job; try { job = new SelectionToDeclarationJob(fEditorPage, textSelection); job.schedule(); job.join(); } catch (CoreException e1) { DsfUIPlugin.log(e1); return null; } catch (InterruptedException e) { DsfUIPlugin.log(e); return null; } //fetch the result return job.getSelectedFunctions(); } return null; } public LineLocation getLineLocation() { return fLineLocation; } public IFunctionDeclaration getFunction() { return fFunction; } public boolean isSuccessful() { return fSuccessful; } }