update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / hint / ShowContainerInfoHandler.java
blob17832a103b2cb049ad02dee8bb13c77d0feb74f1
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;
18 import com.intellij.codeInsight.CodeInsightActionHandler;
19 import com.intellij.ide.structureView.StructureViewBuilder;
20 import com.intellij.ide.structureView.StructureViewModel;
21 import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
22 import com.intellij.lang.LanguageStructureViewBuilder;
23 import com.intellij.openapi.application.ApplicationManager;
24 import com.intellij.openapi.editor.Editor;
25 import com.intellij.openapi.editor.LogicalPosition;
26 import com.intellij.openapi.project.Project;
27 import com.intellij.openapi.util.Key;
28 import com.intellij.openapi.util.TextRange;
29 import com.intellij.psi.*;
30 import com.intellij.psi.xml.XmlFile;
31 import com.intellij.psi.xml.XmlTag;
32 import com.intellij.ui.LightweightHint;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
36 import java.awt.*;
37 import java.lang.ref.WeakReference;
39 public class ShowContainerInfoHandler implements CodeInsightActionHandler {
40 private static final Key<WeakReference<LightweightHint>> MY_LAST_HINT_KEY = Key.create("MY_LAST_HINT_KEY");
41 private static final Key<PsiElement> CONTAINER_KEY = Key.create("CONTAINER_KEY");
43 public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
44 PsiDocumentManager.getInstance(project).commitAllDocuments();
46 PsiElement container = null;
47 WeakReference<LightweightHint> ref = editor.getUserData(MY_LAST_HINT_KEY);
48 if (ref != null){
49 LightweightHint hint = ref.get();
50 if (hint != null && hint.isVisible()){
51 hint.hide();
52 container = hint.getUserData(CONTAINER_KEY);
53 if (!container.isValid()){
54 container = null;
59 if (container == null){
60 int offset = editor.getCaretModel().getOffset();
61 container = file.findElementAt(offset);
62 if (container == null) return;
65 if (file instanceof PsiJavaFile || file instanceof XmlFile) {
66 while(true){
67 container = findContainer(container);
68 if (container == null) return;
69 if (!isDeclarationVisible(container, editor)) break;
72 else {
73 container = null;
74 StructureViewBuilder builder = LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(file);
75 if (builder instanceof TreeBasedStructureViewBuilder) {
76 StructureViewModel model = ((TreeBasedStructureViewBuilder) builder).createStructureViewModel();
77 Object element = model.getCurrentEditorElement();
78 if (element instanceof PsiElement) {
79 container = (PsiElement) element;
80 while(true) {
81 if (container == null || container instanceof PsiFile) {
82 return;
84 if (!isDeclarationVisible(container, editor)) {
85 break;
88 container = container.getParent();
89 while(container != null && DeclarationRangeUtil.getPossibleDeclarationAtRange(container) == null) {
90 container = container.getParent();
91 if (container instanceof PsiFile) return;
96 if (container == null) {
97 return;
101 final TextRange range = DeclarationRangeUtil.getDeclarationRange(container);
102 final PsiElement _container = container;
103 ApplicationManager.getApplication().invokeLater(new Runnable() {
104 public void run() {
105 LightweightHint hint = EditorFragmentComponent.showEditorFragmentHint(editor, range, true);
106 hint.putUserData(CONTAINER_KEY, _container);
107 editor.putUserData(MY_LAST_HINT_KEY, new WeakReference<LightweightHint>(hint));
112 public boolean startInWriteAction() {
113 return false;
116 @Nullable
117 private static PsiElement findContainer(PsiElement element) {
118 PsiElement container = element.getParent();
119 while(true){
120 if (container instanceof PsiFile) return null;
121 if (container instanceof PsiMethod || container instanceof PsiClass || container instanceof PsiClassInitializer) break;
122 if (container instanceof XmlTag) break;
123 container = container.getParent();
125 return container;
128 private static boolean isDeclarationVisible(PsiElement container, Editor editor) {
129 Rectangle viewRect = editor.getScrollingModel().getVisibleArea();
130 final TextRange range = DeclarationRangeUtil.getPossibleDeclarationAtRange(container);
131 if (range == null) {
132 return false;
135 LogicalPosition pos = editor.offsetToLogicalPosition(range.getStartOffset());
136 Point loc = editor.logicalPositionToXY(pos);
137 return loc.y >= viewRect.y;