diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java index b75b6f269199..96e429e058e2 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java @@ -26,6 +26,7 @@ import com.intellij.lang.CodeDocumentationAwareCommenter; import com.intellij.lang.LangBundle; import com.intellij.lang.LanguageCommenters; import com.intellij.lang.documentation.CodeDocumentationProvider; +import com.intellij.lang.documentation.CompositeDocumentationProvider; import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -675,6 +676,11 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext return fetchExternalJavadoc(element, project, docUrls); } + @Override + public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) { + return CompositeDocumentationProvider.hasUrlsFor(this, element, originalElement); + } + public static String fetchExternalJavadoc(PsiElement element, final Project project, final List docURLs) { final JavaDocExternalFilter docFilter = new JavaDocExternalFilter(project); diff --git a/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java b/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java index 021192ced88d..1babe6ea6a1a 100644 --- a/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java +++ b/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java @@ -134,4 +134,23 @@ public class CompositeDocumentationProvider implements DocumentationProvider, Ex } return null; } + + @Override + public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) { + for (DocumentationProvider provider : myProviders) { + if (provider instanceof ExternalDocumentationProvider) { + if (((ExternalDocumentationProvider) provider).hasDocumentationFor(element, originalElement)) return true; + } + else { + if (hasUrlsFor(provider, element, originalElement)) return true; + } + } + return false; + } + + public static boolean hasUrlsFor(DocumentationProvider provider, PsiElement element, PsiElement originalElement) { + final List urls = provider.getUrlFor(element, originalElement); + if (urls != null && !urls.isEmpty()) return true; + return false; + } } diff --git a/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationProvider.java b/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationProvider.java index 46fdb08f86c9..88c2b3de5493 100644 --- a/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationProvider.java +++ b/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationProvider.java @@ -29,4 +29,14 @@ import java.util.List; public interface ExternalDocumentationProvider { @Nullable String fetchExternalDocumentation(final Project project, PsiElement element, final List docUrls); + + /** + * Quick check for existence of external documentation for specified element. Called from action update, so must be fast. + * If not implemented, update check is performed by calling {@link DocumentationProvider#getUrlFor(com.intellij.psi.PsiElement, com.intellij.psi.PsiElement)}. + * + * @param element the element to check for existence of documentation + * @param originalElement the element at caret (on which the action was invoked) + * @return true if the external documentation action should be enabled, false otherwise. + */ + boolean hasDocumentationFor(PsiElement element, PsiElement originalElement); } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java index e2bb2c93856f..f6864cb8a9d9 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java @@ -18,9 +18,10 @@ package com.intellij.ide.actions; import com.intellij.codeInsight.documentation.DocumentationManager; import com.intellij.ide.BrowserUtil; -import com.intellij.ide.IdeBundle; import com.intellij.ide.DataManager; +import com.intellij.ide.IdeBundle; import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -33,8 +34,8 @@ import com.intellij.psi.PsiFile; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; -import java.util.List; import java.util.HashSet; +import java.util.List; public class ExternalJavaDocAction extends AnAction { @@ -100,8 +101,14 @@ public class ExternalJavaDocAction extends AnAction { final PsiElement originalElement = getOriginalElement(LangDataKeys.PSI_FILE.getData(dataContext), editor); DocumentationManager.storeOriginalElement(PlatformDataKeys.PROJECT.getData(dataContext), originalElement, element); final DocumentationProvider provider = DocumentationManager.getProviderFromElement(element); - final List urls = provider.getUrlFor(element, originalElement); - boolean enabled = urls != null && !urls.isEmpty(); + boolean enabled; + if (provider instanceof ExternalDocumentationProvider) { + enabled = ((ExternalDocumentationProvider) provider).hasDocumentationFor(element, originalElement); + } + else { + final List urls = provider.getUrlFor(element, originalElement); + enabled = urls != null && !urls.isEmpty(); + } if (editor != null) { presentation.setEnabled(enabled); if (event.getPlace().equals(ActionPlaces.MAIN_MENU)) { diff --git a/plugins/android/src/org/jetbrains/android/AndroidDocumentationProvider.java b/plugins/android/src/org/jetbrains/android/AndroidDocumentationProvider.java index 9bea6f6dba86..c1957c5a622f 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidDocumentationProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidDocumentationProvider.java @@ -18,6 +18,7 @@ package org.jetbrains.android; import com.android.sdklib.SdkConstants; import com.intellij.codeInsight.javadoc.JavaDocExternalFilter; import com.intellij.facet.ProjectFacetManager; +import com.intellij.lang.documentation.CompositeDocumentationProvider; import com.intellij.lang.documentation.DocumentationProvider; import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.lang.java.JavaDocumentationProvider; @@ -79,6 +80,11 @@ public class AndroidDocumentationProvider implements DocumentationProvider, Exte null; } + @Override + public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) { + return false; + } + private static boolean isMyContext(@NotNull final PsiElement element, @NotNull final Project project) { if (element instanceof PsiClass) { return ApplicationManager.getApplication().runReadAction(new Computable() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java index e8c77a325055..2f0b8c188fa4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.javadoc.JavaDocUtil; import com.intellij.lang.CodeDocumentationAwareCommenter; import com.intellij.lang.LanguageCommenters; import com.intellij.lang.documentation.CodeDocumentationProvider; +import com.intellij.lang.documentation.CompositeDocumentationProvider; import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.lang.java.JavaDocumentationProvider; import com.intellij.openapi.project.Project; @@ -292,6 +293,11 @@ public class GroovyDocumentationProvider implements CodeDocumentationProvider, E return JavaDocumentationProvider.fetchExternalJavadoc(element, project, docUrls); } + @Override + public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) { + return CompositeDocumentationProvider.hasUrlsFor(this, element, originalElement); + } + private static String getMethodCandidateInfo(GrReferenceExpression expr) { final GroovyResolveResult[] candidates = expr.multiResolve(false); final String text = expr.getText();