6
6
package io .flutter .samples ;
7
7
8
8
import com .google .common .annotations .VisibleForTesting ;
9
+ import com .intellij .ide .BrowserUtil ;
9
10
import com .intellij .openapi .application .ApplicationManager ;
10
11
import com .intellij .openapi .editor .Document ;
11
12
import com .intellij .openapi .editor .Editor ;
13
+ import com .intellij .openapi .editor .colors .EditorColors ;
12
14
import com .intellij .openapi .fileEditor .FileEditor ;
13
15
import com .intellij .openapi .fileEditor .TextEditor ;
14
- import com .intellij .openapi .project .DumbAware ;
15
16
import com .intellij .openapi .project .Project ;
16
17
import com .intellij .openapi .util .Computable ;
17
- import com .intellij .openapi .util .Key ;
18
18
import com .intellij .openapi .vfs .VirtualFile ;
19
19
import com .intellij .psi .PsiDocumentManager ;
20
20
import com .intellij .psi .PsiFile ;
21
21
import com .intellij .psi .util .PsiTreeUtil ;
22
22
import com .intellij .ui .EditorNotificationPanel ;
23
- import com .intellij .ui .EditorNotifications ;
23
+ import com .intellij .ui .EditorNotificationProvider ;
24
+ import com .intellij .ui .HyperlinkLabel ;
24
25
import com .jetbrains .lang .dart .psi .DartClass ;
26
+ import icons .FlutterIcons ;
25
27
import io .flutter .sdk .FlutterSdk ;
26
28
import org .jetbrains .annotations .NotNull ;
27
29
import org .jetbrains .annotations .Nullable ;
28
30
31
+ import javax .swing .*;
29
32
import java .util .ArrayList ;
30
33
import java .util .Collections ;
31
34
import java .util .List ;
35
+ import java .util .function .Function ;
32
36
import java .util .regex .Pattern ;
33
37
34
- public class FlutterSampleNotificationProvider extends EditorNotifications .Provider <EditorNotificationPanel > implements DumbAware {
35
- private static final Key <EditorNotificationPanel > KEY = Key .create ("flutter.sample" );
36
-
38
+ public class FlutterSampleNotificationProvider implements EditorNotificationProvider {
37
39
@ NotNull final Project project ;
38
40
39
41
public FlutterSampleNotificationProvider (@ NotNull Project project ) {
40
42
this .project = project ;
41
43
}
42
44
43
- @ NotNull
44
- @ Override
45
- public Key <EditorNotificationPanel > getKey () {
46
- return KEY ;
47
- }
48
-
49
45
@ Nullable
50
46
@ Override
51
- public EditorNotificationPanel createNotificationPanel (@ NotNull VirtualFile file ,
52
- @ NotNull FileEditor fileEditor ,
53
- @ NotNull Project project ) {
54
- if (!(fileEditor instanceof TextEditor textEditor )) {
55
- return null ;
56
- }
57
-
47
+ public Function <? super @ NotNull FileEditor , ? extends @ Nullable JComponent > collectNotificationData (@ NotNull Project project ,
48
+ @ NotNull VirtualFile file ) {
58
49
final FlutterSdk sdk = FlutterSdk .getFlutterSdk (project );
59
50
if (sdk == null ) {
60
51
return null ;
61
52
}
62
53
63
54
final String flutterPackagePath = sdk .getHomePath () + "/packages/flutter/lib/src/" ;
64
- final String filePath = file .getPath ();
65
55
66
56
// Only show for files in the flutter sdk.
57
+ final String filePath = file .getPath ();
67
58
if (!filePath .startsWith (flutterPackagePath )) {
68
59
return null ;
69
60
}
70
61
62
+ return fileEditor -> createPanelForSamples (fileEditor , project , file , filePath , sdk , flutterPackagePath );
63
+ }
64
+
65
+ @ Nullable
66
+ private EditorNotificationPanel createPanelForSamples (@ NotNull FileEditor fileEditor ,
67
+ @ NotNull Project project ,
68
+ @ NotNull VirtualFile file ,
69
+ @ NotNull String filePath ,
70
+ @ NotNull FlutterSdk sdk ,
71
+ @ NotNull String flutterPackagePath ) {
72
+ if (!(fileEditor instanceof TextEditor textEditor )) {
73
+ return null ;
74
+ }
75
+
71
76
final Editor editor = textEditor .getEditor ();
72
77
final Document document = editor .getDocument ();
78
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager .getInstance (project );
79
+ if (psiDocumentManager == null ) {
80
+ return null ;
81
+ }
73
82
74
- final PsiFile psiFile = PsiDocumentManager . getInstance ( project ) .getPsiFile (document );
83
+ final PsiFile psiFile = psiDocumentManager .getPsiFile (document );
75
84
if (psiFile == null || !psiFile .isValid ()) {
76
85
return null ;
77
86
}
@@ -86,7 +95,7 @@ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file
86
95
return samples .isEmpty () ? null : new FlutterSampleActionsPanel (samples );
87
96
}
88
97
89
- private List <FlutterSample > getSamplesFromDoc (String flutterPackagePath , Document document , String filePath ) {
98
+ private List <FlutterSample > getSamplesFromDoc (@ NotNull String flutterPackagePath , @ NotNull Document document , @ NotNull String filePath ) {
90
99
final List <FlutterSample > samples = new ArrayList <>();
91
100
92
101
// Find all candidate class definitions.
@@ -111,7 +120,8 @@ private List<FlutterSample> getSamplesFromDoc(String flutterPackagePath, Documen
111
120
try {
112
121
// Context: https://github.com/flutter/flutter-intellij/issues/5634
113
122
dartdoc = DartDocumentUtils .getDartdocFor (document , declaration );
114
- }catch (IndexOutOfBoundsException e ) {
123
+ }
124
+ catch (IndexOutOfBoundsException e ) {
115
125
// ignore
116
126
}
117
127
if (dartdoc != null && containsDartdocFlutterSample (dartdoc )) {
@@ -127,7 +137,6 @@ private List<FlutterSample> getSamplesFromDoc(String flutterPackagePath, Documen
127
137
}
128
138
}
129
139
}
130
-
131
140
return samples ;
132
141
}
133
142
@@ -153,3 +162,28 @@ public static boolean containsDartdocFlutterSample(@NotNull List<String> lines)
153
162
return false ;
154
163
}
155
164
}
165
+
166
+ class FlutterSampleActionsPanel extends EditorNotificationPanel {
167
+ FlutterSampleActionsPanel (@ NotNull List <FlutterSample > samples ) {
168
+ super (EditorColors .GUTTER_BACKGROUND );
169
+
170
+ icon (FlutterIcons .Flutter );
171
+ text ("View hosted code sample" );
172
+
173
+ for (int i = 0 ; i < samples .size (); i ++) {
174
+ if (i != 0 ) {
175
+ myLinksPanel .add (new JSeparator (SwingConstants .VERTICAL ));
176
+ }
177
+
178
+ final FlutterSample sample = samples .get (i );
179
+
180
+ final HyperlinkLabel label = createActionLabel (sample .getClassName (), () -> browseTo (sample ));
181
+ label .setToolTipText (sample .getHostedDocsUrl ());
182
+ }
183
+ }
184
+
185
+ private void browseTo (FlutterSample sample ) {
186
+ BrowserUtil .browse (sample .getHostedDocsUrl ());
187
+ }
188
+ }
189
+
0 commit comments