1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

- Added hyperlink support to the CEditor

- Added a Navigation preference page to the CEditor
- Changed SourceIndexer to use a BufferedReader
- Modified OpenDeclarationsAction to use selection search parser
This commit is contained in:
Bogdan Gheorghe 2004-03-05 00:45:15 +00:00
parent d928227259
commit 70dac4bf81
8 changed files with 1233 additions and 298 deletions

View file

@ -1,3 +1,6 @@
2004-03-04 Bogdan Gheorghe
Modified SourceIndexer to use BufferedReaders instead of passing in a char array.
2004-02-13 Bogdan Gheorghe 2004-02-13 Bogdan Gheorghe
PR 51232 PR 51232

View file

@ -15,25 +15,28 @@ package org.eclipse.cdt.internal.core.search.indexing;
* @author bgheorgh * @author bgheorgh
*/ */
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.InputStreamReader;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICLogConstants; import org.eclipse.cdt.core.ICLogConstants;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserFactoryError; import org.eclipse.cdt.core.parser.ParserFactoryError;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.index.IDocument; import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
/** /**
* A SourceIndexer indexes source files using the parser. The following items are indexed: * A SourceIndexer indexes source files using the parser. The following items are indexed:
@ -90,11 +93,14 @@ public class SourceIndexer extends AbstractIndexer {
try try
{ {
BufferedInputStream inStream = new BufferedInputStream(resourceFile.getContents());
parser = ParserFactory.createParser( parser = ParserFactory.createParser(
ParserFactory.createScanner( new StringReader( document.getStringContent() ), resourceFile.getLocation().toOSString(), scanInfo, ParserMode.COMPLETE_PARSE, language, requestor, ParserUtil.getScannerLogService() ), ParserFactory.createScanner( new BufferedReader(new InputStreamReader(inStream)), resourceFile.getLocation().toOSString(), scanInfo, ParserMode.COMPLETE_PARSE, language, requestor, ParserUtil.getScannerLogService() ),
requestor, ParserMode.COMPLETE_PARSE, language, ParserUtil.getParserLogService() ); requestor, ParserMode.COMPLETE_PARSE, language, ParserUtil.getParserLogService() );
} catch( ParserFactoryError pfe ) } catch( ParserFactoryError pfe )
{ {
} catch (CoreException e) {
} }
try{ try{

View file

@ -1,3 +1,14 @@
2004-03-04 Bogdan Gheorghe
Added Hyperlinks to CEditor
Added Navigation preference page for CEditor
Modified OpenDeclarationAction to use the selection search mode of the
parser (using the old search as a backup until selection search improves)
* src/org/eclipse/cdt/internal/ui/editor/CEditor.java
* src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferncePage.java
* src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java
* src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java
2004-03-04 David Inglis 2004-03-04 David Inglis
Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=53674 Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=53674

View file

@ -11,6 +11,7 @@ import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICLogConstants;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
@ -20,6 +21,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.internal.ui.IContextMenuConstants; import org.eclipse.cdt.internal.ui.IContextMenuConstants;
import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools; import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools;
import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction;
import org.eclipse.cdt.internal.ui.search.actions.SelectionSearchGroup; import org.eclipse.cdt.internal.ui.search.actions.SelectionSearchGroup;
import org.eclipse.cdt.internal.ui.text.CPairMatcher; import org.eclipse.cdt.internal.ui.text.CPairMatcher;
import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration; import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration;
@ -38,6 +40,7 @@ import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
@ -45,7 +48,10 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension; import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension3;
import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.Annotation;
@ -58,6 +64,7 @@ import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.OverviewRuler; import org.eclipse.jface.text.source.OverviewRuler;
import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionChangedListener;
@ -65,10 +72,27 @@ import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorActionBarContributor; import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IFileEditorInput;
@ -123,6 +147,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
/** The property change listener */ /** The property change listener */
private PropertyChangeListener fPropertyChangeListener = new PropertyChangeListener(); private PropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
/** The mouse listener */
private MouseClickListener fMouseListener;
protected final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' }; protected final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
@ -148,6 +174,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
/** Preference key for compiler task tags */ /** Preference key for compiler task tags */
private final static String TRANSLATION_TASK_TAGS= CCorePlugin.TRANSLATION_TASK_TAGS; private final static String TRANSLATION_TASK_TAGS= CCorePlugin.TRANSLATION_TASK_TAGS;
/** Preference key for hyperlink enablement */
public final static String HYPERLINK_ENABLED = "hyperlinkEnable"; //$NON-NLS-1$
private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener, org.eclipse.jface.util.IPropertyChangeListener { private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener, org.eclipse.jface.util.IPropertyChangeListener {
/* /*
* @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
@ -280,6 +309,14 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
return; return;
} }
if (HYPERLINK_ENABLED.equals(property)) {
if (hyperLinkEnabled())
enableBrowserLikeLinks();
else
disableBrowserLikeLinks();
return;
}
IContentAssistant c= asv.getContentAssistant(); IContentAssistant c= asv.getContentAssistant();
if (c instanceof ContentAssistant) if (c instanceof ContentAssistant)
ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event); ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
@ -290,6 +327,16 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
} }
} }
/**
*
*/
private void disableBrowserLikeLinks() {
if (fMouseListener != null) {
fMouseListener.uninstall();
fMouseListener= null;
}
}
/** /**
* @see ISelectionChangedListener#selectionChanged * @see ISelectionChangedListener#selectionChanged
*/ */
@ -484,6 +531,10 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
fSearchDialogAction = new SearchDialogAction(getSelectionProvider(), this); fSearchDialogAction = new SearchDialogAction(getSelectionProvider(), this);
if (hyperLinkEnabled()){
enableBrowserLikeLinks();
}
} }
public void editorContextMenuAboutToShow(IMenuManager menu) { public void editorContextMenuAboutToShow(IMenuManager menu) {
@ -959,9 +1010,649 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class); IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
if (statusLine != null) if (statusLine != null)
statusLine.setMessage(true, msg, null); statusLine.setMessage(true, msg, null);
}
}
//Links
/**
* Enables browser like links.
*/
private void enableBrowserLikeLinks() {
if (fMouseListener == null) {
fMouseListener= new MouseClickListener();
fMouseListener.install();
}
}
class MouseClickListener
implements
MouseListener,
KeyListener,
MouseMoveListener,
FocusListener,
PaintListener,
IPropertyChangeListener{
/** The session is active. */
private boolean fActive;
/** The currently active style range. */
private IRegion fActiveRegion;
/** The currently active style range as position. */
private Position fRememberedPosition;
/** The hand cursor. */
private Cursor fCursor;
/** The link color. */
private Color fColor;
/** The key modifier mask. */
private int fKeyModifierMask;
/** The key modifier mask. */
private boolean fIncludeMode;
//TODO: Replace Keywords
//Temp. Keywords: Once the selection parser is complete, we can use
//it to determine if a word can be underlined
private String[] fgKeywords= {
"and", "and_eq", "asm", "auto",
"bitand", "bitor", "break",
"case", "catch", "class", "compl", "const", "const_cast", "continue",
"default", "delete", "do", "dynamic_cast",
"else", "enum", "explicit", "export", "extern",
"false", "final", "finally", "for", "friend",
"goto",
"if", "inline",
"mutable",
"namespace", "new", "not", "not_eq",
"operator", "or", "or_eq",
"private", "protected", "public",
"redeclared", "register", "reinterpret_cast", "return", "restrict",
"sizeof", "static", "static_cast", "struct", "switch",
"template", "this", "throw", "true", "try", "typedef", "typeid", "typename",
"union", "using",
"virtual", "volatile",
"while",
"xor", "xor_eq", "bool", "char", "double", "float", "int", "long", "short", "signed", "unsigned", "void", "wchar_t", "_Bool", "_Complex", "_Imaginary",
"false", "NULL", "true", "__DATE__", "__LINE__", "__TIME__", "__FILE__", "__STDC__",
"#define", "#undef", "#error", "#warning", "#pragma", "#ifdef", "#ifndef", "#line", "#undef", "#if", "#else", "#elif", "#endif"
};
public void deactivate() {
deactivate(false);
}
public void deactivate(boolean redrawAll) {
if (!fActive)
return;
repairRepresentation(redrawAll);
fActive= false;
fIncludeMode = false;
}
private void repairRepresentation(boolean redrawAll) {
if (fActiveRegion == null)
return;
ISourceViewer viewer= getSourceViewer();
if (viewer != null) {
resetCursor(viewer);
int offset= fActiveRegion.getOffset();
int length= fActiveRegion.getLength();
// remove style
if (!redrawAll && viewer instanceof ITextViewerExtension2)
((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length);
else
viewer.invalidateTextPresentation();
// remove underline
if (viewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
offset= extension.modelOffset2WidgetOffset(offset);
} else {
offset -= viewer.getVisibleRegion().getOffset();
}
StyledText text= viewer.getTextWidget();
try {
text.redrawRange(offset, length, true);
} catch (IllegalArgumentException x) {
org.eclipse.cdt.internal.core.model.Util.log(x, "Error in CEditor.MouseClickListener.repairRepresentation", ICLogConstants.CDT);
}
}
fActiveRegion= null;
}
private void activateCursor(ISourceViewer viewer) {
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed())
return;
Display display= text.getDisplay();
if (fCursor == null)
fCursor= new Cursor(display, SWT.CURSOR_HAND);
text.setCursor(fCursor);
}
private void resetCursor(ISourceViewer viewer) {
StyledText text= viewer.getTextWidget();
if (text != null && !text.isDisposed())
text.setCursor(null);
if (fCursor != null) {
fCursor.dispose();
fCursor= null;
}
}
public void install() {
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer == null)
return;
StyledText text= sourceViewer.getTextWidget();
if (text == null || text.isDisposed())
return;
updateColor(sourceViewer);
text.addKeyListener(this);
text.addMouseListener(this);
text.addMouseMoveListener(this);
text.addFocusListener(this);
text.addPaintListener(this);
updateKeyModifierMask();
IPreferenceStore preferenceStore= getPreferenceStore();
preferenceStore.addPropertyChangeListener(this);
}
public void uninstall() {
if (fColor != null) {
fColor.dispose();
fColor= null;
}
if (fCursor != null) {
fCursor.dispose();
fCursor= null;
}
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer == null)
return;
IPreferenceStore preferenceStore= getPreferenceStore();
if (preferenceStore != null)
preferenceStore.removePropertyChangeListener(this);
StyledText text= sourceViewer.getTextWidget();
if (text == null || text.isDisposed())
return;
text.removeKeyListener(this);
text.removeMouseListener(this);
text.removeMouseMoveListener(this);
text.removeFocusListener(this);
text.removePaintListener(this);
}
private void updateKeyModifierMask() {
//Add code here to allow for specification of hyperlink trigger key
fKeyModifierMask=262144;
}
private void updateColor(ISourceViewer viewer) {
if (fColor != null)
fColor.dispose();
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed())
return;
Display display= text.getDisplay();
fColor= createColor(getPreferenceStore(), LINKED_POSITION_COLOR, display);
}
/**
* Creates a color from the information stored in the given preference store.
* Returns <code>null</code> if there is no such information available.
*/
private Color createColor(IPreferenceStore store, String key, Display display) {
RGB rgb= null;
if (store.contains(key)) {
if (store.isDefault(key))
rgb= PreferenceConverter.getDefaultColor(store, key);
else
rgb= PreferenceConverter.getColor(store, key);
if (rgb != null)
return new Color(display, rgb);
}
return null;
}
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent event) {
if (!fActive)
return;
if (event.stateMask != fKeyModifierMask) {
deactivate();
return;
}
if (event.button != 1) {
deactivate();
return;
}
}
public void mouseUp(MouseEvent e) {
if (!fActive)
return;
if (e.button != 1) {
deactivate();
return;
}
boolean wasActive= fCursor != null;
boolean wasInclude = fIncludeMode;
deactivate();
if (wasActive) {
if (wasInclude){
IAction action= getAction("OpenInclude"); //$NON-NLS-1$
if (action != null){
action.run();
}
}
else {
IAction action= getAction("OpenDeclarations"); //$NON-NLS-1$
if (action != null)
action.run();
}
}
}
public void keyPressed(KeyEvent event) {
if (fActive) {
deactivate();
return;
}
if (event.keyCode != fKeyModifierMask) {
deactivate();
return;
}
fActive= true;
}
public void keyReleased(KeyEvent event) {
if (!fActive)
return;
deactivate();
}
public void mouseMove(MouseEvent event) {
if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) {
deactivate();
return;
}
if (!fActive) {
if (event.stateMask != fKeyModifierMask)
return;
// modifier was already pressed
fActive= true;
}
ISourceViewer viewer= getSourceViewer();
if (viewer == null) {
deactivate();
return;
}
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed()) {
deactivate();
return;
}
if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) {
deactivate();
return;
}
IRegion region= getCurrentTextRegion(viewer);
if (region == null || region.getLength() == 0) {
repairRepresentation();
return;
}
highlightRegion(viewer, region);
activateCursor(viewer);
}
IRegion getCurrentTextRegion(ISourceViewer viewer) {
int offset= getCurrentTextOffset(viewer);
if (offset == -1)
return null;
//Need some code in here to determine if the selected input should
//be selected - the JDT does this by doing a code complete on the input -
//if there are any elements presented it selects the word
return selectWord(viewer.getDocument(), offset);
}
//TODO: Modify this to work with qualified name
private IRegion selectWord(IDocument document, int anchor) {
try {
int offset= anchor;
char c;
while (offset >= 0) {
c= document.getChar(offset);
if (!Character.isJavaIdentifierPart(c))
break;
--offset;
}
int start= offset;
offset= anchor;
int length= document.getLength();
while (offset < length) {
c= document.getChar(offset);
if (!Character.isJavaIdentifierPart(c))
break;
++offset;
}
int end= offset;
//Allow for new lines
if (start == end)
return new Region(start, 0);
else{
String selWord = null;
String slas = document.get(start,1);
if (slas.equals("\n") ||
slas.equals("\t") ||
slas.equals(" "))
{
selWord =document.get(start+1, end - start - 1);
}
else{
selWord =document.get(start, end - start);
}
//Check for keyword
if (isKeyWord(selWord))
return null;
//Avoid selecting literals, includes etc.
char charX = selWord.charAt(0);
if (charX == '"' ||
charX == '.' ||
charX == '<' ||
charX == '>')
return null;
if (selWord.equals("#include"))
{
//get start of next identifier
int end2 = end;
while (!Character.isJavaIdentifierPart(document.getChar(end2))){
++end2;
}
while (end2 < length){
c = document.getChar(end2);
if (!Character.isJavaIdentifierPart(c) &&
c != '.')
break;
++end2;
}
int finalEnd = end2;
selWord =document.get(start, finalEnd - start);
end = finalEnd + 1;
start--;
fIncludeMode = true;
}
return new Region(start + 1, end - start - 1);
}
} catch (BadLocationException x) {
return null;
}
}
private boolean isKeyWord(String selWord) {
for (int i=0; i<fgKeywords.length; i++){
if (selWord.equals(fgKeywords[i]))
return true;
}
return false;
}
private int getCurrentTextOffset(ISourceViewer viewer) {
try {
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed())
return -1;
Display display= text.getDisplay();
Point absolutePosition= display.getCursorLocation();
Point relativePosition= text.toControl(absolutePosition);
int widgetOffset= text.getOffsetAtLocation(relativePosition);
if (viewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
return extension.widgetOffset2ModelOffset(widgetOffset);
} else {
return widgetOffset + viewer.getVisibleRegion().getOffset();
}
} catch (IllegalArgumentException e) {
return -1;
}
}
private void highlightRegion(ISourceViewer viewer, IRegion region) {
if (region.equals(fActiveRegion))
return;
repairRepresentation();
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed())
return;
// highlight region
int offset= 0;
int length= 0;
if (viewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
IRegion widgetRange= extension.modelRange2WidgetRange(region);
if (widgetRange == null)
return;
offset= widgetRange.getOffset();
length= widgetRange.getLength();
} else {
offset= region.getOffset() - viewer.getVisibleRegion().getOffset();
length= region.getLength();
}
StyleRange oldStyleRange= text.getStyleRangeAtOffset(offset);
Color foregroundColor= fColor;
Color backgroundColor= oldStyleRange == null ? text.getBackground() : oldStyleRange.background;
StyleRange styleRange= new StyleRange(offset, length, foregroundColor, backgroundColor);
text.setStyleRange(styleRange);
// underline
text.redrawRange(offset, length, true);
fActiveRegion= region;
}
private void repairRepresentation() {
repairRepresentation(false);
}
/* (non-Javadoc)
* @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
*/
public void focusGained(FocusEvent arg0) {
}
/* (non-Javadoc)
* @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
*/
public void focusLost(FocusEvent arg0) {
deactivate();
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
*/
public void paintControl(PaintEvent event) {
if (fActiveRegion == null)
return;
ISourceViewer viewer= getSourceViewer();
if (viewer == null)
return;
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed())
return;
int offset= 0;
int length= 0;
if (viewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
IRegion widgetRange= extension.modelRange2WidgetRange(new Region(offset, length));
if (widgetRange == null)
return;
offset= widgetRange.getOffset();
length= widgetRange.getLength();
} else {
IRegion region= viewer.getVisibleRegion();
if (!includes(region, fActiveRegion))
return;
offset= fActiveRegion.getOffset() - region.getOffset();
length= fActiveRegion.getLength();
}
// support for bidi
Point minLocation= getMinimumLocation(text, offset, length);
Point maxLocation= getMaximumLocation(text, offset, length);
int x1= minLocation.x;
int x2= minLocation.x + maxLocation.x - minLocation.x - 1;
int y= minLocation.y + text.getLineHeight() - 1;
GC gc= event.gc;
if (fColor != null && !fColor.isDisposed())
gc.setForeground(fColor);
gc.drawLine(x1, y, x2, y);
}
private boolean includes(IRegion region, IRegion position) {
return
position.getOffset() >= region.getOffset() &&
position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
}
private Point getMinimumLocation(StyledText text, int offset, int length) {
Point minLocation= new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
for (int i= 0; i <= length; i++) {
Point location= text.getLocationAtOffset(offset + i);
if (location.x < minLocation.x)
minLocation.x= location.x;
if (location.y < minLocation.y)
minLocation.y= location.y;
}
return minLocation;
}
private Point getMaximumLocation(StyledText text, int offset, int length) {
Point maxLocation= new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
for (int i= 0; i <= length; i++) {
Point location= text.getLocationAtOffset(offset + i);
if (location.x > maxLocation.x)
maxLocation.x= location.x;
if (location.y > maxLocation.y)
maxLocation.y= location.y;
}
return maxLocation;
}
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(CEditor.LINKED_POSITION_COLOR)) {
ISourceViewer viewer= getSourceViewer();
if (viewer != null)
updateColor(viewer);
}
}
}
/**
* @return
*/
private boolean hyperLinkEnabled() {
IPreferenceStore store= getPreferenceStore();
boolean Value = store.getBoolean(HYPERLINK_ENABLED);
return Value;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.ui.editor.IReconcilingParticipant#reconciled() * @see org.eclipse.cdt.internal.ui.editor.IReconcilingParticipant#reconciled()
*/ */

View file

@ -1,283 +0,0 @@
package org.eclipse.cdt.internal.ui.editor;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.search.BasicSearchResultCollector;
import org.eclipse.cdt.core.search.ICSearchConstants;
import org.eclipse.cdt.core.search.ICSearchScope;
import org.eclipse.cdt.core.search.IMatch;
import org.eclipse.cdt.core.search.OrPattern;
import org.eclipse.cdt.core.search.SearchEngine;
import org.eclipse.cdt.internal.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
import org.eclipse.cdt.ui.CSearchResultLabelProvider;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IUpdate;
/**
* This action opens a java CEditor on the element represented by text selection of
* the connected java source viewer.
*
* Use action from package org.eclipse.jdt.ui.actions
*/
public class OpenDeclarationsAction extends Action implements IUpdate {
private String fDialogTitle;
private String fDialogMessage;
protected CEditor fEditor;
SearchEngine searchEngine = null;
/**
* Creates a new action with the given label and image.
*/
protected OpenDeclarationsAction() {
super();
setText(CEditorMessages.getString("OpenDeclarations.label")); //$NON-NLS-1$
setToolTipText(CEditorMessages.getString("OpenDeclarations.tooltip")); //$NON-NLS-1$
setDescription(CEditorMessages.getString("OpenDeclarations.description")); //$NON-NLS-1$
setDialogTitle(CEditorMessages.getString("OpenDeclarations.dialog.title")); //$NON-NLS-1$
setDialogMessage(CEditorMessages.getString("OpenDeclarations.dialog.message")); //$NON-NLS-1$
searchEngine = new SearchEngine();
}
/**
* Creates a new action with the given image.
*/
public OpenDeclarationsAction(ImageDescriptor image) {
this();
setImageDescriptor(image);
}
/**
* Creates a new action with the given editor
*/
public OpenDeclarationsAction(CEditor editor) {
this();
fEditor = editor;
}
protected void setDialogTitle(String title) {
fDialogTitle= title;
}
protected void setDialogMessage(String message) {
fDialogMessage= message;
}
public void setContentEditor(CEditor editor) {
fEditor= editor;
}
/**
* Return the selected string from the editor
* @return The string currently selected, or null if there is no valid selection
*/
protected String getSelectedStringFromEditor() {
if (fEditor.getSelectionProvider() == null) {
return null;
}
try {
ITextSelection selection= (ITextSelection) fEditor.getSelectionProvider().getSelection();
String sel = selection.getText();
if (sel.equals("")) //$NON-NLS-1$
{
int selStart = selection.getOffset();
IDocumentProvider prov = fEditor.getDocumentProvider();
IDocument doc = prov.getDocument(fEditor.getEditorInput());
sel = getSelection(doc, selStart);
}
return sel;
} catch(Exception x) {
return null;
}
}
/**
* @see IAction#actionPerformed
*/
public void run() {
final String selectedText = getSelectedStringFromEditor();
if(selectedText == null) {
return;
}
final ArrayList elementsFound = new ArrayList();
IRunnableWithProgress runnable = new IRunnableWithProgress()
{
public void run(IProgressMonitor monitor) {
BasicSearchResultCollector resultCollector = new BasicSearchResultCollector(monitor);
IWorkingCopyManager fManager = CUIPlugin.getDefault().getWorkingCopyManager();
ITranslationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput());
ICElement[] projectScopeElement = new ICElement[1];
projectScopeElement[0] = unit.getCProject();//(ICElement)currentScope.getCProject();
ICSearchScope scope = SearchEngine.createCSearchScope(projectScopeElement, true);
OrPattern orPattern = new OrPattern();
// search for global variables, functions, classes, structs, unions, enums and macros
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.VAR, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.FUNCTION, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.METHOD, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.TYPE, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.FIELD, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.MACRO, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, true ));
try {
searchEngine.search(CUIPlugin.getWorkspace(), orPattern, scope, resultCollector, true);
} catch (InterruptedException e) {
}
elementsFound.addAll(resultCollector.getSearchResults());
}
};
try {
ProgressMonitorDialog progressMonitor = new ProgressMonitorDialog(getShell());
progressMonitor.run(true, true, runnable);
if (elementsFound.isEmpty() == true) {
return;
}
IMatch selected= selectCElement(elementsFound, getShell(), fDialogTitle, fDialogMessage);
if (selected != null) {
open(selected);
return;
}
} catch(Exception x) {
CUIPlugin.getDefault().log(x);
}
}
protected Shell getShell() {
return fEditor.getSite().getShell();
}
/**
* Opens the editor on the given element and subsequently selects it.
*/
protected void open(IMatch element) throws CModelException, PartInitException {
IEditorPart part= EditorUtility.openInEditor(element.getResource());
//int line = element.getStartOffset();
//if(line > 0) line--;
if(part instanceof CEditor) {
CEditor ed = (CEditor)part;
try {
IDocument document= ed.getDocumentProvider().getDocument(ed.getEditorInput());
//if(line > 3) {
// ed.selectAndReveal(document.getLineOffset(line - 3), 0);
//}
ed.selectAndReveal(element.getStartOffset() /*document.getLineOffset(line)*/, 0);
} catch (Exception e) {}
}
}
/**
* Shows a dialog for resolving an ambigous C element.
* Utility method that can be called by subclassers.
*/
protected IMatch selectCElement(List elements, Shell shell, String title, String message) {
int nResults= elements.size();
if (nResults == 0)
return null;
if (nResults == 1)
return (IMatch) elements.get(0);
ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, new CSearchResultLabelProvider(), false, false);
dialog.setTitle(title);
dialog.setMessage(message);
dialog.setElements(elements);
if (dialog.open() == Window.OK) {
Object[] selection= dialog.getResult();
if (selection != null && selection.length > 0) {
nResults= selection.length;
for (int i= 0; i < nResults; i++) {
Object current= selection[i];
if (current instanceof IMatch)
return (IMatch) current;
}
}
}
return null;
}
public String getSelection(IDocument doc, int fPos){
int pos= fPos;
char c;
int fStartPos =0, fEndPos=0;
String selectedWord=null;
try{
while (pos >= 0) {
c= doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
--pos;
}
fStartPos= pos + 1;
pos= fPos;
int length= doc.getLength();
while (pos < length) {
c= doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
++pos;
}
fEndPos= pos;
selectedWord = doc.get(fStartPos, (fEndPos - fStartPos));
}
catch(BadLocationException e){
}
return selectedWord;
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.IUpdate#update()
*/
public void update() {
setEnabled(getSelectedStringFromEditor() != null);
}
}

