mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-66333 Quick documentation lookup on mouse hover
1. Added quick doc tooltip actions which allow to view content at the big quick doc control; 2. Removed 'auto quick doc for element under mouse' functionality;
This commit is contained in:
+4
-33
@@ -304,7 +304,7 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="7f3f5" layout-manager="GridLayoutManager" row-count="4" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="7f3f5" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -317,7 +317,7 @@
|
||||
<children>
|
||||
<component id="901e0" class="javax.swing.JCheckBox" binding="myCbEnsureBlankLineBeforeCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Ensure &blank line before end of file on Save"/>
|
||||
@@ -333,44 +333,15 @@
|
||||
</component>
|
||||
<component id="87620" class="javax.swing.JComboBox" binding="myStripTrailingSpacesCombo">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<vspacer id="82d85">
|
||||
<constraints>
|
||||
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="ef4e7" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="bd3fc" class="javax.swing.JCheckBox" binding="myCbShowQuickDocOnCheckBox">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="checkbox.show.quick.doc.on.mouse.over"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="bfacd" class="javax.swing.JTextField" binding="myQuickDocDelayTextField" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="50" height="-1"/>
|
||||
<maximum-size width="50" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="500"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="5df80" binding="myHighlightSettingsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
|
||||
+21
-74
@@ -21,10 +21,8 @@ import com.intellij.application.options.OptionsApplicabilityFilter;
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPass;
|
||||
import com.intellij.codeInsight.documentation.QuickDocOnMouseOverManager;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
@@ -41,7 +39,6 @@ import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -49,11 +46,11 @@ import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
public class EditorOptionsPanel {
|
||||
private JPanel myBehaviourPanel;
|
||||
private JPanel myBehaviourPanel;
|
||||
private JCheckBox myCbHighlightBraces;
|
||||
private static final String STRIP_CHANGED = ApplicationBundle.message("combobox.strip.modified.lines");
|
||||
|
||||
private static final String STRIP_ALL = ApplicationBundle.message("combobox.strip.all");
|
||||
private static final String STRIP_ALL = ApplicationBundle.message("combobox.strip.all");
|
||||
private static final String STRIP_NONE = ApplicationBundle.message("combobox.strip.none");
|
||||
private JComboBox myStripTrailingSpacesCombo;
|
||||
|
||||
@@ -66,34 +63,32 @@ public class EditorOptionsPanel {
|
||||
private JCheckBox myCbHighlightScope;
|
||||
|
||||
private JTextField myClipboardContentLimitTextField;
|
||||
private JCheckBox myCbSmoothScrolling;
|
||||
private JCheckBox myCbVirtualPageAtBottom;
|
||||
private JCheckBox myCbEnableDnD;
|
||||
private JCheckBox myCbEnableWheelFontChange;
|
||||
private JCheckBox myCbHonorCamelHumpsWhenSelectingByClicking;
|
||||
private JCheckBox myCbSmoothScrolling;
|
||||
private JCheckBox myCbVirtualPageAtBottom;
|
||||
private JCheckBox myCbEnableDnD;
|
||||
private JCheckBox myCbEnableWheelFontChange;
|
||||
private JCheckBox myCbHonorCamelHumpsWhenSelectingByClicking;
|
||||
|
||||
private JPanel myHighlightSettingsPanel;
|
||||
private JPanel myHighlightSettingsPanel;
|
||||
private JRadioButton myRbPreferScrolling;
|
||||
private JRadioButton myRbPreferMovingCaret;
|
||||
private JCheckBox myCbRenameLocalVariablesInplace;
|
||||
private JCheckBox myCbHighlightIdentifierUnderCaret;
|
||||
private JCheckBox myCbEnsureBlankLineBeforeCheckBox;
|
||||
private JCheckBox myShowReformatCodeDialogCheckBox;
|
||||
private JCheckBox myShowOptimizeImportsDialogCheckBox;
|
||||
private JCheckBox myCbUseSoftWrapsAtEditor;
|
||||
private JCheckBox myCbUseSoftWrapsAtConsole;
|
||||
private JCheckBox myCbUseCustomSoftWrapIndent;
|
||||
private JTextField myCustomSoftWrapIndent;
|
||||
private JCheckBox myCbShowAllSoftWraps;
|
||||
private JCheckBox myPreselectCheckBox;
|
||||
private JCheckBox myCbShowQuickDocOnCheckBox;
|
||||
private JTextField myQuickDocDelayTextField;
|
||||
private JCheckBox myCbRenameLocalVariablesInplace;
|
||||
private JCheckBox myCbHighlightIdentifierUnderCaret;
|
||||
private JCheckBox myCbEnsureBlankLineBeforeCheckBox;
|
||||
private JCheckBox myShowReformatCodeDialogCheckBox;
|
||||
private JCheckBox myShowOptimizeImportsDialogCheckBox;
|
||||
private JCheckBox myCbUseSoftWrapsAtEditor;
|
||||
private JCheckBox myCbUseSoftWrapsAtConsole;
|
||||
private JCheckBox myCbUseCustomSoftWrapIndent;
|
||||
private JTextField myCustomSoftWrapIndent;
|
||||
private JCheckBox myCbShowAllSoftWraps;
|
||||
private JCheckBox myPreselectCheckBox;
|
||||
|
||||
private final ErrorHighlightingPanel myErrorHighlightingPanel = new ErrorHighlightingPanel();
|
||||
private final MyConfigurable myConfigurable;
|
||||
|
||||
|
||||
public EditorOptionsPanel() {
|
||||
public EditorOptionsPanel(){
|
||||
if (SystemInfo.isMac) {
|
||||
myCbEnableWheelFontChange.setText(ApplicationBundle.message("checkbox.enable.ctrl.mousewheel.changes.font.size.macos"));
|
||||
}
|
||||
@@ -111,7 +106,6 @@ public class EditorOptionsPanel {
|
||||
myCbRenameLocalVariablesInplace.setVisible(OptionsApplicabilityFilter.isApplicable(OptionId.RENAME_IN_PLACE));
|
||||
|
||||
myConfigurable = new MyConfigurable();
|
||||
initQuickDocProcessing();
|
||||
initSoftWrapsSettingsProcessing();
|
||||
}
|
||||
|
||||
@@ -162,9 +156,6 @@ public class EditorOptionsPanel {
|
||||
}
|
||||
|
||||
myCbEnsureBlankLineBeforeCheckBox.setSelected(editorSettings.isEnsureNewLineAtEOF());
|
||||
myCbShowQuickDocOnCheckBox.setSelected(editorSettings.isShowQuickDocOnMouseOverElement());
|
||||
myQuickDocDelayTextField.setText(Long.toString(editorSettings.getQuickDocOnMouseOverElementDelayMillis()));
|
||||
myQuickDocDelayTextField.setEnabled(editorSettings.isShowQuickDocOnMouseOverElement());
|
||||
|
||||
// Advanced mouse
|
||||
myCbEnableDnD.setSelected(editorSettings.isDndEnabled());
|
||||
@@ -244,17 +235,6 @@ public class EditorOptionsPanel {
|
||||
|
||||
editorSettings.setEnsureNewLineAtEOF(myCbEnsureBlankLineBeforeCheckBox.isSelected());
|
||||
|
||||
if (myCbShowQuickDocOnCheckBox.isSelected() ^ editorSettings.isShowQuickDocOnMouseOverElement()) {
|
||||
boolean enabled = myCbShowQuickDocOnCheckBox.isSelected();
|
||||
editorSettings.setShowQuickDocOnMouseOverElement(enabled);
|
||||
ServiceManager.getService(QuickDocOnMouseOverManager.class).setEnabled(enabled);
|
||||
}
|
||||
|
||||
Long quickDocDelay = getQuickDocDelayFromGui();
|
||||
if (quickDocDelay != null) {
|
||||
editorSettings.setQuickDocOnMouseOverElementDelayMillis(quickDocDelay);
|
||||
}
|
||||
|
||||
editorSettings.setDndEnabled(myCbEnableDnD.isSelected());
|
||||
|
||||
editorSettings.setWheelFontChangeEnabled(myCbEnableWheelFontChange.isSelected());
|
||||
@@ -288,23 +268,6 @@ public class EditorOptionsPanel {
|
||||
restartDaemons();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Long getQuickDocDelayFromGui() {
|
||||
String quickDocDelayAsText = myQuickDocDelayTextField.getText();
|
||||
if (StringUtil.isEmptyOrSpaces(quickDocDelayAsText)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
long delay = Long.parseLong(quickDocDelayAsText);
|
||||
return delay > 0 ? delay : null;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// Ignore incorrect value.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void restartDaemons() {
|
||||
Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||
for (Project project : projects) {
|
||||
@@ -378,11 +341,6 @@ public class EditorOptionsPanel {
|
||||
// Strip trailing spaces, ensure EOL on EOF on save
|
||||
isModified |= !getStripTrailingSpacesValue().equals(editorSettings.getStripTrailingSpaces());
|
||||
isModified |= isModified(myCbEnsureBlankLineBeforeCheckBox, editorSettings.isEnsureNewLineAtEOF());
|
||||
isModified |= isModified(myCbShowQuickDocOnCheckBox, editorSettings.isShowQuickDocOnMouseOverElement());
|
||||
Long quickDocDelay = getQuickDocDelayFromGui();
|
||||
if (quickDocDelay != null && !quickDocDelay.equals(Long.valueOf(editorSettings.getQuickDocOnMouseOverElementDelayMillis()))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// advanced mouse
|
||||
isModified |= isModified(myCbEnableDnD, editorSettings.isDndEnabled());
|
||||
@@ -403,9 +361,7 @@ public class EditorOptionsPanel {
|
||||
isModified |= myErrorHighlightingPanel.isModified();
|
||||
return isModified;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static boolean isModified(JToggleButton checkBox, boolean value) {
|
||||
return checkBox.isSelected() != value;
|
||||
}
|
||||
@@ -448,15 +404,6 @@ public class EditorOptionsPanel {
|
||||
return defaultIndent;
|
||||
}
|
||||
|
||||
private void initQuickDocProcessing() {
|
||||
myCbShowQuickDocOnCheckBox.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
myQuickDocDelayTextField.setEnabled(myCbShowQuickDocOnCheckBox.isSelected());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initSoftWrapsSettingsProcessing() {
|
||||
ItemListener listener = new ItemListener() {
|
||||
@Override
|
||||
|
||||
+16
-16
@@ -325,7 +325,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, null);
|
||||
}
|
||||
|
||||
private void doShowJavaDocInfo(final PsiElement element,
|
||||
private void doShowJavaDocInfo(@NotNull final PsiElement element,
|
||||
boolean requestFocus,
|
||||
PopupUpdateProcessor updateProcessor,
|
||||
final PsiElement originalElement,
|
||||
@@ -339,23 +339,23 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
return;
|
||||
}
|
||||
else if (myToolWindow != null) {
|
||||
final Content content = myToolWindow.getContentManager().getSelectedContent();
|
||||
if (content != null) {
|
||||
final DocumentationComponent component = (DocumentationComponent)content.getComponent();
|
||||
if (component.getElement() != element) {
|
||||
content.setDisplayName(getTitle(element, true));
|
||||
fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
|
||||
if (!myToolWindow.isVisible()) myToolWindow.show(null);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (element != null && !allowReuse) {
|
||||
restorePopupBehavior();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
if (allowReuse) {
|
||||
final Content content = myToolWindow.getContentManager().getSelectedContent();
|
||||
if (content != null) {
|
||||
final DocumentationComponent component = (DocumentationComponent)content.getComponent();
|
||||
if (component.getElement() != element) {
|
||||
content.setDisplayName(getTitle(element, true));
|
||||
fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!myToolWindow.isVisible()) {
|
||||
myToolWindow.show(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
restorePopupBehavior();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-375
@@ -1,375 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.documentation;
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationActivationListener;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.*;
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.ui.popup.PopupFactoryImpl;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.containers.WeakHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Serves as a facade to the 'show quick doc on mouse over an element' functionality.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/2/12 9:09 AM
|
||||
*/
|
||||
public class QuickDocOnMouseOverManager {
|
||||
|
||||
@NotNull private final EditorMouseMotionListener myMouseListener = new MyEditorMouseListener();
|
||||
@NotNull private final VisibleAreaListener myVisibleAreaListener = new MyVisibleAreaListener();
|
||||
@NotNull private final CaretListener myCaretListener = new MyCaretListener();
|
||||
@NotNull private final DocumentListener myDocumentListener = new MyDocumentListener();
|
||||
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
@NotNull private final Runnable myRequest = new MyShowQuickDocRequest();
|
||||
@NotNull private final Runnable myHintCloseCallback = new MyCloseDocCallback();
|
||||
@NotNull private final Map<Document, Boolean> myMonitoredDocuments = new WeakHashMap<Document, Boolean>();
|
||||
|
||||
private final Map<Editor, PsiElement /** PSI element which is located under the current mouse position */> myActiveElements
|
||||
= new WeakHashMap<Editor, PsiElement>();
|
||||
|
||||
/** Holds a reference (if any) to the documentation manager used last time to show an 'auto quick doc' popup. */
|
||||
@Nullable private WeakReference<DocumentationManager> myDocumentationManager;
|
||||
|
||||
@Nullable private DelayedQuickDocInfo myDelayedQuickDocInfo;
|
||||
private boolean myEnabled;
|
||||
private boolean myApplicationActive;
|
||||
|
||||
public QuickDocOnMouseOverManager(@NotNull Application application) {
|
||||
EditorFactory factory = EditorFactory.getInstance();
|
||||
if (factory != null) {
|
||||
factory.addEditorFactoryListener(new MyEditorFactoryListener(), application);
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().getMessageBus().connect().subscribe(
|
||||
ApplicationActivationListener.TOPIC,
|
||||
new ApplicationActivationListener() {
|
||||
@Override
|
||||
public void applicationActivated(IdeFrame ideFrame) {
|
||||
myApplicationActive = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationDeactivated(IdeFrame ideFrame) {
|
||||
myApplicationActive = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the manager to enable or disable 'show quick doc automatically when the mouse goes over an editor element' mode.
|
||||
*
|
||||
* @param enabled flag that identifies if quick doc should be automatically shown
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
myEnabled = enabled;
|
||||
myApplicationActive = enabled;
|
||||
if (!enabled) {
|
||||
closeQuickDocIfPossible();
|
||||
myAlarm.cancelAllRequests();
|
||||
}
|
||||
EditorFactory factory = EditorFactory.getInstance();
|
||||
if (factory == null) {
|
||||
return;
|
||||
}
|
||||
for (Editor editor : factory.getAllEditors()) {
|
||||
if (enabled) {
|
||||
registerListeners(editor);
|
||||
}
|
||||
else {
|
||||
unRegisterListeners(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerListeners(@NotNull Editor editor) {
|
||||
editor.addEditorMouseMotionListener(myMouseListener);
|
||||
editor.getScrollingModel().addVisibleAreaListener(myVisibleAreaListener);
|
||||
editor.getCaretModel().addCaretListener(myCaretListener);
|
||||
|
||||
Document document = editor.getDocument();
|
||||
if (myMonitoredDocuments.put(document, Boolean.TRUE) == null) {
|
||||
document.addDocumentListener(myDocumentListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void unRegisterListeners(@NotNull Editor editor) {
|
||||
editor.removeEditorMouseMotionListener(myMouseListener);
|
||||
editor.getScrollingModel().removeVisibleAreaListener(myVisibleAreaListener);
|
||||
editor.getCaretModel().removeCaretListener(myCaretListener);
|
||||
|
||||
Document document = editor.getDocument();
|
||||
if (myMonitoredDocuments.remove(document) != null) {
|
||||
document.removeDocumentListener(myDocumentListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void processMouseMove(@NotNull EditorMouseEvent e) {
|
||||
if (!myApplicationActive || e.getArea() != EditorMouseEventArea.EDITING_AREA) {
|
||||
// Skip if the mouse is not at the editing area.
|
||||
closeQuickDocIfPossible();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.getMouseEvent().getModifiers() != 0) {
|
||||
// Don't show the control when any modifier is active (e.g. Ctrl or Alt is hold). There is a common situation that a user
|
||||
// wants to navigate via Ctrl+click or perform quick evaluate by Alt+click.
|
||||
return;
|
||||
}
|
||||
|
||||
Editor editor = e.getEditor();
|
||||
if (editor.isOneLineMode()) {
|
||||
// Don't want auto quick doc to mess at, say, editor used for debugger condition.
|
||||
return;
|
||||
}
|
||||
|
||||
Project project = editor.getProject();
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentationManager documentationManager = DocumentationManager.getInstance(project);
|
||||
JBPopup hint = documentationManager.getDocInfoHint();
|
||||
if (hint != null) {
|
||||
|
||||
// Skip the event if the control is shown because of explicit 'show quick doc' action call.
|
||||
WeakReference<DocumentationManager> ref = myDocumentationManager;
|
||||
if (ref == null) {
|
||||
return;
|
||||
}
|
||||
DocumentationManager manager = ref.get();
|
||||
if (manager == null || !manager.isCloseOnSneeze()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the event if the mouse is under the opened quick doc control.
|
||||
Point hintLocation = hint.getLocationOnScreen();
|
||||
Dimension hintSize = hint.getSize();
|
||||
int mouseX = e.getMouseEvent().getXOnScreen();
|
||||
int mouseY = e.getMouseEvent().getYOnScreen();
|
||||
if (mouseX >= hintLocation.x && mouseX <= hintLocation.x + hintSize.width && mouseY >= hintLocation.y
|
||||
&& mouseY <= hintLocation.y + hintSize.height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (psiFile == null) {
|
||||
closeQuickDocIfPossible();
|
||||
return;
|
||||
}
|
||||
|
||||
int mouseOffset = editor.logicalPositionToOffset(editor.xyToLogicalPosition(e.getMouseEvent().getPoint()));
|
||||
PsiElement elementUnderMouse = psiFile.findElementAt(mouseOffset);
|
||||
if (elementUnderMouse == null || elementUnderMouse instanceof PsiWhiteSpace) {
|
||||
closeQuickDocIfPossible();
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement targetElementUnderMouse = documentationManager.findTargetElement(editor, mouseOffset, psiFile, elementUnderMouse);
|
||||
if (targetElementUnderMouse == null) {
|
||||
// No PSI element is located under the current mouse position - close quick doc if any.
|
||||
closeQuickDocIfPossible();
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement activeElement = myActiveElements.get(editor);
|
||||
if (targetElementUnderMouse.equals(activeElement)
|
||||
&& (myAlarm.getActiveRequestCount() > 0 // Request to show documentation for the target component has been already queued.
|
||||
|| hint != null)) // Documentation for the target component is being shown.
|
||||
{
|
||||
return;
|
||||
}
|
||||
allowUpdateFromContext(false);
|
||||
closeQuickDocIfPossible();
|
||||
myActiveElements.put(editor, targetElementUnderMouse);
|
||||
myDelayedQuickDocInfo = new DelayedQuickDocInfo(documentationManager, editor, targetElementUnderMouse, elementUnderMouse);
|
||||
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(myRequest, EditorSettingsExternalizable.getInstance().getQuickDocOnMouseOverElementDelayMillis());
|
||||
}
|
||||
|
||||
private void closeQuickDocIfPossible() {
|
||||
myAlarm.cancelAllRequests();
|
||||
DocumentationManager docManager = getDocManager();
|
||||
if (docManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JBPopup hint = docManager.getDocInfoHint();
|
||||
if (hint == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
hint.cancel();
|
||||
myDocumentationManager = null;
|
||||
}
|
||||
|
||||
private void allowUpdateFromContext(boolean allow) {
|
||||
DocumentationManager documentationManager = getDocManager();
|
||||
if (documentationManager != null) {
|
||||
documentationManager.setAllowContentUpdateFromContext(allow);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DocumentationManager getDocManager() {
|
||||
WeakReference<DocumentationManager> ref = myDocumentationManager;
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DocumentationManager docManager = ref.get();
|
||||
if (docManager == null) {
|
||||
return null;
|
||||
}
|
||||
return docManager;
|
||||
}
|
||||
|
||||
private static class DelayedQuickDocInfo {
|
||||
|
||||
@NotNull public final DocumentationManager docManager;
|
||||
@NotNull public final Editor editor;
|
||||
@NotNull public final PsiElement targetElement;
|
||||
@NotNull public final PsiElement originalElement;
|
||||
|
||||
private DelayedQuickDocInfo(@NotNull DocumentationManager docManager,
|
||||
@NotNull Editor editor, @NotNull PsiElement targetElement,
|
||||
@NotNull PsiElement originalElement)
|
||||
{
|
||||
this.docManager = docManager;
|
||||
this.editor = editor;
|
||||
this.targetElement = targetElement;
|
||||
this.originalElement = originalElement;
|
||||
}
|
||||
}
|
||||
|
||||
private class MyShowQuickDocRequest implements Runnable {
|
||||
|
||||
private final HintManager myHintManager = HintManager.getInstance();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
myAlarm.cancelAllRequests();
|
||||
|
||||
// Skip the request if it's outdated (the mouse is moved other another element).
|
||||
DelayedQuickDocInfo info = myDelayedQuickDocInfo;
|
||||
if (info == null || !info.targetElement.equals(myActiveElements.get(info.editor))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the request if there is a control shown as a result of explicit 'show quick doc' (Ctrl + Q) invocation.
|
||||
if (info.docManager.getDocInfoHint() != null && !info.docManager.isCloseOnSneeze()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't want to show a quick doc control if there is an active hint (e.g. the mouse is under an invalid element
|
||||
// and corresponding error info is shown).
|
||||
if (!info.docManager.hasActiveDockedDocWindow() && myHintManager.hasShownHintsThatWillHideByOtherHint(false)) {
|
||||
myAlarm.addRequest(this, EditorSettingsExternalizable.getInstance().getQuickDocOnMouseOverElementDelayMillis());
|
||||
return;
|
||||
}
|
||||
|
||||
info.editor.putUserData(PopupFactoryImpl.ANCHOR_POPUP_POSITION,
|
||||
info.editor.offsetToVisualPosition(info.originalElement.getTextRange().getStartOffset()));
|
||||
try {
|
||||
info.docManager.showJavaDocInfo(info.editor, info.targetElement, info.originalElement, myHintCloseCallback, true, true);
|
||||
myDocumentationManager = new WeakReference<DocumentationManager>(info.docManager);
|
||||
}
|
||||
finally {
|
||||
info.editor.putUserData(PopupFactoryImpl.ANCHOR_POPUP_POSITION, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyCloseDocCallback implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
myActiveElements.clear();
|
||||
myDocumentationManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class MyEditorFactoryListener implements EditorFactoryListener {
|
||||
@Override
|
||||
public void editorCreated(@NotNull EditorFactoryEvent event) {
|
||||
if (myEnabled) {
|
||||
registerListeners(event.getEditor());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editorReleased(@NotNull EditorFactoryEvent event) {
|
||||
if (myEnabled) {
|
||||
// We do this in the 'if' block because editor logs an error on attempt to remove already released listener.
|
||||
unRegisterListeners(event.getEditor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyEditorMouseListener extends EditorMouseMotionAdapter {
|
||||
|
||||
@Override
|
||||
public void mouseMoved(EditorMouseEvent e) {
|
||||
processMouseMove(e);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyVisibleAreaListener implements VisibleAreaListener {
|
||||
@Override
|
||||
public void visibleAreaChanged(VisibleAreaEvent e) {
|
||||
closeQuickDocIfPossible();
|
||||
}
|
||||
}
|
||||
|
||||
private class MyCaretListener implements CaretListener {
|
||||
@Override
|
||||
public void caretPositionChanged(CaretEvent e) {
|
||||
allowUpdateFromContext(true);
|
||||
closeQuickDocIfPossible();
|
||||
}
|
||||
}
|
||||
|
||||
private class MyDocumentListener extends DocumentAdapter {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
closeQuickDocIfPossible();
|
||||
}
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.documentation;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/2/12 9:44 AM
|
||||
*/
|
||||
public class QuickDocOnMouseOverStartupActivity implements StartupActivity {
|
||||
|
||||
@Override
|
||||
public void runActivity(Project project) {
|
||||
if (EditorSettingsExternalizable.getInstance().isShowQuickDocOnMouseOverElement()) {
|
||||
ServiceManager.getService(QuickDocOnMouseOverManager.class).setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,9 @@ import com.intellij.ide.util.EditSourceUtil;
|
||||
import com.intellij.lang.documentation.DocumentationProvider;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.MouseShortcut;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
@@ -59,6 +59,8 @@ import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -72,6 +74,7 @@ import com.intellij.usageView.UsageViewShortNameLocation;
|
||||
import com.intellij.usageView.UsageViewTypeLocation;
|
||||
import com.intellij.util.Processor;
|
||||
import org.intellij.lang.annotations.JdkConstants;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
@@ -87,7 +90,13 @@ import java.util.List;
|
||||
|
||||
public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
|
||||
private static final int ourQuickDocRowsNumber = getIntProperty("quick.doc.desired.rows.number", 1);
|
||||
public static final DataKey<Pair<PsiElement /* documentation anchor */, PsiElement /* element under mouse */>>
|
||||
ELEMENT_UNDER_MOUSE_INFO_KEY = DataKey.create("ElementUnderMouseInfo");
|
||||
|
||||
private static final AnAction[] ourTooltipActions = {
|
||||
new ShowQuickDocFromTooltipAction(), new ShowQuickDocAtPinnedWindowFromTooltipAction()
|
||||
};
|
||||
private static final int ourQuickDocRowsNumber = getIntProperty("quick.doc.desired.rows.number", 1);
|
||||
|
||||
private final TextAttributes ourReferenceAttributes;
|
||||
private HighlightersSet myHighlighter;
|
||||
@@ -276,7 +285,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
String fullText = documentationProvider.generateDoc(element, atPointer);
|
||||
String qName = element instanceof PsiQualifiedNamedElement ? ((PsiQualifiedNamedElement)element).getQualifiedName() : null;
|
||||
String text = DocPreviewUtil.buildPreview(result, qName, fullText, ourQuickDocRowsNumber);
|
||||
return new DocInfo(text, documentationProvider, atPointer);
|
||||
return new DocInfo(text, documentationProvider, element);
|
||||
}
|
||||
return DocInfo.EMPTY;
|
||||
}
|
||||
@@ -638,18 +647,43 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
info.showDocInfo(myDocumentationManager);
|
||||
}
|
||||
|
||||
HyperlinkListener listener = (docInfo.docProvider == null || docInfo.context == null)
|
||||
HyperlinkListener hyperlinkListener = docInfo.docProvider == null
|
||||
? null
|
||||
: new QuickDocHyperlinkListener(myProject, myDocumentationManager, docInfo.docProvider, docInfo.context);
|
||||
JComponent label = HintUtil.createInformationLabel(docInfo.text, listener);
|
||||
final LightweightHint hint = new LightweightHint(label);
|
||||
: new QuickDocHyperlinkListener(myProject, myDocumentationManager, docInfo.docProvider,
|
||||
info.myElementAtPointer);
|
||||
final Ref<QuickDocInfoPane> quickDocPaneRef = new Ref<QuickDocInfoPane>();
|
||||
MouseListener mouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
QuickDocInfoPane pane = quickDocPaneRef.get();
|
||||
if (pane != null) {
|
||||
pane.mouseEntered(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
QuickDocInfoPane pane = quickDocPaneRef.get();
|
||||
if (pane != null) {
|
||||
pane.mouseExited(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
JComponent label = HintUtil.createInformationLabel(docInfo.text, hyperlinkListener, mouseListener);
|
||||
QuickDocInfoPane quickDocPane = null;
|
||||
if (docInfo.documentationAnchor != null) {
|
||||
quickDocPane = new QuickDocInfoPane(docInfo.documentationAnchor, info.myElementAtPointer, label);
|
||||
quickDocPaneRef.set(quickDocPane);
|
||||
}
|
||||
|
||||
JComponent hintContent = quickDocPane == null ? label : quickDocPane;
|
||||
final LightweightHint hint = new LightweightHint(hintContent);
|
||||
final HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
|
||||
Point p = HintManagerImpl.getHintPosition(hint, myEditor, myPosition, HintManager.ABOVE);
|
||||
hintManager.showEditorHint(hint, myEditor, p,
|
||||
HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING,
|
||||
0, false, HintManagerImpl.createHintHint(myEditor, p, hint, HintManager.ABOVE).setContentActive(false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private HighlightersSet installHighlighterSet(Info info, Editor editor) {
|
||||
@@ -708,12 +742,88 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
|
||||
@Nullable public final String text;
|
||||
@Nullable public final DocumentationProvider docProvider;
|
||||
@Nullable public final PsiElement context;
|
||||
@Nullable public final PsiElement documentationAnchor;
|
||||
|
||||
DocInfo(@Nullable String text, @Nullable DocumentationProvider provider, @Nullable PsiElement context) {
|
||||
DocInfo(@Nullable String text, @Nullable DocumentationProvider provider, @Nullable PsiElement documentationAnchor) {
|
||||
this.text = text;
|
||||
docProvider = provider;
|
||||
this.context = context;
|
||||
this.documentationAnchor = documentationAnchor;
|
||||
}
|
||||
}
|
||||
|
||||
private class QuickDocInfoPane extends JLayeredPane implements DataProvider {
|
||||
|
||||
@NotNull private final List<JComponent> myButtons = new ArrayList<JComponent>();
|
||||
@NotNull private final Pair<PsiElement, PsiElement> myElementUnderMouseInfo;
|
||||
@NotNull private final JComponent myBaseDocControl;
|
||||
|
||||
QuickDocInfoPane(@NotNull PsiElement documentationAnchor, @NotNull PsiElement elementUnderMouse, @NotNull JComponent baseDocControl) {
|
||||
myElementUnderMouseInfo = Pair.create(documentationAnchor, elementUnderMouse);
|
||||
myBaseDocControl = baseDocControl;
|
||||
|
||||
PresentationFactory presentationFactory = new PresentationFactory();
|
||||
for (AnAction action : ourTooltipActions) {
|
||||
Icon icon = action.getTemplatePresentation().getIcon();
|
||||
Dimension minSize = new Dimension(icon.getIconWidth(), icon.getIconHeight());
|
||||
myButtons.add(new ActionButton(action, presentationFactory.getPresentation(action), IdeTooltipManager.IDE_TOOLTIP_PLACE, minSize));
|
||||
}
|
||||
Collections.reverse(myButtons);
|
||||
|
||||
setPreferredSize(baseDocControl.getPreferredSize());
|
||||
setMaximumSize(baseDocControl.getMaximumSize());
|
||||
setMinimumSize(baseDocControl.getMinimumSize());
|
||||
setBackground(baseDocControl.getBackground());
|
||||
|
||||
add(baseDocControl, Integer.valueOf(0));
|
||||
for (JComponent button : myButtons) {
|
||||
button.setBorder(null);
|
||||
button.setBackground(baseDocControl.getBackground());
|
||||
add(button, Integer.valueOf(1));
|
||||
button.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
return ELEMENT_UNDER_MOUSE_INFO_KEY.is(dataId) ? myElementUnderMouseInfo : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLayout() {
|
||||
Rectangle bounds = getBounds();
|
||||
myBaseDocControl.setBounds(bounds);
|
||||
|
||||
final int buttonsHGap = 5;
|
||||
int x = bounds.width;
|
||||
for (JComponent button : myButtons) {
|
||||
Dimension buttonSize = button.getPreferredSize();
|
||||
x -= buttonSize.width;
|
||||
button.setBounds(x, 0, buttonSize.width, buttonSize.height);
|
||||
x -= buttonsHGap;
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseEntered(@NotNull MouseEvent e) {
|
||||
processStateChangeIfNecessary(e.getLocationOnScreen(), true);
|
||||
}
|
||||
|
||||
public void mouseExited(@NotNull MouseEvent e) {
|
||||
processStateChangeIfNecessary(e.getLocationOnScreen(), false);
|
||||
}
|
||||
|
||||
private void processStateChangeIfNecessary(@NotNull Point mouseScreenLocation, boolean mouseEntered) {
|
||||
// Don't show 'view quick doc' buttons if docked quick doc control is already active.
|
||||
if (myDocumentationManager.hasActiveDockedDocWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip event triggered when mouse leaves action button area.
|
||||
if (!mouseEntered && new Rectangle(getLocationOnScreen(), getSize()).contains(mouseScreenLocation)) {
|
||||
return;
|
||||
}
|
||||
for (JComponent button : myButtons) {
|
||||
button.setVisible(mouseEntered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.navigation;
|
||||
|
||||
import com.intellij.codeInsight.documentation.DocumentationManager;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/13/12 11:43 AM
|
||||
*/
|
||||
public class ShowQuickDocAtPinnedWindowFromTooltipAction extends ShowQuickDocFromTooltipAction {
|
||||
|
||||
public ShowQuickDocAtPinnedWindowFromTooltipAction() {
|
||||
super(AllIcons.General.Pin_tab);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doActionPerformed(@NotNull Pair<PsiElement, PsiElement> docInfo, @NotNull DocumentationManager docManager) {
|
||||
docManager.createToolWindow(docInfo.first, docInfo.second);
|
||||
}
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.navigation;
|
||||
|
||||
import com.intellij.codeInsight.documentation.DocumentationManager;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.IdeTooltip;
|
||||
import com.intellij.ide.IdeTooltipManager;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/13/12 10:00 AM
|
||||
*/
|
||||
public class ShowQuickDocFromTooltipAction extends AnAction {
|
||||
|
||||
@NotNull private final IdeTooltipManager myTooltipManager = IdeTooltipManager.getInstance();
|
||||
@NotNull private final DataManager myDataManager = DataManager.getInstance();
|
||||
|
||||
private WeakReference<Pair<PsiElement, PsiElement>> myInfo;
|
||||
|
||||
public ShowQuickDocFromTooltipAction() {
|
||||
this(AllIcons.Actions.Find);
|
||||
}
|
||||
|
||||
public ShowQuickDocFromTooltipAction(@NotNull Icon icon) {
|
||||
String className = getClass().getName();
|
||||
String actionId = className.substring(0, className.lastIndexOf("Action"));
|
||||
getTemplatePresentation().setText(ActionsBundle.actionText(actionId));
|
||||
getTemplatePresentation().setDescription(ActionsBundle.actionDescription(actionId));
|
||||
getTemplatePresentation().setIcon(icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
|
||||
// We can't use data context from the given event because it's built from the focused component and IDE tooltip doesn't have focus.
|
||||
IdeTooltip tooltip = myTooltipManager.getCurrentTooltip();
|
||||
if (tooltip == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JComponent component = tooltip.getTipComponent();
|
||||
if (component == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pair<PsiElement, PsiElement> info = CtrlMouseHandler.ELEMENT_UNDER_MOUSE_INFO_KEY.getData(myDataManager.getDataContext(component));
|
||||
if (info != null) {
|
||||
// Target info is retrieved during AnAction.update() processing because IDE tooltip is closed on action activation,
|
||||
// i.e. IdeTooltipManager.getCurrentComponent() returns null during AnAction.actionPerformed() execution.
|
||||
myInfo = new WeakReference<Pair<PsiElement, PsiElement>>(info);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
WeakReference<Pair<PsiElement, PsiElement>> infoRef = myInfo;
|
||||
if (infoRef == null) {
|
||||
return;
|
||||
}
|
||||
Pair<PsiElement, PsiElement> info = infoRef.get();
|
||||
if (info == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
myInfo = null;
|
||||
doActionPerformed(info, DocumentationManager.getInstance(project));
|
||||
}
|
||||
|
||||
protected void doActionPerformed(@NotNull Pair<PsiElement/* documentation anchor */, PsiElement/* element under mouse */> docInfo,
|
||||
@NotNull DocumentationManager docManager)
|
||||
{
|
||||
docManager.showJavaDocInfo(docInfo.first, docInfo.second, true, null);
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,9 @@ import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
public class HintUtil {
|
||||
public static final Color INFORMATION_COLOR = new Color(253, 254, 226);
|
||||
@@ -49,10 +52,13 @@ public class HintUtil {
|
||||
}
|
||||
|
||||
public static JComponent createInformationLabel(@NotNull String text) {
|
||||
return createInformationLabel(text, null);
|
||||
return createInformationLabel(text, null, null);
|
||||
}
|
||||
|
||||
public static JComponent createInformationLabel(@NotNull String text, @Nullable HyperlinkListener listener) {
|
||||
|
||||
public static JComponent createInformationLabel(@NotNull String text,
|
||||
@Nullable HyperlinkListener hyperlinkListener,
|
||||
@Nullable MouseListener mouseListener)
|
||||
{
|
||||
HintHint hintHint = new HintHint().setTextBg(INFORMATION_COLOR).setTextFg(Color.black).setFont(getBoldFont()).setAwtTooltip(true);
|
||||
|
||||
HintLabel label = new HintLabel();
|
||||
@@ -67,8 +73,11 @@ public class HintUtil {
|
||||
label.setOpaque(true);
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
label.myPane.addHyperlinkListener(listener);
|
||||
if (hyperlinkListener != null) {
|
||||
label.myPane.addHyperlinkListener(hyperlinkListener);
|
||||
}
|
||||
if (mouseListener != null) {
|
||||
label.myPane.addMouseListener(mouseListener);
|
||||
}
|
||||
|
||||
return label;
|
||||
|
||||
@@ -57,6 +57,8 @@ import java.awt.event.MouseEvent;
|
||||
|
||||
public class IdeTooltipManager implements ApplicationComponent, AWTEventListener {
|
||||
|
||||
public static final String IDE_TOOLTIP_PLACE = "IdeTooltip";
|
||||
|
||||
public static final Color GRAPHITE_COLOR = new Color(100, 100, 100, 230);
|
||||
private RegistryValue myIsEnabled;
|
||||
|
||||
@@ -64,8 +66,8 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
private Component myQueuedComponent;
|
||||
|
||||
private BalloonImpl myCurrentTipUi;
|
||||
private MouseEvent myCurrentEvent;
|
||||
private boolean myCurrentTipIsCentered;
|
||||
private MouseEvent myCurrentEvent;
|
||||
private boolean myCurrentTipIsCentered;
|
||||
|
||||
private Runnable myHideRunnable;
|
||||
|
||||
@@ -75,12 +77,12 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
|
||||
private final Alarm myAlarm = new Alarm();
|
||||
|
||||
private int myX;
|
||||
private int myY;
|
||||
private int myX;
|
||||
private int myY;
|
||||
private RegistryValue myMode;
|
||||
|
||||
private IdeTooltip myCurrentTooltip;
|
||||
private Runnable myShowRequest;
|
||||
private Runnable myShowRequest;
|
||||
private IdeTooltip myQueuedTooltip;
|
||||
|
||||
|
||||
@@ -341,7 +343,11 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
}
|
||||
}, tooltip.getDismissDelay());
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public IdeTooltip getCurrentTooltip() {
|
||||
return myCurrentTooltip;
|
||||
}
|
||||
|
||||
public Color getTextForeground(boolean awtTooltip) {
|
||||
return useGraphite(awtTooltip) ? Color.white : UIUtil.getToolTipForeground();
|
||||
|
||||
-25
@@ -19,7 +19,6 @@ import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.ExportableApplicationComponent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
|
||||
import com.intellij.openapi.options.OptionsBundle;
|
||||
import com.intellij.openapi.util.DefaultJDOMExternalizer;
|
||||
@@ -51,8 +50,6 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
|
||||
public boolean IS_CARET_INSIDE_TABS;
|
||||
@NonNls public String STRIP_TRAILING_SPACES = "Changed";
|
||||
public boolean IS_ENSURE_NEWLINE_AT_EOF = false;
|
||||
public boolean SHOW_QUICK_DOC_ON_MOUSE_OVER_ELEMENT = false;
|
||||
public long QUICK_DOC_ON_MOUSE_OVER_DELAY_MS = 500;
|
||||
public boolean IS_CARET_BLINKING = true;
|
||||
public int CARET_BLINKING_PERIOD = 500;
|
||||
public boolean IS_RIGHT_MARGIN_SHOWN = true;
|
||||
@@ -368,28 +365,6 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
|
||||
myOptions.STRIP_TRAILING_SPACES = stripTrailingSpaces;
|
||||
}
|
||||
|
||||
public boolean isShowQuickDocOnMouseOverElement() {
|
||||
return myOptions.SHOW_QUICK_DOC_ON_MOUSE_OVER_ELEMENT;
|
||||
}
|
||||
|
||||
public void setShowQuickDocOnMouseOverElement(boolean show) {
|
||||
myOptions.SHOW_QUICK_DOC_ON_MOUSE_OVER_ELEMENT = show;
|
||||
}
|
||||
|
||||
public long getQuickDocOnMouseOverElementDelayMillis() {
|
||||
return myOptions.QUICK_DOC_ON_MOUSE_OVER_DELAY_MS;
|
||||
}
|
||||
|
||||
public void setQuickDocOnMouseOverElementDelayMillis(long delay) throws IllegalArgumentException {
|
||||
if (delay <= 0) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Non-positive delay for the 'show quick doc on mouse over element' value detected! Expected positive value but got %d",
|
||||
delay
|
||||
));
|
||||
}
|
||||
myOptions.QUICK_DOC_ON_MOUSE_OVER_DELAY_MS = delay;
|
||||
}
|
||||
|
||||
public boolean isRefrainFromScrolling() {
|
||||
return myOptions.REFRAIN_FROM_SCROLLING;
|
||||
}
|
||||
|
||||
@@ -201,6 +201,10 @@ action.CompareTwoFiles.text=Compare Two _Files
|
||||
action.CompareTwoFiles.description=Compare two selected files
|
||||
action.CompareFileWithEditor.text=Co_mpare File with Editor
|
||||
action.CompareFileWithEditor.description=Compare selected file with editor
|
||||
action.ShowQuickDocFromTooltip.text=Full documentation
|
||||
action.ShowQuickDocFromTooltip.description=Show full documentation
|
||||
action.ShowQuickDocAtPinnedWindowFromTooltip.text=Full documentation in pinned window
|
||||
action.ShowQuickDocAtPinnedWindowFromTooltip.description=Show full documentation in pinned window
|
||||
|
||||
group.LocalHistory.text=Local _History
|
||||
action.LocalHistory.ShowHistory.text=Show _History
|
||||
|
||||
@@ -734,9 +734,6 @@
|
||||
serviceImplementation="com.intellij.ide.todo.TodoConfiguration"/>
|
||||
<indexPatternProvider implementation="com.intellij.ide.todo.TodoIndexPatternProvider"/>
|
||||
|
||||
<applicationService serviceImplementation="com.intellij.codeInsight.documentation.QuickDocOnMouseOverManager"/>
|
||||
<postStartupActivity implementation="com.intellij.codeInsight.documentation.QuickDocOnMouseOverStartupActivity"/>
|
||||
|
||||
<hectorComponentProvider implementation="com.intellij.codeInsight.daemon.PowerSaveHectorProvider"/>
|
||||
|
||||
<copyPastePostProcessor implementation="com.intellij.codeInsight.editorActions.CopyPasteIndentProcessor"/>
|
||||
|
||||
Reference in New Issue
Block a user