|
From: <caw...@us...> - 2007-05-02 13:17:11
|
Revision: 2415
http://svn.sourceforge.net/rubyeclipse/?rev=2415&view=rev
Author: cawilliams
Date: 2007-05-02 06:17:08 -0700 (Wed, 02 May 2007)
Log Message:
-----------
Rip out the old hover extension point and replace it with one based on JDT - this allows us to more easily modify the popup, and override nly the methods we choose.
Also hook up the new extension point to the editor, and add a bunch of new hovers.
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/plugin.xml
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/Strings.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/EditorUtility.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyEditorMessages.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/WorkingCopyManager.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/AbstractRubyEditorTextHover.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyHoverMessages.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/PreferenceConstants.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/ruby/hover/IRubyEditorTextHover.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/RubydocHoverStyleSheet.css
trunk/org.rubypeople.rdt.ui/schema/rubyEditorTextHovers.exsd
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/BestMatchHover.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/ProblemHover.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverDescriptor.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverProxy.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubySourceHover.java
Removed Paths:
-------------
trunk/org.rubypeople.rdt.ui/schema/textHoverProvider.exsd
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
Added: trunk/org.rubypeople.rdt.ui/RubydocHoverStyleSheet.css
===================================================================
--- trunk/org.rubypeople.rdt.ui/RubydocHoverStyleSheet.css (rev 0)
+++ trunk/org.rubypeople.rdt.ui/RubydocHoverStyleSheet.css 2007-05-02 13:17:08 UTC (rev 2415)
@@ -0,0 +1,30 @@
+/* Font definitions */
+body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font-family: sans-serif; font-size: 9pt }
+pre { font-family: monospace; font-size: 9pt }
+
+/* Margins */
+body { overflow: auto; margin-top: 0; margin-bottom: 4; margin-left: 3; margin-right: 0 }
+h1 { margin-top: 5; margin-bottom: 1 }
+h2 { margin-top: 25; margin-bottom: 3 }
+h3 { margin-top: 20; margin-bottom: 3 }
+h4 { margin-top: 20; margin-bottom: 3 }
+h5 { margin-top: 0; margin-bottom: 0 }
+p { margin-top: 10px; margin-bottom: 10px }
+pre { margin-left: 6 }
+ul { margin-top: 0; margin-bottom: 10 }
+li { margin-top: 0; margin-bottom: 0 }
+li p { margin-top: 0; margin-bottom: 0 }
+ol { margin-top: 0; margin-bottom: 10 }
+dl { margin-top: 0; margin-bottom: 10 }
+dt { margin-top: 0; margin-bottom: 0; font-weight: bold }
+dd { margin-top: 0; margin-bottom: 0 }
+
+/* Styles and colors */
+a:link { color: #0000FF }
+a:hover { color: #000080 }
+a:visited { text-decoration: underline }
+h4 { font-style: italic }
+strong { font-weight: bold }
+em { font-style: italic }
+var { font-style: italic }
+th { font-weight: bold }
Modified: trunk/org.rubypeople.rdt.ui/plugin.xml
===================================================================
--- trunk/org.rubypeople.rdt.ui/plugin.xml 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/plugin.xml 2007-05-02 13:17:08 UTC (rev 2415)
@@ -8,6 +8,7 @@
<extension-point id="editorPopupExtender" name="%editorPopupExtender" schema="schema/org.rubypeople.rdt.ui.editorPopupExtender.exsd"/>
<extension-point id="rubyTemplateProvider" name="Ruby template provider" schema="schema/rubyTemplateProvider.exsd"/>
<extension-point id="quickFixProcessors" name="%quickFixProcessorExtensionPoint" schema="schema/quickFixProcessors.exsd"/>
+ <extension-point id="rubyEditorTextHovers" name="%rubyEditorTextHover" schema="schema/rubyEditorTextHovers.exsd"/>
<extension
point="org.eclipse.ui.preferencePages">
@@ -921,12 +922,38 @@
id="org.rubypeople.rdt.ui.search.RubySearchResultPage"
searchResultClass="org.rubypeople.rdt.internal.ui.search.RubySearchResult"/>
</extension>
-
- <extension
- point="org.rubypeople.rdt.ui.textHoverProvider">
- <textHoverProvider class="org.rubypeople.rdt.internal.ui.text.ruby.hover.RiDocHoverProvider" />
+
+ <extension point="org.rubypeople.rdt.ui.rubyEditorTextHovers">
+ <hover
+ label="%sequentialHover"
+ description="%sequentialHoverDescription"
+ class="org.rubypeople.rdt.internal.ui.text.ruby.hover.BestMatchHover"
+ id="org.rubypeople.rdt.ui.BestMatchHover">
+ </hover>
+ <hover
+ label="%problemHover"
+ description="%problemHoverDescription"
+ class="org.rubypeople.rdt.internal.ui.text.ruby.hover.ProblemHover"
+ id="org.rubypeople.rdt.ui.ProblemHover">
+ </hover>
+ <hover
+ id="org.rubypeople.rdt.ui.RiDocHover"
+ class="org.rubypeople.rdt.internal.ui.text.ruby.hover.RiDocHoverProvider"
+ label="%rdocHover"/>
+ <hover
+ label="%sourceHover"
+ description="%sourceHoverDescription"
+ class="org.rubypeople.rdt.internal.ui.text.ruby.hover.RubySourceHover"
+ id="org.rubypeople.rdt.ui.RubySourceHover">
+ </hover>
+ <hover
+ label="%annotationHover"
+ description="%annotationHoverDescription"
+ class="org.rubypeople.rdt.internal.ui.text.ruby.hover.AnnotationHover"
+ id="org.rubypeople.rdt.ui.AnnotationHover">
+ </hover>
</extension>
-
+
<extension
point="org.eclipse.ui.popupMenus">
<viewerContribution
Added: trunk/org.rubypeople.rdt.ui/schema/rubyEditorTextHovers.exsd
===================================================================
--- trunk/org.rubypeople.rdt.ui/schema/rubyEditorTextHovers.exsd (rev 0)
+++ trunk/org.rubypeople.rdt.ui/schema/rubyEditorTextHovers.exsd 2007-05-02 13:17:08 UTC (rev 2415)
@@ -0,0 +1,139 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.rubypeople.rdt.ui">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.rubypeople.rdt.ui" id="rubyEditorTextHovers" name="%rubyEditorTextHover"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to plug-in text hovers in a Ruby editor.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <element ref="hover"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="hover">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ the id, typically the same as the fully qualified class name.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ the fully qualified class name implementing the interface org.rubypeople.rdt.ui.text.ruby.hover.IRubyEditorTextHover
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.rubypeople.rdt.ui.text.ruby.hover.IRubyEditorTextHover"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string">
+ <annotation>
+ <documentation>
+ the translatable label for this hover.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ the translatable description for this hover.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="activate" type="boolean" use="default" value="false">
+ <annotation>
+ <documentation>
+ if the attribute is set to "true" it will force this plug-in to be loaded on hover activation.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ RDT 1.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ 2007 Aptana, Inc.
+ </documentation>
+ </annotation>
+
+</schema>
Deleted: trunk/org.rubypeople.rdt.ui/schema/textHoverProvider.exsd
===================================================================
--- trunk/org.rubypeople.rdt.ui/schema/textHoverProvider.exsd 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/schema/textHoverProvider.exsd 2007-05-02 13:17:08 UTC (rev 2415)
@@ -1,120 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Schema file written by PDE -->
-<schema targetNamespace="org.rubypeople.rdt.ui.TextHoverProvider">
-<annotation>
- <appInfo>
- <meta.schema plugin="org.rubypeople.rdt.ui" id="textHoverProvider" name="Text Hover Provider"/>
- </appInfo>
- <documentation>
-
- </documentation>
- </annotation>
-
- <element name="extension">
- <complexType>
- <sequence>
- <element ref="textHoverProvider"/>
- </sequence>
- <attribute name="point" type="string" use="required">
- <annotation>
- <documentation>
-
- </documentation>
- </annotation>
- </attribute>
- <attribute name="id" type="string">
- <annotation>
- <documentation>
-
- </documentation>
- </annotation>
- </attribute>
- <attribute name="name" type="string">
- <annotation>
- <documentation>
-
- </documentation>
- </annotation>
- </attribute>
- </complexType>
- </element>
-
- <element name="textHoverProvider">
- <complexType>
- <attribute name="class" type="string" use="required">
- <annotation>
- <documentation>
- The class that implements org.rubypeople.rdt.ui.extensions.ITextHoverProvider.
- </documentation>
- <appInfo>
- <meta.attribute kind="java" basedOn="org.rubypeople.rdt.ui.extensions.ITextHoverProvider"/>
- </appInfo>
- </annotation>
- </attribute>
-
- <attribute name="fileExtension" type="string" use="optional">
- <annotation>
- <documentation>
- Use this to restrict the application of this hover to particular file extensions.
- </documentation>
- <appInfo>
- <meta.attribute kind="java" basedOn="org.rubypeople.rdt.ui.extensions.ITextHoverProvider"/>
- </appInfo>
- </annotation>
- </attribute>
-
-
-
- </complexType>
-
- </element>
-
-
-
-
- <annotation>
- <appInfo>
- <meta.section type="since"/>
- </appInfo>
- <documentation>
- [Enter the first release in which this extension point appears.]
- </documentation>
- </annotation>
-
- <annotation>
- <appInfo>
- <meta.section type="examples"/>
- </appInfo>
- <documentation>
- [Enter extension point usage example here.]
- </documentation>
- </annotation>
-
- <annotation>
- <appInfo>
- <meta.section type="apiInfo"/>
- </appInfo>
- <documentation>
- [Enter API information here.]
- </documentation>
- </annotation>
-
- <annotation>
- <appInfo>
- <meta.section type="implementation"/>
- </appInfo>
- <documentation>
- [Enter information about supplied implementation of this extension point.]
- </documentation>
- </annotation>
-
- <annotation>
- <appInfo>
- <meta.section type="copyright"/>
- </appInfo>
- <documentation>
-
- </documentation>
- </annotation>
-
-</schema>
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/Strings.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/Strings.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/corext/util/Strings.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -1,6 +1,11 @@
package org.rubypeople.rdt.internal.corext.util;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.formatter.IndentManipulation;
public class Strings {
@@ -144,4 +149,127 @@
return result.toString();
}
+ /**
+ * Converts the given string into an array of lines. The lines
+ * don't contain any line delimiter characters.
+ *
+ * @return the string converted into an array of strings. Returns <code>
+ * null</code> if the input string can't be converted in an array of lines.
+ */
+ public static String[] convertIntoLines(String input) {
+ try {
+ ILineTracker tracker= new DefaultLineTracker();
+ tracker.set(input);
+ int size= tracker.getNumberOfLines();
+ String result[]= new String[size];
+ for (int i= 0; i < size; i++) {
+ IRegion region= tracker.getLineInformation(i);
+ int offset= region.getOffset();
+ result[i]= input.substring(offset, offset + region.getLength());
+ }
+ return result;
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Removes the common number of indents from all lines. If a line
+ * only consists out of white space it is ignored.
+
+ * @param project the java project from which to get the formatter
+ * preferences, or <code>null</code> for global preferences
+ * @since 3.1
+ */
+ public static void trimIndentation(String[] lines, IRubyProject project) {
+ trimIndentation(lines, CodeFormatterUtil.getTabWidth(project), CodeFormatterUtil.getIndentWidth(project), true);
+ }
+
+ /**
+ * Removes the common number of indents from all lines. If a line
+ * only consists out of white space it is ignored. If <code>
+ * considerFirstLine</code> is false the first line will be ignored.
+ * @since 3.1
+ */
+ public static void trimIndentation(String[] lines, int tabWidth, int indentWidth, boolean considerFirstLine) {
+ String[] toDo= new String[lines.length];
+ // find indentation common to all lines
+ int minIndent= Integer.MAX_VALUE; // very large
+ for (int i= considerFirstLine ? 0 : 1; i < lines.length; i++) {
+ String line= lines[i];
+ if (containsOnlyWhitespaces(line))
+ continue;
+ toDo[i]= line;
+ int indent= computeIndentUnits(line, tabWidth, indentWidth);
+ if (indent < minIndent) {
+ minIndent= indent;
+ }
+ }
+
+ if (minIndent > 0) {
+ // remove this indent from all lines
+ for (int i= considerFirstLine ? 0 : 1; i < toDo.length; i++) {
+ String s= toDo[i];
+ if (s != null)
+ lines[i]= trimIndent(s, minIndent, tabWidth, indentWidth);
+ else {
+ String line= lines[i];
+ int indent= computeIndentUnits(line, tabWidth, indentWidth);
+ if (indent > minIndent)
+ lines[i]= trimIndent(line, minIndent, tabWidth, indentWidth);
+ else
+ lines[i]= trimLeadingTabsAndSpaces(line);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the given number of indents from the line. Asserts that the given line
+ * has the requested number of indents. If <code>indentsToRemove <= 0</code>
+ * the line is returned.
+ *
+ * @since 3.1
+ */
+ public static String trimIndent(String line, int indentsToRemove, int tabWidth, int indentWidth) {
+ return IndentManipulation.trimIndent(line, indentsToRemove, tabWidth, indentWidth);
+ }
+
+ /**
+ * Removes leading tabs and spaces from the given string. If the string
+ * doesn't contain any leading tabs or spaces then the string itself is
+ * returned.
+ */
+ public static String trimLeadingTabsAndSpaces(String line) {
+ int size= line.length();
+ int start= size;
+ for (int i= 0; i < size; i++) {
+ char c= line.charAt(i);
+ if (!IndentManipulation.isIndentChar(c)) {
+ start= i;
+ break;
+ }
+ }
+ if (start == 0)
+ return line;
+ else if (start == size)
+ return ""; //$NON-NLS-1$
+ else
+ return line.substring(start);
+ }
+
+ /**
+ * Concatenate the given strings into one strings using the passed line delimiter as a
+ * delimiter. No delimiter is added to the last line.
+ */
+ public static String concatenate(String[] lines, String delimiter) {
+ StringBuffer buffer= new StringBuffer();
+ for (int i= 0; i < lines.length; i++) {
+ if (i > 0)
+ buffer.append(delimiter);
+ buffer.append(lines[i]);
+ }
+ return buffer.toString();
+ }
+
}
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyPlugin.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -17,6 +17,7 @@
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
@@ -47,6 +48,7 @@
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.ConfigurationElementSorter;
import org.osgi.framework.BundleContext;
import org.rubypeople.rdt.core.IBuffer;
import org.rubypeople.rdt.core.IRubyScript;
@@ -66,8 +68,8 @@
import org.rubypeople.rdt.internal.ui.text.IRubyColorConstants;
import org.rubypeople.rdt.internal.ui.text.PreferencesAdapter;
import org.rubypeople.rdt.internal.ui.text.folding.RubyFoldingStructureProviderRegistry;
+import org.rubypeople.rdt.internal.ui.text.ruby.hover.RubyEditorTextHoverDescriptor;
import org.rubypeople.rdt.internal.ui.text.template.contentassist.RubyTemplateAccess;
-import org.rubypeople.rdt.ui.IWorkingCopyManager;
import org.rubypeople.rdt.ui.PreferenceConstants;
import org.rubypeople.rdt.ui.text.RubyTextTools;
@@ -80,7 +82,7 @@
protected RubyTextTools textTools;
protected RubyFileMatcher rubyFileMatcher;
- private IWorkingCopyManager fWorkingCopyManager;
+ private WorkingCopyManager fWorkingCopyManager;
private RubyDocumentProvider fDocumentProvider;
protected PropertyResourceBundle pluginProperties;
@@ -106,6 +108,8 @@
private MembersOrderPreferenceCache fMembersOrderPreferenceCache;
private RubyScriptDocumentProvider fExternalRubyDocumentProvider;
+ private RubyEditorTextHoverDescriptor[] fRubyEditorTextHoverDescriptors;
+
/**
* Default instance of the appearance type filters.
* @since 1.0
@@ -414,7 +418,7 @@
/**
* @return
*/
- public IWorkingCopyManager getWorkingCopyManager() {
+ public WorkingCopyManager getWorkingCopyManager() {
if (fWorkingCopyManager == null) {
RubyDocumentProvider provider = getRubyDocumentProvider();
fWorkingCopyManager = new WorkingCopyManager(provider);
@@ -584,4 +588,39 @@
}
return section;
}
+
+ /**
+ * Returns all Ruby editor text hovers contributed to the workbench.
+ *
+ * @return an array of RubyEditorTextHoverDescriptor
+ * @since 1.0
+ */
+ public RubyEditorTextHoverDescriptor[] getRubyEditorTextHoverDescriptors() {
+ if (fRubyEditorTextHoverDescriptors == null) {
+ fRubyEditorTextHoverDescriptors= RubyEditorTextHoverDescriptor.getContributedHovers();
+ ConfigurationElementSorter sorter= new ConfigurationElementSorter() {
+ /*
+ * @see org.eclipse.ui.texteditor.ConfigurationElementSorter#getConfigurationElement(java.lang.Object)
+ */
+ public IConfigurationElement getConfigurationElement(Object object) {
+ return ((RubyEditorTextHoverDescriptor)object).getConfigurationElement();
+ }
+ };
+ sorter.sort(fRubyEditorTextHoverDescriptors);
+
+ // Move Best Match hover to front
+ for (int i= 0; i < fRubyEditorTextHoverDescriptors.length - 1; i++) {
+ if (PreferenceConstants.ID_BESTMATCH_HOVER.equals(fRubyEditorTextHoverDescriptors[i].getId())) {
+ RubyEditorTextHoverDescriptor hoverDescriptor= fRubyEditorTextHoverDescriptors[i];
+ for (int j= i; j > 0; j--)
+ fRubyEditorTextHoverDescriptors[j]= fRubyEditorTextHoverDescriptors[j-1];
+ fRubyEditorTextHoverDescriptors[0]= hoverDescriptor;
+ break;
+ }
+
+ }
+ }
+
+ return fRubyEditorTextHoverDescriptors;
+ }
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/EditorUtility.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/EditorUtility.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/EditorUtility.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -8,10 +8,12 @@
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.SWT;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
@@ -35,6 +37,7 @@
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.core.ExternalRubyScript;
+import org.rubypeople.rdt.internal.core.util.Messages;
import org.rubypeople.rdt.internal.corext.util.RubyModelUtil;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.ui.PreferenceConstants;
@@ -285,4 +288,68 @@
return null;
}
+ /**
+ * Maps the localized modifier name to a code in the same
+ * manner as #findModifier.
+ *
+ * @param modifierName the modifier name
+ * @return the SWT modifier bit, or <code>0</code> if no match was found
+ * @since 2.1.1
+ */
+ public static int findLocalizedModifier(String modifierName) {
+ if (modifierName == null)
+ return 0;
+
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
+ return SWT.CTRL;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
+ return SWT.SHIFT;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
+ return SWT.ALT;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
+ return SWT.COMMAND;
+
+ return 0;
+ }
+
+ /**
+ * Returns the modifier string for the given SWT modifier
+ * modifier bits.
+ *
+ * @param stateMask the SWT modifier bits
+ * @return the modifier string
+ * @since 2.1.1
+ */
+ public static String getModifierString(int stateMask) {
+ String modifierString= ""; //$NON-NLS-1$
+ if ((stateMask & SWT.CTRL) == SWT.CTRL)
+ modifierString= appendModifierString(modifierString, SWT.CTRL);
+ if ((stateMask & SWT.ALT) == SWT.ALT)
+ modifierString= appendModifierString(modifierString, SWT.ALT);
+ if ((stateMask & SWT.SHIFT) == SWT.SHIFT)
+ modifierString= appendModifierString(modifierString, SWT.SHIFT);
+ if ((stateMask & SWT.COMMAND) == SWT.COMMAND)
+ modifierString= appendModifierString(modifierString, SWT.COMMAND);
+
+ return modifierString;
+ }
+
+ /**
+ * Appends to modifier string of the given SWT modifier bit
+ * to the given modifierString.
+ *
+ * @param modifierString the modifier string
+ * @param modifier an int with SWT modifier bit
+ * @return the concatenated modifier string
+ * @since 2.1.1
+ */
+ private static String appendModifierString(String modifierString, int modifier) {
+ if (modifierString == null)
+ modifierString= ""; //$NON-NLS-1$
+ String newModifierString= Action.findModifierString(modifier);
+ if (modifierString.length() == 0)
+ return newModifierString;
+ return Messages.format(RubyEditorMessages.EditorUtility_concatModifierStrings, new String[] {modifierString, newModifierString});
+ }
+
}
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyEditorMessages.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyEditorMessages.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyEditorMessages.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -35,6 +35,7 @@
public static String ToggleComment_error_message;
public static String CompletionProcessor_ContextInfo_value_pattern;
public static String CompletionProcessor_ContextInfo_display_pattern;
+ public static String EditorUtility_concatModifierStrings;
private static ResourceBundle fgResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/WorkingCopyManager.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/WorkingCopyManager.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/WorkingCopyManager.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -18,6 +18,7 @@
import org.eclipse.jface.text.Assert;
import org.eclipse.ui.IEditorInput;
import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.internal.corext.util.RubyModelUtil;
import org.rubypeople.rdt.ui.IWorkingCopyManager;
import org.rubypeople.rdt.ui.IWorkingCopyManagerExtension;
@@ -80,10 +81,33 @@
* @see org.eclipse.jdt.ui.IWorkingCopyManager#getWorkingCopy(org.eclipse.ui.IEditorInput)
*/
public IRubyScript getWorkingCopy(IEditorInput input) {
- IRubyScript unit = fMap == null ? null : (IRubyScript) fMap.get(input);
- return unit != null ? unit : fDocumentProvider.getWorkingCopy(input);
+ return getWorkingCopy(input, true);
}
+ /**
+ * Returns the working copy remembered for the compilation unit encoded in the
+ * given editor input.
+ * <p>
+ * Note: This method must not be part of the public {@link IWorkingCopyManager} API.
+ * </p>
+ *
+ * @param input the editor input
+ * @param primaryOnly if <code>true</code> only primary working copies will be returned
+ * @return the working copy of the compilation unit, or <code>null</code> if the
+ * input does not encode an editor input, or if there is no remembered working
+ * copy for this compilation unit
+ * @since 3.2
+ */
+ public IRubyScript getWorkingCopy(IEditorInput input, boolean primaryOnly) {
+ IRubyScript unit= fMap == null ? null : (IRubyScript) fMap.get(input);
+ if (unit == null)
+ unit= fDocumentProvider.getWorkingCopy(input);
+ if (unit != null && (!primaryOnly || RubyModelUtil.isPrimary(unit)))
+ return unit;
+ return null;
+ }
+
+
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.IWorkingCopyManagerExtension#setWorkingCopy(org.eclipse.ui.IEditorInput,
* org.eclipse.jdt.core.ICompilationUnit)
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/AbstractRubyEditorTextHover.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/AbstractRubyEditorTextHover.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/AbstractRubyEditorTextHover.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -1,17 +1,22 @@
/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2006 IBM 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/cpl-v10.html
- *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.rubypeople.rdt.internal.ui.text.ruby.hover;
-import java.util.List;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
@@ -20,14 +25,18 @@
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.commands.ICommand;
-import org.eclipse.ui.commands.ICommandManager;
-import org.eclipse.ui.commands.IKeySequenceBinding;
-import org.eclipse.ui.keys.KeySequence;
+import org.eclipse.ui.keys.IBindingService;
+import org.osgi.framework.Bundle;
+import org.rubypeople.rdt.core.ICodeAssist;
import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.core.util.Messages;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
+import org.rubypeople.rdt.internal.ui.rubyeditor.RubyScriptEditorInput;
+import org.rubypeople.rdt.internal.ui.rubyeditor.WorkingCopyManager;
import org.rubypeople.rdt.internal.ui.text.HTMLTextPresenter;
import org.rubypeople.rdt.internal.ui.text.RubyWordFinder;
import org.rubypeople.rdt.ui.PreferenceConstants;
@@ -36,19 +45,20 @@
/**
* Abstract class for providing hover information for Ruby elements.
- *
- * @since 2.1
+ *
+ * @since 1.0
*/
public abstract class AbstractRubyEditorTextHover implements IRubyEditorTextHover, ITextHoverExtension {
-
+ /**
+ * The style sheet (css).
+ * @since 1.0
+ */
+ private static String fgStyleSheet;
private IEditorPart fEditor;
- private ICommand fCommand;
+ private IBindingService fBindingService;
{
- ICommandManager commandManager= PlatformUI.getWorkbench().getCommandSupport().getCommandManager();
- fCommand= commandManager.getCommand(IRubyEditorActionDefinitionIds.SHOW_RDOC);
- if (!fCommand.isDefined())
- fCommand= null;
+ fBindingService= (IBindingService)PlatformUI.getWorkbench().getAdapter(IBindingService.class);
}
/*
@@ -61,25 +71,68 @@
protected IEditorPart getEditor() {
return fEditor;
}
-
+
+ protected ICodeAssist getCodeAssist() {
+ if (fEditor != null) {
+ IEditorInput input= fEditor.getEditorInput();
+ if (input instanceof RubyScriptEditorInput) {
+ RubyScriptEditorInput cfeInput= (RubyScriptEditorInput) input;
+ return cfeInput.getRubyScript();
+ }
+
+ WorkingCopyManager manager= RubyPlugin.getDefault().getWorkingCopyManager();
+ return manager.getWorkingCopy(input, false);
+ }
+
+ return null;
+ }
+
/*
* @see ITextHover#getHoverRegion(ITextViewer, int)
*/
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
return RubyWordFinder.findWord(textViewer.getDocument(), offset);
}
-
+
/*
* @see ITextHover#getHoverInfo(ITextViewer, IRegion)
*/
- public abstract String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion);
-
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+
+ /*
+ * The region should be a word region an not of length 0.
+ * This check is needed because codeSelect(...) also finds
+ * the Ruby element if the offset is behind the word.
+ */
+ if (hoverRegion.getLength() == 0)
+ return null;
+
+ ICodeAssist resolve= getCodeAssist();
+ if (resolve != null) {
+ try {
+ IRubyElement[] result= resolve.codeSelect(hoverRegion.getOffset(), hoverRegion.getLength());
+ if (result == null)
+ return null;
+
+ int nResults= result.length;
+ if (nResults == 0)
+ return null;
+
+ return getHoverInfo(result);
+
+ } catch (RubyModelException x) {
+ return null;
+ }
+ }
+ return null;
+ }
+
/**
* Provides hover information for the given Ruby elements.
- *
- * @param javaElements the Ruby elements for which to provide hover information
+ *
+ * @param rubyElements the Ruby elements for which to provide hover information
* @return the hover information string
- * @since 2.1
+ * @since 1.0
*/
protected String getHoverInfo(IRubyElement[] rubyElements) {
return null;
@@ -87,7 +140,7 @@
/*
* @see ITextHoverExtension#getHoverControlCreator()
- * @since 3.0
+ * @since 1.0
*/
public IInformationControlCreator getHoverControlCreator() {
return new IInformationControlCreator() {
@@ -96,44 +149,52 @@
}
};
}
-
+
/**
* Returns the tool tip affordance string.
- *
+ *
* @return the affordance string or <code>null</code> if disabled or no key binding is defined
- * @since 3.0
+ * @since 1.0
*/
protected String getTooltipAffordanceString() {
- if (!RubyPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE))
+ if (fBindingService == null || !RubyPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE))
return null;
-
- KeySequence[] sequences= getKeySequences();
- if (sequences == null)
+
+ String keySequence= fBindingService.getBestActiveBindingFormattedFor(IRubyEditorActionDefinitionIds.SHOW_RDOC);
+ if (keySequence == null)
return null;
- String keySequence= sequences[0].format();
- return RubyHoverMessages.getFormattedString(RubyHoverMessages.RubyTextHover_makeStickyHint, keySequence);
+ return Messages.format(RubyHoverMessages.RubyTextHover_makeStickyHint, keySequence == null ? "" : keySequence); //$NON-NLS-1$
}
/**
- * Returns the array of valid key sequence bindings for the
- * show tool tip description command.
- *
- * @return the array with the {@link KeySequence}s
- *
- * @since 3.0
+ * Returns the style sheet.
+ *
+ * @since 1.0
*/
- private KeySequence[] getKeySequences() {
- if (fCommand != null) {
- List list= fCommand.getKeySequenceBindings();
- if (!list.isEmpty()) {
- KeySequence[] keySequences= new KeySequence[list.size()];
- for (int i= 0; i < keySequences.length; i++) {
- keySequences[i]= ((IKeySequenceBinding) list.get(i)).getKeySequence();
+ protected static String getStyleSheet() {
+ if (fgStyleSheet == null) {
+ Bundle bundle= Platform.getBundle(RubyPlugin.getPluginId());
+ URL styleSheetURL= bundle.getEntry("/RubydocHoverStyleSheet.css"); //$NON-NLS-1$
+ if (styleSheetURL != null) {
+ try {
+ styleSheetURL= FileLocator.toFileURL(styleSheetURL);
+ BufferedReader reader= new BufferedReader(new InputStreamReader(styleSheetURL.openStream()));
+ StringBuffer buffer= new StringBuffer(200);
+ String line= reader.readLine();
+ while (line != null) {
+ buffer.append(line);
+ buffer.append('\n');
+ line= reader.readLine();
+ }
+ fgStyleSheet= buffer.toString();
+ } catch (IOException ex) {
+ RubyPlugin.log(ex);
+ fgStyleSheet= ""; //$NON-NLS-1$
}
- return keySequences;
- }
+ }
}
- return null;
+ return fgStyleSheet;
}
+
}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/BestMatchHover.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/BestMatchHover.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/BestMatchHover.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.ui.text.ruby.hover;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextHoverExtension;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.information.IInformationProviderExtension2;
+import org.eclipse.ui.IEditorPart;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+import org.rubypeople.rdt.ui.PreferenceConstants;
+import org.rubypeople.rdt.ui.text.ruby.hover.IRubyEditorTextHover;
+
+/**
+ * Caution: this implementation is a layer breaker and contains some "shortcuts"
+ */
+public class BestMatchHover extends AbstractRubyEditorTextHover implements ITextHoverExtension, IInformationProviderExtension2 {
+
+ private List fTextHoverSpecifications;
+ private List fInstantiatedTextHovers;
+ private ITextHover fBestHover;
+
+ public BestMatchHover() {
+ installTextHovers();
+ }
+
+ public BestMatchHover(IEditorPart editor) {
+ this();
+ setEditor(editor);
+ }
+
+ /**
+ * Installs all text hovers.
+ */
+ private void installTextHovers() {
+
+ // initialize lists - indicates that the initialization happened
+ fTextHoverSpecifications= new ArrayList(2);
+ fInstantiatedTextHovers= new ArrayList(2);
+
+ // populate list
+ RubyEditorTextHoverDescriptor[] hoverDescs= RubyPlugin.getDefault().getRubyEditorTextHoverDescriptors();
+ for (int i= 0; i < hoverDescs.length; i++) {
+ // ensure that we don't add ourselves to the list
+ if (!PreferenceConstants.ID_BESTMATCH_HOVER.equals(hoverDescs[i].getId()))
+ fTextHoverSpecifications.add(hoverDescs[i]);
+ }
+ }
+
+ private void checkTextHovers() {
+ if (fTextHoverSpecifications.size() == 0)
+ return;
+
+ for (Iterator iterator= new ArrayList(fTextHoverSpecifications).iterator(); iterator.hasNext(); ) {
+ RubyEditorTextHoverDescriptor spec= (RubyEditorTextHoverDescriptor) iterator.next();
+
+ IRubyEditorTextHover hover= spec.createTextHover();
+ if (hover != null) {
+ hover.setEditor(getEditor());
+ addTextHover(hover);
+ fTextHoverSpecifications.remove(spec);
+ }
+ }
+ }
+
+ protected void addTextHover(ITextHover hover) {
+ if (!fInstantiatedTextHovers.contains(hover))
+ fInstantiatedTextHovers.add(hover);
+ }
+
+ /*
+ * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+ */
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+
+ checkTextHovers();
+ fBestHover= null;
+
+ if (fInstantiatedTextHovers == null)
+ return null;
+
+ for (Iterator iterator= fInstantiatedTextHovers.iterator(); iterator.hasNext(); ) {
+ ITextHover hover= (ITextHover)iterator.next();
+
+ String s= hover.getHoverInfo(textViewer, hoverRegion);
+ if (s != null && s.trim().length() > 0) {
+ fBestHover= hover;
+ return s;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
+ * @since 3.0
+ */
+ public IInformationControlCreator getHoverControlCreator() {
+ if (fBestHover instanceof ITextHoverExtension)
+ return ((ITextHoverExtension)fBestHover).getHoverControlCreator();
+
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
+ * @since 3.0
+ */
+ public IInformationControlCreator getInformationPresenterControlCreator() {
+ if (fBestHover instanceof IInformationProviderExtension2)
+ return ((IInformationProviderExtension2)fBestHover).getInformationPresenterControlCreator();
+
+ return null;
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/ProblemHover.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/ProblemHover.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/ProblemHover.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.ui.text.ruby.hover;
+
+/**
+ * This annotation hover shows the description of the
+ * selected ruby annotation.
+ *
+ * @since 1.0
+ */
+public class ProblemHover extends AbstractAnnotationHover {
+
+ public ProblemHover() {
+ super(false);
+ }
+
+}
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -10,16 +10,14 @@
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.ui.IEditorInput;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
-import org.rubypeople.rdt.launching.IVMInstall;
import org.rubypeople.rdt.launching.RubyRuntime;
-import org.rubypeople.rdt.ui.extensions.ITextHoverProvider;
-
-public class RiDocHoverProvider implements ITextHoverProvider {
- public String getHoverInfo(IEditorInput input, ITextViewer textViewer, IRegion hoverRegion){
- File ri = RubyRuntime.getRI();
+public class RiDocHoverProvider extends AbstractRubyEditorTextHover {
+
+ @Override
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+ File ri = RubyRuntime.getRI();
if (ri == null || !ri.exists() || !ri.isFile()) return null;
List<String> args = new ArrayList<String>();
@@ -64,8 +62,7 @@
RubyPlugin.log(e);
}
}
- }
-
+ }
return null;
}
}
Deleted: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java 2007-05-01 18:09:19 UTC (rev 2414)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -1,82 +0,0 @@
-package org.rubypeople.rdt.internal.ui.text.ruby.hover;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextViewer;
-import org.rubypeople.rdt.internal.ui.RubyPlugin;
-import org.rubypeople.rdt.ui.extensions.ITextHoverProvider;
-
-/**
- * Generic TextHover that uses installed extensions for getting information;
- * when the TextHover is requested then all installed TextHoverProvider
- * extensions will be asked to provide a String to show for the location.
- *
- * @author murphee
- *
- */
-public class RubyCodeTextHover extends AbstractRubyEditorTextHover {
-
- public static final String RDT_UI_NAMESPACE = "org.rubypeople.rdt.ui";
- public static final String RDT_UI_TEXTHOVERPROVIDER = "textHoverProvider";
-
- private List fExtensions;
-
- public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
- List extensions = initExtensions();
- if (extensions.isEmpty())
- return null;
- for (int i = 0; i < extensions.size(); i++) {
- ITextHoverProvider currentProvider = (ITextHoverProvider) extensions.get(i);
- String hoverText = currentProvider.getHoverInfo(getEditor().getEditorInput(), textViewer, hoverRegion);
- if (hoverText != null) {
- return hoverText;
- }
- }
- return null;
- }
-
- private List initExtensions() {
- if (fExtensions == null) {
- fExtensions = new ArrayList();
- IExtensionPoint point = getTextHoverExtensionPoint();
- if (point == null)
- return fExtensions;
- IExtension[] exts = point.getExtensions();
- for (int i = 0; i < exts.length; i++) {
- IConfigurationElement[] elem = exts[i].getConfigurationElements();
- String attrs[] = elem[0].getAttributeNames();
- try {
- Object tempProv = elem[0].createExecutableExtension("class");
- if (tempProv instanceof ITextHoverProvider) {
- ITextHoverProvider prov = (ITextHoverProvider) tempProv;
- fExtensions.add(prov);
- }
- } catch (Exception e) {
- RubyPlugin.log(e);
- }
- }
- }
- return fExtensions;
- }
-
- private IExtensionPoint getTextHoverExtensionPoint() {
- IExtensionRegistry reg = Platform.getExtensionRegistry();
- IExtensionPoint[] points = reg.getExtensionPoints(RDT_UI_NAMESPACE);
- if (points == null)
- return null;
- for (int i = 0; i < points.length; i++) {
- IExtensionPoint currentPoint = points[i];
- if (currentPoint.getUniqueIdentifier().endsWith(RDT_UI_TEXTHOVERPROVIDER)) {
- return currentPoint;
- }
- }
- return null;
- }
-}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverDescriptor.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverDescriptor.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverDescriptor.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.rubypeople.rdt.internal.ui.text.ruby.hover;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.swt.SWT;
+import org.osgi.framework.Bundle;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+import org.rubypeople.rdt.internal.ui.rubyeditor.EditorUtility;
+import org.rubypeople.rdt.ui.PreferenceConstants;
+import org.rubypeople.rdt.ui.text.ruby.hover.IRubyEditorTextHover;
+
+/**
+ * Describes a Ruby editor text hover.
+ *
+ * @since 1.0
+ */
+public class RubyEditorTextHoverDescriptor {
+
+ private static final String RUBY_EDITOR_TEXT_HOVER_EXTENSION_POINT= "org.rubypeople.rdt.ui.rubyEditorTextHovers"; //$NON-NLS-1$
+ private static final String HOVER_TAG= "hover"; //$NON-NLS-1$
+ private static final String ID_ATTRIBUTE= "id"; //$NON-NLS-1$
+ private static final String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$
+ private static final String LABEL_ATTRIBUTE= "label"; //$NON-NLS-1$
+ private static final String ACTIVATE_PLUG_IN_ATTRIBUTE= "activate"; //$NON-NLS-1$
+ private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$
+
+ public static final String NO_MODIFIER= "0"; //$NON-NLS-1$
+ public static final String DISABLED_TAG= "!"; //$NON-NLS-1$
+ public static final String VALUE_SEPARATOR= ";"; //$NON-NLS-1$
+
+ private int fStateMask;
+ private String fModifierString;
+ private boolean fIsEnabled;
+
+ private IConfigurationElement fElement;
+
+
+ /**
+ * Returns all Ruby editor text hovers contributed to the workbench.
+ */
+ public static RubyEditorTextHoverDescriptor[] getContributedHovers() {
+ IExtensionRegistry registry= Platform.getExtensionRegistry();
+ IConfigurationElement[] elements= registry.getConfigurationElementsFor(RUBY_EDITOR_TEXT_HOVER_EXTENSION_POINT);
+ RubyEditorTextHoverDescriptor[] hoverDescs= createDescriptors(elements);
+ initializeFromPreferences(hoverDescs);
+ return hoverDescs;
+ }
+
+ /**
+ * Computes the state mask for the given modifier string.
+ *
+ * @param modifiers the string with the modifiers, separated by '+', '-', ';', ',' or '.'
+ * @return the state mask or -1 if the input is invalid
+ */
+ public static int computeStateMask(String modifiers) {
+ if (modifiers == null)
+ return -1;
+
+ if (modifiers.length() == 0)
+ return SWT.NONE;
+
+ int stateMask= 0;
+ StringTokenizer modifierTokenizer= new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
+ while (modifierTokenizer.hasMoreTokens()) {
+ int modifier= EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
+ if (modifier == 0 || (stateMask & modifier) == modifier)
+ return -1;
+ stateMask= stateMask | modifier;
+ }
+ return stateMask;
+ }
+
+ /**
+ * Creates a new Ruby Editor text hover descriptor from the given configuration element.
+ */
+ private RubyEditorTextHoverDescriptor(IConfigurationElement element) {
+ Assert.isNotNull(element);
+ fElement= element;
+ }
+
+ /**
+ * Creates the Ruby editor text hover.
+ */
+ public IRubyEditorTextHover createTextHover() {
+ String pluginId = fElement.getContributor().getName();
+ boolean isHoversPlugInActivated= Platform.getBundle(pluginId).getState() == Bundle.ACTIVE;
+ if (isHoversPlugInActivated || canActivatePlugIn()) {
+ try {
+ return (IRubyEditorTextHover)fElement.createExecutableExtension(CLASS_ATTRIBUTE);
+ } catch (CoreException x) {
+ RubyPlugin.log(new Status(IStatus.ERROR, RubyPlugin.getPluginId(), 0, RubyHoverMessages.RubyTextHover_createTextHover, null));
+ }
+ }
+
+ return null;
+ }
+
+ //---- XML Attribute accessors ---------------------------------------------
+
+ /**
+ * Returns the hover's id.
+ */
+ public String getId() {
+ return fElement.getAttribute(ID_ATTRIBUTE);
+ }
+
+ /**
+ * Returns the hover's class name.
+ */
+ public String getHoverClassName() {
+ return fElement.getAttribute(CLASS_ATTRIBUTE);
+ }
+
+ /**
+ * Returns the hover's label.
+ */
+ public String getLabel() {
+ String label= fElement.getAttribute(LABEL_ATTRIBUTE);
+ if (label != null)
+ return label;
+
+ // Return simple class name
+ label= getHoverClassName();
+ int lastDot= label.lastIndexOf('.');
+ if (lastDot >= 0 && lastDot < label.length() - 1)
+ return label.substring(lastDot + 1);
+ else
+ return label;
+ }
+
+ /**
+ * Returns the hover's description.
+ *
+ * @return the hover's description or <code>null</code> if not provided
+ */
+ public String getDescription() {
+ return fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
+ }
+
+
+ public boolean canActivatePlugIn() {
+ return Boolean.valueOf(fElement.getAttribute(ACTIVATE_PLUG_IN_ATTRIBUTE)).booleanValue();
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null || !obj.getClass().equals(this.getClass()) || getId() == null)
+ return false;
+ return getId().equals(((RubyEditorTextHoverDescriptor)obj).getId());
+ }
+
+ public int hashCode() {
+ return getId().hashCode();
+ }
+
+ private static RubyEditorTextHoverDescriptor[] createDescriptors(IConfigurationElement[] elements) {
+ List result= new ArrayList(elements.length);
+ for (int i= 0; i < elements.length; i++) {
+ IConfigurationElement element= elements[i];
+ if (HOVER_TAG.equals(element.getName())) {
+ RubyEditorTextHoverDescriptor desc= new RubyEditorTextHoverDescriptor(element);
+ result.add(desc);
+ }
+ }
+ return (RubyEditorTextHoverDescriptor[])result.toArray(new RubyEditorTextHoverDescriptor[result.size()]);
+ }
+
+ private static void initializeFromPreferences(RubyEditorTextHoverDescriptor[] hovers) {
+ String compiledTextHoverModifiers= RubyPlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
+
+ StringTokenizer tokenizer= new StringTokenizer(compiledTextHoverModifiers, VALUE_SEPARATOR);
+ HashMap idToModifier= new HashMap(tokenizer.countTokens() / 2);
+
+ while (tokenizer.hasMoreTokens()) {
+ String id= tokenizer.nextToken();
+ if (tokenizer.hasMoreTokens())
+ idToModifier.put(id, tokenizer.nextToken());
+ }
+
+ String compiledTextHoverModifierMasks= RubyPlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
+
+ tokenizer= new StringTokenizer(compiledTextHoverModifierMasks, VALUE_SEPARATOR);
+ HashMap idToModifierMask= new HashMap(tokenizer.countTokens() / 2);
+
+ while (tokenizer.hasMoreTokens()) {
+ String id= tokenizer.nextToken();
+ if (tokenizer.hasMoreTokens())
+ idToModifierMask.put(id, tokenizer.nextToken());
+ }
+
+ for (int i= 0; i < hovers.length; i++) {
+ String modifierString= (String)idToModifier.get(hovers[i].getId());
+ boolean enabled= true;
+ if (modifierString == null)
+ modifierString= DISABLED_TAG;
+
+ if (modifierString.startsWith(DISABLED_TAG)) {
+ enabled= false;
+ modifierString= modifierString.substring(1);
+ }
+
+ if (modifierString.equals(NO_MODIFIER))
+ modifierString= ""; //$NON-NLS-1$
+
+ hovers[i].fModifierString= modifierString;
+ hovers[i].fIsEnabled= enabled;
+ hovers[i].fStateMask= computeStateMask(modifierString);
+ if (hovers[i].fStateMask == -1) {
+ // Fallback: use stored modifier masks
+ try {
+ hovers[i].fStateMask= Integer.parseInt((String)idToModifierMask.get(hovers[i].getId()));
+ } catch (NumberFormatException ex) {
+ hovers[i].fStateMask= -1;
+ }
+ // Fix modifier string
+ int stateMask= hovers[i].fStateMask;
+ if (stateMask == -1)
+ hovers[i].fModifierString= ""; //$NON-NLS-1$
+ else
+ hovers[i].fModifierString= EditorUtility.getModifierString(stateMask);
+ }
+ }
+ }
+
+ /**
+ * Returns the configured modifier getStateMask for this hover.
+ *
+ * @return the hover modifier stateMask or -1 if no hover is configured
+ */
+ public int getStateMask() {
+ return fStateMask;
+ }
+
+ /**
+ * Returns the modifier String as set in the preference store.
+ *
+ * @return the modifier string
+ */
+ public String getModifierString() {
+ return fModifierString;
+ }
+
+ /**
+ * Returns whether this hover is enabled or not.
+ *
+ * @return <code>true</code> if enabled
+ */
+ public boolean isEnabled() {
+ return fIsEnabled;
+ }
+
+ /**
+ * Returns this hover descriptors configuration element.
+ *
+ * @return the configuration element
+ * @since 3.0
+ */
+ public IConfigurationElement getConfigurationElement() {
+ return fElement;
+ }
+}
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverProxy.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverProxy.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyEditorTextHoverProxy.java 2007-05-02 13:17:08 UTC (rev 2415)
@@ -0,0 +1,109 @@
+/**************...
[truncated message content] |