blob: 6af124a4e323ff6524e7be33a48d06c8ae3c8d16 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.ui.editor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.resources.IResource;
import org.eclipse.xwt.IEventConstants;
import org.eclipse.xwt.XWT;
import org.eclipse.xwt.XWTMaps;
import org.eclipse.xwt.internal.utils.UserData;
import org.eclipse.xwt.javabean.metadata.Metaclass;
import org.eclipse.xwt.metadata.IEvent;
import org.eclipse.xwt.metadata.IMetaclass;
import org.eclipse.xwt.metadata.IProperty;
import org.eclipse.xwt.utils.NamedColorsUtil;
import org.eclipse.xwt.utils.ResourceManager;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
import org.eclipse.wst.xml.ui.internal.contentassist.AbstractContentAssistProcessor;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages;
import org.eclipse.wst.xml.ui.internal.preferences.XMLUIPreferenceNames;
import org.eclipse.wst.xml.ui.internal.templates.TemplateContextTypeIdsXML;
import org.eclipse.xwt.ui.utils.ImageManager;
import org.eclipse.xwt.vex.contentassist.SelectionCompletionProposal;
import org.eclipse.xwt.vex.contentassist.VEXTemplateCompletionProcessor;
import org.eclipse.xwt.vex.dom.DomHelper;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XWTContentAssistProcessor extends AbstractContentAssistProcessor
implements IPropertyChangeListener {
static final String HANDLER_PREFIX = "on";
static SelectionCompletionProposal[] booleanProposals;
static SelectionCompletionProposal[] colorsProposals;
static SelectionCompletionProposal[] stylesProposals;
static SelectionCompletionProposal[] acceleratorsProposals;
protected IPreferenceStore fPreferenceStore = null;
protected IResource fResource = null;
private VEXTemplateCompletionProcessor fTemplateProcessor = null;
private List<String> fTemplateContexts = new ArrayList<String>();
protected Comparator<ICompletionProposal> comparator = new Comparator<ICompletionProposal>() {
public int compare(ICompletionProposal o1, ICompletionProposal o2) {
return o1.getDisplayString().compareTo(o2.getDisplayString());
}
};
static SelectionCompletionProposal[] getBooleanProposals() {
if (booleanProposals == null) {
String[] values = new String[] { "True", "False" };
Image image = ImageManager
.get(XMLEditorPluginImages.IMG_OBJ_ATTRIBUTE);
booleanProposals = new SelectionCompletionProposal[values.length];
for (int j = 0; j < values.length; j++) {
String pattern = "\"" + values[j] + "\"";
booleanProposals[j] = new SelectionCompletionProposal(pattern,
0, 0, 1, values[j].length(), image, values[j], null,
null);
}
}
return booleanProposals;
}
static SelectionCompletionProposal[] getColorsProposals() {
if (colorsProposals == null) {
Collection<String> names = XWTMaps.getColorKeys();
String[] colorNames = NamedColorsUtil.getColorNames();
colorsProposals = new SelectionCompletionProposal[names.size()
+ colorNames.length];
int i = 0;
for (String colorStr : names) {
Color color = ResourceManager.resources.getColor(colorStr);
SelectionCompletionProposal p = createColorProposal(color,
colorStr);
if (p != null) {
colorsProposals[i++] = p;
}
}
for (String colorName : colorNames) {
Color color = ResourceManager.resources.getColor(colorName);
SelectionCompletionProposal p = createColorProposal(color,
colorName);
if (p != null) {
colorsProposals[i++] = p;
}
}
}
return colorsProposals;
}
static SelectionCompletionProposal createColorProposal(Color color,
String colorName) {
if (color != null) {
String pattern = "\"" + colorName + "\"";
Image image = new Image(null, 16, 16);
GC gc = new GC(image);
gc.setBackground(color);
gc.fillRectangle(0, 0, 16, 16);
gc.dispose();
return new SelectionCompletionProposal(pattern, 0, 0, 1,
colorName.length(), image, colorName, null, null);
}
return null;
}
static SelectionCompletionProposal[] getStylesProposals() {
if (stylesProposals == null) {
Collection<String> names = XWTMaps.getStyleKeys();
stylesProposals = new SelectionCompletionProposal[names.size()];
int i = 0;
for (String string : names) {
String pattern = "\"" + string + "\"";
stylesProposals[i++] = new SelectionCompletionProposal(pattern,
0, 0, 1, string.length(), null, string, null, null);
}
}
return stylesProposals;
}
static SelectionCompletionProposal[] getAcceleratorsProposals() {
if (acceleratorsProposals == null) {
Collection<String> names = XWTMaps.getAcceleratorKeys();
acceleratorsProposals = new SelectionCompletionProposal[names
.size()];
int i = 0;
for (String string : names) {
String pattern = "\"" + string + "\"";
acceleratorsProposals[i++] = new SelectionCompletionProposal(
pattern, 0, 0, 1, string.length(), null, string, null,
null);
}
}
return acceleratorsProposals;
}
@Override
protected void addAttributeNameProposals(
ContentAssistRequest contentAssistRequest) {
addXAMLPropertyNameProposals(contentAssistRequest);
addTemplates(contentAssistRequest, TemplateContextTypeIdsXML.ATTRIBUTE);
super.addAttributeNameProposals(contentAssistRequest);
}
private void addXAMLPropertyNameProposals(
ContentAssistRequest contentAssistRequest) {
List<ICompletionProposal> proposalCollector = new ArrayList<ICompletionProposal>();
List<ICompletionProposal> macrosCollector = new ArrayList<ICompletionProposal>();
//
Node node = contentAssistRequest.getNode();
String name = getNodeName(node);
HashSet<String> existing = new HashSet<String>();
NamedNodeMap namedNodeMap = node.getAttributes();
for (int i = 0; i < namedNodeMap.getLength(); i++) {
Node attributeNode = namedNodeMap.item(i);
String attributeName = attributeNode.getNodeName();
existing.add(attributeName);
}
boolean useProposalList = !contentAssistRequest.shouldSeparate();
int offset = contentAssistRequest.getReplacementBeginPosition();
int replacementLength = contentAssistRequest.getReplacementLength();
IDocument document = fTextViewer.getDocument();
String prefixed = null;
try {
prefixed = document.get(offset, replacementLength).toLowerCase();
} catch (BadLocationException e1) {
}
IMetaclass metaclass = XWT.getMetaclass(name,
DomHelper.lookupNamespaceURI(node));
if (metaclass != null) {
IProperty[] properties = metaclass.getProperties();
for (IProperty property : properties) {
Class<?> propertyType = property.getType();
if (propertyType != null
&& Control.class.isAssignableFrom(propertyType)) {
continue;
}
String propertyName = property.getName();
if (prefixed != null
&& !propertyName.toLowerCase().startsWith(prefixed)) {
continue;
}
if (!existing.contains(propertyName)) {
String defaultValueString = "";
if (propertyName.equalsIgnoreCase("style")) {
propertyName = "x:style";
defaultValueString = "SWT.NONE";
}
String replacementString = propertyName + "=\""
+ defaultValueString + "\" ";
Image image = JavaPluginImages
.get(JavaPluginImages.IMG_FIELD_PUBLIC);
SelectionCompletionProposal proposal = new SelectionCompletionProposal(
replacementString, offset, replacementLength,
propertyName.length() + 2,
defaultValueString.length(), image, propertyName,
null, "Property: " + propertyName);
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
}
IEvent[] events = metaclass.getEvents();
for (IEvent event : events) {
String eventName = event.getName();
if (prefixed != null
&& !eventName.toLowerCase().startsWith(prefixed)) {
continue;
}
eventName = Character.toUpperCase(eventName.charAt(0))
+ eventName.substring(1) + IEventConstants.SUFFIX;
if (event.getName() != null
&& (event.getName().equals(IEventConstants.XWT_LOADED) ||
event.getName().equals(IEventConstants.XWT_LOADED_EVENT))) {
eventName = IEventConstants.XWT_LOADED_EVENT;
}
if (!existing.contains(eventName)) {
String replacementString = eventName + "=\""
+ HANDLER_PREFIX + eventName + "\" ";
Image image = ImageManager.get(ImageManager.IMG_EVENT);
SelectionCompletionProposal proposal = new SelectionCompletionProposal(
replacementString, offset, replacementLength,
eventName.length() + 2, eventName.length()
+ HANDLER_PREFIX.length(), image,
eventName, null, "Event: " + eventName);
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
}
}
Node parentNode = node.getParentNode();
String parentName = getNodeName(parentNode);
try {
IMetaclass parentMetaclass = XWT.getMetaclass(parentName,
DomHelper.lookupNamespaceURI(parentNode));
if (parentMetaclass != null) {
// Attached property
}
} catch (Exception e) {
}
Collections.sort(proposalCollector, comparator);
Collections.sort(macrosCollector, comparator);
for (ICompletionProposal proposal : proposalCollector) {
contentAssistRequest.addProposal(proposal);
}
for (ICompletionProposal proposal : macrosCollector) {
contentAssistRequest.addMacro(proposal);
}
}
@Override
protected void addAttributeValueProposals(
ContentAssistRequest contentAssistRequest) {
addXAMLPropertyValueProposals(contentAssistRequest);
addTemplates(contentAssistRequest,
TemplateContextTypeIdsXML.ATTRIBUTE_VALUE);
super.addAttributeValueProposals(contentAssistRequest);
}
private void addXAMLPropertyValueProposals(
ContentAssistRequest contentAssistRequest) {
List<ICompletionProposal> proposalCollector = new ArrayList<ICompletionProposal>();
List<ICompletionProposal> macrosCollector = new ArrayList<ICompletionProposal>();
IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
String name = getNodeName(node);
IMetaclass metaclass = XWT.getMetaclass(name,
DomHelper.lookupNamespaceURI(node));
StyledText textWidget = fTextViewer.getTextWidget();
if (metaclass != null) {
// Find the attribute region and name for which this position should
// have a value proposed
IStructuredDocumentRegion open = node
.getFirstStructuredDocumentRegion();
ITextRegionList openRegions = open.getRegions();
int m = openRegions.indexOf(contentAssistRequest.getRegion());
if (m < 0) {
return;
}
ITextRegion nameRegion = null;
while (m >= 0) {
nameRegion = openRegions.get(m--);
if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
break;
}
}
// the name region is REQUIRED to do anything useful
if (nameRegion != null) {
// Retrieve the declaration
CMElementDeclaration elementDecl = getCMElementDeclaration(node);
// String attributeName = nameRegion.getText();
String attributeName = open.getText(nameRegion);
IProperty property = metaclass.findProperty(attributeName);
if (attributeName.equalsIgnoreCase("x:style")
|| property != null) {
int offset = contentAssistRequest
.getReplacementBeginPosition();
int replacementLength = contentAssistRequest
.getReplacementLength();
boolean useProposalList = !contentAssistRequest
.shouldSeparate();
String prefixed = null;
String prefixedQuote = "";
boolean fullValue = true;
try {
int caretIndex = textWidget.getCaretOffset();
IDocument document = fTextViewer.getDocument();
prefixed = document.get(offset, caretIndex - offset)
.toLowerCase();
if (prefixed.equals("\"\"")) {
prefixed = null;
}
} catch (BadLocationException e1) {
}
if (prefixed != null) {
prefixedQuote = prefixed + "\"";
fullValue = false;
}
// filter accelerators of menu element.
if (attributeName.equalsIgnoreCase("accelerator")) {
SelectionCompletionProposal[] proposals = getAcceleratorsProposals();
for (int j = 0; j < proposals.length; j++) {
String pattern = proposals[j]
.getReplacementString();
if (prefixed != null
&& ((!pattern.toLowerCase().startsWith(
prefixed) && !fullValue) || prefixedQuote
.equalsIgnoreCase(pattern))) {
continue;
}
proposals[j].setReplacementOffset(offset);
proposals[j]
.setReplacementLength(replacementLength);
if (useProposalList) {
proposalCollector.add(proposals[j]);
} else {
macrosCollector.add(proposals[j]);
}
}
Collections.sort(proposalCollector, comparator);
Collections.sort(macrosCollector, comparator);
for (ICompletionProposal proposal : proposalCollector) {
contentAssistRequest.addProposal(proposal);
}
for (ICompletionProposal proposal : macrosCollector) {
contentAssistRequest.addMacro(proposal);
}
return;
}
// styles TODO: filter styles of each element.
if (attributeName.equalsIgnoreCase("x:style")) {
SelectionCompletionProposal[] proposals = getStylesProposals();
for (int j = 0; j < proposals.length; j++) {
String pattern = proposals[j]
.getReplacementString();
if (prefixed != null
&& ((!pattern.toLowerCase().startsWith(
prefixed) && !fullValue) || prefixedQuote
.equalsIgnoreCase(pattern))) {
continue;
}
proposals[j].setReplacementOffset(offset);
proposals[j]
.setReplacementLength(replacementLength);
if (useProposalList) {
proposalCollector.add(proposals[j]);
} else {
macrosCollector.add(proposals[j]);
}
}
Collections.sort(proposalCollector, comparator);
Collections.sort(macrosCollector, comparator);
for (ICompletionProposal proposal : proposalCollector) {
contentAssistRequest.addProposal(proposal);
}
for (ICompletionProposal proposal : macrosCollector) {
contentAssistRequest.addMacro(proposal);
}
return;
}
Class<?> javaType = property.getType();
if (javaType == Boolean.class || javaType == boolean.class) {
SelectionCompletionProposal[] proposals = getBooleanProposals();
for (int j = 0; j < proposals.length; j++) {
String pattern = proposals[j]
.getReplacementString();
if (prefixed != null
&& ((!pattern.toLowerCase().startsWith(
prefixed) && !fullValue) || prefixedQuote
.equalsIgnoreCase(pattern))) {
continue;
}
proposals[j].setReplacementOffset(offset);
proposals[j]
.setReplacementLength(replacementLength);
if (useProposalList) {
proposalCollector.add(proposals[j]);
} else {
macrosCollector.add(proposals[j]);
}
}
} else if (javaType != null && javaType.isEnum()) {
Object[] objects = javaType.getEnumConstants();
IConverter converter = XWT.findConvertor(javaType,
String.class);
for (int j = 0; j < objects.length; j++) {
String valueString = "";
if (converter != null) {
Object stringValue = converter
.convert(objects[j]);
if (stringValue != null) {
valueString = stringValue.toString();
}
} else {
valueString = objects[j].toString();
}
String pattern = "\"" + valueString + "\"";
if (prefixed != null
&& ((!pattern.toLowerCase().startsWith(
prefixed) && !fullValue) || prefixedQuote
.equalsIgnoreCase(pattern))) {
continue;
}
Image image = ImageManager
.get(XMLEditorPluginImages.IMG_OBJ_ENUM);
SelectionCompletionProposal proposal = new SelectionCompletionProposal(
pattern, offset, replacementLength, 1,
valueString.length(), image, valueString,
null, null);
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
} else if (javaType.isAssignableFrom(Color.class)) {
SelectionCompletionProposal[] colorsProposals = getColorsProposals();
for (SelectionCompletionProposal proposal : colorsProposals) {
String pattern = proposal.getReplacementString();
if (prefixed != null
&& ((!pattern.toLowerCase().startsWith(
prefixed) && !fullValue) || prefixedQuote
.equalsIgnoreCase(pattern))) {
continue;
}
proposal.setReplacementOffset(offset);
proposal.setReplacementLength(replacementLength);
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
}
} else {
IEvent[] allEvents = metaclass.getEvents();
JavaProject javaProject = (JavaProject) textWidget
.getData("javaProject");
String className = (String) textWidget.getData("className");
List<String> javaMethods = getJavaMethods(javaProject,
className);
int offset = contentAssistRequest
.getReplacementBeginPosition();
int caretIndex = textWidget.getCaretOffset();
IDocument document = fTextViewer.getDocument();
String prefixed = null;
try {
prefixed = document.get(offset + 1, caretIndex - offset
- 1);
} catch (BadLocationException e) {
e.printStackTrace();
}
int replacementLength = contentAssistRequest
.getReplacementLength();
boolean useProposalList = !contentAssistRequest
.shouldSeparate();
for (Iterator<String> iterator = javaMethods.iterator(); iterator
.hasNext();) {
String valueString = iterator.next();
if (valueString.equals(prefixed))
continue;
String pattern = "\"" + valueString + "\"";
SelectionCompletionProposal proposal = new SelectionCompletionProposal(
pattern, offset, replacementLength, 1,
valueString.length(), null, valueString, null,
null);
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
}
}
}
Collections.sort(proposalCollector, comparator);
Collections.sort(macrosCollector, comparator);
for (ICompletionProposal proposal : proposalCollector) {
contentAssistRequest.addProposal(proposal);
}
for (ICompletionProposal proposal : macrosCollector) {
contentAssistRequest.addMacro(proposal);
}
}
@Override
protected void addEmptyDocumentProposals(
ContentAssistRequest contentAssistRequest) {
addTemplates(contentAssistRequest, TemplateContextTypeIdsXML.NEW);
super.addEmptyDocumentProposals(contentAssistRequest);
}
@Override
protected void addTagInsertionProposals(
ContentAssistRequest contentAssistRequest, int childPosition) {
addXAMLElementProposals(contentAssistRequest);
addTemplates(contentAssistRequest, TemplateContextTypeIdsXML.TAG);
super.addTagInsertionProposals(contentAssistRequest, childPosition);
}
private void addXAMLElementProposals(
ContentAssistRequest contentAssistRequest) {
List<ICompletionProposal> proposalCollector = new ArrayList<ICompletionProposal>();
List<ICompletionProposal> macrosCollector = new ArrayList<ICompletionProposal>();
List<String> addedTags = new ArrayList<String>();
boolean useProposalList = !contentAssistRequest.shouldSeparate();
int offset = contentAssistRequest.getReplacementBeginPosition();
int replacementLength = contentAssistRequest.getReplacementLength();
String prefixed = null;
try {
IDocument document = fTextViewer.getDocument();
prefixed = document.get(offset, replacementLength).toLowerCase();
} catch (BadLocationException e1) {
}
Node node = contentAssistRequest.getNode();
if (node == null) {
return;
}
if (node instanceof IDOMText) {
IDOMText text = (IDOMText) node;
offset = text.getStartOffset();
replacementLength = text.getLength();
try {
IDocument document = fTextViewer.getDocument();
prefixed = document.get(offset, replacementLength).trim()
.toLowerCase();
} catch (BadLocationException e1) {
}
} else if (node instanceof IDOMNode) {
IDOMNode domNode = (IDOMNode) node;
NodeList children = domNode.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child instanceof IDOMText) {
IDOMText text = (IDOMText) child;
offset = text.getStartOffset();
replacementLength = text.getLength();
try {
IDocument document = fTextViewer.getDocument();
prefixed = document.get(offset, replacementLength)
.trim().toLowerCase();
} catch (BadLocationException e1) {
}
break;
}
}
}
while (node.getNodeType() != Node.ELEMENT_NODE) {
node = node.getParentNode();
if (node == null) {
return;
}
}
boolean containControls = false;
String name = getNodeName(node);
if (name.indexOf(".") != -1) {
if (name.toLowerCase().endsWith(".control")) {
name = "Control";// Add controls to TabItem, CoolItem...
containControls = true;
} else {
List<SelectionCompletionProposal> proposals = createPropertyNodeProposals(
name, offset, replacementLength);
if (useProposalList) {
proposalCollector.addAll(proposals);
} else {
macrosCollector.addAll(proposals);
}
Collections.sort(proposalCollector, comparator);
Collections.sort(macrosCollector, comparator);
for (ICompletionProposal proposal : proposalCollector) {
contentAssistRequest.addProposal(proposal);
}
for (ICompletionProposal proposal : macrosCollector) {
contentAssistRequest.addMacro(proposal);
}
return;
}
}
IMetaclass metaclass = XWT.getMetaclass(name,
DomHelper.lookupNamespaceURI(node));
String tagName = name + ".Resources";
if (!addedTags.contains(tagName)
&& (prefixed == null || tagName.toLowerCase().startsWith(
prefixed))) {
addedTags.add(tagName);
String pattern = "<" + tagName + "></" + tagName + ">";
Image image = ImageManager.get(ImageManager.IMG_RESOURCES);
SelectionCompletionProposal proposal = new SelectionCompletionProposal(
pattern, offset, replacementLength, tagName.length() + 2,
0, image, tagName, null, "Element resources");
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
// layout
String layout = name + ".layout";
if (!addedTags.contains(layout)
&& (prefixed == null || layout.startsWith(prefixed))) {
SelectionCompletionProposal layoutProposal = createLayoutProposal(
metaclass, layout, offset, replacementLength);
if (layoutProposal != null) {
if (useProposalList) {
proposalCollector.add(layoutProposal);
} else {
macrosCollector.add(layoutProposal);
}
}
}
// layoutData
String layoutData = name + ".layoutData";
if (!addedTags.contains(layout)
&& (prefixed == null || layout.startsWith(prefixed))) {
SelectionCompletionProposal proposal = createLayoutDataProposal(
metaclass, layoutData, offset, replacementLength);
if (proposal != null) {
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
}
if (metaclass != null) {
if (containControls
|| Composite.class.isAssignableFrom(metaclass.getType())) {
IMetaclass[] metaclasses = XWT.getAllMetaclasses();
for (IMetaclass type : metaclasses) {
if (Control.class.isAssignableFrom(type.getType())
&& !type.isAbstract()) {
String typeName = type.getName();
if (prefixed != null
&& !typeName.toLowerCase().startsWith(prefixed)) {
continue;
}
if (addedTags.contains(typeName)) {
continue;
} else {
addedTags.add(typeName);
}
String pattern = "<" + typeName + "></" + typeName
+ ">";
Image image = ImageManager
.get(ImageManager.IMG_ELEMENT);
SelectionCompletionProposal proposal = new SelectionCompletionProposal(
pattern, offset, replacementLength,
typeName.length() + 2, 0, image, typeName,
null, null);
if (useProposalList) {
proposalCollector.add(proposal);
} else {
macrosCollector.add(proposal);
}
}
}
}
}
Collections.sort(proposalCollector, comparator);
Collections.sort(macrosCollector, comparator);
for (ICompletionProposal proposal : proposalCollector) {
contentAssistRequest.addProposal(proposal);
}
for (ICompletionProposal proposal : macrosCollector) {
contentAssistRequest.addMacro(proposal);
}
}
private List<SelectionCompletionProposal> createPropertyNodeProposals(
String tagName, int offset, int replacementLength) {
int index = tagName.indexOf(".");
if (index == -1) {
return Collections.emptyList();
}
List<SelectionCompletionProposal> proposals = new ArrayList<SelectionCompletionProposal>();
String property = tagName.substring(index + 1);
if ("layout".equalsIgnoreCase(property)) {
String[] layouts = new String[] { "GridLayout", "FillLayout",
"RowLayout", "StackLayout", "FormLayout" };
for (int i = 0; i < layouts.length; i++) {
String pattern = "<" + layouts[i] + "/>";
Image image = ImageManager.get(ImageManager.IMG_ELEMENT);
SelectionCompletionProposal p = new SelectionCompletionProposal(
pattern, offset, replacementLength,
layouts[i].length() + 2, 0, image, layouts[i], null,
"Container Layout.");
proposals.add(p);
}
} else if ("layoutData".equalsIgnoreCase(property)) {
String[] layoutDatas = new String[] { "GridData", "StackData",
"FormData", "RowData" };
for (int i = 0; i < layoutDatas.length; i++) {
String pattern = "<" + layoutDatas[i] + "></" + layoutDatas[i]
+ ">";
Image image = ImageManager.get(ImageManager.IMG_ELEMENT);
SelectionCompletionProposal p = new SelectionCompletionProposal(
pattern, offset, replacementLength,
layoutDatas[i].length() + 2, 0, image, layoutDatas[i],
null, "Container LayoutData.");
proposals.add(p);
}
}
return proposals;
}
private SelectionCompletionProposal createLayoutDataProposal(
IMetaclass metaclass, String layoutData, int offset,
int replacementLength) {
if (!Control.class.isAssignableFrom(metaclass.getType())) {
return null;
}
String pattern = "<" + layoutData + "></" + layoutData + ">";
Image image = JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC);
return new SelectionCompletionProposal(pattern, offset,
replacementLength, layoutData.length() + 2, 0, image,
layoutData, null, "Control LayoutData.");
}
private SelectionCompletionProposal createLayoutProposal(
IMetaclass metaclass, String tagName, int offset,
int replacementLength) {
if (!Composite.class.isAssignableFrom(metaclass.getType())) {
return null;
}
String pattern = "<" + tagName + "></" + tagName + ">";
Image image = JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC);
return new SelectionCompletionProposal(pattern, offset,
replacementLength, tagName.length() + 2, 0, image, tagName,
null, "Container Layout.");
}
private String getNodeName(Node node) {
String name = node.getNodeName();
int index = name.indexOf(":");
if (index != -1) {
name = name.substring(index + 1);
}
return name;
}
/**
* Adds templates to the list of proposals
*
* @param contentAssistRequest
* @param context
*/
private void addTemplates(ContentAssistRequest contentAssistRequest,
String context) {
addTemplates(contentAssistRequest, context,
contentAssistRequest.getReplacementBeginPosition());
}
/**
* Adds templates to the list of proposals
*
* @param contentAssistRequest
* @param context
* @param startOffset
*/
private void addTemplates(ContentAssistRequest contentAssistRequest,
String context, int startOffset) {
if (contentAssistRequest == null) {
return;
}
// if already adding template proposals for a certain context type, do
// not add again
if (!fTemplateContexts.contains(context)) {
fTemplateContexts.add(context);
boolean useProposalList = !contentAssistRequest.shouldSeparate();
if (getTemplateCompletionProcessor() != null) {
getTemplateCompletionProcessor().setContextType(context);
ICompletionProposal[] proposals = getTemplateCompletionProcessor()
.computeCompletionProposals(fTextViewer, startOffset);
for (int i = 0; i < proposals.length; ++i) {
if (useProposalList) {
contentAssistRequest.addProposal(proposals[i]);
} else {
contentAssistRequest.addMacro(proposals[i]);
}
}
}
}
}
@Override
protected ContentAssistRequest computeCompletionProposals(
int documentPosition, String matchString,
ITextRegion completionRegion, IDOMNode treeNode, IDOMNode xmlnode) {
ContentAssistRequest request = super.computeCompletionProposals(
documentPosition, matchString, completionRegion, treeNode,
xmlnode);
// bug115927 use original document position for all/any region
// templates
addTemplates(request, TemplateContextTypeIdsXML.ALL, documentPosition);
return request;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.xml.ui.contentassist.AbstractContentAssistProcessor#
* computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
*/
@Override
public ICompletionProposal[] computeCompletionProposals(
ITextViewer textViewer, int documentPosition) {
fTemplateContexts.clear();
return super.computeCompletionProposals(textViewer, documentPosition);
}
protected IPreferenceStore getPreferenceStore() {
if (fPreferenceStore == null) {
fPreferenceStore = XMLUIPlugin.getDefault().getPreferenceStore();
}
return fPreferenceStore;
}
protected VEXTemplateCompletionProcessor getTemplateCompletionProcessor() {
if (fTemplateProcessor == null) {
fTemplateProcessor = new VEXTemplateCompletionProcessor();
}
return fTemplateProcessor;
}
@Override
protected void init() {
getPreferenceStore().addPropertyChangeListener(this);
reinit();
}
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
if ((property.compareTo(XMLUIPreferenceNames.AUTO_PROPOSE) == 0)
|| (property.compareTo(XMLUIPreferenceNames.AUTO_PROPOSE_CODE) == 0)) {
reinit();
}
}
protected void reinit() {
String key = XMLUIPreferenceNames.AUTO_PROPOSE;
boolean doAuto = getPreferenceStore().getBoolean(key);
if (doAuto) {
key = XMLUIPreferenceNames.AUTO_PROPOSE_CODE;
completionProposalAutoActivationCharacters = getPreferenceStore()
.getString(key).toCharArray();
} else {
completionProposalAutoActivationCharacters = null;
}
}
@Override
public void release() {
super.release();
getPreferenceStore().removePropertyChangeListener(this);
}
private List<String> getJavaMethods(JavaProject javaProject,
String className) {
List<String> javaMethods = new ArrayList<String>();
try {
IType type = javaProject.findType(className);
IMethod[] methods = type.getMethods();
for (int i = 0; i < methods.length; i++) {
IMethod method = methods[i];
String methodName = method.getElementName();
javaMethods.add(methodName);
}
} catch (JavaModelException e) {
e.printStackTrace();
}
return javaMethods;
}
}