1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Breakpoints presentation in the Disassembly view.

This commit is contained in:
Mikhail Khodjaiants 2004-04-27 23:19:26 +00:00
parent 06ad029125
commit 970cec46b6
16 changed files with 1434 additions and 73 deletions

View file

@ -1,3 +1,21 @@
2004-04-27 Mikhail Khodjaiants
Breakpoints presentation in the Disassembly view.
* HTML2TextReader.java: new
* HTMLPrinter.java: new
* HTMLTextPresenter.java: new
* LineBreakingReader.java: new
* SingleCharReader.java: new
* SubstitutionTextReader.java: new
* ToggleBreakpointAdapter.java
* DisassemblyMessages.properties
* DisassemblyAnnotationHover.java: new
* DisassemblyAnnotationModel.java: new
* DisassemblyDocumentProvider.java
* DisassemblyEditorInput.java
* DisassemblyMarkerAnnotationModel.java: deleted
* DisassemblyView.java
* DisassemblyViewerConfiguration.java: new
2004-04-23 Mikhail Khodjaiants
Fix for bug 58711: Breakpoint race condition.
Notify the Breakpoint Manager when the install count of breakpoint is changed.

View file

@ -0,0 +1,297 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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.debug.internal.ui;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyMessages;
import org.eclipse.jface.text.TextPresentation;
/**
* Reads the text contents from a reader of HTML contents and translates
* the tags or cut them out.
*/
public class HTML2TextReader extends SubstitutionTextReader {
private static final String EMPTY_STRING= ""; //$NON-NLS-1$
private static final Map fgEntityLookup;
private static final Set fgTags;
static {
fgTags= new HashSet();
fgTags.add("b"); //$NON-NLS-1$
fgTags.add("br"); //$NON-NLS-1$
fgTags.add("h5"); //$NON-NLS-1$
fgTags.add("p"); //$NON-NLS-1$
fgTags.add("dl"); //$NON-NLS-1$
fgTags.add("dt"); //$NON-NLS-1$
fgTags.add("dd"); //$NON-NLS-1$
fgTags.add("li"); //$NON-NLS-1$
fgTags.add("ul"); //$NON-NLS-1$
fgTags.add("pre"); //$NON-NLS-1$
fgEntityLookup= new HashMap(7);
fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$
fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$
fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$
fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$
fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$
fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$
fgEntityLookup.put("quot", "\""); //$NON-NLS-1$ //$NON-NLS-2$
}
private int fCounter= 0;
private TextPresentation fTextPresentation;
private int fBold= 0;
private int fStartOffset= -1;
private boolean fInParagraph= false;
private boolean fIsPreformattedText= false;
/**
* Transforms the html text from the reader to formatted text.
* @param presentation If not <code>null</code>, formattings will be applied to
* the presentation.
*/
public HTML2TextReader(Reader reader, TextPresentation presentation) {
super(new PushbackReader(reader));
fTextPresentation= presentation;
}
public int read() throws IOException {
int c= super.read();
if (c != -1)
++ fCounter;
return c;
}
protected void startBold() {
if (fBold == 0)
fStartOffset= fCounter;
++ fBold;
}
protected void startPreformattedText() {
fIsPreformattedText= true;
setSkipWhitespace(false);
}
protected void stopPreformattedText() {
fIsPreformattedText= false;
setSkipWhitespace(true);
}
protected void stopBold() {
-- fBold;
if (fBold == 0) {
if (fTextPresentation != null) {
fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.BOLD));
}
fStartOffset= -1;
}
}
/*
* @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
*/
protected String computeSubstitution(int c) throws IOException {
if (c == '<')
return processHTMLTag();
else if (c == '&')
return processEntity();
else if (fIsPreformattedText)
return processPreformattedText(c);
return null;
}
private String html2Text(String html) {
if (html == null || html.length() == 0)
return EMPTY_STRING;
String tag= html;
if ('/' == tag.charAt(0))
tag= tag.substring(1);
if (!fgTags.contains(tag))
return EMPTY_STRING;
if ("pre".equals(html)) { //$NON-NLS-1$
startPreformattedText();
return EMPTY_STRING;
}
if ("/pre".equals(html)) { //$NON-NLS-1$
stopPreformattedText();
return EMPTY_STRING;
}
if (fIsPreformattedText)
return EMPTY_STRING;
if ("b".equals(html)) { //$NON-NLS-1$
startBold();
return EMPTY_STRING;
}
if ("h5".equals(html) || "dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$
startBold();
return EMPTY_STRING;
}
if ("dl".equals(html)) //$NON-NLS-1$
return LINE_DELIM;
if ("dd".equals(html)) //$NON-NLS-1$
return "\t"; //$NON-NLS-1$
if ("li".equals(html)) //$NON-NLS-1$
return LINE_DELIM + "\t" + DisassemblyMessages.getString( "HTML2TextReader.dash" ); //$NON-NLS-1$ //$NON-NLS-2$
if ("/b".equals(html)) { //$NON-NLS-1$
stopBold();
return EMPTY_STRING;
}
if ("p".equals(html)) { //$NON-NLS-1$
fInParagraph= true;
return LINE_DELIM;
}
if ("br".equals(html)) //$NON-NLS-1$
return LINE_DELIM;
if ("/p".equals(html)) { //$NON-NLS-1$
boolean inParagraph= fInParagraph;
fInParagraph= false;
return inParagraph ? EMPTY_STRING : LINE_DELIM;
}
if ("/h5".equals(html) || "/dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$
stopBold();
return LINE_DELIM;
}
if ("/dd".equals(html)) //$NON-NLS-1$
return LINE_DELIM;
return EMPTY_STRING;
}
/*
* A '<' has been read. Process a html tag
*/
private String processHTMLTag() throws IOException {
StringBuffer buf= new StringBuffer();
int ch;
do {
ch= nextChar();
while (ch != -1 && ch != '>') {
buf.append(Character.toLowerCase((char) ch));
ch= nextChar();
if (ch == '"'){
buf.append(Character.toLowerCase((char) ch));
ch= nextChar();
while (ch != -1 && ch != '"'){
buf.append(Character.toLowerCase((char) ch));
ch= nextChar();
}
}
if (ch == '<'){
unread(ch);
return '<' + buf.toString();
}
}
if (ch == -1)
return null;
int tagLen= buf.length();
// needs special treatment for comments
if ((tagLen >= 3 && "!--".equals(buf.substring(0, 3))) //$NON-NLS-1$
&& !(tagLen >= 5 && "--!".equals(buf.substring(tagLen - 3)))) { //$NON-NLS-1$
// unfinished comment
buf.append(ch);
} else {
break;
}
} while (true);
return html2Text(buf.toString());
}
private String processPreformattedText(int c) {
if (c == '\r' || c == '\n')
fCounter++;
return null;
}
private void unread(int ch) throws IOException {
((PushbackReader) getReader()).unread(ch);
}
protected String entity2Text(String symbol) {
if (symbol.length() > 1 && symbol.charAt(0) == '#') {
int ch;
try {
if (symbol.charAt(1) == 'x') {
ch= Integer.parseInt(symbol.substring(2), 16);
} else {
ch= Integer.parseInt(symbol.substring(1), 10);
}
return EMPTY_STRING + (char)ch;
} catch (NumberFormatException e) {
}
} else {
String str= (String) fgEntityLookup.get(symbol);
if (str != null) {
return str;
}
}
return "&" + symbol; // not found //$NON-NLS-1$
}
/*
* A '&' has been read. Process a entity
*/
private String processEntity() throws IOException {
StringBuffer buf= new StringBuffer();
int ch= nextChar();
while (Character.isLetterOrDigit((char)ch) || ch == '#') {
buf.append((char) ch);
ch= nextChar();
}
if (ch == ';')
return entity2Text(buf.toString());
buf.insert(0, '&');
if (ch != -1)
buf.append((char) ch);
return buf.toString();
}
}

