1- using Flow . Launcher . Infrastructure . Logger ;
2- using Flow . Launcher . Infrastructure . UserSettings ;
3- using Flow . Launcher . Plugin ;
4- using Flow . Launcher . Plugin . SharedCommands ;
5- using System ;
1+ using System ;
62using System . Collections . Generic ;
73using System . IO ;
84using System . Linq ;
95using System . Windows ;
106using System . Windows . Forms ;
11- using Flow . Launcher . Core . Resource ;
127using CommunityToolkit . Mvvm . DependencyInjection ;
8+ using Flow . Launcher . Infrastructure . Logger ;
9+ using Flow . Launcher . Infrastructure . UserSettings ;
10+ using Flow . Launcher . Plugin ;
11+ using Flow . Launcher . Plugin . SharedCommands ;
1312
1413namespace Flow . Launcher . Core . ExternalPlugins . Environments
1514{
@@ -43,8 +42,11 @@ internal AbstractPluginEnvironment(List<PluginMetadata> pluginMetadataList, Plug
4342
4443 internal IEnumerable < PluginPair > Setup ( )
4544 {
45+ // If no plugin is using the language, return empty list
4646 if ( ! PluginMetadataList . Any ( o => o . Language . Equals ( Language , StringComparison . OrdinalIgnoreCase ) ) )
47+ {
4748 return new List < PluginPair > ( ) ;
49+ }
4850
4951 if ( ! string . IsNullOrEmpty ( PluginsSettingsFilePath ) && FilesFolders . FileExists ( PluginsSettingsFilePath ) )
5052 {
@@ -56,24 +58,55 @@ internal IEnumerable<PluginPair> Setup()
5658 }
5759
5860 var noRuntimeMessage = string . Format (
59- InternationalizationManager . Instance . GetTranslation ( "runtimePluginInstalledChooseRuntimePrompt" ) ,
61+ API . GetTranslation ( "runtimePluginInstalledChooseRuntimePrompt" ) ,
6062 Language ,
6163 EnvName ,
6264 Environment . NewLine
6365 ) ;
6466 if ( API . ShowMsgBox ( noRuntimeMessage , string . Empty , MessageBoxButton . YesNo ) == MessageBoxResult . No )
6567 {
66- var msg = string . Format ( InternationalizationManager . Instance . GetTranslation ( "runtimePluginChooseRuntimeExecutable" ) , EnvName ) ;
67- string selectedFile ;
68+ var msg = string . Format ( API . GetTranslation ( "runtimePluginChooseRuntimeExecutable" ) , EnvName ) ;
6869
69- selectedFile = GetFileFromDialog ( msg , FileDialogFilter ) ;
70+ var selectedFile = GetFileFromDialog ( msg , FileDialogFilter ) ;
7071
7172 if ( ! string . IsNullOrEmpty ( selectedFile ) )
73+ {
7274 PluginsSettingsFilePath = selectedFile ;
73-
75+ }
7476 // Nothing selected because user pressed cancel from the file dialog window
75- if ( string . IsNullOrEmpty ( selectedFile ) )
76- InstallEnvironment ( ) ;
77+ else
78+ {
79+ var forceDownloadMessage = string . Format (
80+ API . GetTranslation ( "runtimeExecutableInvalidChooseDownload" ) ,
81+ Language ,
82+ EnvName ,
83+ Environment . NewLine
84+ ) ;
85+
86+ // Let users select valid path or choose to download
87+ while ( string . IsNullOrEmpty ( selectedFile ) )
88+ {
89+ if ( API . ShowMsgBox ( forceDownloadMessage , string . Empty , MessageBoxButton . YesNo ) == MessageBoxResult . Yes )
90+ {
91+ // Continue select file
92+ selectedFile = GetFileFromDialog ( msg , FileDialogFilter ) ;
93+ }
94+ else
95+ {
96+ // User selected no, break the loop
97+ break ;
98+ }
99+ }
100+
101+ if ( ! string . IsNullOrEmpty ( selectedFile ) )
102+ {
103+ PluginsSettingsFilePath = selectedFile ;
104+ }
105+ else
106+ {
107+ InstallEnvironment ( ) ;
108+ }
109+ }
77110 }
78111 else
79112 {
@@ -86,7 +119,7 @@ internal IEnumerable<PluginPair> Setup()
86119 }
87120 else
88121 {
89- API . ShowMsgBox ( string . Format ( InternationalizationManager . Instance . GetTranslation ( "runtimePluginUnableToSetExecutablePath" ) , Language ) ) ;
122+ API . ShowMsgBox ( string . Format ( API . GetTranslation ( "runtimePluginUnableToSetExecutablePath" ) , Language ) ) ;
90123 Log . Error ( "PluginsLoader" ,
91124 $ "Not able to successfully set { EnvName } path, setting's plugin executable path variable is still an empty string.",
92125 $ "{ Language } Environment") ;
@@ -99,13 +132,11 @@ internal IEnumerable<PluginPair> Setup()
99132
100133 private void EnsureLatestInstalled ( string expectedPath , string currentPath , string installedDirPath )
101134 {
102- if ( expectedPath == currentPath )
103- return ;
135+ if ( expectedPath == currentPath ) return ;
104136
105137 FilesFolders . RemoveFolderIfExists ( installedDirPath , ( s ) => API . ShowMsgBox ( s ) ) ;
106138
107139 InstallEnvironment ( ) ;
108-
109140 }
110141
111142 internal abstract PluginPair CreatePluginPair ( string filePath , PluginMetadata metadata ) ;
@@ -126,7 +157,7 @@ private IEnumerable<PluginPair> SetPathForPluginPairs(string filePath, string la
126157 return pluginPairs ;
127158 }
128159
129- private string GetFileFromDialog ( string title , string filter = "" )
160+ private static string GetFileFromDialog ( string title , string filter = "" )
130161 {
131162 var dlg = new OpenFileDialog
132163 {
@@ -140,7 +171,6 @@ private string GetFileFromDialog(string title, string filter = "")
140171
141172 var result = dlg . ShowDialog ( ) ;
142173 return result == DialogResult . OK ? dlg . FileName : string . Empty ;
143-
144174 }
145175
146176 /// <summary>
@@ -183,31 +213,33 @@ public static void PreStartPluginExecutablePathUpdate(Settings settings)
183213 else
184214 {
185215 if ( IsUsingPortablePath ( settings . PluginSettings . PythonExecutablePath , DataLocation . PythonEnvironmentName ) )
216+ {
186217 settings . PluginSettings . PythonExecutablePath
187218 = GetUpdatedEnvironmentPath ( settings . PluginSettings . PythonExecutablePath ) ;
219+ }
188220
189221 if ( IsUsingPortablePath ( settings . PluginSettings . NodeExecutablePath , DataLocation . NodeEnvironmentName ) )
222+ {
190223 settings . PluginSettings . NodeExecutablePath
191224 = GetUpdatedEnvironmentPath ( settings . PluginSettings . NodeExecutablePath ) ;
225+ }
192226 }
193227 }
194228
195229 private static bool IsUsingPortablePath ( string filePath , string pluginEnvironmentName )
196230 {
197- if ( string . IsNullOrEmpty ( filePath ) )
198- return false ;
231+ if ( string . IsNullOrEmpty ( filePath ) ) return false ;
199232
200233 // DataLocation.PortableDataPath returns the current portable path, this determines if an out
201234 // of date path is also a portable path.
202- var portableAppEnvLocation = $ "UserData\\ { DataLocation . PluginEnvironments } \\ { pluginEnvironmentName } " ;
235+ var portableAppEnvLocation = Path . Combine ( "UserData" , DataLocation . PluginEnvironments , pluginEnvironmentName ) ;
203236
204237 return filePath . Contains ( portableAppEnvLocation ) ;
205238 }
206239
207240 private static bool IsUsingRoamingPath ( string filePath )
208241 {
209- if ( string . IsNullOrEmpty ( filePath ) )
210- return false ;
242+ if ( string . IsNullOrEmpty ( filePath ) ) return false ;
211243
212244 return filePath . StartsWith ( DataLocation . RoamingDataPath ) ;
213245 }
@@ -217,8 +249,8 @@ private static string GetUpdatedEnvironmentPath(string filePath)
217249 var index = filePath . IndexOf ( DataLocation . PluginEnvironments ) ;
218250
219251 // get the substring after "Environments" because we can not determine it dynamically
220- var ExecutablePathSubstring = filePath . Substring ( index + DataLocation . PluginEnvironments . Count ( ) ) ;
221- return $ "{ DataLocation . PluginEnvironmentsPath } { ExecutablePathSubstring } ";
252+ var executablePathSubstring = filePath [ ( index + DataLocation . PluginEnvironments . Length ) .. ] ;
253+ return $ "{ DataLocation . PluginEnvironmentsPath } { executablePathSubstring } ";
222254 }
223255 }
224256}
0 commit comments