001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.cnd.debugger.gdb;
043:
044: import java.io.IOException;
045: import javax.swing.JEditorPane;
046: import javax.swing.text.BadLocationException;
047: import javax.swing.text.Element;
048: import javax.swing.text.StyledDocument;
049:
050: import org.openide.cookies.EditorCookie;
051: import org.openide.loaders.DataObject;
052: import org.openide.text.Annotation;
053: import org.openide.text.DataEditorSupport;
054: import org.openide.text.Line;
055: import org.openide.text.NbDocument;
056: import org.openide.text.Line.Part;
057: import org.netbeans.api.debugger.DebuggerEngine;
058: import org.netbeans.api.debugger.DebuggerManager;
059: import org.openide.nodes.Node;
060: import org.openide.windows.TopComponent;
061:
062: /*
063: * ToolTipAnnotation.java
064: * This class implements "Balloon Evaluation" feature.
065: *
066: * @author Nik Molchanov (copied from JPDA implementation)
067: */
068: public class ToolTipAnnotation extends Annotation {
069:
070: private String expression;
071:
072: public String getShortDescription() {
073: DebuggerEngine currentEngine = DebuggerManager
074: .getDebuggerManager().getCurrentEngine();
075: if (currentEngine == null) {
076: return null;
077: }
078: GdbDebugger debugger = currentEngine.lookupFirst(null,
079: GdbDebugger.class);
080: if (debugger == null) {
081: return null;
082: }
083: Part lp = (Part) getAttachedAnnotatable();
084: if (lp == null) {
085: return null;
086: }
087: Line line = lp.getLine();
088: DataObject dob = DataEditorSupport.findDataObject(line);
089: if (dob == null) {
090: return null;
091: }
092: EditorCookie ec = dob.getCookie(EditorCookie.class);
093: if (ec == null) {
094: return null;
095: }
096:
097: try {
098: StyledDocument doc = ec.openDocument();
099: JEditorPane ep = getCurrentEditor();
100: if (ep == null) {
101: return null;
102: }
103: synchronized (this ) {
104: expression = getIdentifier(doc, ep, NbDocument
105: .findLineOffset(doc, lp.getLine()
106: .getLineNumber())
107: + lp.getColumn());
108: if (expression == null) {
109: return null;
110: }
111: }
112: try {
113: // There is a small window during debugger startup when getGdbProxy() returns null
114: return debugger.evaluateToolTip(expression);
115: } catch (NullPointerException npe) {
116: }
117: } catch (IOException e) {
118: }
119: return null;
120: }
121:
122: public String getAnnotationType() {
123: return null; // Currently return null annotation type
124: }
125:
126: private static String getIdentifier(StyledDocument doc,
127: JEditorPane ep, int offset) {
128: String t = null;
129: if ((ep.getSelectionStart() <= offset)
130: && (offset <= ep.getSelectionEnd())) {
131: t = ep.getSelectedText();
132: }
133: if (t != null) {
134: return t;
135: }
136:
137: int line = NbDocument.findLineNumber(doc, offset);
138: int col = NbDocument.findLineColumn(doc, offset);
139: try {
140: Element lineElem = NbDocument.findLineRootElement(doc)
141: .getElement(line);
142:
143: if (lineElem == null) {
144: return null;
145: }
146: int lineStartOffset = lineElem.getStartOffset();
147: int lineLen = lineElem.getEndOffset() - lineStartOffset;
148: t = doc.getText(lineStartOffset, lineLen);
149: int identStart = col;
150: while (identStart > 0
151: && (Character.isJavaIdentifierPart(t
152: .charAt(identStart - 1)) || (t
153: .charAt(identStart - 1) == '.'))) {
154: identStart--;
155: }
156: int identEnd = col;
157: while (identEnd < lineLen
158: && Character.isJavaIdentifierPart(t
159: .charAt(identEnd))) {
160: identEnd++;
161: }
162:
163: if (identStart == identEnd) {
164: return null;
165: }
166: return t.substring(identStart, identEnd);
167: } catch (BadLocationException e) {
168: return null;
169: }
170: }
171:
172: /**
173: * Returns current editor component instance.
174: *
175: * Used in: ToolTipAnnotation
176: */
177: private static JEditorPane getCurrentEditor() {
178: EditorCookie e = getCurrentEditorCookie();
179: if (e == null) {
180: return null;
181: }
182: JEditorPane[] op = EditorContextImpl.getOpenedPanes(e);
183: if ((op == null) || (op.length < 1)) {
184: return null;
185: }
186: return op[0];
187: }
188:
189: /**
190: * Returns current editor component instance.
191: *
192: * @return current editor component instance
193: */
194: private static EditorCookie getCurrentEditorCookie() {
195: Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
196: if (nodes == null || nodes.length != 1) {
197: return null;
198: }
199: Node n = nodes[0];
200: return (EditorCookie) n.getCookie(EditorCookie.class);
201: }
202: }
|