View file

@ -0,0 +1,152 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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.debug.internal.ui;
import java.io.IOException;
import java.io.Reader;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* Provides a set of convenience methods for creating HTML pages.
*/
public class HTMLPrinter {
private HTMLPrinter() {
}
private static String replace(String text, char c, String s) {
int previous= 0;
int current= text.indexOf(c, previous);
if (current == -1)
return text;
StringBuffer buffer= new StringBuffer();
while (current > -1) {
buffer.append(text.substring(previous, current));
buffer.append(s);
previous= current + 1;
current= text.indexOf(c, previous);
}
buffer.append(text.substring(previous));
return buffer.toString();
}
public static String convertToHTMLContent(String content) {
content= replace(content, '<', "&lt;"); //$NON-NLS-1$
return replace(content, '>', "&gt;"); //$NON-NLS-1$
}
public static String read(Reader rd) {
StringBuffer buffer= new StringBuffer();
char[] readBuffer= new char[2048];
try {
int n= rd.read(readBuffer);
while (n > 0) {
buffer.append(readBuffer, 0, n);
n= rd.read(readBuffer);
}
return buffer.toString();
} catch (IOException x) {
}
return null;
}
public static void insertPageProlog(StringBuffer buffer, int position, RGB bgRGB) {
if (bgRGB == null)
insertPageProlog(buffer, position);
else {
StringBuffer pageProlog= new StringBuffer(60);
pageProlog.append("<html><body text=\"#000000\" bgcolor=\""); //$NON-NLS-1$
appendColor(pageProlog, bgRGB);
pageProlog.append("\"><font size=-1>"); //$NON-NLS-1$
buffer.insert(position, pageProlog.toString());
}
}
private static void appendColor(StringBuffer buffer, RGB rgb) {
buffer.append('#');
buffer.append(Integer.toHexString(rgb.red));
buffer.append(Integer.toHexString(rgb.green));
buffer.append(Integer.toHexString(rgb.blue));
}
public static void insertPageProlog(StringBuffer buffer, int position) {
RGB bgColor= null;
IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (window != null) {
Display display= window.getShell().getDisplay();
if (display != null && !display.isDisposed())
bgColor= display.getSystemColor(SWT.COLOR_INFO_BACKGROUND).getRGB();
}
if (bgColor == null)
bgColor= new RGB(255,255, 225); // RGB value of info bg color on WindowsXP
insertPageProlog(buffer, position, bgColor); //$NON-NLS-1$
}
public static void addPageProlog(StringBuffer buffer) {
insertPageProlog(buffer, buffer.length());
}
public static void addPageEpilog(StringBuffer buffer) {
buffer.append("</font></body></html>"); //$NON-NLS-1$
}
public static void startBulletList(StringBuffer buffer) {
buffer.append("<ul>"); //$NON-NLS-1$
}
public static void endBulletList(StringBuffer buffer) {
buffer.append("</ul>"); //$NON-NLS-1$
}
public static void addBullet(StringBuffer buffer, String bullet) {
if (bullet != null) {
buffer.append("<li>"); //$NON-NLS-1$
buffer.append(bullet);
buffer.append("</li>"); //$NON-NLS-1$
}
}
public static void addSmallHeader(StringBuffer buffer, String header) {
if (header != null) {
buffer.append("<h5>"); //$NON-NLS-1$
buffer.append(header);
buffer.append("</h5>"); //$NON-NLS-1$
}
}
public static void addParagraph(StringBuffer buffer, String paragraph) {
if (paragraph != null) {
buffer.append("<p>"); //$NON-NLS-1$
buffer.append(paragraph);
}
}
public static void addParagraph(StringBuffer buffer, Reader paragraphReader) {
if (paragraphReader != null)
addParagraph(buffer, read(paragraphReader));
}
}

