diff --git a/flutter-idea/src/io/flutter/samples/FlutterSampleActionsPanel.java b/flutter-idea/src/io/flutter/samples/FlutterSampleActionsPanel.java deleted file mode 100644 index 9fdd4b0d2c..0000000000 --- a/flutter-idea/src/io/flutter/samples/FlutterSampleActionsPanel.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2019 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -package io.flutter.samples; - -import com.intellij.ide.BrowserUtil; -import com.intellij.openapi.editor.colors.EditorColors; -import com.intellij.ui.EditorNotificationPanel; -import com.intellij.ui.HyperlinkLabel; -import icons.FlutterIcons; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.util.List; - -public class FlutterSampleActionsPanel extends EditorNotificationPanel { - FlutterSampleActionsPanel(@NotNull List samples) { - super(EditorColors.GUTTER_BACKGROUND); - - icon(FlutterIcons.Flutter); - text("View hosted code sample"); - - for (int i = 0; i < samples.size(); i++) { - if (i != 0) { - myLinksPanel.add(new JSeparator(SwingConstants.VERTICAL)); - } - - final FlutterSample sample = samples.get(i); - - final HyperlinkLabel label = createActionLabel(sample.getClassName(), () -> browseTo(sample)); - label.setToolTipText(sample.getHostedDocsUrl()); - } - } - - private void browseTo(FlutterSample sample) { - BrowserUtil.browse(sample.getHostedDocsUrl()); - } -} diff --git a/flutter-idea/src/io/flutter/samples/FlutterSampleNotificationProvider.java b/flutter-idea/src/io/flutter/samples/FlutterSampleNotificationProvider.java index b7cf80272f..7b4f0a602c 100644 --- a/flutter-idea/src/io/flutter/samples/FlutterSampleNotificationProvider.java +++ b/flutter-idea/src/io/flutter/samples/FlutterSampleNotificationProvider.java @@ -6,72 +6,81 @@ package io.flutter.samples; import com.google.common.annotations.VisibleForTesting; +import com.intellij.ide.BrowserUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.ui.EditorNotificationPanel; -import com.intellij.ui.EditorNotifications; +import com.intellij.ui.EditorNotificationProvider; +import com.intellij.ui.HyperlinkLabel; import com.jetbrains.lang.dart.psi.DartClass; +import icons.FlutterIcons; import io.flutter.sdk.FlutterSdk; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Function; import java.util.regex.Pattern; -public class FlutterSampleNotificationProvider extends EditorNotifications.Provider implements DumbAware { - private static final Key KEY = Key.create("flutter.sample"); - +public class FlutterSampleNotificationProvider implements EditorNotificationProvider { @NotNull final Project project; public FlutterSampleNotificationProvider(@NotNull Project project) { this.project = project; } - @NotNull - @Override - public Key getKey() { - return KEY; - } - @Nullable @Override - public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, - @NotNull FileEditor fileEditor, - @NotNull Project project) { - if (!(fileEditor instanceof TextEditor textEditor)) { - return null; - } - + public Function collectNotificationData(@NotNull Project project, + @NotNull VirtualFile file) { final FlutterSdk sdk = FlutterSdk.getFlutterSdk(project); if (sdk == null) { return null; } final String flutterPackagePath = sdk.getHomePath() + "/packages/flutter/lib/src/"; - final String filePath = file.getPath(); // Only show for files in the flutter sdk. + final String filePath = file.getPath(); if (!filePath.startsWith(flutterPackagePath)) { return null; } + return fileEditor -> createPanelForSamples(fileEditor, project, file, filePath, sdk, flutterPackagePath); + } + + @Nullable + private EditorNotificationPanel createPanelForSamples(@NotNull FileEditor fileEditor, + @NotNull Project project, + @NotNull VirtualFile file, + @NotNull String filePath, + @NotNull FlutterSdk sdk, + @NotNull String flutterPackagePath) { + if (!(fileEditor instanceof TextEditor textEditor)) { + return null; + } + final Editor editor = textEditor.getEditor(); final Document document = editor.getDocument(); + final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + if (psiDocumentManager == null) { + return null; + } - final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + final PsiFile psiFile = psiDocumentManager.getPsiFile(document); if (psiFile == null || !psiFile.isValid()) { return null; } @@ -79,14 +88,17 @@ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file // Run the code to query the document in a read action. final List samples = ApplicationManager.getApplication(). runReadAction((Computable>)() -> { - //noinspection CodeBlock2Expr return getSamplesFromDoc(flutterPackagePath, document, filePath); }); - return samples.isEmpty() ? null : new FlutterSampleActionsPanel(samples); + if (samples != null && !samples.isEmpty()) { + return new FlutterSampleActionsPanel(samples); + } + return null; } - private List getSamplesFromDoc(String flutterPackagePath, Document document, String filePath) { + @NotNull + private List getSamplesFromDoc(@NotNull String flutterPackagePath, @NotNull Document document, @NotNull String filePath) { final List samples = new ArrayList<>(); // Find all candidate class definitions. @@ -111,7 +123,8 @@ private List getSamplesFromDoc(String flutterPackagePath, Documen try { // Context: https://github.com/flutter/flutter-intellij/issues/5634 dartdoc = DartDocumentUtils.getDartdocFor(document, declaration); - }catch (IndexOutOfBoundsException e) { + } + catch (IndexOutOfBoundsException e) { // ignore } if (dartdoc != null && containsDartdocFlutterSample(dartdoc)) { @@ -127,7 +140,6 @@ private List getSamplesFromDoc(String flutterPackagePath, Documen } } } - return samples; } @@ -153,3 +165,28 @@ public static boolean containsDartdocFlutterSample(@NotNull List lines) return false; } } + +class FlutterSampleActionsPanel extends EditorNotificationPanel { + FlutterSampleActionsPanel(@NotNull List samples) { + super(EditorColors.GUTTER_BACKGROUND); + + icon(FlutterIcons.Flutter); + text("View example on flutter.dev"); + + for (int i = 0; i < samples.size(); i++) { + if (i != 0) { + myLinksPanel.add(new JSeparator(SwingConstants.VERTICAL)); + } + + final FlutterSample sample = samples.get(i); + + final HyperlinkLabel label = createActionLabel(sample.getClassName(), () -> browseTo(sample)); + label.setToolTipText(sample.getHostedDocsUrl()); + } + } + + private void browseTo(FlutterSample sample) { + BrowserUtil.browse(sample.getHostedDocsUrl()); + } +} +