4
4
5
5
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart' ;
6
6
import 'package:flutter/foundation.dart' show visibleForTesting;
7
- import 'package:flutter/services.dart' ;
8
7
9
- const MethodChannel _channel =
10
- MethodChannel ('plugins.flutter.dev/file_selector_linux' );
11
-
12
- const String _typeGroupLabelKey = 'label' ;
13
- const String _typeGroupExtensionsKey = 'extensions' ;
14
- const String _typeGroupMimeTypesKey = 'mimeTypes' ;
15
-
16
- const String _openFileMethod = 'openFile' ;
17
- const String _getSavePathMethod = 'getSavePath' ;
18
- const String _getDirectoryPathMethod = 'getDirectoryPath' ;
19
-
20
- const String _acceptedTypeGroupsKey = 'acceptedTypeGroups' ;
21
- const String _confirmButtonTextKey = 'confirmButtonText' ;
22
- const String _initialDirectoryKey = 'initialDirectory' ;
23
- const String _multipleKey = 'multiple' ;
24
- const String _suggestedNameKey = 'suggestedName' ;
8
+ import 'src/messages.g.dart' ;
25
9
26
10
/// An implementation of [FileSelectorPlatform] for Linux.
27
11
class FileSelectorLinux extends FileSelectorPlatform {
28
- /// The MethodChannel that is being used by this implementation of the plugin.
29
- @visibleForTesting
30
- MethodChannel get channel => _channel;
12
+ /// Creates a new plugin implementation instance.
13
+ FileSelectorLinux ({
14
+ @visibleForTesting FileSelectorApi ? api,
15
+ }) : _hostApi = api ?? FileSelectorApi ();
16
+
17
+ final FileSelectorApi _hostApi;
31
18
32
19
/// Registers the Linux implementation.
33
20
static void registerWith () {
@@ -40,19 +27,16 @@ class FileSelectorLinux extends FileSelectorPlatform {
40
27
String ? initialDirectory,
41
28
String ? confirmButtonText,
42
29
}) async {
43
- final List <Map <String , Object >> serializedTypeGroups =
44
- _serializeTypeGroups (acceptedTypeGroups);
45
- final List <String >? path = await _channel.invokeListMethod <String >(
46
- _openFileMethod,
47
- < String , dynamic > {
48
- if (serializedTypeGroups.isNotEmpty)
49
- _acceptedTypeGroupsKey: serializedTypeGroups,
50
- 'initialDirectory' : initialDirectory,
51
- _confirmButtonTextKey: confirmButtonText,
52
- _multipleKey: false ,
53
- },
54
- );
55
- return path == null ? null : XFile (path.first);
30
+ final List <String > paths = await _hostApi.showFileChooser (
31
+ PlatformFileChooserActionType .open,
32
+ PlatformFileChooserOptions (
33
+ allowedFileTypes:
34
+ _platformTypeGroupsFromXTypeGroups (acceptedTypeGroups),
35
+ currentFolderPath: initialDirectory,
36
+ acceptButtonLabel: confirmButtonText,
37
+ selectMultiple: false ,
38
+ ));
39
+ return paths.isEmpty ? null : XFile (paths.first);
56
40
}
57
41
58
42
@override
@@ -61,19 +45,16 @@ class FileSelectorLinux extends FileSelectorPlatform {
61
45
String ? initialDirectory,
62
46
String ? confirmButtonText,
63
47
}) async {
64
- final List <Map <String , Object >> serializedTypeGroups =
65
- _serializeTypeGroups (acceptedTypeGroups);
66
- final List <String >? pathList = await _channel.invokeListMethod <String >(
67
- _openFileMethod,
68
- < String , dynamic > {
69
- if (serializedTypeGroups.isNotEmpty)
70
- _acceptedTypeGroupsKey: serializedTypeGroups,
71
- _initialDirectoryKey: initialDirectory,
72
- _confirmButtonTextKey: confirmButtonText,
73
- _multipleKey: true ,
74
- },
75
- );
76
- return pathList? .map ((String path) => XFile (path)).toList () ?? < XFile > [];
48
+ final List <String > paths = await _hostApi.showFileChooser (
49
+ PlatformFileChooserActionType .open,
50
+ PlatformFileChooserOptions (
51
+ allowedFileTypes:
52
+ _platformTypeGroupsFromXTypeGroups (acceptedTypeGroups),
53
+ currentFolderPath: initialDirectory,
54
+ acceptButtonLabel: confirmButtonText,
55
+ selectMultiple: true ,
56
+ ));
57
+ return paths.map ((String path) => XFile (path)).toList ();
77
58
}
78
59
79
60
@override
@@ -98,78 +79,76 @@ class FileSelectorLinux extends FileSelectorPlatform {
98
79
List <XTypeGroup >? acceptedTypeGroups,
99
80
SaveDialogOptions options = const SaveDialogOptions (),
100
81
}) async {
101
- final List <Map <String , Object >> serializedTypeGroups =
102
- _serializeTypeGroups (acceptedTypeGroups);
103
82
// TODO(stuartmorgan): Add the selected type group here and return it. See
104
83
// https://github.com/flutter/flutter/issues/107093
105
- final String ? path = await _channel.invokeMethod <String >(
106
- _getSavePathMethod,
107
- < String , dynamic > {
108
- if (serializedTypeGroups.isNotEmpty)
109
- _acceptedTypeGroupsKey: serializedTypeGroups,
110
- _initialDirectoryKey: options.initialDirectory,
111
- _suggestedNameKey: options.suggestedName,
112
- _confirmButtonTextKey: options.confirmButtonText,
113
- },
114
- );
115
- return path == null ? null : FileSaveLocation (path);
84
+ final List <String > paths = await _hostApi.showFileChooser (
85
+ PlatformFileChooserActionType .save,
86
+ PlatformFileChooserOptions (
87
+ allowedFileTypes:
88
+ _platformTypeGroupsFromXTypeGroups (acceptedTypeGroups),
89
+ currentFolderPath: options.initialDirectory,
90
+ currentName: options.suggestedName,
91
+ acceptButtonLabel: options.confirmButtonText,
92
+ ));
93
+ return paths.isEmpty ? null : FileSaveLocation (paths.first);
116
94
}
117
95
118
96
@override
119
97
Future <String ?> getDirectoryPath ({
120
98
String ? initialDirectory,
121
99
String ? confirmButtonText,
122
100
}) async {
123
- final List <String >? path = await _channel
124
- .invokeListMethod <String >(_getDirectoryPathMethod, < String , dynamic > {
125
- _initialDirectoryKey: initialDirectory,
126
- _confirmButtonTextKey: confirmButtonText,
127
- });
128
- return path? .first;
101
+ final List <String > paths = await _hostApi.showFileChooser (
102
+ PlatformFileChooserActionType .chooseDirectory,
103
+ PlatformFileChooserOptions (
104
+ currentFolderPath: initialDirectory,
105
+ acceptButtonLabel: confirmButtonText,
106
+ selectMultiple: false ,
107
+ ));
108
+ return paths.isEmpty ? null : paths.first;
129
109
}
130
110
131
111
@override
132
112
Future <List <String >> getDirectoryPaths ({
133
113
String ? initialDirectory,
134
114
String ? confirmButtonText,
135
115
}) async {
136
- final List < String > ? pathList = await _channel
137
- . invokeListMethod < String >(_getDirectoryPathMethod, < String , dynamic > {
138
- _initialDirectoryKey : initialDirectory,
139
- _confirmButtonTextKey : confirmButtonText ,
140
- _multipleKey : true ,
141
- });
142
- return pathList ?? < String > [] ;
116
+ return _hostApi. showFileChooser (
117
+ PlatformFileChooserActionType .chooseDirectory,
118
+ PlatformFileChooserOptions (
119
+ currentFolderPath : initialDirectory ,
120
+ acceptButtonLabel : confirmButtonText ,
121
+ selectMultiple : true ,
122
+ )) ;
143
123
}
144
124
}
145
125
146
- List <Map <String , Object >> _serializeTypeGroups (List <XTypeGroup >? groups) {
147
- return (groups ?? < XTypeGroup > []).map (_serializeTypeGroup).toList ();
126
+ List <PlatformTypeGroup >? _platformTypeGroupsFromXTypeGroups (
127
+ List <XTypeGroup >? groups) {
128
+ return groups? .map (_platformTypeGroupFromXTypeGroup).toList ();
148
129
}
149
130
150
- Map <String , Object > _serializeTypeGroup (XTypeGroup group) {
151
- final Map <String , Object > serialization = < String , Object > {
152
- _typeGroupLabelKey: group.label ?? '' ,
153
- };
131
+ PlatformTypeGroup _platformTypeGroupFromXTypeGroup (XTypeGroup group) {
132
+ final String label = group.label ?? '' ;
154
133
if (group.allowsAny) {
155
- serialization[_typeGroupExtensionsKey] = < String > ['*' ];
156
- } else {
157
- if ((group.extensions? .isEmpty ?? true ) &&
158
- (group.mimeTypes? .isEmpty ?? true )) {
159
- throw ArgumentError ('Provided type group $group does not allow '
160
- 'all files, but does not set any of the Linux-supported filter '
161
- 'categories. "extensions" or "mimeTypes" must be non-empty for Linux '
162
- 'if anything is non-empty.' );
163
- }
164
- if (group.extensions? .isNotEmpty ?? false ) {
165
- serialization[_typeGroupExtensionsKey] = group.extensions
134
+ return PlatformTypeGroup (
135
+ label: label,
136
+ extensions: < String > ['*' ],
137
+ );
138
+ }
139
+ if ((group.extensions? .isEmpty ?? true ) &&
140
+ (group.mimeTypes? .isEmpty ?? true )) {
141
+ throw ArgumentError ('Provided type group $group does not allow '
142
+ 'all files, but does not set any of the Linux-supported filter '
143
+ 'categories. "extensions" or "mimeTypes" must be non-empty for Linux '
144
+ 'if anything is non-empty.' );
145
+ }
146
+ return PlatformTypeGroup (
147
+ label: label,
148
+ // Covert to GtkFileFilter's *.<extension> format.
149
+ extensions: group.extensions
166
150
? .map ((String extension ) => '*.$extension ' )
167
151
.toList () ??
168
- < String > [];
169
- }
170
- if (group.mimeTypes? .isNotEmpty ?? false ) {
171
- serialization[_typeGroupMimeTypesKey] = group.mimeTypes ?? < String > [];
172
- }
173
- }
174
- return serialization;
152
+ < String > [],
153
+ mimeTypes: group.mimeTypes ?? < String > []);
175
154
}
0 commit comments