View file

@ -0,0 +1,188 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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.debug.internal.ui;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyMessages;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;
public class HTMLTextPresenter implements DefaultInformationControl.IInformationPresenter {
private static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
private int fCounter;
private boolean fEnforceUpperLineLimit;
public HTMLTextPresenter(boolean enforceUpperLineLimit) {
super();
fEnforceUpperLineLimit= enforceUpperLineLimit;
}
public HTMLTextPresenter() {
this(true);
}
protected Reader createReader(String hoverInfo, TextPresentation presentation) {
return new HTML2TextReader(new StringReader(hoverInfo), presentation);
}
protected void adaptTextPresentation(TextPresentation presentation, int offset, int insertLength) {
int yoursStart= offset;
int yoursEnd= offset + insertLength -1;
yoursEnd= Math.max(yoursStart, yoursEnd);
Iterator e= presentation.getAllStyleRangeIterator();
while (e.hasNext()) {
StyleRange range= (StyleRange) e.next();
int myStart= range.start;
int myEnd= range.start + range.length -1;
myEnd= Math.max(myStart, myEnd);
if (myEnd < yoursStart)
continue;
if (myStart < yoursStart)
range.length += insertLength;
else
range.start += insertLength;
}
}
private void append(StringBuffer buffer, String string, TextPresentation presentation) {
int length= string.length();
buffer.append(string);
if (presentation != null)
adaptTextPresentation(presentation, fCounter, length);
fCounter += length;
}
private String getIndent(String line) {
int length= line.length();
int i= 0;
while (i < length && Character.isWhitespace(line.charAt(i))) ++i;
return (i == length ? line : line.substring(0, i)) + " "; //$NON-NLS-1$
}
/*
* @see IHoverInformationPresenter#updatePresentation(Display display, String, TextPresentation, int, int)
*/
public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
if (hoverInfo == null)
return null;
GC gc= new GC(display);
try {
StringBuffer buffer= new StringBuffer();
int maxNumberOfLines= Math.round(maxHeight / gc.getFontMetrics().getHeight());
fCounter= 0;
LineBreakingReader reader= new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth);
boolean lastLineFormatted= false;
String lastLineIndent= null;
String line=reader.readLine();
boolean lineFormatted= reader.isFormattedLine();
boolean firstLineProcessed= false;
while (line != null) {
if (fEnforceUpperLineLimit && maxNumberOfLines <= 0)
break;
if (firstLineProcessed) {
if (!lastLineFormatted)
append(buffer, LINE_DELIM, null);
else {
append(buffer, LINE_DELIM, presentation);
if (lastLineIndent != null)
append(buffer, lastLineIndent, presentation);
}
}
append(buffer, line, null);
firstLineProcessed= true;
lastLineFormatted= lineFormatted;
if (!lineFormatted)
lastLineIndent= null;
else if (lastLineIndent == null)
lastLineIndent= getIndent(line);
line= reader.readLine();
lineFormatted= reader.isFormattedLine();
maxNumberOfLines--;
}
if (line != null) {
append(buffer, LINE_DELIM, lineFormatted ? presentation : null);
append(buffer, DisassemblyMessages.getString( "HTMLTextPresenter.ellipsis" ), presentation); //$NON-NLS-1$
}
return trim(buffer, presentation);
} catch (IOException e) {
DebugPlugin.log(e);
return null;
} finally {
gc.dispose();
}
}
private String trim(StringBuffer buffer, TextPresentation presentation) {
int length= buffer.length();
int end= length -1;
while (end >= 0 && Character.isWhitespace(buffer.charAt(end)))
-- end;
if (end == -1)
return ""; //$NON-NLS-1$
if (end < length -1)
buffer.delete(end + 1, length);
else
end= length;
int start= 0;
while (start < end && Character.isWhitespace(buffer.charAt(start)))
++ start;
buffer.delete(0, start);
presentation.setResultWindow(new Region(start, buffer.length()));
return buffer.toString();
}
}

