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.
17 package com
.intellij
.codeInsight
.lookup
.impl
;
19 import com
.intellij
.codeInsight
.CodeInsightSettings
;
20 import com
.intellij
.codeInsight
.completion
.impl
.CamelHumpMatcher
;
21 import com
.intellij
.codeInsight
.daemon
.DaemonCodeAnalyzer
;
22 import com
.intellij
.codeInsight
.documentation
.DocumentationManager
;
23 import com
.intellij
.codeInsight
.hint
.EditorHintListener
;
24 import com
.intellij
.codeInsight
.hint
.HintManager
;
25 import com
.intellij
.codeInsight
.lookup
.*;
26 import com
.intellij
.openapi
.Disposable
;
27 import com
.intellij
.openapi
.components
.ProjectComponent
;
28 import com
.intellij
.openapi
.editor
.Editor
;
29 import com
.intellij
.openapi
.editor
.EditorFactory
;
30 import com
.intellij
.openapi
.editor
.event
.EditorFactoryAdapter
;
31 import com
.intellij
.openapi
.editor
.event
.EditorFactoryEvent
;
32 import com
.intellij
.openapi
.project
.Project
;
33 import com
.intellij
.openapi
.util
.Disposer
;
34 import com
.intellij
.psi
.PsiDocumentManager
;
35 import com
.intellij
.psi
.PsiFile
;
36 import com
.intellij
.ui
.LightweightHint
;
37 import com
.intellij
.util
.Alarm
;
38 import com
.intellij
.util
.messages
.MessageBus
;
39 import org
.jetbrains
.annotations
.NotNull
;
41 import java
.beans
.PropertyChangeListener
;
42 import java
.beans
.PropertyChangeSupport
;
44 public class LookupManagerImpl
extends LookupManager
implements ProjectComponent
{
45 private final Project myProject
;
47 protected LookupImpl myActiveLookup
= null;
48 protected Editor myActiveLookupEditor
= null;
49 private final PropertyChangeSupport myPropertyChangeSupport
= new PropertyChangeSupport(this);
51 private boolean myIsDisposed
;
53 public LookupManagerImpl(Project project
, MessageBus bus
) {
56 bus
.connect().subscribe(EditorHintListener
.TOPIC
, new EditorHintListener() {
57 public void hintShown(final Project project
, final LightweightHint hint
, final int flags
) {
58 if (project
== myProject
) {
59 Lookup lookup
= getActiveLookup();
60 if (lookup
!= null && (flags
& HintManager
.HIDE_BY_LOOKUP_ITEM_CHANGE
) != 0) {
61 lookup
.addLookupListener(new LookupAdapter() {
62 public void currentItemChanged(LookupEvent event
) {
66 public void itemSelected(LookupEvent event
) {
70 public void lookupCanceled(LookupEvent event
) {
82 public String
getComponentName() {
83 return "LookupManager";
86 public void initComponent() {
89 public void disposeComponent() {
92 public void projectOpened() {
94 final EditorFactoryAdapter myEditorFactoryListener
= new EditorFactoryAdapter() {
95 public void editorReleased(EditorFactoryEvent event
) {
96 if (event
.getEditor() == myActiveLookupEditor
) {
101 EditorFactory
.getInstance().addEditorFactoryListener(myEditorFactoryListener
);
102 Disposer
.register(myProject
, new Disposable() {
103 public void dispose() {
104 EditorFactory
.getInstance().removeEditorFactoryListener(myEditorFactoryListener
);
109 public void projectClosed() {
113 public Lookup
showLookup(final Editor editor
,
114 @NotNull LookupElement
[] items
,
116 @NotNull final LookupArranger arranger
) {
117 final LookupImpl lookup
= createLookup(editor
, items
, prefix
, arranger
);
122 public LookupImpl
createLookup(final Editor editor
,
123 @NotNull LookupElement
[] items
,
125 @NotNull final LookupArranger arranger
) {
128 final CodeInsightSettings settings
= CodeInsightSettings
.getInstance();
130 final PsiFile psiFile
= PsiDocumentManager
.getInstance(myProject
).getPsiFile(editor
.getDocument());
132 final Alarm alarm
= new Alarm();
133 final Runnable request
= new Runnable() {
135 DocumentationManager
.getInstance(myProject
).showJavaDocInfo(editor
, psiFile
, false);
138 if (settings
.AUTO_POPUP_JAVADOC_INFO
) {
139 alarm
.addRequest(request
, settings
.JAVADOC_INFO_DELAY
);
142 final DaemonCodeAnalyzer daemonCodeAnalyzer
= DaemonCodeAnalyzer
.getInstance(myProject
);
143 if (daemonCodeAnalyzer
!= null) {
144 daemonCodeAnalyzer
.setUpdateByTimerEnabled(false);
146 myActiveLookup
= new LookupImpl(myProject
, editor
, arranger
);
147 myActiveLookupEditor
= editor
;
148 myActiveLookup
.addLookupListener(new LookupAdapter() {
149 public void itemSelected(LookupEvent event
) {
153 public void lookupCanceled(LookupEvent event
) {
157 public void currentItemChanged(LookupEvent event
) {
158 alarm
.cancelAllRequests();
159 if (settings
.AUTO_POPUP_JAVADOC_INFO
) {
160 alarm
.addRequest(request
, settings
.JAVADOC_INFO_DELAY
);
164 private void dispose() {
165 alarm
.cancelAllRequests();
166 if (daemonCodeAnalyzer
!= null) {
167 daemonCodeAnalyzer
.setUpdateByTimerEnabled(true);
169 if (myActiveLookup
== null) return;
170 myActiveLookup
.removeLookupListener(this);
171 Lookup lookup
= myActiveLookup
;
172 myActiveLookup
= null;
173 myActiveLookupEditor
= null;
174 myPropertyChangeSupport
.firePropertyChange(PROP_ACTIVE_LOOKUP
, lookup
, null);
178 if (items
.length
> 0) {
179 for (final LookupElement item
: items
) {
180 if (prefix
!= null) {
181 item
.setPrefixMatcher(new CamelHumpMatcher(prefix
));
183 myActiveLookup
.addItem(item
);
185 myActiveLookup
.refreshUi();
188 myPropertyChangeSupport
.firePropertyChange(PROP_ACTIVE_LOOKUP
, null, myActiveLookup
);
189 return myActiveLookup
;
192 public void hideActiveLookup() {
193 if (myActiveLookup
!= null) {
194 myActiveLookup
.hide();
198 public Lookup
getActiveLookup() {
199 return myActiveLookup
;
202 public void addPropertyChangeListener(PropertyChangeListener listener
) {
203 myPropertyChangeSupport
.addPropertyChangeListener(listener
);
206 public void removePropertyChangeListener(PropertyChangeListener listener
) {
207 myPropertyChangeSupport
.removePropertyChangeListener(listener
);
210 public boolean isDisposed() {