# HG changeset patch # User Peter Hofer # Date 1306934560 -7200 # Node ID 6960cc79f664e889824502a5ac99c6fa416b1d70 # Parent 7596ae867a7bc654341020822ed3d4bd599537a0 IdealGraphVisualizer: Import editor component from C1XVisualizer diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/build.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/build.xml Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,8 @@ + + + + + + Builds, tests, and runs the project at.ssw.visualizer.texteditor. + + diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/manifest.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/manifest.mf Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +OpenIDE-Module: at.ssw.visualizer.texteditor +OpenIDE-Module-Layer: at/ssw/visualizer/texteditor/layer.xml +OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/texteditor/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/build-impl.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/build-impl.xml Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,45 @@ + + + + + + + + + + + + + You must set 'suite.dir' to point to your containing module suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/genfiles.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/genfiles.properties Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,8 @@ +build.xml.data.CRC32=d16e475b +build.xml.script.CRC32=eccfca0f +build.xml.stylesheet.CRC32=a56c6a5b@1.45.1 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=d16e475b +nbproject/build-impl.xml.script.CRC32=72c794c1 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1 diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/platform.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/platform.properties Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,125 @@ +# Deprecated since 5.0u1; for compatibility with 5.0: +disabled.clusters=\ + apisupport1,\ + enterprise4,\ + harness,\ + java1,\ + mobility8,\ + nb6.0,\ + profiler2,\ + ruby1,\ + uml4,\ + visualweb1,\ + xml1 +disabled.modules=\ + org.apache.xml.resolver,\ + org.netbeans.api.debugger,\ + org.netbeans.api.xml,\ + org.netbeans.core.ide,\ + org.netbeans.core.multiview,\ + org.netbeans.core.output2,\ + org.netbeans.insane,\ + org.netbeans.lib.cvsclient,\ + org.netbeans.libs.commons_logging,\ + org.netbeans.libs.freemarker,\ + org.netbeans.libs.ini4j,\ + org.netbeans.libs.jsch,\ + org.netbeans.libs.jsr223,\ + org.netbeans.libs.lucene,\ + org.netbeans.libs.svnClientAdapter,\ + org.netbeans.libs.xerces,\ + org.netbeans.modules.autoupdate.services,\ + org.netbeans.modules.autoupdate.ui,\ + org.netbeans.modules.classfile,\ + org.netbeans.modules.core.kit,\ + org.netbeans.modules.css.visual,\ + org.netbeans.modules.db,\ + org.netbeans.modules.db.core,\ + org.netbeans.modules.db.kit,\ + org.netbeans.modules.db.sql.editor,\ + org.netbeans.modules.db.sql.visualeditor,\ + org.netbeans.modules.dbapi,\ + org.netbeans.modules.defaults,\ + org.netbeans.modules.diff,\ + org.netbeans.modules.editor.bookmarks,\ + org.netbeans.modules.editor.bracesmatching,\ + org.netbeans.modules.editor.codetemplates,\ + org.netbeans.modules.editor.completion,\ + org.netbeans.modules.editor.errorstripe,\ + org.netbeans.modules.editor.errorstripe.api,\ + org.netbeans.modules.editor.guards,\ + org.netbeans.modules.editor.highlights,\ + org.netbeans.modules.editor.indent,\ + org.netbeans.modules.editor.kit,\ + org.netbeans.modules.editor.structure,\ + org.netbeans.modules.extbrowser,\ + org.netbeans.modules.favorites,\ + org.netbeans.modules.html,\ + org.netbeans.modules.html.editor,\ + org.netbeans.modules.html.editor.lib,\ + org.netbeans.modules.html.lexer,\ + org.netbeans.modules.httpserver,\ + org.netbeans.modules.ide.kit,\ + org.netbeans.modules.image,\ + org.netbeans.modules.javahelp,\ + org.netbeans.modules.jumpto,\ + org.netbeans.modules.languages,\ + org.netbeans.modules.languages.bat,\ + org.netbeans.modules.languages.css,\ + org.netbeans.modules.languages.diff,\ + org.netbeans.modules.languages.javascript,\ + org.netbeans.modules.languages.manifest,\ + org.netbeans.modules.languages.sh,\ + org.netbeans.modules.localhistory,\ + org.netbeans.modules.project.ant,\ + org.netbeans.modules.project.libraries,\ + org.netbeans.modules.projectapi,\ + org.netbeans.modules.projectui,\ + org.netbeans.modules.projectuiapi,\ + org.netbeans.modules.properties,\ + org.netbeans.modules.properties.syntax,\ + org.netbeans.modules.refactoring.api,\ + org.netbeans.modules.schema2beans,\ + org.netbeans.modules.servletapi,\ + org.netbeans.modules.subversion,\ + org.netbeans.modules.tasklist.kit,\ + org.netbeans.modules.tasklist.projectint,\ + org.netbeans.modules.tasklist.todo,\ + org.netbeans.modules.tasklist.ui,\ + org.netbeans.modules.templates,\ + org.netbeans.modules.timers,\ + org.netbeans.modules.usersguide,\ + org.netbeans.modules.utilities,\ + org.netbeans.modules.utilities.project,\ + org.netbeans.modules.versioning,\ + org.netbeans.modules.versioning.system.cvss,\ + org.netbeans.modules.versioning.util,\ + org.netbeans.modules.web.flyingsaucer,\ + org.netbeans.modules.xml.axi,\ + org.netbeans.modules.xml.catalog,\ + org.netbeans.modules.xml.core,\ + org.netbeans.modules.xml.lexer,\ + org.netbeans.modules.xml.multiview,\ + org.netbeans.modules.xml.retriever,\ + org.netbeans.modules.xml.schema.completion,\ + org.netbeans.modules.xml.schema.model,\ + org.netbeans.modules.xml.tax,\ + org.netbeans.modules.xml.text,\ + org.netbeans.modules.xml.tools,\ + org.netbeans.modules.xml.wsdl.model,\ + org.netbeans.modules.xml.xam,\ + org.netbeans.modules.xml.xdm,\ + org.netbeans.modules.xsl,\ + org.netbeans.spi.debugger.ui,\ + org.netbeans.spi.editor.hints,\ + org.netbeans.spi.navigator,\ + org.netbeans.spi.palette,\ + org.netbeans.spi.tasklist,\ + org.netbeans.spi.viewmodel,\ + org.netbeans.swing.dirchooser,\ + org.openide.compat,\ + org.openide.util.enumerations +enabled.clusters=\ + ide8,\ + platform7 +nbplatform.active=default diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.properties Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,2 @@ +javac.source=1.5 +javac.compilerargs=-Xlint -Xlint:-serial diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.xml Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,152 @@ + + + org.netbeans.modules.apisupport.project + + + at.ssw.visualizer.texteditor + + + + at.ssw.visualizer + + + + + + at.ssw.visualizer.model + + + + + + org.netbeans.modules.editor + + + + 3 + 1.42.1.3.9.2 + + + + org.netbeans.modules.editor.fold + + + + 1 + 1.10.1 + + + + org.netbeans.modules.editor.lib + + + + 3 + 3.8.1.13.8 + + + + org.netbeans.modules.editor.lib2 + + + + 1 + 1.28.1.2 + + + + org.netbeans.modules.editor.mimelookup + + + + 1 + 1.11.1 + + + + org.netbeans.modules.editor.settings + + + + 1 + 1.24.1 + + + + org.netbeans.modules.editor.util + + + + 1 + 1.28.1 + + + + org.openide.actions + + + + 6.9.1.1 + + + + org.openide.awt + + + + 7.23.1 + + + + org.openide.nodes + + + + 7.9.1.1 + + + + org.openide.text + + + + 6.22.1 + + + + org.openide.util + + + + 7.22.1.1 + + + + org.openide.util.lookup + + + + 8.3.1 + + + + org.openide.windows + + + + 6.26.1 + + + + + at.ssw.visualizer.texteditor + at.ssw.visualizer.texteditor.fold + at.ssw.visualizer.texteditor.highlight + at.ssw.visualizer.texteditor.hyperlink + at.ssw.visualizer.texteditor.model + at.ssw.visualizer.texteditor.tooltip + at.ssw.visualizer.texteditor.view + + + + diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/suite.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/suite.properties Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,1 @@ +suite.dir=${basedir}/.. diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Bundle.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Bundle.properties Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,1 @@ +OpenIDE-Module-Name=Text Editor diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Editor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Editor.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,127 @@ +package at.ssw.visualizer.texteditor; + +import at.ssw.visualizer.core.selection.Selection; +import at.ssw.visualizer.core.selection.SelectionManager; +import at.ssw.visualizer.core.selection.SelectionProvider; +import at.ssw.visualizer.model.cfg.BasicBlock; +import at.ssw.visualizer.texteditor.model.BlockRegion; +import at.ssw.visualizer.texteditor.model.Text; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.openide.text.CloneableEditor; +import org.openide.windows.TopComponent; + +/** + * Abstract template class of a Editor class of the Visualizer. + * + * Must be initialized with a custom EditorSupport class and the + * method creatClonedObject must be overwritten by + * the Editor implementation. + * + * @author Alexander Reder + */ +public abstract class Editor extends CloneableEditor implements SelectionProvider { + + protected Selection selection; + private boolean selectionUpdating; + private BasicBlock[] curBlocks; + private boolean initialized; + + protected Editor(EditorSupport support) { + super(support); + selection = new Selection(); + selection.put(support.getControlFlowGraph()); + selection.addChangeListener(selectionListener); + } + + public Selection getSelection() { + return selection; + } + + @Override + protected void componentShowing() { + super.componentShowing(); + if (!initialized) { + getEditorPane().addCaretListener(caretListener); + initialized = true; + } + } + + @Override + protected void componentActivated() { + super.componentActivated(); + SelectionManager.getDefault().setSelection(selection); + } + + @Override + protected void componentClosed() { + super.componentClosed(); + SelectionManager.getDefault().removeSelection(selection); + } + + @Override + public int getPersistenceType() { + return TopComponent.PERSISTENCE_NEVER; + } + + private ChangeListener selectionListener = new ChangeListener() { + public void stateChanged(ChangeEvent event) { + if (selectionUpdating) { + return; + } + selectionUpdating = true; + + Text text = (Text) getEditorPane().getDocument().getProperty(Text.class); + BasicBlock[] newBlocks = selection.get(BasicBlock[].class); + + if (newBlocks != null && newBlocks.length > 0 && !Arrays.equals(curBlocks, newBlocks)) { + BlockRegion r = text.getBlocks().get(newBlocks[0]); + int startOffset = r.getNameStart(); + int endOffset = r.getNameEnd(); + + if (newBlocks.length > 1) { + for (BasicBlock b : newBlocks) { + r = text.getBlocks().get(b); + startOffset = Math.min(startOffset, r.getStart()); + endOffset = Math.max(endOffset, r.getEnd()); + } + } + + getEditorPane().select(startOffset, endOffset); + } + curBlocks = newBlocks; + selectionUpdating = false; + } + }; + + + private CaretListener caretListener = new CaretListener() { + public void caretUpdate(CaretEvent event) { + if (selectionUpdating) { + return; + } + selectionUpdating = true; + + Text text = (Text) getEditorPane().getDocument().getProperty(Text.class); + List newBlocks = new ArrayList(); + int startOffset = Math.min(event.getDot(), event.getMark()); + int endOffset = Math.max(event.getDot(), event.getMark()); + + for (BlockRegion region : text.getBlocks().values()) { + if (region.getStart() <= endOffset && region.getEnd() > startOffset) { + newBlocks.add(region.getBlock()); + } + } + + curBlocks = newBlocks.toArray(new BasicBlock[newBlocks.size()]); + selection.put(curBlocks); + selectionUpdating = false; + } + }; + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorKit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorKit.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,31 @@ +package at.ssw.visualizer.texteditor; + +import at.ssw.visualizer.texteditor.tooltip.ToolTipAction; +import javax.swing.Action; +import javax.swing.text.TextAction; +import org.netbeans.modules.editor.NbEditorKit; + +/** + * Abstract template class of a EditorKit class of the Visualizer. + * + * The scanner field must be initialized with the + * custom Scanner implementation and the method + * getContentType must be overwritten and return the mime type + * for the editor. + * + * @author Alexander Reder + */ +public abstract class EditorKit extends NbEditorKit { + + @Override + protected Action[] getCustomActions() { + Action[] prev = super.getCustomActions(); + Action[] added = new Action[]{new ToolTipAction()}; + if (prev != null) { + return TextAction.augmentList(prev, added); + } else { + return added; + } + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorSupport.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,151 @@ +package at.ssw.visualizer.texteditor; + +import at.ssw.visualizer.model.Compilation; +import at.ssw.visualizer.model.cfg.ControlFlowGraph; +import at.ssw.visualizer.texteditor.model.Text; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.beans.VetoableChangeListener; +import java.beans.VetoableChangeSupport; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Date; +import javax.swing.text.EditorKit; +import javax.swing.text.StyledDocument; +import org.openide.cookies.EditorCookie; +import org.openide.cookies.EditCookie; +import org.openide.text.CloneableEditorSupport; +import org.openide.windows.CloneableOpenSupport; + +/** + * Abstract template class of a EditorSupport class of the + * Visulizer. + * + * The text field must be initialized by the implementing class + * and the methods createCloneableEditor and + * initializeCloneableEditor must be overwritten by the implenting class. + * createCloneableEditor must return a custom implementation + * of the Editor class. + * initializeClonableEditor is used to set the icon, e.g. + * editor.setIcon(Utilities.loadImage(IconsImage)); . + * + * @author Bernhard Stiftner + * @author Christian Wimmer + * @author Alexander Reder + */ +public abstract class EditorSupport extends CloneableEditorSupport implements EditCookie, EditorCookie, EditorCookie.Observable { + + protected ControlFlowGraph cfg; + protected Text text; + + protected EditorSupport(ControlFlowGraph cfg) { + super(new Env()); + ((Env) this.env).editorSupport = this; + this.cfg = cfg; + } + + public ControlFlowGraph getControlFlowGraph() { + return cfg; + } + + @Override + protected StyledDocument createStyledDocument(EditorKit kit) { + StyledDocument doc = super.createStyledDocument(kit); + + // Back-link from Document to our internal data model. + doc.putProperty(Text.class, text); + doc.putProperty(Compilation.class, cfg.getCompilation()); + doc.putProperty(ControlFlowGraph.class, cfg); + + return doc; + } + + public abstract String getMimeType(); + + protected String messageOpening() { + return "Opening " + messageToolTip(); + } + + protected String messageOpened() { + return "Opened " + messageToolTip(); + } + + protected String messageSave() { + throw new UnsupportedOperationException("Not supported yet."); + } + + protected String messageName() { + return cfg.getCompilation().getShortName(); + } + + protected String messageToolTip() { + return cfg.getCompilation().getMethod() + " - " + cfg.getName(); + } + + public static class Env implements CloneableEditorSupport.Env { + + private PropertyChangeSupport prop = new PropertyChangeSupport(this); + private VetoableChangeSupport veto = new VetoableChangeSupport(this); + + /** + * Back-link to outer class EditorSupport. Env must be a static class + * because it is passed to super constructor of EditorSupport. + */ + private EditorSupport editorSupport; + + public InputStream inputStream() throws IOException { + return new ByteArrayInputStream(editorSupport.text.getText().getBytes()); + } + + public OutputStream outputStream() throws IOException { + throw new IOException("Editor is readonly"); + } + + public Date getTime() { + return editorSupport.cfg.getCompilation().getDate(); + } + + public String getMimeType() { + return editorSupport.getMimeType(); + } + + public boolean isValid() { + return true; + } + + public boolean isModified() { + return false; + } + + public void markModified() throws IOException { + throw new IOException("Editor is readonly"); + } + + public void unmarkModified() { + // Nothing to do. + } + + public CloneableOpenSupport findCloneableOpenSupport() { + return editorSupport; + } + + public void addPropertyChangeListener(PropertyChangeListener l) { + prop.addPropertyChangeListener(l); + } + + public void removePropertyChangeListener(PropertyChangeListener l) { + prop.removePropertyChangeListener(l); + } + + public void addVetoableChangeListener(VetoableChangeListener l) { + veto.addVetoableChangeListener(l); + } + + public void removeVetoableChangeListener(VetoableChangeListener l) { + veto.removeVetoableChangeListener(l); + } + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/fold/FoldManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/fold/FoldManager.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,81 @@ +package at.ssw.visualizer.texteditor.fold; + +import at.ssw.visualizer.texteditor.model.FoldingRegion; +import at.ssw.visualizer.texteditor.model.Text; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JComponent; +import javax.swing.event.DocumentEvent; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import org.netbeans.api.editor.fold.Fold; +import org.netbeans.editor.CodeFoldingSideBar; +import org.netbeans.spi.editor.fold.FoldHierarchyTransaction; +import org.netbeans.spi.editor.fold.FoldOperation; + +/** + * + * @author Alexander Reder + */ +public class FoldManager implements org.netbeans.spi.editor.fold.FoldManager { + + protected FoldOperation operation; + + public void init(FoldOperation operation) { + this.operation = operation; + } + + public void initFolds(FoldHierarchyTransaction transaction) { + Document document = operation.getHierarchy().getComponent().getDocument(); + Text text = (Text) document.getProperty(Text.class); + if (document.getLength() == 0 || text == null) { + return; + } + + try { + for (FoldingRegion fr : text.getFoldings()) { + operation.addToHierarchy(fr.getKind(), fr.getKind().toString(), fr.isInitiallyCollapsed(), fr.getStart(), fr.getEnd(), 0, 0, null, transaction); + } + } catch (BadLocationException ex) { + Logger logger = Logger.getLogger(FoldManager.class.getName()); + logger.log(Level.SEVERE, ex.getMessage(), ex); + } + } + + public void insertUpdate(DocumentEvent arg0, FoldHierarchyTransaction arg1) { + } + + public void removeUpdate(DocumentEvent arg0, FoldHierarchyTransaction arg1) { + } + + public void changedUpdate(DocumentEvent arg0, FoldHierarchyTransaction arg1) { + } + + public void removeEmptyNotify(Fold arg0) { + } + + public void removeDamagedNotify(Fold arg0) { + } + + public void expandNotify(Fold arg0) { + } + + public void release() { + } + + public static class FoldManagerFactory implements org.netbeans.spi.editor.fold.FoldManagerFactory { + + public FoldManager createFoldManager() { + return new FoldManager(); + } + } + + public static class SideBarFactory implements org.netbeans.editor.SideBarFactory { + + public JComponent createSideBar(JTextComponent target) { + return new CodeFoldingSideBar(target); + } + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/highlight/HighlightsContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/highlight/HighlightsContainer.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,119 @@ +package at.ssw.visualizer.texteditor.highlight; + +import at.ssw.visualizer.texteditor.model.Scanner; +import at.ssw.visualizer.texteditor.model.Text; +import at.ssw.visualizer.texteditor.model.TextRegion; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.Caret; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import javax.swing.text.SimpleAttributeSet; +import org.netbeans.api.editor.mimelookup.MimeLookup; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.editor.settings.FontColorSettings; +import org.netbeans.editor.TokenID; +import org.netbeans.spi.editor.highlighting.HighlightsSequence; +import org.netbeans.spi.editor.highlighting.ZOrder; +import org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer; +import org.openide.util.WeakListeners; + +/** + * + * @author Christian Wimmer + * @author Alexander Reder + */ +public class HighlightsContainer extends AbstractHighlightsContainer { + + private static final String HIGHLIGHT_COLORING = "at-ssw-visualizer-highlight"; + + protected final JTextComponent component; + protected final Document document; + protected final AttributeSet highlightColoring; + protected final Scanner scanner; + + protected TextRegion[] curRegions = null; + + private final CaretListener caretListener = new CaretListener() { + + public void caretUpdate(CaretEvent event) { + TextRegion[] newRegions = findRegions(); + if (newRegions != curRegions) { + curRegions = newRegions; + fireHighlightsChange(0, document.getLength()); + } + } + + }; + + protected HighlightsContainer(JTextComponent component, Document document) { + this.document = document; + this.component = component; + component.addCaretListener(WeakListeners.create(CaretListener.class, caretListener, component)); + + // Load the coloring. + Text t = (Text) document.getProperty(Text.class); + MimePath mimePath = MimePath.parse(t.getMimeType()); + FontColorSettings fcs = MimeLookup.getLookup(mimePath).lookup(FontColorSettings.class); + AttributeSet highlight = fcs.getFontColors(HIGHLIGHT_COLORING); + highlightColoring = highlight != null ? highlight : SimpleAttributeSet.EMPTY; + + scanner = t.getScanner(); + scanner.setText(document); + curRegions = findRegions(); + } + + public HighlightsSequence getHighlights(int startOffset, int endOffset) { + return new RegionSequence(); + } + + protected TextRegion[] findRegions() { + Text text = (Text) document.getProperty(Text.class); + Caret caret = component.getCaret(); + if (text == null || caret == null) { + return null; + } + scanner.findTokenBegin(caret.getDot()); + TokenID token = scanner.nextToken(); + if (token.getNumericID() < 0) { + return null; + } + + return text.getHighlighting(scanner.getTokenString()); + } + + protected class RegionSequence implements HighlightsSequence { + + private int idx = -1; + + public boolean moveNext() { + idx++; + return curRegions != null && idx < curRegions.length; + } + + public int getStartOffset() { + return curRegions[idx].getStart(); + } + + public int getEndOffset() { + return curRegions[idx].getEnd(); + } + + public AttributeSet getAttributes() { + return highlightColoring; + } + } + + public static final class HighlightsLayerFactory implements org.netbeans.spi.editor.highlighting.HighlightsLayerFactory { + + public org.netbeans.spi.editor.highlighting.HighlightsLayer[] createLayers(Context context) { + Text t = (Text) context.getDocument().getProperty(Text.class); + if(t == null) { + return new org.netbeans.spi.editor.highlighting.HighlightsLayer[0]; + } + return new org.netbeans.spi.editor.highlighting.HighlightsLayer[]{org.netbeans.spi.editor.highlighting.HighlightsLayer.create("at-ssw-visualizer-highlighting", ZOrder.SHOW_OFF_RACK, true, new HighlightsContainer(context.getComponent(), context.getDocument()))}; + } + + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/hyperlink/HyperlinkProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/hyperlink/HyperlinkProvider.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,57 @@ +package at.ssw.visualizer.texteditor.hyperlink; + +import at.ssw.visualizer.texteditor.model.Scanner; +import at.ssw.visualizer.texteditor.model.Text; +import at.ssw.visualizer.texteditor.model.TextRegion; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import org.netbeans.editor.TokenID; +import org.netbeans.editor.Utilities; + +/** + * + * @author Bernhard Stiftner + * @author Christian Wimmer + * @author Alexander Reder + */ +public class HyperlinkProvider implements org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider { + + protected Scanner scanner = null; + + protected TextRegion findTarget(Document doc, int offset) { + Text text = (Text) doc.getProperty(Text.class); + if (text == null) { + return null; + } + + scanner = text.getScanner(); + scanner.setText(doc); + scanner.findTokenBegin(offset); + TokenID token = scanner.nextToken(); + if (token.getNumericID() < 0) { + return null; + } + + return text.getHyperlinkTarget(scanner.getTokenString()); + } + + public boolean isHyperlinkPoint(Document doc, int offset) { + return findTarget(doc, offset) != null; + } + + public int[] getHyperlinkSpan(Document doc, int offset) { + if (findTarget(doc, offset) != null) { + return new int[]{scanner.getTokenOffset(), scanner.getTokenOffset() + scanner.getTokenLength()}; + } + return null; + } + + public void performClickAction(Document doc, int offset) { + TextRegion target = findTarget(doc, offset); + if (target != null) { + JTextComponent editor = Utilities.getFocusedComponent(); + editor.select(target.getStart(), target.getEnd()); + } + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/layer.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/layer.xml Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/BlockRegion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/BlockRegion.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,35 @@ +package at.ssw.visualizer.texteditor.model; + +import at.ssw.visualizer.model.cfg.BasicBlock; + +/** + * + * @author Christian Wimmer + */ +public class BlockRegion extends TextRegion { + + private BasicBlock block; + + private int nameStart; + private int nameEnd; + + public BlockRegion(BasicBlock block, int start, int end, int nameStart, int nameEnd) { + super(start, end); + this.block = block; + this.nameStart = nameStart; + this.nameEnd = nameEnd; + } + + + public BasicBlock getBlock() { + return block; + } + + public int getNameStart() { + return nameStart; + } + + public int getNameEnd() { + return nameEnd; + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/FoldingRegion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/FoldingRegion.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,32 @@ +package at.ssw.visualizer.texteditor.model; + +import org.netbeans.api.editor.fold.FoldType; + +/** + * + * @author Christian Wimmer + * @author Alexander Reder + */ +public class FoldingRegion extends TextRegion { + + + private FoldType kind; + private boolean initallyCollapsed; + + + public FoldingRegion(FoldType kind, int start, int end, boolean initiallyCollapsed) { + super(start, end); + this.kind = kind; + this.initallyCollapsed = initiallyCollapsed; + } + + + public FoldType getKind() { + return kind; + } + + public boolean isInitiallyCollapsed() { + return initallyCollapsed; + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/HoverParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/HoverParser.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,117 @@ +package at.ssw.visualizer.texteditor.model; + +import java.util.Iterator; + +/** + * + * @author ChristianWimmer + */ +public class HoverParser implements Iterator { + + private static String HOVER_START = "<@"; + private static String HOVER_SEP = "|@"; + private static String HOVER_END = ">@"; + private String text; + private int curPos; + private String curText; + private String curHover; + private boolean curNewLine; + + public static String firstLine(String text) { + if (text == null) { + return ""; + } + HoverParser p = new HoverParser(text); + StringBuilder result = new StringBuilder(text.length()); + while (p.hasNext()) { + String part = p.next(); + if (p.isNewLine()) { + break; + } + result.append(part); + } + return result.toString(); + } + + public HoverParser(String text) { + this.text = text; + } + + private void advance() { + int lineStart = text.indexOf('\n', curPos); + int nextStart = text.indexOf(HOVER_START, curPos); + + if (lineStart == curPos) { + curText = "\n"; + curHover = null; + curPos = lineStart + 1; + curNewLine = true; + while (curPos < text.length() && text.charAt(curPos) <= ' ') { + curPos++; + } + return; + } + curNewLine = false; + if (lineStart != -1 && (nextStart == -1 || lineStart < nextStart)) { + curText = text.substring(curPos, lineStart); + curHover = null; + curPos = lineStart; + return; + } + + if (nextStart == curPos) { + int nextSep = text.indexOf(HOVER_SEP, nextStart); + if (nextSep != -1) { + int nextEnd = text.indexOf(HOVER_END, nextSep); + if (nextEnd != -1) { + curText = text.substring(nextStart + HOVER_START.length(), nextSep); + curHover = text.substring(nextSep + HOVER_SEP.length(), nextEnd); + while (curHover.endsWith("\n")) { + curHover = curHover.substring(0, curHover.length() - 1); + } + curPos = nextEnd + HOVER_END.length(); + return; + } + } + } + + if (nextStart == curPos) { + // Incomplete hover sequence. Make sure we make progress by just advancing to the next chararter. + nextStart++; + } + + if (nextStart != -1) { + curText = text.substring(curPos, nextStart); + curHover = null; + curPos = nextStart; + } else if (curPos < text.length()) { + curText = text.substring(curPos); + curHover = null; + curPos = text.length(); + } else { + curText = null; + curHover = null; + } + } + + public boolean hasNext() { + return curPos < text.length(); + } + + public String next() { + advance(); + return curText; + } + + public String getHover() { + return curHover; + } + + public boolean isNewLine() { + return curNewLine; + } + + public void remove() { + throw new UnsupportedOperationException("Not supported."); + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Scanner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Scanner.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,192 @@ +package at.ssw.visualizer.texteditor.model; + +import java.util.BitSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import org.netbeans.editor.Syntax; +import org.netbeans.editor.TokenContextPath; + +/** + * The implementing class must specify the used TokenIDs and + * implement the scanner for the specified text. + * + * @author Alexander Reder + * @author Christian Wimmer + */ +public abstract class Scanner extends Syntax { + protected static final int EOF = 0; + protected static final BitSet DIGIT = charsOf("0123456789"); + protected static final BitSet HEX = charsOf("0123456789abcdefABCDEF"); + protected static final BitSet LETTER = charsOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + protected static final BitSet LETTER_DIGIT = charsOf("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + protected static final BitSet LC_LETTER = charsOf("_abcdefghijklmnopqrstuvwxyz"); + protected static final BitSet LC_LETTER_DIGIT = charsOf("0123456789_abcdefghijklmnopqrstuvwxyz"); + + protected static BitSet charsOf(String s) { + BitSet result = new BitSet(); + for (int i = 0; i < s.length(); i++) { + result.set(s.charAt(i)); + } + return result; + } + + protected BitSet whitespace; + protected char ch; + + public Scanner(String whitespace, TokenContextPath tokenContextPath) { + this.whitespace = charsOf(whitespace); + this.whitespace.set(EOF); + + this.tokenContextPath = tokenContextPath; + } + + public void setText(Document document) { + try { + setText(document.getText(0, document.getLength()), 0, document.getLength()); + } catch (BadLocationException ex) { + Logger logger = Logger.getLogger(Scanner.class.getName()); + logger.log(Level.SEVERE, ex.getMessage(), ex); + } + } + + public void setText(String s, int offset, int length) { + this.buffer = s.toCharArray(); + this.offset = offset; + this.tokenOffset = offset; + this.stopOffset = Math.min(buffer.length, offset + length); + } + + public String getTokenString() { + return new String(buffer, getTokenOffset(), getTokenLength()); + } + + public void findTokenBegin(int offset) { + this.offset = Math.max(offset, 0); + findTokenBegin(); + } + + /** + * If offset is in a token this method will read backwards until a + * whitespace character occurs. + */ + protected void findTokenBegin() { + if (offset >= stopOffset) { + offset = stopOffset - 1; + } + + if (!whitespace.get(buffer[offset])) { + while (offset > 0 && !whitespace.get(buffer[offset - 1])) { + offset--; + } + } + ch = buffer[offset]; + tokenOffset = offset; + } + + /** + * Reads the next character. + */ + protected void readNext() { + offset++; + if (offset < stopOffset) { + ch = buffer[offset]; + } else { + ch = EOF; + } + } + + protected boolean isWhitespace() { + boolean result = false; + while (whitespace.get(ch) && ch != EOF) { + result = true; + readNext(); + } + return result; + } + + /** + * Read to the next whitespace + */ + protected void readToWhitespace() { + do { + readNext(); + } while (!whitespace.get(ch)); + } + + private boolean readNextOrRestart(boolean result, boolean readNext) { + if (result) { + if (readNext) { + readNext(); + } + } else { + offset = tokenOffset; + ch = buffer[offset]; + } + return result; + } + + protected boolean isKeyword(Set keywords) { + int beginOffset = offset; + int endOffset = offset; + while (endOffset < stopOffset && !whitespace.get(buffer[endOffset])) { + endOffset++; + } + String word = new String(buffer, beginOffset, endOffset - beginOffset); + if (!keywords.contains(word)) { + return false; + } + + offset = endOffset - 1; + readNext(); + return true; + } + + protected boolean expectEnd() { + return readNextOrRestart(whitespace.get(ch), false); + } + + protected boolean expectEnd(char expected) { + return readNextOrRestart(ch == expected, false) && offset + 1 < stopOffset && whitespace.get(buffer[offset + 1]); + } + + protected boolean expectChar(char expected) { + return readNextOrRestart(ch == expected, true); + } + + protected boolean expectChar(BitSet expected) { + return readNextOrRestart(expected.get(ch), true); + } + + protected boolean expectChars(BitSet expected) { + while (expected.get(ch)) { + readNext(); + } + return true; + } + + protected boolean skipUntil(char expected) { + while (ch != expected && !whitespace.get(ch)) { + readNext(); + } + return expectChar(expected); + } + + protected boolean beforeChar(char before) { + int curOffset = offset - 1; + while (curOffset >= 0 && buffer[curOffset] != before && whitespace.get(buffer[curOffset])) { + curOffset--; + } + return curOffset >= 0 && buffer[curOffset] == before; + } + + protected boolean beforeChars(BitSet before) { + int curOffset = offset - 1; + while (curOffset >= 0 && !before.get(buffer[curOffset]) && whitespace.get(buffer[curOffset])) { + curOffset--; + } + return curOffset >= 0 && before.get(buffer[curOffset]); + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Text.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Text.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,91 @@ +package at.ssw.visualizer.texteditor.model; + +import at.ssw.visualizer.model.Compilation; +import at.ssw.visualizer.model.cfg.BasicBlock; +import at.ssw.visualizer.model.cfg.ControlFlowGraph; +import java.util.Map; + +/** + * @author Christian Wimmer + * @author Alexander Reder + */ +public class Text { + + private Compilation compilation; + private ControlFlowGraph cfg; + + private String text; + private FoldingRegion[] foldings; + private Map hyperlinks; + private Map stringHovers; + private Map regionHovers; + private Map highlighting; + private Map blocks; + private Scanner scanner; + private String mimeType; + + + public Text(ControlFlowGraph cfg, String text, FoldingRegion[] foldings, Map hyperlinks, Map stringHovers, Map regionHovers, Map highlighting, Map blocks, Scanner scanner, String mimeType) { + this.compilation = cfg.getCompilation(); + this.cfg = cfg; + this.text = text; + this.foldings = foldings; + this.hyperlinks = hyperlinks; + this.stringHovers = stringHovers; + this.regionHovers = regionHovers; + this.highlighting = highlighting; + this.blocks = blocks; + this.scanner = scanner; + this.mimeType = mimeType; + } + + + public Compilation getCompilation() { + return compilation; + } + + public ControlFlowGraph getCfg() { + return cfg; + } + + public String getText() { + return text; + } + + public FoldingRegion[] getFoldings() { + return foldings; + } + + public TextRegion getHyperlinkTarget(String key) { + return hyperlinks.get(key); + } + + public String getStringHover(String key) { + return stringHovers.get(key); + } + + public String getRegionHover(int position) { + for (TextRegion r : regionHovers.keySet()) { + if (r.getStart() <= position && r.getEnd() >= position) { + return regionHovers.get(r); + } + } + return null; + } + + public TextRegion[] getHighlighting(String key) { + return highlighting.get(key); + } + + public Map getBlocks() { + return blocks; + } + + public Scanner getScanner() { + return scanner; + } + + public String getMimeType() { + return mimeType; + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextBuilder.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,113 @@ +package at.ssw.visualizer.texteditor.model; + +import at.ssw.visualizer.model.cfg.BasicBlock; +import at.ssw.visualizer.model.cfg.ControlFlowGraph; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Alexander Reder + */ +public abstract class TextBuilder { + + protected StringBuilder text; + protected Scanner scanner; + protected List foldingRegions; + protected Map hyperlinks; + protected Map stringHovers; + protected Map regionHovers; + protected Map highlighting; + protected Map blocks; + protected Set hoverKeys; + protected Map hoverDefinitions; + protected Map> hoverReferences; + + public TextBuilder() { + text = new StringBuilder(4 * 1024); + foldingRegions = new ArrayList(); + hyperlinks = new HashMap(); + stringHovers = new HashMap(); + regionHovers = new HashMap(); + highlighting = new HashMap(); + blocks = new HashMap(); + hoverKeys = new HashSet(); + hoverDefinitions = new HashMap(); + hoverReferences = new HashMap>(); + } + + public abstract Text buildDocument(ControlFlowGraph cfg); + + protected abstract void buildHighlighting(); + + protected Text buildText(ControlFlowGraph cfg, String mimeType) { + buildHovers(); + buildHighlighting(); + return new Text(cfg, text.toString(), foldingRegions.toArray(new FoldingRegion[foldingRegions.size()]), hyperlinks, stringHovers, regionHovers, highlighting, blocks, scanner, mimeType); + } + + protected void appendBlockDetails(BasicBlock block) { + text.append(blockDetails(block)); + } + + protected String blockDetails(BasicBlock block) { + StringBuilder sb = new StringBuilder(); + sb.append(block.getName()); + hoverKeys.add(block.getName()); + appendBlockList(sb, " <- ", block.getPredecessors()); + appendBlockList(sb, " -> ", block.getSuccessors()); + appendBlockList(sb, " xh ", block.getXhandlers()); + if (block.getDominator() != null) { + sb.append(" dom ").append(block.getDominator().getName()); + } + sb.append(" [").append(block.getFromBci()).append(", ").append(block.getToBci()).append("]"); + appendList(sb, " ", block.getFlags()); + + if (block.getLoopDepth() > 0) { + sb.append(" (loop ").append(block.getLoopIndex()).append(" depth ").append(block.getLoopDepth()).append(")"); + } + return sb.toString(); + } + + protected void appendBlockList(StringBuilder sb, String prefix, List blocks) { + for (BasicBlock block : blocks) { + sb.append(prefix); + prefix = ","; + sb.append(block.getName()); + } + } + + private void appendList(StringBuilder sb, String prefix, List values) { + for (String value : values) { + sb.append(prefix).append(value); + prefix = ","; + } + } + + protected void buildHovers() { + StringBuilder sb; + for(String key : hoverKeys) { + sb = new StringBuilder(); + if(hoverDefinitions.containsKey(key) && hoverReferences.containsKey(key)) { + sb.append("Definition;\n"); + sb.append(hoverDefinitions.get(key)); + sb.append("\n"); + } + if(hoverReferences.containsKey(key)) { + sb.append("References:\n"); + for(String ref : hoverReferences.get(key)) { + sb.append(ref); + sb.append("\n"); + } + } + if(sb.length() > 0) { + stringHovers.put(key, sb.toString().substring(0, sb.length() - 1)); + } + } + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextRegion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextRegion.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,27 @@ +package at.ssw.visualizer.texteditor.model; + +/** + * + * @author Christian Wimmer + * @author Alexander Reder + */ +public class TextRegion { + + private int start; + private int end; + + public TextRegion(int start, int end) { + this.start = start; + this.end = end; + } + + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/preferences.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/preferences.xml Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,6 @@ + + + + + + diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/StyledToolTip.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/StyledToolTip.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,57 @@ +package at.ssw.visualizer.texteditor.tooltip; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.border.LineBorder; +import javax.swing.text.EditorKit; + +/** + * + * @author Bernhard Stiftner + * @author Christian Wimmer + * @author Alexander Reder + */ +public class StyledToolTip extends JPanel { + + public static final int BORDER = 2; + + private final String text; + private final JEditorPane toolTipPane; + + public StyledToolTip(String text, EditorKit editorKit) { + this.text = text; + + setBackground(new Color(235, 235, 163)); + setBorder(new LineBorder(Color.BLACK)); + setOpaque(true); + setLayout(new BorderLayout()); + + toolTipPane = new JEditorPane(); + toolTipPane.setEditable(false); + toolTipPane.setEditorKit(editorKit); + toolTipPane.setText(text); + + add(toolTipPane, BorderLayout.CENTER); + } + + @Override + public Dimension getPreferredSize() { + // Workaround: JEditorPane does not provide a proper width (only few pixels), + // so make the tooltip as large as the editor it is shown in + Dimension prefSize = super.getPreferredSize(); + prefSize.width = Integer.MAX_VALUE; + return prefSize; + } + + @Override + protected void paintComponent(Graphics g) { + // Workaround: Add a new line at the end so that the caret is not in the visible area. + toolTipPane.setText(text + "\n"); + + super.paintComponent(g); + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/ToolTipAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/ToolTipAction.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,67 @@ +package at.ssw.visualizer.texteditor.tooltip; + +import at.ssw.visualizer.texteditor.model.Scanner; +import at.ssw.visualizer.texteditor.model.Text; +import java.awt.event.ActionEvent; +import javax.swing.text.JTextComponent; +import org.netbeans.api.editor.EditorActionRegistration; +import org.netbeans.editor.BaseDocument; +import org.netbeans.editor.EditorUI; +import org.netbeans.editor.PopupManager; +import org.netbeans.editor.TokenID; +import org.netbeans.editor.Utilities; +import org.netbeans.editor.ext.ExtKit; +import org.netbeans.editor.ext.ToolTipSupport; +import org.netbeans.modules.editor.NbEditorKit; + +/** + * + * @author Christian Wimmer + * @author Alexander Reder + */ +public class ToolTipAction extends NbEditorKit.NbBuildToolTipAction { + public ToolTipAction() { + putValue(NAME, ExtKit.buildToolTipAction); + } + + @Override + public void actionPerformed(ActionEvent evt, JTextComponent target) { + if (!showTooltip(target)) { + super.actionPerformed(evt, target); + } + } + + private boolean showTooltip(JTextComponent target) { + BaseDocument document = Utilities.getDocument(target); + Text text = (Text) document.getProperty(Text.class); + if (text == null) { + return false; + } + + EditorUI ui = Utilities.getEditorUI(target); + ToolTipSupport tts = ui.getToolTipSupport(); + int offset = target.viewToModel(tts.getLastMouseEvent().getPoint()); + + String toolTipText = text.getRegionHover(offset); + + if (toolTipText == null) { + Scanner scanner = text.getScanner(); + scanner.setText(document); + scanner.findTokenBegin(offset); + TokenID token = scanner.nextToken(); + if (token.getNumericID() < 0) { + return false; + } + + toolTipText = text.getStringHover(scanner.getTokenString()); + if (toolTipText == null) { + return false; + } + } + + StyledToolTip tooltip = new StyledToolTip(toolTipText, target.getUI().getEditorKit(target)); + + tts.setToolTip(tooltip, PopupManager.ViewPortBounds, PopupManager.Largest, 0, 0); + return true; + } +} diff -r 7596ae867a7b -r 6960cc79f664 src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/view/AbstractTextViewTopComponent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/view/AbstractTextViewTopComponent.java Wed Jun 01 15:22:40 2011 +0200 @@ -0,0 +1,78 @@ +package at.ssw.visualizer.texteditor.view; + +import at.ssw.visualizer.core.selection.Selection; +import at.ssw.visualizer.core.selection.SelectionManager; +import at.ssw.visualizer.model.cfg.BasicBlock; +import at.ssw.visualizer.model.cfg.ControlFlowGraph; +import at.ssw.visualizer.texteditor.EditorKit; +import java.awt.BorderLayout; +import java.util.Arrays; +import javax.swing.BorderFactory; +import javax.swing.JEditorPane; +import javax.swing.JScrollPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.openide.windows.TopComponent; + +/** + * + * @author Alexander Reder + */ +public abstract class AbstractTextViewTopComponent extends TopComponent { + + protected ControlFlowGraph curCFG; + protected BasicBlock[] curBlocks; + + private JEditorPane editorPane; + + // EditorKit must be set in the imlementation class + public AbstractTextViewTopComponent(EditorKit kit) { + editorPane = new JEditorPane(); + editorPane.setEditorKit(kit); + editorPane.setEditable(false); + JScrollPane scrollPane = new JScrollPane(editorPane); + scrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + setLayout(new BorderLayout()); + add(scrollPane); + } + + @Override + protected void componentShowing() { + super.componentShowing(); + SelectionManager.getDefault().addChangeListener(selectionChangeListener); + updateContent(); + } + + @Override + protected void componentHidden() { + super.componentHidden(); + SelectionManager.getDefault().removeChangeListener(selectionChangeListener); + curCFG = null; + curBlocks = null; + } + + + private ChangeListener selectionChangeListener = new ChangeListener() { + public void stateChanged(ChangeEvent event) { + updateContent(); + } + }; + + protected void updateContent() { + Selection selection = SelectionManager.getDefault().getCurSelection(); + ControlFlowGraph newCFG = selection.get(ControlFlowGraph.class); + BasicBlock[] newBlocks = selection.get(BasicBlock[].class); + + if (newCFG == null || newBlocks == null || newBlocks.length == 0) { + editorPane.setText("No block selected\n"); + } else if (curCFG != newCFG || !Arrays.equals(curBlocks, newBlocks)) { + editorPane.setText(getContent(newCFG, newBlocks)); + } + curCFG = newCFG; + curBlocks = newBlocks; + } + + protected abstract String getContent(ControlFlowGraph cfg, BasicBlock[] blocks); + +}