View file

@ -0,0 +1,113 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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.debug.internal.ui;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.text.BreakIterator;
import org.eclipse.swt.graphics.GC;
/*
* Not a real reader. Could change if requested
*/
public class LineBreakingReader {
private BufferedReader fReader;
private GC fGC;
private int fMaxWidth;
private String fLine;
private int fOffset;
private BreakIterator fLineBreakIterator;
/**
* Creates a reader that breaks an input text to fit in a given width.
* @param reader Reader of the input text
* @param gc The graphic context that defines the currently used font sizes
* @param maxLineWidth The max width (pixes) where the text has to fit in
*/
public LineBreakingReader(Reader reader, GC gc, int maxLineWidth) {
fReader= new BufferedReader(reader);
fGC= gc;
fMaxWidth= maxLineWidth;
fOffset= 0;
fLine= null;
fLineBreakIterator= BreakIterator.getLineInstance();
}
public boolean isFormattedLine() {
return fLine != null;
}
/**
* Reads the next line. The lengths of the line will not exceed the gived maximum
* width.
*/
public String readLine() throws IOException {
if (fLine == null) {
String line= fReader.readLine();
if (line == null)
return null;
int lineLen= fGC.textExtent(line).x;
if (lineLen < fMaxWidth) {
return line;
}
fLine= line;
fLineBreakIterator.setText(line);
fOffset= 0;
}
int breakOffset= findNextBreakOffset(fOffset);
String res;
if (breakOffset != BreakIterator.DONE) {
res= fLine.substring(fOffset, breakOffset);
fOffset= findWordBegin(breakOffset);
if (fOffset == fLine.length()) {
fLine= null;
}
} else {
res= fLine.substring(fOffset);
fLine= null;
}
return res;
}
private int findNextBreakOffset(int currOffset) {
int currWidth= 0;
int nextOffset= fLineBreakIterator.following(currOffset);
while (nextOffset != BreakIterator.DONE) {
String word= fLine.substring(currOffset, nextOffset);
int wordWidth= fGC.textExtent(word).x;
int nextWidth= wordWidth + currWidth;
if (nextWidth > fMaxWidth) {
if (currWidth > 0) {
return currOffset;
} else {
return nextOffset;
}
}
currWidth= nextWidth;
currOffset= nextOffset;
nextOffset= fLineBreakIterator.next();
}
return nextOffset;
}
private int findWordBegin(int idx) {
while (idx < fLine.length() && Character.isWhitespace(fLine.charAt(idx))) {
idx++;
}
return idx;
}
}

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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.debug.internal.ui;
import java.io.IOException;
import java.io.Reader;
public abstract class SingleCharReader extends Reader {
/**
* @see Reader#read()
*/
public abstract int read() throws IOException;
/**
* @see Reader#read(char[],int,int)
*/
public int read(char cbuf[], int off, int len) throws IOException {
int end= off + len;
for (int i= off; i < end; i++) {
int ch= read();
if (ch == -1) {
if (i == off) {
return -1;
} else {
return i - off;
}
}
cbuf[i]= (char)ch;
}
return len;
}
/**
* @see Reader#ready()
*/
public boolean ready() throws IOException {
return true;
}
/**
* Gets the content as a String
*/
public String getString() throws IOException {
StringBuffer buf= new StringBuffer();
int ch;
while ((ch= read()) != -1) {
buf.append((char)ch);
}
return buf.toString();
}
}

View file

