1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Linq ;
5+ using MonoGame . Utilities ;
6+
7+ namespace Myra . Graphics2D . UI . File
8+ {
9+ // === Platform dependent code for FileDialog class
10+ public partial class FileDialog
11+ {
12+ /// <summary>
13+ /// Platform specific code for <see cref="FileDialog"/>
14+ /// </summary>
15+ protected static class Platform
16+ {
17+ private static IReadOnlyList < string > _userPaths ;
18+ /// <summary>
19+ /// Return a predetermined list of directories under the user's HOME folder, depending on OS.
20+ /// </summary>
21+ public static IReadOnlyList < string > SystemUserPlacePaths
22+ {
23+ get
24+ {
25+ if ( _userPaths == null )
26+ {
27+ switch ( CurrentPlatform . OS )
28+ {
29+ case OS . Windows :
30+ _userPaths = _GetWindowsPlaces ( ) ;
31+ break ;
32+ case OS . MacOSX :
33+ _userPaths = _GetWindowsPlaces ( ) ; //TODO Mac/OSX specific - using old windows code for now!
34+ break ;
35+ case OS . Linux :
36+ _userPaths = _GetLinuxPlaces ( ) ;
37+ break ;
38+ default :
39+ throw new PlatformNotSupportedException ( CurrentPlatform . OS . ToString ( ) ) ;
40+ }
41+ }
42+ return _userPaths ;
43+ }
44+ }
45+
46+ private static string _homePath = string . Empty ;
47+ public static string UserHomePath
48+ {
49+ get
50+ {
51+ if ( string . IsNullOrEmpty ( _homePath ) )
52+ {
53+ _homePath = ( Environment . OSVersion . Platform == PlatformID . Unix || Environment . OSVersion . Platform == PlatformID . MacOSX )
54+ ? Environment . GetEnvironmentVariable ( "HOME" )
55+ : Environment . ExpandEnvironmentVariables ( "%HOMEDRIVE%%HOMEPATH%" ) ;
56+ }
57+ return _homePath ;
58+ }
59+ }
60+
61+ private static string _osUser = string . Empty ;
62+ /// <summary>
63+ /// Returns the name of the user logged into the system
64+ /// </summary>
65+ public static string SystemUsername
66+ {
67+ get
68+ {
69+ if ( string . IsNullOrEmpty ( _osUser ) )
70+ _osUser = UserHomePath . Split ( new char [ ] { Path . DirectorySeparatorChar } , StringSplitOptions . RemoveEmptyEntries ) . Last ( ) ;
71+ return _osUser ;
72+ }
73+ }
74+
75+ /// <summary>
76+ /// Append <see cref="Location"/> directories under the user's HOME directory.
77+ /// </summary>
78+ /// <param name="placeList">What folders to try to add relative to the HOME directory.</param>
79+ public static void AppendUserPlacesOnSystem ( List < Location > appendResult , IReadOnlyList < string > placeList )
80+ {
81+ ThrowIfNull ( appendResult ) ;
82+
83+ string homePath = UserHomePath ;
84+ var places = new List < string > ( placeList . Count ) ;
85+
86+ // Special label for HOME directory
87+ if ( CurrentPlatform . OS != OS . Windows )
88+ appendResult . Add ( new Location ( "Home" , SystemUsername , homePath , false ) ) ;
89+ else
90+ places . Add ( homePath ) ;
91+
92+ foreach ( string folder in placeList )
93+ {
94+ places . Add ( Path . Combine ( homePath , folder ) ) ;
95+ }
96+
97+ foreach ( string path in places )
98+ {
99+ if ( ! Directory . Exists ( path ) )
100+ continue ;
101+
102+ //TODO check permissions for those places here
103+ //Location.TryAccess(path);
104+
105+ appendResult . Add ( new Location ( string . Empty , Path . GetFileName ( path ) , path , false ) ) ;
106+ }
107+ }
108+
109+ /// <summary>
110+ /// Append a list of <see cref="Location"/> for devices we can visit, depending on platform.
111+ /// </summary>
112+ /// <exception cref="PlatformNotSupportedException"></exception>
113+ public static void AppendDrivesOnSystem ( List < Location > appendResult )
114+ {
115+ ThrowIfNull ( appendResult ) ;
116+
117+ switch ( CurrentPlatform . OS )
118+ {
119+ case OS . Windows :
120+ _GetWindowsDrives ( appendResult ) ;
121+ return ;
122+ case OS . MacOSX :
123+ _GetWindowsDrives ( appendResult ) ; //TODO Mac/OSX specific - using old windows code for now!
124+ return ;
125+ case OS . Linux :
126+ _GetLinuxDrives ( appendResult ) ;
127+ return ;
128+ default :
129+ throw new PlatformNotSupportedException ( CurrentPlatform . OS . ToString ( ) ) ;
130+ }
131+ }
132+
133+ #region Windows
134+ private static void _GetWindowsDrives ( List < Location > appendResult )
135+ {
136+ foreach ( DriveInfo d in DriveInfo . GetDrives ( ) )
137+ {
138+ switch ( d . DriveType )
139+ {
140+ case DriveType . CDRom : //Acceptable
141+ case DriveType . Fixed :
142+ case DriveType . Network :
143+ case DriveType . Removable :
144+ break ;
145+ case DriveType . NoRootDirectory : //Skip These
146+ case DriveType . Unknown :
147+ case DriveType . Ram :
148+ default :
149+ continue ;
150+ }
151+
152+ try
153+ {
154+ string vol = string . Empty ;
155+ if ( ! string . IsNullOrEmpty ( d . VolumeLabel ) && d . VolumeLabel != d . RootDirectory . FullName )
156+ vol = d . VolumeLabel ;
157+
158+ appendResult . Add ( new Location ( vol , d . Name , d . RootDirectory . FullName , true ) ) ;
159+ }
160+ catch ( Exception )
161+ {
162+ }
163+ }
164+ }
165+ private static IReadOnlyList < string > _GetWindowsPlaces ( )
166+ {
167+ return new [ ] { "Desktop" , "Downloads" , "Documents" , "Pictures" } ;
168+ }
169+ #endregion Windows
170+ #region Linux
171+ private static void _GetLinuxDrives ( List < Location > appendResult )
172+ {
173+ string tmpFileName = Path . GetTempFileName ( ) ;
174+ string [ ] bashResult ;
175+ try
176+ {
177+ // The all caps words after o directly corelate to output string indexes. Some strings may return empty.
178+ BashRunner . Run ( $ "lsblk -no TYPE,NAME,LABEL,MOUNTPOINT --raw > { tmpFileName } ") ;
179+ bashResult = System . IO . File . ReadAllLines ( tmpFileName ) ;
180+ }
181+ finally
182+ {
183+ System . IO . File . Delete ( tmpFileName ) ;
184+ }
185+
186+ const string RawSpace = @"\x20" ;
187+ foreach ( string deviceLine in bashResult )
188+ {
189+ string [ ] splits = deviceLine . Split ( new [ ] { ' ' } , StringSplitOptions . None ) ;
190+
191+ if ( splits [ 0 ] != "part" ) //TYPE
192+ continue ; // We only want partitioned file systems.
193+
194+ splits [ 2 ] = splits [ 2 ] . Replace ( RawSpace , " " ) ;
195+ if ( string . Equals ( splits [ 2 ] , "System Reserved" ) ) //LABEL
196+ continue ;
197+
198+ if ( string . IsNullOrEmpty ( splits [ 3 ] ) || string . Equals ( splits [ 3 ] , "/boot" ) )
199+ continue ;
200+ splits [ 3 ] = splits [ 3 ] . Replace ( RawSpace , " " ) ; ; //MOUNTPOINT
201+
202+ appendResult . Add ( new Location ( splits [ 1 ] , splits [ 2 ] , splits [ 3 ] , true ) ) ;
203+ }
204+ }
205+ private static IReadOnlyList < string > _GetLinuxPlaces ( )
206+ {
207+ return new [ ] { "Desktop" , "Downloads" , "Documents" , "Pictures" } ;
208+ }
209+ #endregion Linux
210+
211+ private static void ThrowIfNull ( List < Location > obj )
212+ {
213+ if ( obj == null )
214+ throw new NullReferenceException ( ) ;
215+ }
216+ }
217+ }
218+ }
0 commit comments