1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug #205030 : CHelpProvider for providing F1/hover docs info via XML should be implemented

This commit is contained in:
Oleg Krasilnikov 2007-10-24 09:30:40 +00:00
parent 2a94956ebe
commit 475c93f89d
9 changed files with 651 additions and 2 deletions

View file

@ -427,3 +427,5 @@ Cproject.desc=Create a new C project
TemplatePreferencePage.name=Template Default Values
Template.Engine.Wizard=template entries contributor
ConfigManager=Dialog for Configurations management
HelpInfo=Allows contributing the map files to the map-file-based CDT CHelpProvider.

View file

@ -22,6 +22,7 @@
<extension-point id="completionProposalComputer" name="%completionProposalComputer" schema="schema/completionProposalComputer.exsd"/>
<extension-point id="newCfgDialog" name="%NewCfgDialog.name" schema="schema/newCfgDialog.exsd"/>
<extension-point id="ConfigManager" name="%ConfigManager" schema="schema/ConfigManager.exsd"/>
<extension-point id="HelpInfo" name="%HelpInfo" schema="schema/HelpInfo.exsd"/>
<extension
point="org.eclipse.core.runtime.adapters">
@ -2257,4 +2258,12 @@
markerType="org.eclipse.cdt.core.problem">
</updater>
</extension>
</plugin>
<extension
point="org.eclipse.cdt.ui.CHelpProvider">
<provider
class="org.eclipse.cdt.internal.ui.help.CHelpProvider"
id="org.eclipse.cdt.ui.provider1">
</provider>
</extension>
</plugin>

View file

@ -0,0 +1,127 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.ui">
<annotation>
<appInfo>
<meta.schema plugin="org.eclipse.cdt.ui" id="HelpInfo" name="Allows contributing the map files to the map-file-based CDT CHelpProvider."/>
</appInfo>
<documentation>
Allows contributing the map files to
the map-file-based CDT CHelpProvider.
</documentation>
</annotation>
<element name="extension">
<complexType>
<sequence>
<element ref="helpInfo" minOccurs="1" maxOccurs="unbounded"/>
</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>
<appInfo>
<meta.attribute translatable="true"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="helpInfo">
<annotation>
<documentation>
Allows defining map-file path relative to the plugin directory.
</documentation>
</annotation>
<complexType>
<attribute name="file" type="string" use="required">
<annotation>
<documentation>
Contains map-file path relative to the plugin directory.
</documentation>
<appInfo>
<meta.attribute kind="resource"/>
</appInfo>
</annotation>
</attribute>
<attribute name="format" type="string">
<annotation>
<documentation>
May contain ID of map file format.
For now, there&apos;s only one (default) help map format.
</documentation>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appInfo>
<meta.section type="since"/>
</appInfo>
<documentation>
CDT 4.0.2
</documentation>
</annotation>
<annotation>
<appInfo>
<meta.section type="examples"/>
</appInfo>
<documentation>
&lt;extension
point=&quot;org.eclipse.cdt.ui.HelpInfo&quot;
id=&quot;org.eclipse.cdt.ui.help.cpp&quot;
name=&quot;C++ Help&quot;&gt;
&lt;helpInfo file=&quot;data1.xml&quot;/&gt;
&lt;helpInfo file=&quot;data2.xml&quot;/&gt;
&lt;helpInfo file=&quot;data3.xml&quot;/&gt;
&lt;/extension&gt;
</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>

View file