@ -0,0 +1,148 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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.debug.internal.ui;
import java.io.IOException;
import java.io.Reader;
/**
* Reads the text contents from a reader and computes for each character
* a potential substitution. The substitution may eat more characters than
* only the one passed into the computation routine.
*/
public abstract class SubstitutionTextReader extends SingleCharReader {
protected static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
private Reader fReader;
private boolean fWasWhiteSpace;
private int fCharAfterWhiteSpace;
/**
* Tells whether white space characters are skipped.
*/
private boolean fSkipWhiteSpace= true;
private boolean fReadFromBuffer;
private StringBuffer fBuffer;
private int fIndex;
protected SubstitutionTextReader(Reader reader) {
fReader= reader;
fBuffer= new StringBuffer();
fIndex= 0;
fReadFromBuffer= false;
fCharAfterWhiteSpace= -1;
fWasWhiteSpace= true;
}
/**
* Implement to compute the substitution for the given character and
* if necessary subsequent characters. Use <code>nextChar</code>
* to read subsequent characters.
*/
protected abstract String computeSubstitution(int c) throws IOException;
/**
* Returns the internal reader.
*/
protected Reader getReader() {
return fReader;
}
/**
* Returns the next character.
*/
protected int nextChar() throws IOException {
fReadFromBuffer= (fBuffer.length() > 0);
if (fReadFromBuffer) {
char ch= fBuffer.charAt(fIndex++);
if (fIndex >= fBuffer.length()) {
fBuffer.setLength(0);
fIndex= 0;
}
return ch;
} else {
int ch= fCharAfterWhiteSpace;
if (ch == -1) {
ch= fReader.read();
}
if (fSkipWhiteSpace && Character.isWhitespace((char)ch)) {
do {
ch= fReader.read();
} while (Character.isWhitespace((char)ch));
if (ch != -1) {
fCharAfterWhiteSpace= ch;
return ' ';
}
} else {
fCharAfterWhiteSpace= -1;
}
return ch;
}
}
/**
* @see Reader#read()
*/
public int read() throws IOException {
int c;
do {
c= nextChar();
while (!fReadFromBuffer) {
String s= computeSubstitution(c);
if (s == null)
break;
if (s.length() > 0)
fBuffer.insert(0, s);
c= nextChar();
}
} while (fSkipWhiteSpace && fWasWhiteSpace && (c == ' '));
fWasWhiteSpace= (c == ' ' || c == '\r' || c == '\n');
return c;
}
/**
* @see Reader#ready()
*/
public boolean ready() throws IOException {
return fReader.ready();
}
/**
* @see Reader#close()
*/
public void close() throws IOException {
fReader.close();
}
/**
* @see Reader#reset()
*/
public void reset() throws IOException {
fReader.reset();
fWasWhiteSpace= true;
fCharAfterWhiteSpace= -1;
fBuffer.setLength(0);
fIndex= 0;
}
protected final void setSkipWhitespace(boolean state) {
fSkipWhiteSpace= state;
}
protected final boolean isSkippingWhitespace() {
return fSkipWhiteSpace;
}
}

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyEditorInpu
import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyView;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
@ -251,6 +252,10 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget {
if ( input instanceof IStorageEditorInput ) {
return ((IStorageEditorInput)input).getStorage().getName();
}
if ( input instanceof DisassemblyEditorInput ) {
IFile file = ((DisassemblyEditorInput)input).getModuleFile();
return ( file != null ) ? file.getLocation().toOSString() : ""; //$NON-NLS-1$
}
return ""; //$NON-NLS-1$
}
}

View file

