diff options
author | William R. Swanson | 2012-03-05 20:47:39 +0000 |
---|---|---|
committer | William R. Swanson | 2012-03-05 20:47:39 +0000 |
commit | 38289ccdd0077eb33161f4c995986909e2651b9e (patch) | |
tree | c0d75926b5a25e93cca2a6db4baa06bdf6302b17 /visualizer | |
parent | 2fb4b4feefcc501ec52342185fdd9797aa053793 (diff) | |
download | org.eclipse.cdt-38289ccdd0077eb33161f4c995986909e2651b9e.tar.gz org.eclipse.cdt-38289ccdd0077eb33161f4c995986909e2651b9e.tar.xz org.eclipse.cdt-38289ccdd0077eb33161f4c995986909e2651b9e.zip |
Bug 373138: Add new text-selection visualizer example.
- visualizer/org.eclipse.cdt.visualizer.ui
- src/org/eclipse/cdt/visualizer/ui/util/ScrollPanel.java
- add ScrollPanel UI class
- visualizer/org.eclipse.cdt.visualizer.examples
- src/org/eclipse/cdt/visualizer/examples/
- VisualizerExamplesPlugin.java
- add UIResourceManager instance to plugin
- src/org/eclipse/cdt/visualizer/examples/sourcegraph/
- SourceGraphVisualizer.java
- visualizer implementation
- SourceGraphControl.java
- graphic visualization control
(displayed in ScrollPanel by SourceGraphVisualizer)
- plugin.xml
- add extension point declaration for new visualizer example
- resources/messages.properties
- add string resource file
- .classpath
- add "resources/" directory as a source path
- META-INF/MANIFEST.MF
- add a couple plugin dependencies
Diffstat (limited to 'visualizer')
8 files changed, 574 insertions, 2 deletions
diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/.classpath b/visualizer/org.eclipse.cdt.visualizer.examples/.classpath index ad32c83a788..31db9a91174 100644 --- a/visualizer/org.eclipse.cdt.visualizer.examples/.classpath +++ b/visualizer/org.eclipse.cdt.visualizer.examples/.classpath @@ -3,5 +3,6 @@ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="resources"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/META-INF/MANIFEST.MF b/visualizer/org.eclipse.cdt.visualizer.examples/META-INF/MANIFEST.MF index 128d1797ef9..469bd93cc42 100644 --- a/visualizer/org.eclipse.cdt.visualizer.examples/META-INF/MANIFEST.MF +++ b/visualizer/org.eclipse.cdt.visualizer.examples/META-INF/MANIFEST.MF @@ -7,8 +7,10 @@ Bundle-Activator: org.eclipse.cdt.visualizer.examples.VisualizerExamplesPlugin Bundle-Vendor: %provider.name Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.jface.text, org.eclipse.cdt.visualizer.ui, - org.eclipse.core.resources + org.eclipse.cdt.visualizer.core Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.visualizer.examples, diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/plugin.xml b/visualizer/org.eclipse.cdt.visualizer.examples/plugin.xml index b5635af2c86..34ded7f47cf 100644 --- a/visualizer/org.eclipse.cdt.visualizer.examples/plugin.xml +++ b/visualizer/org.eclipse.cdt.visualizer.examples/plugin.xml @@ -7,6 +7,10 @@ class="org.eclipse.cdt.visualizer.examples.problemvisualizer.ProblemVisualizer" id="org.eclipse.cdt.visualizer.examples.ProblemVisualizer"> </visualizer> + <visualizer + class="org.eclipse.cdt.visualizer.examples.sourcegraph.SourceGraphVisualizer" + id="org.eclipse.cdt.visualizer.examples.sourcegraph"> + </visualizer> </extension> </plugin> diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/resources/messages.properties b/visualizer/org.eclipse.cdt.visualizer.examples/resources/messages.properties new file mode 100644 index 00000000000..ae481841bb3 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.examples/resources/messages.properties @@ -0,0 +1,19 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Application string resources +# ----------------------------------------------------------------------------- + +# SourceGraphVisualizer example +SourceGraphVisualizer.name=source_graph +SourceGraphVisualizer.displayName=Source Graph Visualizer +SourceGraphVisualizer.description=Displays graphic representation of selected source text. diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/VisualizerExamplesPlugin.java b/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/VisualizerExamplesPlugin.java index 18463bca343..c064f9cb287 100644 --- a/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/VisualizerExamplesPlugin.java +++ b/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/VisualizerExamplesPlugin.java @@ -6,10 +6,16 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Marc Khouzam (Ericsson) - initial API and implementation + * Marc Khouzam (Ericsson) - initial API and implementation + * William R. Swanson (Tilera) - added resource manager *******************************************************************************/ package org.eclipse.cdt.visualizer.examples; +import org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin; +import org.eclipse.cdt.visualizer.ui.util.UIResourceManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -24,6 +30,9 @@ public class VisualizerExamplesPlugin extends AbstractUIPlugin { // The shared instance private static VisualizerExamplesPlugin plugin; + /** Resource manager */ + protected static UIResourceManager s_resources = null; + /** * The constructor */ @@ -38,6 +47,9 @@ public class VisualizerExamplesPlugin extends AbstractUIPlugin { public void start(BundleContext context) throws Exception { super.start(context); plugin = this; + + // initialize resource management (strings, images, fonts, colors, etc.) + getPluginResources(); } /* @@ -46,6 +58,9 @@ public class VisualizerExamplesPlugin extends AbstractUIPlugin { */ @Override public void stop(BundleContext context) throws Exception { + // clean up resource management + cleanupPluginResources(); + plugin = null; super.stop(context); } @@ -59,4 +74,52 @@ public class VisualizerExamplesPlugin extends AbstractUIPlugin { return plugin; } + // --- resource management --- + + /** Returns resource manager for this plugin */ + public UIResourceManager getPluginResources() { + if (s_resources == null) { + s_resources = new UIResourceManager(this); + s_resources.setParentManager(CDTVisualizerUIPlugin.getResources()); + } + + return s_resources; + } + + /** Releases resource manager for this plugin. */ + public void cleanupPluginResources() { + s_resources.dispose(); + } + + /** Convenience method for getting plugin resource manager */ + public static UIResourceManager getResources() { + return getDefault().getPluginResources(); + } + + /** Convenience method for looking up string resources */ + public static String getString(String key) { + return getDefault().getPluginResources().getString(key); + } + /** Convenience method for looking up string resources */ + public static String getString(String key, Object... arguments) { + return getDefault().getPluginResources().getString(key, arguments); + } + + /** Convenience method for looking up image resources */ + public static Image getImage(String key) { + return getDefault().getPluginResources().getImage(key); + } + /** Convenience method for looking up image resources */ + public static ImageDescriptor getImageDescriptor(String key) { + return getDefault().getPluginResources().getImageDescriptor(key); + } + + /** Convenience method for looking up font resources */ + public static Font getFont(String fontName, int height) { + return getDefault().getPluginResources().getFont(fontName, height); + } + /** Convenience method for looking up font resources */ + public static Font getFont(String fontName, int height, int style) { + return getDefault().getPluginResources().getFont(fontName, height, style); + } } diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/sourcegraph/SourceGraphControl.java b/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/sourcegraph/SourceGraphControl.java new file mode 100644 index 00000000000..71f60d1b46e --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/sourcegraph/SourceGraphControl.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.examples.sourcegraph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Hashtable; + +import org.eclipse.cdt.visualizer.ui.canvas.BufferedCanvas; +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +// --------------------------------------------------------------------------- +// SourceGraphControl +// --------------------------------------------------------------------------- + +/** Simple control that displays a graph based on a source text selection. */ +public class SourceGraphControl extends BufferedCanvas +{ + // --- constants --- + + /** Margin used in drawing graph and computing control height. */ + public static final int MARGIN = 10; + + /** Line height used in drawing graph and computing control height. */ + public static final int LINE_HEIGHT = 20; + + // --- members --- + + /** Text we're currently displaying. */ + protected String m_sourceText = ""; //$NON-NLS-1$ + + /** Data structure used to hold character stats. */ + class CharStat + implements Comparable<CharStat> + { + public String characters; + public int count; + public CharStat(String c) { + characters = c; + count = 0; + } + @Override + public int compareTo(CharStat o) { + int c1 = count; + int c2 = o.count; + int cmp = (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0; + // we want to sort in descending order, so negate result + return -cmp; + }; + }; + + /** List of characters we discovered and their occurrences. */ + ArrayList<CharStat> m_characters; + + + // --- constructors/destructors --- + + /** Constructor. */ + public SourceGraphControl(Composite parent) { + super(parent); + m_characters = new ArrayList<CharStat>(); + } + + /** Dispose method. */ + @Override + public void dispose() { + super.dispose(); + } + + + // --- accessors --- + + /** Sets source text to graph. */ + public void setSourceText(String text) + { + processText(text); + SourceGraphControl.this.update(); + } + + + // --- text processing methods --- + + /** Processes text into digested display form. */ + public void processText(String text) + { + if (text == null) text = ""; //$NON-NLS-1$ + m_sourceText = text; + + // TODO: reuse the array/hashtable and stat objects + + Hashtable<String, CharStat> characters = + new Hashtable<String, CharStat>(); + + int len = m_sourceText.length(); + int fragment_length = 2; + if (len >= fragment_length) { + for (int i = 0; i<len-fragment_length+1; ++i) { + String c = m_sourceText.substring(i,i+fragment_length); + + // Don't bother with fragments containing spaces + // and non-printing chars. + boolean skip = false; + for (int j=0; j<c.length(); ++j) + { + if (c.charAt(j) <= 32 || c.charAt(j) > 127) { + skip = true; + break; + } + } + if (skip) continue; + + CharStat cs = characters.get(c); + if (cs == null) { + cs = new CharStat(c); + characters.put(c, cs); + } + ++cs.count; + } + } + + m_characters.clear(); + m_characters.addAll(characters.values()); + Collections.sort(m_characters); + + characters.clear(); + + Rectangle bounds = getBounds(); + int height = MARGIN * 2 + m_characters.size() * LINE_HEIGHT; + bounds.height = height; + setBounds(bounds); + + } + + // --- painting methods --- + + /** Invoked when canvas repaint event is raised. + * Default implementation clears canvas to background color. + */ + @Override + public void paintCanvas(GC gc) { + gc.setBackground(Colors.BLACK); + gc.setForeground(Colors.WHITE); + + clearCanvas(gc); + + int margin = MARGIN; + int tw = 90; + int tw2 = 45; + int lh = LINE_HEIGHT; + + int x = margin; + int y = margin; + + Rectangle area = getClientArea(); + int w = area.width - margin*2 - tw; + + int maxcount = 0; + for (CharStat cs : m_characters) + { + // We're sorted in descending order, so first element + // that we draw will always have the largest count. + if (maxcount == 0) maxcount = cs.count; + + gc.drawText("[" + cs.characters + "]", x, y); //$NON-NLS-1$ //$NON-NLS-2$ + gc.drawText("(" + cs.count + ")", x + tw2, y); //$NON-NLS-1$ //$NON-NLS-2$ + + double proportion = cs.count * 1.0 / maxcount; + int bw = (int) Math.round(proportion * w); + Color oldb = gc.getBackground(); + if (proportion > .70) + gc.setBackground(Colors.GREEN); + else if (proportion > .40) + gc.setBackground(Colors.YELLOW); + else + gc.setBackground(Colors.RED); + gc.fillRectangle(x + tw, y, bw, lh-5); + gc.setBackground(oldb); + + y += lh; + } + } + + + // --- update methods --- + + /** + * Refresh the control's content based on current data. + */ + public void refresh() { + SourceGraphControl.this.update(); + } + + // --- event handlers --- + + /** Invoked when panel is resized. */ + @Override + public void resized(Rectangle bounds) { + refresh(); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/sourcegraph/SourceGraphVisualizer.java b/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/sourcegraph/SourceGraphVisualizer.java new file mode 100644 index 00000000000..1a0fe97823a --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.examples/src/org/eclipse/cdt/visualizer/examples/sourcegraph/SourceGraphVisualizer.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.examples.sourcegraph; + +import org.eclipse.cdt.visualizer.examples.VisualizerExamplesPlugin; +import org.eclipse.cdt.visualizer.ui.Visualizer; +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.cdt.visualizer.ui.util.ScrollPanel; +import org.eclipse.cdt.visualizer.ui.util.SelectionManager; +import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +//--------------------------------------------------------------------------- +// SourceGraphVisualizer +//--------------------------------------------------------------------------- + +public class SourceGraphVisualizer extends Visualizer +{ + // --- constants --- + + /** Eclipse ID for this view */ + public static final String ECLIPSE_ID = "org.eclipse.cdt.visualizer.examples.sourcegraph"; //$NON-NLS-1$ + + + // --- members --- + + /** ScrollPanel container for visualizer control. */ + ScrollPanel m_scrollPanel = null; + + /** visualizer control (downcast reference) */ + SourceGraphControl m_sourceGraphControl = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public SourceGraphVisualizer() + { + super(VisualizerExamplesPlugin.getString("SourceGraphVisualizer.name"), //$NON-NLS-1$ + VisualizerExamplesPlugin.getString("SourceGraphVisualizer.displayName"), //$NON-NLS-1$ + VisualizerExamplesPlugin.getString("SourceGraphVisualizer.description") //$NON-NLS-1$ + ); + } + + /** Dispose method. */ + @Override + public void dispose() { + super.dispose(); + } + + + // --- control management --- + + /** Creates and returns visualizer control on specified parent. */ + @Override + public Control createControl(Composite parent) + { + if (m_sourceGraphControl == null) { + + m_scrollPanel = new ScrollPanel(parent); + m_scrollPanel.setBackground(Colors.BLACK); + + m_sourceGraphControl = new SourceGraphControl(m_scrollPanel); + m_scrollPanel.setContent(m_sourceGraphControl); + + // source graph control sets its own height based on the graph size + m_scrollPanel.setAutoResizeHeight(false); + // auto-resize to fit scrollpanel width + m_scrollPanel.setAutoResizeWidth(true); + + setControl(m_scrollPanel); + } + return getControl(); + } + + /** Invoked when visualizer control should be disposed. */ + @Override + public void disposeControl() + { + if (m_sourceGraphControl != null) { + setControl(null); + m_sourceGraphControl.dispose(); + m_scrollPanel.dispose(); + m_sourceGraphControl = null; + m_scrollPanel = null; + } + } + + // --- visualizer events --- + + @Override + public void visualizerDeselected() { + } + + @Override + public void visualizerSelected() { + } + + + // --- update methods --- + + /** + * Refresh the visualizer display based on the existing data. + */ + public void refresh() { + m_sourceGraphControl.refresh(); + } + + // --- selection handling --- + + /** Invoked when selection changes, to determine whether this + * visualizer knows how to display the current selection. + */ + @Override + public int handlesSelection(ISelection selection) { + Object s = SelectionUtils.getSelectedObject(selection); + if (s instanceof TextSelection) return 1; + return 0; + } + + /** Invoked when workbench selection changes and this visualizer + * is selected to display it. + */ + @Override + public void workbenchSelectionChanged(ISelection selection) { + TextSelection s = + (TextSelection) SelectionUtils.getSelectedObject(selection); + String text = s.getText(); + m_sourceGraphControl.setSourceText(text); + } + + public SelectionManager getSelectionManager() { + return m_selectionManager; + } + + + // --- menu/toolbar management --- + + /** Invoked when visualizer is selected, to populate the toolbar. */ + @Override + public void populateToolBar(IToolBarManager toolBarManager) + {} + + /** Invoked when visualizer is selected, to populate the toolbar's menu. */ + @Override + public void populateMenu(IMenuManager menuManager) + {} + + + // --- context menu handling --- + + /** Invoked when visualizer view's context menu is invoked, to populate it. */ + @Override + public void populateContextMenu(IMenuManager menuManager) + {} + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/ScrollPanel.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/ScrollPanel.java new file mode 100644 index 00000000000..0ce636b9573 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/ScrollPanel.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009 Tilera Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + + +// --------------------------------------------------------------------------- +// ScrollPanel +// --------------------------------------------------------------------------- + +/** + * Container panel that adds scrollbar(s) to a content control. + */ +public class ScrollPanel extends ScrolledComposite +{ + // --- constructors/destructors --- + + /** Constructor. */ + public ScrollPanel(Composite parent) + { + this(parent, null, true, true); + } + + /** Constructor. */ + public ScrollPanel(Composite parent, boolean hscrollbar, boolean vscrollbar) + { + this(parent, null, hscrollbar, vscrollbar); + } + + /** Constructor. */ + public ScrollPanel(Composite parent, Control contentControl, boolean hscrollbar, boolean vscrollbar) + { + super(parent, ((hscrollbar) ? SWT.H_SCROLL : SWT.NONE) | + ((vscrollbar) ? SWT.V_SCROLL : SWT.NONE)); + initScrollPanel(contentControl, hscrollbar, vscrollbar); + } + + /** Dispose method. */ + public void dispose() { + cleanupScrollPanel(); + super.dispose(); + } + + /** Overridden to permit subclassing */ + protected void checkSubclass() { + // do nothing -- superclass implementation throws a "Subclassing not allowed" exception + } + + + // --- init methods --- + + /** Initializes control */ + protected void initScrollPanel(Control contentControl, boolean hscrollbar, boolean vscrollbar) { + setMinSize(0,0); + setShowFocusedControl(true); + // If user doesn't want either scrollbar, we'll auto-size in that direction by default. + setAutoResizeWidth(! hscrollbar); + setAutoResizeHeight(! vscrollbar); + if (contentControl != null) setContent(contentControl); + } + + /** Cleans up control */ + protected void cleanupScrollPanel() { + } + + + // --- methods --- + + /** Sets whether ScrollPanel auto-resizes the width of its contained control + * to match the size of the scrollpanel's content area, save when the control + * is smaller than the minimum width. (This also implicitly disables/hides + * the scrollbar when the control is auto-sized.) + */ + public void setAutoResizeWidth(boolean resizeWidth) { + setExpandHorizontal(resizeWidth); + } + + /** Sets whether ScrollPanel auto-resizes the height of its contained control + * to match the size of the scrollpanel's content area, save when the control + * is smaller than the minimum width. (This also implicitly disables/hides + * the scrollbar when the control is auto-sized.) + */ + public void setAutoResizeHeight(boolean resizeHeight) { + setExpandVertical(resizeHeight); + } +} |