@ -0,0 +1,110 @@
package org.eclipse.cdt.internal.ui.help;
import java.util.ArrayList;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.eclipse.cdt.ui.FunctionPrototypeSummary;
import org.eclipse.cdt.ui.IFunctionSummary;
import org.eclipse.cdt.ui.IRequiredInclude;
public class CFunctionSummary implements IFunctionSummary {
private static final String ATTR_STD = "standard"; //$NON-NLS-1$
private static final String NODE_NAME = "name"; //$NON-NLS-1$
private static final String NODE_DESC = "description"; //$NON-NLS-1$
private static final String NODE_INCL = "include"; //$NON-NLS-1$
private static final String NODE_TYPE = "returnType"; //$NON-NLS-1$
private static final String NODE_ARGS = "arguments"; //$NON-NLS-1$
private static final String SP = " "; //$NON-NLS-1$
private static final String LB = "("; //$NON-NLS-1$
private static final String RB = ")"; //$NON-NLS-1$
private String name = null;
private String desc = null;
private IRequiredInclude[] incs = null;
IFunctionPrototypeSummary fps = null;
public CFunctionSummary(Element e, String defName) {
name = defName; // if there's no "name" tag, keyword used instead
String args = null;
String type = null;
NodeList list = e.getChildNodes();
ArrayList incList = new ArrayList();
for(int j = 0; j < list.getLength(); j++){
Node node = list.item(j);
if(node.getNodeType() != Node.ELEMENT_NODE)
continue;
String s = node.getNodeName().trim();
String t = node.getFirstChild().getNodeValue().trim();
if(NODE_NAME.equals(s)){
name = t;
} else if(NODE_DESC.equals(s)){
desc = t;
} else if(NODE_ARGS.equals(s)){
args = t;
} else if(NODE_TYPE.equals(s)){
type = t;
} else if(NODE_INCL.equals(s)){
boolean std = true;
if (((Element)node).hasAttribute(ATTR_STD)) {
String st = ((Element)node).getAttribute(ATTR_STD);
std = (st == null || st.equalsIgnoreCase("true") //$NON-NLS-1$
|| st.equalsIgnoreCase("yes")); //$NON-NLS-1$
}
incList.add(new RequiredInclude(t, std));
}
}
if (incList.size() > 0)
incs = (IRequiredInclude[])incList.toArray(
new IRequiredInclude[incList.size()]);
fps = new FunctionPrototypeSummary(type + SP + name + LB + args + RB);
}
public String getDescription() {
return desc;
}
public IRequiredInclude[] getIncludes() {
return incs;
}
public String getName() {
return name;
}
public String getNamespace() {
return null;
}
public IFunctionPrototypeSummary getPrototype() {
return fps;
}
/**
* This class implements IRequiredInclude interface
*/
private class RequiredInclude implements IRequiredInclude {
private String iname;
private boolean std;
private RequiredInclude(String s, boolean b) {
iname = s;
std = b;
}
public String getIncludeName() {
return iname;
}
public boolean isStandard() {
return std;
}
public String toString() {
if (std)
return "#include <" + iname + ">"; //$NON-NLS-1$ //$NON-NLS-2$
else
return "#include \"" + iname + "\""; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public String toString() {
return "<functionSummary> : " + getPrototype().getPrototypeString(false); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,144 @@
package org.eclipse.cdt.internal.ui.help;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.eclipse.help.IHelpResource;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.eclipse.cdt.ui.ICHelpBook;
import org.eclipse.cdt.ui.ICHelpResourceDescriptor;
import org.eclipse.cdt.ui.IFunctionSummary;
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
public class CHelpBook implements ICHelpBook {
private static final String ATTR_TITLE = "title"; //$NON-NLS-1$
private static final String ATTR_BTYPE = "type"; //$NON-NLS-1$
private static final String NODE_ENTRY = "entry"; //$NON-NLS-1$
private int type;
private String title;
private TreeMap entries;
public CHelpBook(Element e) {
entries = new TreeMap();
if (e.hasAttribute(ATTR_TITLE))
title = e.getAttribute(ATTR_TITLE).trim();
if (e.hasAttribute(ATTR_BTYPE)) {
try {
type = Integer.parseInt(e.getAttribute(ATTR_TITLE));
} catch (NumberFormatException ee) {}
}
NodeList list = e.getChildNodes();
for(int i = 0; i < list.getLength(); i++){
Node node = list.item(i);
if(node.getNodeType() != Node.ELEMENT_NODE) continue;
if(NODE_ENTRY.equals(node.getNodeName())) {
CHelpEntry he = new CHelpEntry((Element)node);
if (he.isValid())
add(he.getKeyword(), he);
}
}
}
public int getCHelpType() {
return type;
}
public String getTitle() {
return title;
}
private void add(String keyword, Object entry) {
entries.put(keyword, entry);
}
public IFunctionSummary getFunctionInfo(
ICHelpInvocationContext context,
String name) {
if (entries.containsKey(name)) {
CHelpEntry he = (CHelpEntry)entries.get(name);
IFunctionSummary[] fs = he.getFunctionSummary();
if (fs != null && fs.length > 0)
return fs[0];
// TODO: function summary selection
}
return null;
}
/**
* Temporary implementation with slow search
* @param context
* @param prefix
* @return matching functions
*/
public List getMatchingFunctions(
ICHelpInvocationContext context,
String prefix) {
Collection col = null;
if (prefix == null || prefix.trim().length() == 0) {
// return whole data
col = entries.values();
} else {
String pr1 = prefix.trim();
byte[] bs = pr1.getBytes();
int i = bs.length - 1;
while (i >= 0) {
byte b = bs[i];
if (++b > bs[i]) { // no overflow
bs[i] = b;
break;
} else
i--;
}
SortedMap sm = (i>-1) ?
entries.subMap(pr1, new String(bs)) :
entries.tailMap(pr1);
col = sm.values();
}
if (col.size() > 0)
return new ArrayList(col);
else
return null;
}
public ICHelpResourceDescriptor getHelpResources(
ICHelpInvocationContext context, String name) {
if (entries.containsKey(name)) {
CHelpEntry he = (CHelpEntry)entries.get(name);
IHelpResource[] hr = he.getHelpResource();
if (hr != null && hr.length > 0)
return new HRDescriptor(this, hr);
}
return null;
}
private class HRDescriptor implements ICHelpResourceDescriptor {
private ICHelpBook book;
private IHelpResource[] res;
HRDescriptor(ICHelpBook _book, IHelpResource[] _res) {
book = _book;
res = _res;
}
public ICHelpBook getCHelpBook() {
return book;
}
public IHelpResource[] getHelpResources() {
return res;
}
}
public String toString() {
return "<helpBook title=\"" +title +"\" type=\"" + type + "\">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}

View file

@ -0,0 +1,62 @@
package org.eclipse.cdt.internal.ui.help;
import java.util.ArrayList;
import org.eclipse.help.IHelpResource;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.eclipse.cdt.ui.IFunctionSummary;
public class CHelpEntry {
private static final String ATTR_KEYWD = "keyword"; //$NON-NLS-1$
private static final String NODE_TOPIC = "topic"; //$NON-NLS-1$
private static final String NODE_FSUMM = "functionSummary"; //$NON-NLS-1$
private String keyword = null;
private boolean isValid = true;
private CHelpTopic[] hts = null;
private CFunctionSummary[] fss = null;
public CHelpEntry(Element e) {
keyword = e.getAttribute(ATTR_KEYWD).trim();
ArrayList obs1 = new ArrayList();
ArrayList obs2 = new ArrayList();
NodeList list = e.getChildNodes();
for(int i = 0; i < list.getLength(); i++){
Node node = list.item(i);
if (node.getNodeType() != Node.ELEMENT_NODE)
continue;
if (NODE_FSUMM.equals(node.getNodeName())){
obs1.add(new CFunctionSummary((Element)node, keyword));
} else if (NODE_TOPIC.equals(node.getNodeName())) {
obs2.add(new CHelpTopic((Element)node, keyword));
}
}
fss = (CFunctionSummary[])obs1.toArray(new CFunctionSummary[obs1.size()]);
hts = (CHelpTopic[])obs2.toArray(new CHelpTopic[obs2.size()]);
}
/**
* Returns true if help entry is correct
* Returns false if entry is empty or when
* subsequent processing failed somehow.
* @return entry state
*/
public boolean isValid() {
return isValid;
}
public String getKeyword() {
return keyword;
}
public IFunctionSummary[] getFunctionSummary() {
return fss;
}
public IHelpResource[] getHelpResource() {
return hts;
}
public String toString() {
return "<entry keyword=\"" + keyword + "\">"; //$NON-NLS-1$ //$NON-NLS-2$
}
}

View file

@ -0,0 +1,166 @@
package org.eclipse.cdt.internal.ui.help;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.eclipse.cdt.ui.ICHelpBook;
import org.eclipse.cdt.ui.ICHelpProvider;
import org.eclipse.cdt.ui.ICHelpResourceDescriptor;
import org.eclipse.cdt.ui.IFunctionSummary;
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
public class CHelpProvider implements ICHelpProvider {
private static final String EXTENSION_POINT_ID = "org.eclipse.cdt.ui.HelpInfo"; //$NON-NLS-1$
private static final String ELEMENT_NAME = "helpInfo"; //$NON-NLS-1$
private static final String ATTRIB_FILE = "file"; //$NON-NLS-1$
private static final String NODE_HEAD = "documentation"; //$NON-NLS-1$
private static final String NODE_BOOK = "helpBook"; //$NON-NLS-1$
ICHelpBook[] hbs = null;
public ICHelpBook[] getCHelpBooks() {
return hbs;
}
public IFunctionSummary getFunctionInfo(
ICHelpInvocationContext context,
ICHelpBook[] helpBooks,
String name) {
for (int i=0; i<helpBooks.length; i++) {
if (helpBooks[i] instanceof CHelpBook) {
IFunctionSummary fs = ((CHelpBook)helpBooks[i]).getFunctionInfo(context, name);
if (fs != null) // if null, try with another book
return fs;
}
}
return null;
}
public ICHelpResourceDescriptor[] getHelpResources(
ICHelpInvocationContext context, ICHelpBook[] helpBooks, String name) {
ArrayList lst = new ArrayList();
for (int i=0; i<helpBooks.length; i++) {
if (helpBooks[i] instanceof CHelpBook) {
ICHelpResourceDescriptor hrd =
((CHelpBook)helpBooks[i]).getHelpResources(context, name);
if (hrd != null)
lst.add(hrd);
}
}
if (lst.size() > 0)
return (ICHelpResourceDescriptor[])lst.toArray(
new ICHelpResourceDescriptor[lst.size()]);
else
return null;
}
public IFunctionSummary[] getMatchingFunctions(
ICHelpInvocationContext context, ICHelpBook[] helpBooks,
String prefix) {
ArrayList lst = new ArrayList();
for (int i=0; i<helpBooks.length; i++) {
if (helpBooks[i] instanceof CHelpBook) {
List fs = ((CHelpBook)helpBooks[i]).getMatchingFunctions(context, prefix);
if (fs != null) // if null, try with another book
lst.addAll(fs);
}
}
if (lst.size() > 0)
return (IFunctionSummary[])lst.toArray(new IFunctionSummary[lst.size()]);
else
return null;
}
public void initialize() {
loadExtensions();
System.out.println();
}
private void loadExtensions()
{
IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
.getExtensionPoint(EXTENSION_POINT_ID);
if (extensionPoint == null) return;
IExtension[] extensions = extensionPoint.getExtensions();
if (extensions == null) return;
ArrayList chbl = new ArrayList();
for (int i = 0; i < extensions.length; ++i) {
String pluginId = extensions[i].getNamespaceIdentifier();
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
for (int k = 0; k < elements.length; k++) {
if (elements[k].getName().equals(ELEMENT_NAME)) {
loadFile(elements[k], chbl, pluginId);
}
}
}
if (chbl.size() > 0) {
hbs = (ICHelpBook[])chbl.toArray(new ICHelpBook[chbl.size()]);
}
}
private void loadFile(IConfigurationElement el, ArrayList chbl, String pluginId) {
String fname = el.getAttribute(ATTRIB_FILE);
if (fname == null || fname.trim().length() == 0) return;
URL x = FileLocator.find(Platform.getBundle(pluginId), new Path(fname), null);
if (x == null) return;
try { x = FileLocator.toFileURL(x);
} catch (IOException e) { return; }
fname = x.getPath();
if (fname == null || fname.trim().length() == 0) return;
// format is not supported for now
// String format = el.getAttribute(ATTRIB_FORMAT);
Document doc = null;
try {
InputStream stream = new FileInputStream(fname);
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
InputSource src = new InputSource(reader);
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
doc = builder.parse(src);
} catch (ParserConfigurationException e) {
} catch (SAXException e) {
} catch (IOException e) {
}
Element e = doc.getDocumentElement();
if(NODE_HEAD.equals(e.getNodeName())){
NodeList list = e.getChildNodes();
for(int j = 0; j < list.getLength(); j++){
Node node = list.item(j);
if(node.getNodeType() != Node.ELEMENT_NODE) continue;
if(NODE_BOOK.equals(node.getNodeName())){
chbl.add(new CHelpBook((Element)node));
}
}
}
}
}

View file

@ -0,0 +1,28 @@
package org.eclipse.cdt.internal.ui.help;
import org.eclipse.help.IHelpResource;
import org.w3c.dom.Element;
public class CHelpTopic implements IHelpResource {
private static final String ATTR_TITLE = "title"; //$NON-NLS-1$
private static final String ATTR_HREF = "href"; //$NON-NLS-1$
private String href = null;
private String title = null;
public CHelpTopic(Element e, String defTitle) {
href = e.getAttribute(ATTR_HREF).trim();
title = e.getAttribute(ATTR_TITLE).trim();
if (title == null || title.length() == 0)
title = defTitle;
}
public String getHref() {
return href;
}
public String getLabel() {
return title;
}
public String toString() {
return "<topic href=\"" + href + "\" title=\"" + title + "\">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}

View file

@ -117,7 +117,8 @@ public class CUIHelp {
ITextSelection selection = (ITextSelection)editor.getSite().getSelectionProvider().getSelection();
IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
IRegion region = CWordFinder.findWord(document, selection.getOffset());
expression = document.get(region.getOffset(), region.getLength());
if (region != null)
expression = document.get(region.getOffset(), region.getLength());
}
catch(Exception e){
}