@ -0,0 +1,145 @@
/**********************************************************************
* Copyright (c) 2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.debug.internal.ui.HTMLPrinter;
import org.eclipse.core.resources.IMarker;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.texteditor.MarkerAnnotation;
/**
* Annotation hovering support for disassembly view.
*/
public class DisassemblyAnnotationHover implements IAnnotationHover {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
*/
public String getHoverInfo( ISourceViewer sourceViewer, int lineNumber ) {
List markers = getMarkersForLine( sourceViewer, lineNumber );
if ( markers != null ) {
if ( markers.size() == 1 ) {
// optimization
IMarker marker = (IMarker)markers.get( 0 );
String message = marker.getAttribute( IMarker.MESSAGE, (String)null );
if ( message != null && message.trim().length() > 0 )
return formatSingleMessage( message );
}
else {
List messages = new ArrayList();
Iterator e = markers.iterator();
while( e.hasNext() ) {
IMarker marker = (IMarker)e.next();
String message = marker.getAttribute( IMarker.MESSAGE, (String)null );
if ( message != null && message.trim().length() > 0 )
messages.add( message.trim() );
}
if ( messages.size() == 1 )
return formatSingleMessage( (String)messages.get( 0 ) );
if ( messages.size() > 1 )
return formatMultipleMessages( messages );
}
}
return null;
}
/**
* Returns the distance to the ruler line.
*/
protected int compareRulerLine( Position position, IDocument document, int line ) {
if ( position.getOffset() > -1 && position.getLength() > -1 ) {
try {
int markerLine = document.getLineOfOffset( position.getOffset() );
if ( line == markerLine )
return 1;
if ( markerLine <= line && line <= document.getLineOfOffset( position.getOffset() + position.getLength() ) )
return 2;
}
catch( BadLocationException x ) {
}
}
return 0;
}
/*
* Formats a message as HTML text.
*/
private String formatSingleMessage( String message ) {
StringBuffer buffer = new StringBuffer();
HTMLPrinter.addPageProlog( buffer );
HTMLPrinter.addParagraph( buffer, HTMLPrinter.convertToHTMLContent( message ) );
HTMLPrinter.addPageEpilog( buffer );
return buffer.toString();
}
/*
* Formats several message as HTML text.
*/
private String formatMultipleMessages( List messages ) {
StringBuffer buffer = new StringBuffer();
HTMLPrinter.addPageProlog( buffer );
HTMLPrinter.addParagraph( buffer, HTMLPrinter.convertToHTMLContent( DisassemblyMessages.getString( "DisassemblyAnnotationHover.Multiple_markers_at_this_line_1" ) ) ); //$NON-NLS-1$
HTMLPrinter.startBulletList( buffer );
Iterator e = messages.iterator();
while( e.hasNext() )
HTMLPrinter.addBullet( buffer, HTMLPrinter.convertToHTMLContent( (String)e.next() ) );
HTMLPrinter.endBulletList( buffer );
HTMLPrinter.addPageEpilog( buffer );
return buffer.toString();
}
/**
* Returns one marker which includes the ruler's line of activity.
*/
protected List getMarkersForLine( ISourceViewer viewer, int line ) {
IDocument document = viewer.getDocument();
IAnnotationModel model = viewer.getAnnotationModel();
if ( model == null )
return null;
List exact = new ArrayList();
List including = new ArrayList();
Iterator e = model.getAnnotationIterator();
while( e.hasNext() ) {
Object o = e.next();
if ( o instanceof MarkerAnnotation ) {
MarkerAnnotation a = (MarkerAnnotation)o;
switch( compareRulerLine( model.getPosition( a ), document, line ) ) {
case 1:
exact.add( a.getMarker() );
break;
case 2:
including.add( a.getMarker() );
break;
}
}
}
return select( exact, including );
}
/**
* Selects a set of markers from the two lists. By default, it just returns
* the set of exact matches.
*/
protected List select( List exactMatch, List including ) {
return exactMatch;
}
}

View file

