update copyright
[fedora-idea.git] / xml / impl / src / com / intellij / codeInsight / hint / api / impls / XmlParameterInfoHandler.java
blobf5cb164cc0c68cafc4e0e4933789731b49b391df
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.codeInsight.hint.api.impls;
18 import com.intellij.codeInsight.CodeInsightBundle;
19 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
20 import com.intellij.codeInsight.lookup.LookupElement;
21 import com.intellij.codeInsight.lookup.MutableLookupElement;
22 import com.intellij.openapi.util.TextRange;
23 import com.intellij.psi.PsiElement;
24 import com.intellij.psi.PsiFile;
25 import com.intellij.psi.xml.XmlFile;
26 import com.intellij.psi.xml.XmlTag;
27 import com.intellij.psi.xml.XmlToken;
28 import com.intellij.psi.xml.XmlTokenType;
29 import com.intellij.xml.XmlAttributeDescriptor;
30 import com.intellij.xml.XmlElementDescriptor;
31 import com.intellij.lang.parameterInfo.*;
32 import org.jetbrains.annotations.NotNull;
33 import org.jetbrains.annotations.Nullable;
35 import java.util.Arrays;
36 import java.util.Comparator;
38 /**
39 * Created by IntelliJ IDEA.
40 * User: Maxim.Mossienko
41 * Date: Feb 1, 2006
42 * Time: 9:18:45 PM
43 * To change this template use File | Settings | File Templates.
45 public class XmlParameterInfoHandler implements ParameterInfoHandler<XmlTag,XmlElementDescriptor> {
46 private static final Comparator<XmlAttributeDescriptor> COMPARATOR = new Comparator<XmlAttributeDescriptor>() {
47 public int compare(final XmlAttributeDescriptor o1, final XmlAttributeDescriptor o2) {
48 return o1.getName().compareTo(o2.getName());
52 public Object[] getParametersForLookup(LookupElement item, ParameterInfoContext context) {
53 if (!(item instanceof MutableLookupElement)) return null;
54 final Object lookupItem = ((MutableLookupElement)item).getObject();
55 if (lookupItem instanceof XmlElementDescriptor) return new Object[]{lookupItem};
56 return null;
59 public Object[] getParametersForDocumentation(final XmlElementDescriptor p, final ParameterInfoContext context) {
60 return getSortedDescriptors(p);
63 private static XmlAttributeDescriptor[] getSortedDescriptors(final XmlElementDescriptor p) {
64 final XmlAttributeDescriptor[] xmlAttributeDescriptors = p.getAttributesDescriptors(null);
65 Arrays.sort(xmlAttributeDescriptors, COMPARATOR);
66 return xmlAttributeDescriptors;
69 public boolean couldShowInLookup() {
70 return true;
73 public XmlTag findElementForParameterInfo(final CreateParameterInfoContext context) {
74 final XmlTag tag = findXmlTag(context.getFile(), context.getOffset());
75 final XmlElementDescriptor descriptor = tag != null ? tag.getDescriptor() : null;
77 if (descriptor == null) {
78 DaemonCodeAnalyzer.getInstance(context.getProject()).updateVisibleHighlighters(context.getEditor());
79 return null;
82 context.setItemsToShow(new Object[] {descriptor});
83 return tag;
86 public void showParameterInfo(final @NotNull XmlTag element, final CreateParameterInfoContext context) {
87 context.showHint(element, element.getTextRange().getStartOffset() + 1, this);
90 public XmlTag findElementForUpdatingParameterInfo(final UpdateParameterInfoContext context) {
91 final XmlTag tag = findXmlTag(context.getFile(), context.getOffset());
92 if (tag != null) {
93 final PsiElement currentXmlTag = context.getParameterOwner();
94 if (currentXmlTag == null || currentXmlTag == tag) return tag;
97 return null;
100 public void updateParameterInfo(@NotNull final XmlTag o, final UpdateParameterInfoContext context) {
101 if (context.getParameterOwner() == null || o.equals(context.getParameterOwner())) {
102 context.setParameterOwner( o );
103 } else {
104 context.removeHint();
108 public String getParameterCloseChars() {
109 return null;
112 public boolean tracksParameterIndex() {
113 return false;
116 @Nullable
117 private static XmlTag findXmlTag(PsiFile file, int offset){
118 if (!(file instanceof XmlFile)) return null;
120 PsiElement element = file.findElementAt(offset);
121 if (element == null) return null;
122 element = element.getParent();
124 while (element != null) {
125 if (element instanceof XmlTag) {
126 XmlTag tag = (XmlTag)element;
128 final PsiElement[] children = tag.getChildren();
130 if (offset <= children[0].getTextRange().getStartOffset()) return null;
132 for (PsiElement child : children) {
133 final TextRange range = child.getTextRange();
134 if (range.getStartOffset() <= offset && range.getEndOffset() > offset) return tag;
136 if (child instanceof XmlToken) {
137 XmlToken token = (XmlToken)child;
138 if (token.getTokenType() == XmlTokenType.XML_TAG_END) return null;
142 return null;
145 element = element.getParent();
148 return null;
151 public void updateUI(XmlElementDescriptor o, ParameterInfoUIContext context) {
152 updateElementDescriptor(o, context);
155 private static void updateElementDescriptor(XmlElementDescriptor descriptor, ParameterInfoUIContext context) {
156 final XmlAttributeDescriptor[] attributes = descriptor != null ? getSortedDescriptors(descriptor) : XmlAttributeDescriptor.EMPTY;
158 StringBuffer buffer = new StringBuffer();
159 int highlightStartOffset = -1;
160 int highlightEndOffset = -1;
162 if (attributes.length == 0) {
163 buffer.append(CodeInsightBundle.message("xml.tag.info.no.attributes"));
165 else {
166 StringBuffer text1 = new StringBuffer(" ");
167 StringBuffer text2 = new StringBuffer(" ");
168 StringBuffer text3 = new StringBuffer(" ");
170 final XmlTag parameterOwner = (XmlTag)context.getParameterOwner();
172 for (XmlAttributeDescriptor attribute : attributes) {
173 if (parameterOwner != null && parameterOwner.getAttributeValue(attribute.getName()) != null) {
174 if (!(text1.toString().equals(" "))) {
175 text1.append(", ");
177 text1.append(attribute.getName());
179 else if (attribute.isRequired()) {
180 if (!(text2.toString().equals(" "))) {
181 text2.append(", ");
183 text2.append(attribute.getName());
185 else {
186 if (!(text3.toString().equals(" "))) {
187 text3.append(", ");
189 text3.append(attribute.getName());
193 if (!text1.toString().equals(" ") && !text2.toString().equals(" ")) {
194 text1.append(", ");
197 if (!text2.toString().equals(" ") && !text3.toString().equals(" ")) {
198 text2.append(", ");
201 if (!text1.toString().equals(" ") && !text3.toString().equals(" ") && text2.toString().equals(" ")) {
202 text1.append(", ");
205 buffer.append(text1);
206 highlightStartOffset = buffer.length();
207 buffer.append(text2);
208 highlightEndOffset = buffer.length();
209 buffer.append(text3);
212 context.setupUIComponentPresentation(buffer.toString(), highlightStartOffset, highlightEndOffset, false,
213 false, true, context.getDefaultParameterColor());