View file

@ -206,7 +206,8 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_INDICATION_COLOR)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_INDICATION_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_INDICATION)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_INDICATION));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.HYPERLINK_ENABLED));
OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
overlayKeys.toArray(keys); overlayKeys.toArray(keys);
return new OverlayPreferenceStore(getPreferenceStore(), keys); return new OverlayPreferenceStore(getPreferenceStore(), keys);
@ -291,6 +292,9 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP
store.setDefault(ContentAssistPreference.ORDER_PROPOSALS, false); store.setDefault(ContentAssistPreference.ORDER_PROPOSALS, false);
store.setDefault(ContentAssistPreference.ADD_INCLUDE, true); store.setDefault(ContentAssistPreference.ADD_INCLUDE, true);
store.setDefault(CEditor.HYPERLINK_ENABLED,true);
} }
/* /*
@ -920,11 +924,37 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP
item.setImage(CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT)); item.setImage(CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT));
item.setControl(createContentAssistPage(folder)); item.setControl(createContentAssistPage(folder));
item = new TabItem(folder, SWT.NONE);
item.setText("Navigation");
item.setImage(CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT));
item.setControl(createNavPage(folder));
initialize(); initialize();
return folder; return folder;
} }
/**
* @param folder
* @return
*/
private Control createNavPage(Composite parent) {
Composite navComposite = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
navComposite.setLayout(layout);
Button navCheck = new Button(navComposite,SWT.CHECK);
navCheck.setText("Enable Hyperlink Navigation");
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
navCheck.setLayoutData(gd);
navCheck.addSelectionListener(fCheckBoxListener);
fCheckBoxes.put(navCheck, CEditor.HYPERLINK_ENABLED);
return navComposite;
}
private void initialize() { private void initialize() {
fFontEditor.setPreferenceStore(getPreferenceStore()); fFontEditor.setPreferenceStore(getPreferenceStore());

View file

@ -17,6 +17,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICLogConstants;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
@ -30,7 +31,6 @@ import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.ParseError.ParseErrorKind;
import org.eclipse.cdt.core.parser.ast.ASTClassKind; import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
@ -187,12 +187,13 @@ public abstract class FindAction extends Action {
try{ try{
node = parser.parse(selectionStart,selectionEnd); node = parser.parse(selectionStart,selectionEnd);
} }
catch (ParseError er){ catch (ParseError er){}
ParseErrorKind per = er.getErrorKind(); catch (Exception ex){}
er.printStackTrace(); catch ( VirtualMachineError vmErr){
if (vmErr instanceof OutOfMemoryError){
org.eclipse.cdt.internal.core.model.Util.log(null, "Selection Search Out Of Memory error: " + vmErr.getMessage() + " on File: " + resourceFile.getName(), ICLogConstants.CDT); //$NON-NLS-1$ //$NON-NLS-2$
}
} }
catch (Exception ex){
ex.printStackTrace();}
if (node == null){ if (node == null){
operationNotAvailableDialog(); operationNotAvailableDialog();

View file

@ -0,0 +1,476 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.search.actions;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICLogConstants;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserFactoryError;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.search.BasicSearchResultCollector;
import org.eclipse.cdt.core.search.ICSearchConstants;
import org.eclipse.cdt.core.search.ICSearchPattern;
import org.eclipse.cdt.core.search.ICSearchScope;
import org.eclipse.cdt.core.search.IMatch;
import org.eclipse.cdt.core.search.OrPattern;
import org.eclipse.cdt.core.search.SearchEngine;
import org.eclipse.cdt.core.search.ICSearchConstants.SearchFor;
import org.eclipse.cdt.internal.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
import org.eclipse.cdt.internal.ui.search.CSearchMessages;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
import org.eclipse.cdt.ui.CSearchResultLabelProvider;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IUpdate;
public class OpenDeclarationsAction extends Action implements IUpdate {
private String fDialogTitle;
private String fDialogMessage;
protected CEditor fEditor;
SearchEngine searchEngine = null;
/**
* Creates a new action with the given label and image.
*/
protected OpenDeclarationsAction() {
setText(CEditorMessages.getString("OpenDeclarations.label")); //$NON-NLS-1$
setToolTipText(CEditorMessages.getString("OpenDeclarations.tooltip")); //$NON-NLS-1$
setDescription(CEditorMessages.getString("OpenDeclarations.description")); //$NON-NLS-1$
setDialogTitle(CEditorMessages.getString("OpenDeclarations.dialog.title")); //$NON-NLS-1$
setDialogMessage(CEditorMessages.getString("OpenDeclarations.dialog.message")); //$NON-NLS-1$
searchEngine = new SearchEngine();
}
/**
* Creates a new action with the given editor
*/
public OpenDeclarationsAction(CEditor editor) {
this();
fEditor = editor;
}
protected void setDialogTitle(String title) {
fDialogTitle= title;
}
protected void setDialogMessage(String message) {
fDialogMessage= message;
}
/**
* Return the selected string from the editor
* @return The string currently selected, or null if there is no valid selection
*/
protected SelSearchNode getSelectedStringFromEditor() {
if (fEditor.getSelectionProvider() == null) {
return null;
}
try {
ISelectionProvider selectionProvider = fEditor.getSelectionProvider();
ITextSelection textSelection= (ITextSelection) selectionProvider.getSelection();
String seltext = textSelection.getText();
SelSearchNode sel = null;
if (seltext.equals("")) //$NON-NLS-1$
{
int selStart = textSelection.getOffset();
IDocumentProvider prov = fEditor.getDocumentProvider();
IDocument doc = prov.getDocument(fEditor.getEditorInput());
//TODO: Change this to work with qualified identifiers
sel = getSelection(doc, selStart);
}
else {
sel = new SelSearchNode();
sel.selText= seltext;
sel.selStart = textSelection.getOffset();
sel.selEnd = textSelection.getOffset() + textSelection.getLength();
}
return sel;
} catch(Exception x) {
return null;
}
}
/**
* @see IAction#actionPerformed
*/
public void run() {
final SelSearchNode selNode = getSelectedStringFromEditor();
if(selNode == null) {
return;
}
final ArrayList elementsFound = new ArrayList();
IRunnableWithProgress runnable = new IRunnableWithProgress()
{
public void run(IProgressMonitor monitor) {
BasicSearchResultCollector resultCollector = new BasicSearchResultCollector(monitor);
IWorkingCopyManager fManager = CUIPlugin.getDefault().getWorkingCopyManager();
ITranslationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput());
//TODO: Change to Project Scope
ICElement[] projectScopeElement = new ICElement[1];
projectScopeElement[0] = unit.getCProject();//(ICElement)currentScope.getCProject();
ICSearchScope scope = SearchEngine.createCSearchScope(projectScopeElement, true);
IFile resourceFile = fEditor.getInputFile();
IParser parser = setupParser(resourceFile);
IASTNode node = null;
try{
int selectionStart = selNode.selStart;
int selectionEnd = selNode.selEnd;
node = parser.parse(selectionStart,selectionEnd);
}
catch (ParseError er){}
catch ( VirtualMachineError vmErr){
if (vmErr instanceof OutOfMemoryError){
org.eclipse.cdt.internal.core.model.Util.log(null, "Open Declarations Out Of Memory error: " + vmErr.getMessage() + " on File: " + resourceFile.getName(), ICLogConstants.CDT); //$NON-NLS-1$ //$NON-NLS-2$
}
}
catch (Exception ex){}
finally{
if (node == null){
return;
}
SearchFor searchFor = getSearchForFromNode(node);
ICSearchPattern pattern = SearchEngine.createSearchPattern( selNode.selText,searchFor,ICSearchConstants.DECLARATIONS,true);
try {
searchEngine.search(CUIPlugin.getWorkspace(), pattern, scope, resultCollector, true);
} catch (InterruptedException e) {
}
elementsFound.addAll(resultCollector.getSearchResults());
}
}
};
try {
ProgressMonitorDialog progressMonitor = new ProgressMonitorDialog(getShell());
progressMonitor.run(true, true, runnable);
if (elementsFound.isEmpty() == true) {
//TODO: Get rid of back up search when selection search improves
//MessageDialog.openInformation(getShell(),CSearchMessages.getString("CSearchOperation.operationUnavailable.title"), CSearchMessages.getString("CSearchOperation.operationUnavailable.message")); //$NON-NLS-1$
temporaryBackUpSearch();
return;
}
IMatch selected= selectCElement(elementsFound, getShell(), fDialogTitle, fDialogMessage);
if (selected != null) {
open(selected);
return;
}
} catch(Exception x) {
CUIPlugin.getDefault().log(x);
}
}
protected Shell getShell() {
return fEditor.getSite().getShell();
}
protected void temporaryBackUpSearch(){
final SelSearchNode selNode = getSelectedStringFromEditor();
if (selNode == null)
return;
final ArrayList elementsFound = new ArrayList();
IRunnableWithProgress runnable = new IRunnableWithProgress()
{
public void run(IProgressMonitor monitor) {
String selectedText = selNode.selText;
BasicSearchResultCollector resultCollector = new BasicSearchResultCollector(monitor);
IWorkingCopyManager fManager = CUIPlugin.getDefault().getWorkingCopyManager();
ITranslationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput());
ICElement[] projectScopeElement = new ICElement[1];
projectScopeElement[0] = unit.getCProject();//(ICElement)currentScope.getCProject();
ICSearchScope scope = SearchEngine.createCSearchScope(projectScopeElement, true);
IFile resourceFile = fEditor.getInputFile();
OrPattern orPattern = new OrPattern();
// search for global variables, functions, classes, structs, unions, enums and macros
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.VAR, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.FUNCTION, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.METHOD, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.TYPE, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.FIELD, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.MACRO, ICSearchConstants.DECLARATIONS, true ));
orPattern.addPattern(SearchEngine.createSearchPattern( selectedText, ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, true ));
try {
searchEngine.search(CUIPlugin.getWorkspace(), orPattern, scope, resultCollector, true);
} catch (InterruptedException e) {
}
elementsFound.addAll(resultCollector.getSearchResults());
}
};
try {
ProgressMonitorDialog progressMonitor = new ProgressMonitorDialog(getShell());
progressMonitor.run(true, true, runnable);
if (elementsFound.isEmpty() == true) {
MessageDialog.openInformation(getShell(),CSearchMessages.getString("CSearchOperation.operationUnavailable.title"), CSearchMessages.getString("CSearchOperation.operationUnavailable.message")); //$NON-NLS-1$
return;
}
IMatch selected= selectCElement(elementsFound, getShell(), fDialogTitle, fDialogMessage);
if (selected != null) {
open(selected);
return;
}
} catch(Exception x) {
CUIPlugin.getDefault().log(x);
}
}
/**
* Opens the editor on the given element and subsequently selects it.
*/
protected void open(IMatch element) throws CModelException, PartInitException {
IEditorPart part= EditorUtility.openInEditor(element.getResource());
//int line = element.getStartOffset();
//if(line > 0) line--;
if(part instanceof CEditor) {
CEditor ed = (CEditor)part;
try {
IDocument document= ed.getDocumentProvider().getDocument(ed.getEditorInput());
//if(line > 3) {
// ed.selectAndReveal(document.getLineOffset(line - 3), 0);
//}
ed.selectAndReveal(element.getStartOffset() /*document.getLineOffset(line)*/, 0);
} catch (Exception e) {}
}
}
/**
* Shows a dialog for resolving an ambigous C element.
* Utility method that can be called by subclassers.
*/
protected IMatch selectCElement(List elements, Shell shell, String title, String message) {
int nResults= elements.size();
if (nResults == 0)
return null;
if (nResults == 1)
return (IMatch) elements.get(0);
ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, new CSearchResultLabelProvider(), false, false);
dialog.setTitle(title);
dialog.setMessage(message);
dialog.setElements(elements);
if (dialog.open() == Window.OK) {
Object[] selection= dialog.getResult();
if (selection != null && selection.length > 0) {
nResults= selection.length;
for (int i= 0; i < nResults; i++) {
Object current= selection[i];
if (current instanceof IMatch)
return (IMatch) current;
}
}
}
return null;
}
public SelSearchNode getSelection(IDocument doc, int fPos){
int pos= fPos;
char c;
int fStartPos =0, fEndPos=0;
String selectedWord=null;
try{
while (pos >= 0) {
c= doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
--pos;
}
fStartPos= pos + 1;
pos= fPos;
int length= doc.getLength();
while (pos < length) {
c= doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
++pos;
}
fEndPos= pos;
selectedWord = doc.get(fStartPos, (fEndPos - fStartPos));
}
catch(BadLocationException e){
}
SelSearchNode sel = new SelSearchNode();
sel.selText = selectedWord;
sel.selStart = fStartPos;
sel.selEnd = fEndPos;
return sel;
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.IUpdate#update()
*/
public void update() {
setEnabled(getSelectedStringFromEditor() != null);
}
protected IParser setupParser(IFile resourceFile){
//Get the scanner info
IProject currentProject = resourceFile.getProject();
IScannerInfo scanInfo = new ScannerInfo();
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(currentProject);
if (provider != null){
IScannerInfo buildScanInfo = provider.getScannerInformation(currentProject);
if (buildScanInfo != null){
scanInfo = new ScannerInfo(buildScanInfo.getDefinedSymbols(), buildScanInfo.getIncludePaths());
}
}
//C or CPP?
ParserLanguage language = CoreModel.getDefault().hasCCNature(currentProject) ? ParserLanguage.CPP : ParserLanguage.C;
IParser parser = null;
FileReader reader = null;
try {
reader = new FileReader(resourceFile.getLocation().toFile());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try
{
parser = ParserFactory.createParser(
ParserFactory.createScanner( reader, resourceFile.getLocation().toOSString(), scanInfo, ParserMode.SELECTION_PARSE, language, new NullSourceElementRequestor(), ParserUtil.getScannerLogService() ),
new NullSourceElementRequestor(), ParserMode.SELECTION_PARSE, language, ParserUtil.getParserLogService() );
} catch( ParserFactoryError pfe ){}
return parser;
}
private SearchFor getSearchForFromNode(IASTNode node){
SearchFor searchFor = null;
if (node instanceof IASTClassSpecifier){
//Find out if class, struct, union
IASTClassSpecifier tempNode = (IASTClassSpecifier) node;
if(tempNode.getClassKind().equals(ASTClassKind.CLASS)){
searchFor = ICSearchConstants.CLASS;
}
else if (tempNode.getClassKind().equals(ASTClassKind.STRUCT)){
searchFor = ICSearchConstants.STRUCT;
}
else if (tempNode.getClassKind().equals(ASTClassKind.UNION)){
searchFor = ICSearchConstants.UNION;
}
}
else if (node instanceof IASTMethod){
searchFor = ICSearchConstants.METHOD;
}
else if (node instanceof IASTFunction){
searchFor = ICSearchConstants.FUNCTION;
}
else if (node instanceof IASTField){
searchFor = ICSearchConstants.FIELD;
}
else if (node instanceof IASTVariable){
searchFor = ICSearchConstants.VAR;
}
else if (node instanceof IASTEnumerationSpecifier){
searchFor = ICSearchConstants.ENUM;
}
else if (node instanceof IASTEnumerator){
searchFor = ICSearchConstants.FIELD;
}
else if (node instanceof IASTNamespaceDefinition){
searchFor = ICSearchConstants.NAMESPACE;
}
return searchFor;
}
class SelSearchNode{
protected String selText;
protected int selStart;
protected int selEnd;
}
}