@ -0,0 +1,216 @@
/**********************************************************************
* Copyright (c) 2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointsListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.texteditor.MarkerAnnotation;
/**
* Annotation model for Disassembly view.
*/
public class DisassemblyAnnotationModel extends AnnotationModel implements IBreakpointsListener {
private DisassemblyEditorInput fInput;
private IDocument fDisassemblyDocument;
/**
* Constructor for DisassemblyAnnotationModel.
*/
public DisassemblyAnnotationModel( IDocument document ) {
super();
fDisassemblyDocument = document;
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener( this );
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
*/
public void breakpointsAdded( final IBreakpoint[] breakpoints ) {
if ( getInput().equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ||
getInput().equals( DisassemblyEditorInput.PENDING_EDITOR_INPUT ) )
return;
asyncExec( new Runnable() {
public void run() {
breakpointsAdded0( breakpoints );
}
} );
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
*/
public void breakpointsRemoved( final IBreakpoint[] breakpoints, IMarkerDelta[] deltas ) {
if ( getInput().equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ||
getInput().equals( DisassemblyEditorInput.PENDING_EDITOR_INPUT ) )
return;
asyncExec( new Runnable() {
public void run() {
breakpointsRemoved0( breakpoints );
}
} );
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
*/
public void breakpointsChanged( final IBreakpoint[] breakpoints, IMarkerDelta[] deltas ) {
if ( getInput().equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ||
getInput().equals( DisassemblyEditorInput.PENDING_EDITOR_INPUT ) )
return;
asyncExec( new Runnable() {
public void run() {
breakpointsChanged0( breakpoints );
}
} );
}
protected void breakpointsAdded0( IBreakpoint[] breakpoints ) {
for ( int i = 0; i < breakpoints.length; ++i ) {
if ( breakpoints[i] instanceof ICLineBreakpoint && isApplicable( breakpoints[i] ) ) {
addBreakpointAnnotation( (ICLineBreakpoint)breakpoints[i] );
}
}
fireModelChanged();
}
protected void breakpointsRemoved0( IBreakpoint[] breakpoints ) {
removeAnnotations( findAnnotationsforBreakpoints( breakpoints ), true, false );
}
protected void breakpointsChanged0( IBreakpoint[] breakpoints ) {
List annotations = findAnnotationsforBreakpoints( breakpoints );
List markers = new ArrayList( annotations.size() );
Iterator it = annotations.iterator();
while( it.hasNext() ) {
MarkerAnnotation ma = (MarkerAnnotation)it.next();
markers.add( ma.getMarker() );
modifyAnnotationPosition( ma, getPosition( ma ), false );
}
for ( int i = 0; i < breakpoints.length; ++i ) {
if ( breakpoints[i] instanceof ICLineBreakpoint && !markers.contains( breakpoints[i].getMarker() ) ) {
addBreakpointAnnotation( (ICLineBreakpoint)breakpoints[i] );
}
}
fireModelChanged();
}
protected DisassemblyEditorInput getInput() {
return this.fInput;
}
protected void setInput( DisassemblyEditorInput input ) {
DisassemblyEditorInput oldInput = this.fInput;
this.fInput = input;
if ( this.fInput != null && !this.fInput.equals( oldInput ) )
updateAnnotations();
}
private boolean isApplicable( IBreakpoint breakpoint ) {
return true;
}
private void addBreakpointAnnotation( ICLineBreakpoint breakpoint ) {
Position position = createBreakpointPosition( breakpoint );
if ( position != null ) {
try {
addAnnotation( createMarkerAnnotation( breakpoint ), position, false );
}
catch( BadLocationException e ) {
}
}
}
private Position createBreakpointPosition( ICLineBreakpoint breakpoint ) {
Position position = null;
DisassemblyEditorInput input = getInput();
if ( input != null ) {
long address = input.getBreakpointAddress( breakpoint );
int start = -1;
if ( address > 0 && fDisassemblyDocument != null ) {
int instrNumber = input.getInstructionNumber( address );
if ( instrNumber > 0 ) {
try {
start = fDocument.getLineOffset( instrNumber - 1 );
if ( start > -1 ) {
return new Position( start, fDisassemblyDocument.getLineLength( instrNumber - 1 ) );
}
}
catch( BadLocationException e ) {
}
}
}
}
return position;
}
private MarkerAnnotation createMarkerAnnotation( IBreakpoint breakpoint ) {
return new MarkerAnnotation( breakpoint.getMarker() );
}
protected void dispose() {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener( this );
}
private List findAnnotationsforBreakpoints( IBreakpoint[] breakpoints ) {
List annotations = new LinkedList();
Iterator it = getAnnotationIterator();
while ( it.hasNext() ) {
Annotation ann = (Annotation)it.next();
if ( ann instanceof MarkerAnnotation ) {
IMarker marker = ((MarkerAnnotation)ann).getMarker();
if ( marker != null ) {
for ( int i = 0; i < breakpoints.length; ++i ) {
if ( marker.equals( breakpoints[i].getMarker() ) ) {
annotations.add( ann );
}
}
}
}
}
return annotations;
}
private void asyncExec( Runnable r ) {
Display display = DebugUIPlugin.getStandardDisplay();
if ( display != null )
display.asyncExec( r );
}
private void updateAnnotations() {
asyncExec( new Runnable() {
public void run() {
doUpdateAnnotations();
}
} );
}
protected void doUpdateAnnotations() {
breakpointsAdded0( DebugPlugin.getDefault().getBreakpointManager().getBreakpoints() );
}
}

View file

@ -25,7 +25,8 @@ public class DisassemblyDocumentProvider implements IDocumentProvider {
private IDocument fDocument;
private DisassemblyMarkerAnnotationModel fAnnotationModel;
// private DisassemblyMarkerAnnotationModel fAnnotationModel;
private DisassemblyAnnotationModel fAnnotationModel;
/**
* Constructor for DisassemblyDocumentProvider.
@ -121,7 +122,8 @@ public class DisassemblyDocumentProvider implements IDocumentProvider {
*/
public IAnnotationModel getAnnotationModel( Object element ) {
if ( fAnnotationModel == null ) {
fAnnotationModel = new DisassemblyMarkerAnnotationModel();
// fAnnotationModel = new DisassemblyMarkerAnnotationModel( getDocument( element ) );
fAnnotationModel = new DisassemblyAnnotationModel( getDocument( element ) );
}
fAnnotationModel.setInput( ( element instanceof DisassemblyEditorInput ) ? (DisassemblyEditorInput)element : null );
return fAnnotationModel;
@ -156,5 +158,8 @@ public class DisassemblyDocumentProvider implements IDocumentProvider {
}
protected void dispose() {
if ( fAnnotationModel != null ) {
fAnnotationModel.dispose();
}
}
}

View file

@ -13,11 +13,14 @@ package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import java.util.Arrays;
import org.eclipse.cdt.debug.core.model.IAsmInstruction;
import org.eclipse.cdt.debug.core.model.IBreakpointTarget;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICStackFrame;
import org.eclipse.cdt.debug.core.model.IDisassembly;
import org.eclipse.cdt.debug.core.model.IExecFileInfo;
import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.debug.core.DebugException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;
@ -72,6 +75,21 @@ public class DisassemblyEditorInput implements IEditorInput {
return result;
}
public long getBreakpointAddress( ICLineBreakpoint breakpoint ) {
IDisassembly dis = getDisassembly();
if ( dis != null ) {
IBreakpointTarget bt = (IBreakpointTarget)dis.getDebugTarget().getAdapter( IBreakpointTarget.class );
if ( bt != null ) {
try {
return bt.getBreakpointAddress( breakpoint );
}
catch( DebugException e ) {
}
}
}
return 0;
}
private void createContent() {
StringBuffer lines = new StringBuffer();
int maxFunctionName = 0;
@ -234,7 +252,7 @@ public class DisassemblyEditorInput implements IEditorInput {
return ( fStorage != null ) ? fStorage.getContents() : ""; //$NON-NLS-1$
}
public int getLineNumber( long address ) {
public int getInstructionNumber( long address ) {
return ( fStorage != null ) ? fStorage.getLineNumber( address ) : 0;
}
@ -245,4 +263,8 @@ public class DisassemblyEditorInput implements IEditorInput {
public IFile getModuleFile() {
return ( fStorage != null ) ? fStorage.getModuleFile() : null;
}
public long getBreakpointAddress( ICLineBreakpoint breakpoint ) {
return ( fStorage != null ) ? fStorage.getBreakpointAddress( breakpoint ) : 0;
}
}

View file

@ -1,69 +0,0 @@
/**********************************************************************
* Copyright (c) 2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.Position;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
/**
* Marker annotation model for disassembly.
*/
public class DisassemblyMarkerAnnotationModel extends ResourceMarkerAnnotationModel {
private DisassemblyEditorInput fInput;
public DisassemblyMarkerAnnotationModel() {
super( ResourcesPlugin.getWorkspace().getRoot() );
}
protected DisassemblyEditorInput getInput() {
return this.fInput;
}
protected void setInput( DisassemblyEditorInput input ) {
this.fInput = input;
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#deleteMarkers(org.eclipse.core.resources.IMarker[])
*/
protected void deleteMarkers( IMarker[] markers ) throws CoreException {
// TODO Auto-generated method stub
super.deleteMarkers( markers );
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#isAcceptable(org.eclipse.core.resources.IMarker)
*/
protected boolean isAcceptable( IMarker marker ) {
// TODO Auto-generated method stub
return super.isAcceptable( marker );
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#retrieveMarkers()
*/
protected IMarker[] retrieveMarkers() throws CoreException {
// TODO Auto-generated method stub
return super.retrieveMarkers();
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#createPositionFromMarker(org.eclipse.core.resources.IMarker)
*/
protected Position createPositionFromMarker( IMarker marker ) {
// TODO Auto-generated method stub
return super.createPositionFromMarker( marker );
}
}

View file

@ -1,3 +1,6 @@
DisassemblyDocumentProvider.Pending_1=Pending...
DisassemblyInstructionPointerAnnotation.Current_Pointer_1=Current Disassembly Instruction Pointer
DisassemblyInstructionPointerAnnotation.Secondary_Pointer_1=Secondary Disassembly Instruction Pointer
DisassemblyAnnotationHover.Multiple_markers_at_this_line_1=Multiple markers at this line
HTMLTextPresenter.ellipsis=
HTML2TextReader.dash=-

View file

@ -74,6 +74,7 @@ public class DisassemblyView extends AbstractDebugEventHandlerView
IDebugExceptionHandler,
IDisassemblyListener {
/**
* The width of the vertical ruler.
*/
@ -140,6 +141,7 @@ public class DisassemblyView extends AbstractDebugEventHandlerView
fVerticalRuler = createVerticalRuler();
SourceViewer viewer = createSourceViewer( parent, fVerticalRuler );
viewer.configure( new DisassemblyViewerConfiguration() );
getSourceViewerDecorationSupport( viewer );
EditorsPlugin.getDefault().getPreferenceStore().addPropertyChangeListener( this );
@ -402,7 +404,7 @@ public class DisassemblyView extends AbstractDebugEventHandlerView
*/
private IRegion getLineInformation( long address, IEditorInput input ) {
if ( input instanceof DisassemblyEditorInput ) {
int line = ((DisassemblyEditorInput)input).getLineNumber( address );
int line = ((DisassemblyEditorInput)input).getInstructionNumber( address );
if ( line > 0 ) {
try {
return getSourceViewer().getDocument().getLineInformation( --line );

View file

@ -0,0 +1,56 @@
/**********************************************************************
* Copyright (c) 2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import org.eclipse.cdt.debug.internal.ui.HTMLTextPresenter;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
/**
* Viewer configuration for disassembly.
*/
public class DisassemblyViewerConfiguration extends SourceViewerConfiguration {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
*/
public IAnnotationHover getAnnotationHover( ISourceViewer sourceViewer ) {
return new DisassemblyAnnotationHover();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getInformationControlCreator(org.eclipse.jface.text.source.ISourceViewer)
*/
public IInformationControlCreator getInformationControlCreator( ISourceViewer sourceViewer ) {
return getInformationControlCreator( sourceViewer, true );
}
public IInformationControlCreator getInformationControlCreator( ISourceViewer sourceViewer, final boolean cutDown ) {
return new IInformationControlCreator() {
public IInformationControl createInformationControl( Shell parent ) {
int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
return new DefaultInformationControl( parent, style, new HTMLTextPresenter( cutDown ) );
// return new HoverBrowserControl(parent);
}
};
}
}