1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Bug 423679: CEditor navigation actions disabled outside of CEditor

The Open Declaration (F3), etc. actions use code in the ASTProvider.  If
the provider is not able to get an AST then the actions are disabled.
The implementation of the ASTProvider has an "instanceof CEditor" check
the result being that ASTProvider can only be used when the editor is a
CEditor.

This breaks our use case where we have a CEditor embedded as a tab in a
multi-pane editor (see org.eclipse.papyrus.infra.core.sasheditor
.editor.AbstractMultiPageSashEditor).

This patch modifies the ASTProvider to use #getAdapter instead of only
the instanceof check.  I've kept the common case (where the editor is a
CEditor) unchanged and added the new code as extra handling.

I've also introduced a public interface, ITranslationUnitProvider, to
avoid forcing clients to adapt to the internal CEditor class.  The only
part of CEditor that ASTProvider cares about is the ITranslationUnit.
The existing implementation has an unchecked cast.  The new interface
provides the required type directly.

Change-Id: Ie7e68e8909928374fa11fe2b8a857f09d042fb5c
Signed-off-by: Andrew Eidsness <andrewe@jfront.com>
Reviewed-on: https://git.eclipse.org/r/20026
Tested-by: Hudson CI
Reviewed-by: Doug Schaefer <dschaefer@qnx.com>
IP-Clean: Doug Schaefer <dschaefer@qnx.com>
This commit is contained in:
Andrew Eidsness 2013-12-10 21:08:26 -05:00 committed by Doug Schaefer
parent 71fa7cf819
commit d046e0a25f
5 changed files with 102 additions and 47 deletions

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2013 Zeligsoft (2009) Limited.
* 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
*/
package org.eclipse.cdt.core.model;
/**
* Represents a workbench object that is able to provide instances of ITranslationUnit. For
* example, the CEditor (in the CDT UI plugin) implements this interface in order to provide
* the IWorkingCopy of the editor's active translation unit.
*
* @since 5.6
*/
public interface ITranslationUnitHolder {
/**
* Returns the translation unit that is provided by the receiver or null if there is no
* such translation unit.
*/
public ITranslationUnit getTranslationUnit();
}

View file

@ -20,6 +20,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPart;
@ -33,6 +34,7 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.ITranslationUnitHolder;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.ASTCache;
@ -222,7 +224,17 @@ public final class ASTProvider {
return false;
String id= ref.getId();
return CUIPlugin.EDITOR_ID.equals(id) || ref.getPart(false) instanceof CEditor;
if (CUIPlugin.EDITOR_ID.equals(id))
return true;
IWorkbenchPart part = ref.getPart(false);
if (part instanceof CEditor)
return true;
// Other editors can behave as CEditors if they can provide a copy of their ITranslationUnit.
if (part instanceof IEditorPart)
return part.getAdapter(ITranslationUnitHolder.class) != null;
return false;
}
}
@ -264,14 +276,17 @@ public final class ASTProvider {
}
private void activeEditorChanged(IWorkbenchPart editor) {
ICElement cElement= null;
if (editor instanceof CEditor) {
cElement= ((CEditor) editor).getInputCElement();
ITranslationUnit tu = null;
if (editor != null) {
ITranslationUnitHolder provider = (ITranslationUnitHolder) editor.getAdapter(ITranslationUnitHolder.class);
if (provider != null)
tu = provider.getTranslationUnit();
}
synchronized (this) {
fActiveEditor= editor;
fTimeStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
fCache.setActiveElement((ITranslationUnit) cElement);
fCache.setActiveElement(tu);
}
}

View file

@ -184,6 +184,7 @@ import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.ITranslationUnitHolder;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.ICEditor;
@ -241,7 +242,7 @@ import org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
/**
* C/C++ source editor.
*/
public class CEditor extends TextEditor implements ICEditor, ISelectionChangedListener, ICReconcilingListener {
public class CEditor extends TextEditor implements ICEditor, ISelectionChangedListener, ICReconcilingListener, ITranslationUnitHolder {
/** Marker used for synchronization from Problems View to the editor on double-click. */
private IMarker fSyncProblemsViewMarker;
@ -1514,6 +1515,11 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
return CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(getEditorInput());
}
@Override
public ITranslationUnit getTranslationUnit() {
return getInputCElement();
}
/**
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
*/
@ -1575,7 +1581,8 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
fTemplatesPage = new CTemplatesPage(this);
}
return fTemplatesPage;
}
} else if (adapterClass.isAssignableFrom(ITranslationUnitHolder.class))
return this;
return super.getAdapter(adapterClass);
}

View file

@ -89,8 +89,8 @@ public class SelectionParseAction extends Action {
clearStatusLine();
IEditorPart editor = EditorUtility.openInEditor(path, fEditor.getInputCElement());
if (editor instanceof ITextEditor) {
ITextEditor textEditor = (ITextEditor) editor;
ITextEditor textEditor = EditorUtility.getTextEditor(editor);
if (textEditor != null) {
textEditor.selectAndReveal(currentOffset, currentLength);
} else {
reportSourceFileOpenFailure(path);
@ -101,8 +101,8 @@ public class SelectionParseAction extends Action {
clearStatusLine();
IEditorPart editor = EditorUtility.openInEditor(tu, true);
if (editor instanceof ITextEditor) {
ITextEditor textEditor = (ITextEditor) editor;
ITextEditor textEditor = EditorUtility.getTextEditor(editor);
if (textEditor != null) {
textEditor.selectAndReveal(currentOffset, currentLength);
} else {
reportSourceFileOpenFailure(tu.getPath());

View file

@ -869,10 +869,10 @@ public class EditorUtility {
}
}
if (!(ep instanceof ITextEditor))
ITextEditor textEditor = getTextEditor(ep);
if (textEditor == null)
return saveUnknownEditors;
ITextEditor textEditor= (ITextEditor) ep;
IDocumentProvider documentProvider= textEditor.getDocumentProvider();
if (!(documentProvider instanceof TextFileDocumentProvider))
return saveUnknownEditors;
@ -1030,9 +1030,9 @@ public class EditorUtility {
if(window != null) {
IWorkbenchPage activePage = window.getActivePage();
if(activePage != null) {
IEditorPart activeEditor = activePage.getActiveEditor();
if(activeEditor instanceof ITextEditor) {
IEditorInput editorInput = ((ITextEditor)activeEditor).getEditorInput();
ITextEditor activeEditor = getTextEditor(activePage.getActiveEditor());
if (activeEditor != null) {
IEditorInput editorInput = activeEditor.getEditorInput();
IFile file = ResourceUtil.getFile(editorInput);
if(file != null) {
project = file.getProject();
@ -1042,4 +1042,14 @@ public class EditorUtility {
}
return project;
}
/**
* Tries to convert the given editor to an implementation of ITextEditor. Returns that implementation
* if possible and null otherwise.
*
* @param editor The editor to be converted or null if there is nothing to convert.
*/
public static ITextEditor getTextEditor(IEditorPart editor) {
return editor == null ? null : (ITextEditor) editor.getAdapter(ITextEditor.class);
}
}