diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form index 176342098b45..4beef3e72391 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form @@ -2,7 +2,7 @@
- + @@ -304,7 +304,7 @@ - + @@ -317,7 +317,7 @@ - + @@ -325,7 +325,7 @@ - + @@ -333,13 +333,40 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java index 334745b88800..6d78682352b5 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java @@ -21,8 +21,10 @@ 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; @@ -38,7 +40,10 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.components.JBCheckBox; +import com.intellij.ui.components.JBLabel; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -46,11 +51,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; @@ -63,32 +68,35 @@ 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 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 JBCheckBox myCbShowQuickDocOnMouseMove; + private JBLabel myQuickDocDelayLabel; + private JTextField myQuickDocDelayTextField; 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")); } @@ -106,6 +114,7 @@ public class EditorOptionsPanel { myCbRenameLocalVariablesInplace.setVisible(OptionsApplicabilityFilter.isApplicable(OptionId.RENAME_IN_PLACE)); myConfigurable = new MyConfigurable(); + initQuickDocProcessing(); initSoftWrapsSettingsProcessing(); } @@ -113,7 +122,7 @@ public class EditorOptionsPanel { public void reset() { EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance(); CodeInsightSettings codeInsightSettings = CodeInsightSettings.getInstance(); - UISettings uiSettings=UISettings.getInstance(); + UISettings uiSettings = UISettings.getInstance(); // Display @@ -156,6 +165,10 @@ public class EditorOptionsPanel { } myCbEnsureBlankLineBeforeCheckBox.setSelected(editorSettings.isEnsureNewLineAtEOF()); + myCbShowQuickDocOnMouseMove.setSelected(editorSettings.isShowQuickDocOnMouseOverElement()); + myQuickDocDelayTextField.setText(Long.toString(editorSettings.getQuickDocOnMouseOverElementDelayMillis())); + myQuickDocDelayTextField.setEnabled(editorSettings.isShowQuickDocOnMouseOverElement()); + myQuickDocDelayLabel.setEnabled(editorSettings.isShowQuickDocOnMouseOverElement()); // Advanced mouse myCbEnableDnD.setSelected(editorSettings.isDndEnabled()); @@ -235,6 +248,17 @@ public class EditorOptionsPanel { editorSettings.setEnsureNewLineAtEOF(myCbEnsureBlankLineBeforeCheckBox.isSelected()); + if (myCbShowQuickDocOnMouseMove.isSelected() ^ editorSettings.isShowQuickDocOnMouseOverElement()) { + boolean enabled = myCbShowQuickDocOnMouseMove.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()); @@ -268,6 +292,23 @@ 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) { @@ -342,6 +383,12 @@ public class EditorOptionsPanel { isModified |= !getStripTrailingSpacesValue().equals(editorSettings.getStripTrailingSpaces()); isModified |= isModified(myCbEnsureBlankLineBeforeCheckBox, editorSettings.isEnsureNewLineAtEOF()); + isModified |= isModified(myCbShowQuickDocOnMouseMove, editorSettings.isShowQuickDocOnMouseOverElement()); + Long quickDocDelay = getQuickDocDelayFromGui(); + if (quickDocDelay != null && !quickDocDelay.equals(Long.valueOf(editorSettings.getQuickDocOnMouseOverElementDelayMillis()))) { + return true; + } + // advanced mouse isModified |= isModified(myCbEnableDnD, editorSettings.isDndEnabled()); isModified |= isModified(myCbEnableWheelFontChange, editorSettings.isWheelFontChangeEnabled()); @@ -404,6 +451,16 @@ public class EditorOptionsPanel { return defaultIndent; } + private void initQuickDocProcessing() { + myCbShowQuickDocOnMouseMove.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + myQuickDocDelayTextField.setEnabled(myCbShowQuickDocOnMouseMove.isSelected()); + myQuickDocDelayLabel.setEnabled(myCbShowQuickDocOnMouseMove.isSelected()); + } + }); + } + private void initSoftWrapsSettingsProcessing() { ItemListener listener = new ItemListener() { @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 0b6578c54635..e1891f71febd 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -95,6 +95,8 @@ public class DocumentationManager extends DockablePopupManagertrue if quick doc control is configured to not prevent user-IDE interaction (e.g. should be closed if + * the user presses a key); + * false otherwise + */ + public boolean isCloseOnSneeze() { + return myCloseOnSneeze; + } + public static DocumentationManager getInstance(Project project) { return ServiceManager.getService(project, DocumentationManager.class); } @@ -169,6 +180,7 @@ public class DocumentationManager extends DockablePopupManager'element' argument is a {@code Runnable} descriptor + * @param closeCallback callback to be notified on target hint close (if any) + * @param closeOnSneeze flag that defines whether quick doc control should be as non-obtrusive as possible. E.g. there are at least + * two possible situations - the quick doc is shown automatically on mouse over element; the quick doc is shown + * on explicit action call (Ctrl+Q). We want to close the doc on, say, editor viewport position change + * at the first situation but don't want to do that at the second + * @param allowReuse defines whether currently requested documentation should reuse existing doc control (if any) + */ + public void showJavaDocInfo(@NotNull Editor editor, + @NotNull final PsiElement element, + @NotNull final PsiElement original, + @Nullable Runnable closeCallback, + boolean closeOnSneeze, + boolean allowReuse) + { + myEditor = editor; + myCloseOnSneeze = closeOnSneeze; + showJavaDocInfo(element, original, allowReuse, closeCallback); + } + public void showJavaDocInfo(@NotNull final PsiElement element, final PsiElement original, boolean allowReuse, @@ -403,6 +442,7 @@ public class DocumentationManager extends DockablePopupManager() { @Override public Boolean compute() { + myCloseOnSneeze = false; if (closeCallback != null) { closeCallback.run(); } @@ -420,6 +460,9 @@ public class DocumentationManager extends DockablePopupManager() { @Override public boolean fun(KeyEvent event) { + if (myCloseOnSneeze) { + closeDocHint(); + } return false; } }) @@ -476,7 +519,11 @@ public class DocumentationManager extends DockablePopupManager + * 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 myMonitoredDocuments = new WeakHashMap(); + + private final Map myActiveElements + = new WeakHashMap(); + + /** Holds a reference (if any) to the documentation manager used last time to show an 'auto quick doc' popup. */ + @Nullable private WeakReference 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 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 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(info.docManager); + myDocumentationManager = new WeakReference(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(); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverStartupActivity.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverStartupActivity.java new file mode 100644 index 000000000000..99dd92ebd14e --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverStartupActivity.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 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); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java index 8a7a3422ed8c..d35ef8346a68 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java @@ -51,6 +51,8 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex public boolean IS_CARET_INSIDE_TABS; @NonNls public String STRIP_TRAILING_SPACES = 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; @@ -369,6 +371,28 @@ 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; } diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index dc6463ddc643..49facb201cfa 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -764,6 +764,9 @@ serviceImplementation="com.intellij.ide.todo.TodoConfiguration"/> + + +