2 * Copyright 2000-2015 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.
18 * Class ValueLookupManager
21 package com.intellij.xdebugger.impl.evaluate.quick.common;
23 import com.intellij.openapi.components.ServiceManager;
24 import com.intellij.openapi.editor.Editor;
25 import com.intellij.openapi.editor.EditorFactory;
26 import com.intellij.openapi.editor.event.EditorMouseAdapter;
27 import com.intellij.openapi.editor.event.EditorMouseEvent;
28 import com.intellij.openapi.editor.event.EditorMouseEventArea;
29 import com.intellij.openapi.editor.event.EditorMouseMotionListener;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.util.Key;
32 import com.intellij.openapi.util.registry.Registry;
33 import com.intellij.util.Alarm;
34 import com.intellij.xdebugger.impl.DebuggerSupport;
35 import org.jetbrains.annotations.NotNull;
39 public class ValueLookupManager extends EditorMouseAdapter implements EditorMouseMotionListener {
41 * @see com.intellij.xdebugger.XDebuggerUtil#disableValueLookup(com.intellij.openapi.editor.Editor)
43 public static final Key<Boolean> DISABLE_VALUE_LOOKUP = Key.create("DISABLE_VALUE_LOOKUP");
45 private final Project myProject;
46 private final Alarm myAlarm;
47 private AbstractValueHint myRequest = null;
48 private final DebuggerSupport[] mySupports;
49 private boolean myListening;
51 public ValueLookupManager(Project project) {
53 mySupports = DebuggerSupport.getDebuggerSupports();
54 myAlarm = new Alarm(project);
57 public void startListening() {
60 EditorFactory.getInstance().getEventMulticaster().addEditorMouseMotionListener(this, myProject);
61 EditorFactory.getInstance().getEventMulticaster().addEditorMouseListener(this, myProject);
66 public void mouseDragged(EditorMouseEvent e) {
70 public void mouseExited(EditorMouseEvent e) {
71 myAlarm.cancelAllRequests();
75 public void mouseMoved(EditorMouseEvent e) {
80 Editor editor = e.getEditor();
81 if (editor.getProject() != null && editor.getProject() != myProject) {
85 ValueHintType type = AbstractValueHint.getHintType(e);
86 if (e.getArea() != EditorMouseEventArea.EDITING_AREA ||
87 DISABLE_VALUE_LOOKUP.get(editor) == Boolean.TRUE ||
89 myAlarm.cancelAllRequests();
93 Point point = e.getMouseEvent().getPoint();
94 if (myRequest != null && !myRequest.isKeepHint(editor, point)) {
97 else if (type == ValueHintType.MOUSE_OVER_HINT && myRequest != null && !myRequest.isHintHidden() && myRequest.isInsideCurrentRange(editor, point)) {
101 for (DebuggerSupport support : mySupports) {
102 QuickEvaluateHandler handler = support.getQuickEvaluateHandler();
103 if (handler.isEnabled(myProject)) {
104 requestHint(handler, editor, point, type);
110 private void requestHint(final QuickEvaluateHandler handler, final Editor editor, final Point point, @NotNull final ValueHintType type) {
111 final Rectangle area = editor.getScrollingModel().getVisibleArea();
112 myAlarm.cancelAllRequests();
113 if (type == ValueHintType.MOUSE_OVER_HINT) {
114 if (Registry.is("debugger.valueTooltipAutoShow")) {
115 myAlarm.addRequest(new Runnable() {
118 if (area.equals(editor.getScrollingModel().getVisibleArea())) {
119 showHint(handler, editor, point, type);
122 }, getDelay(handler));
126 showHint(handler, editor, point, type);
130 private int getDelay(QuickEvaluateHandler handler) {
131 int delay = handler.getValueLookupDelay(myProject);
132 if (myRequest != null && !myRequest.isHintHidden()) {
133 delay = Math.max(100, delay); // if hint is showing, delay should not be too small, see IDEA-141464
138 public void hideHint() {
139 if (myRequest != null) {
140 myRequest.hideHint();
145 public void showHint(@NotNull QuickEvaluateHandler handler, @NotNull Editor editor, @NotNull Point point, @NotNull ValueHintType type) {
146 myAlarm.cancelAllRequests();
147 if (editor.isDisposed() || !handler.canShowHint(myProject)) {
151 final AbstractValueHint request = handler.createValueHint(myProject, editor, point, type);
152 if (request != null) {
153 if (myRequest != null && myRequest.equals(request)) {
157 if (!request.canShowHint()) {
160 if (myRequest != null && myRequest.isInsideHint(editor, point)) {
167 myRequest.invokeHint(new Runnable() {
170 if (myRequest != null && myRequest == request) {
178 public static ValueLookupManager getInstance(Project project) {
179 return ServiceManager.getService(project, ValueLookupManager.class);