Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit bcadce3

Browse files
author
Juan Ángel Dausa
committed
* Migrate set initial directory.
* Migrate open multiple files. * Migrate windows get save path. * Rename variable and methods, reorder functions and remove unused parameters. * Remove CPP implementation. * Update package version.
1 parent 7d5ff59 commit bcadce3

31 files changed

+1619
-2049
lines changed

packages/file_selector/file_selector_windows/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 0.10.0
22

3+
* Migrate CCP implementation to Dart.
34
* Updates minimum Flutter version to 2.10.
45

56
## 0.9.1+2

packages/file_selector/file_selector_windows/example/windows/flutter/generated_plugins.cmake

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#
44

55
list(APPEND FLUTTER_PLUGIN_LIST
6-
file_selector_windows
76
)
87

98
list(APPEND FLUTTER_FFI_PLUGIN_LIST

packages/file_selector/file_selector_windows/lib/file_selector_windows.dart

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
// found in the LICENSE file.
44

55
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
6-
6+
import 'package:file_selector_windows/src/dart_file_selector_api.dart';
77
import 'src/messages.g.dart';
88

99
/// An implementation of [FileSelectorPlatform] for Windows.
1010
class FileSelectorWindows extends FileSelectorPlatform {
11-
final FileSelectorApi _hostApi = FileSelectorApi();
11+
/// Constructor for filePicker.
12+
FileSelectorWindows([this._filePicker]) {
13+
_filePicker = _filePicker ?? DartFileSelectorAPI();
14+
_internalFilePicker = _filePicker!;
15+
}
16+
17+
late DartFileSelectorAPI _internalFilePicker;
18+
late DartFileSelectorAPI? _filePicker;
1219

1320
/// Registers the Windows implementation.
14-
static void registerWith() {
15-
FileSelectorPlatform.instance = FileSelectorWindows();
21+
static void registerWith([DartFileSelectorAPI? filePicker]) {
22+
FileSelectorPlatform.instance = FileSelectorWindows(filePicker);
1623
}
1724

1825
@override
@@ -21,15 +28,15 @@ class FileSelectorWindows extends FileSelectorPlatform {
2128
String? initialDirectory,
2229
String? confirmButtonText,
2330
}) async {
24-
final List<String?> paths = await _hostApi.showOpenDialog(
25-
SelectionOptions(
31+
final List<String> paths = _internalFilePicker.getFiles(
32+
selectionOptions: SelectionOptions(
2633
allowMultiple: false,
2734
selectFolders: false,
2835
allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups),
2936
),
30-
initialDirectory,
31-
confirmButtonText);
32-
return paths.isEmpty ? null : XFile(paths.first!);
37+
initialDirectory: initialDirectory,
38+
confirmButtonText: confirmButtonText);
39+
return paths.isEmpty ? null : XFile(paths.first);
3340
}
3441

3542
@override
@@ -38,14 +45,14 @@ class FileSelectorWindows extends FileSelectorPlatform {
3845
String? initialDirectory,
3946
String? confirmButtonText,
4047
}) async {
41-
final List<String?> paths = await _hostApi.showOpenDialog(
42-
SelectionOptions(
48+
final List<String?> paths = _internalFilePicker.getFiles(
49+
selectionOptions: SelectionOptions(
4350
allowMultiple: true,
4451
selectFolders: false,
4552
allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups),
4653
),
47-
initialDirectory,
48-
confirmButtonText);
54+
initialDirectory: initialDirectory,
55+
confirmButtonText: confirmButtonText);
4956
return paths.map((String? path) => XFile(path!)).toList();
5057
}
5158

@@ -56,32 +63,28 @@ class FileSelectorWindows extends FileSelectorPlatform {
5663
String? suggestedName,
5764
String? confirmButtonText,
5865
}) async {
59-
final List<String?> paths = await _hostApi.showSaveDialog(
60-
SelectionOptions(
61-
allowMultiple: false,
62-
selectFolders: false,
63-
allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups),
64-
),
65-
initialDirectory,
66-
suggestedName,
67-
confirmButtonText);
68-
return paths.isEmpty ? null : paths.first!;
66+
final String? path = _internalFilePicker.getSavePath(
67+
initialDirectory: initialDirectory,
68+
suggestedFileName: suggestedName,
69+
confirmButtonText: confirmButtonText,
70+
selectionOptions: SelectionOptions(
71+
allowMultiple: false,
72+
selectFolders: false,
73+
allowedTypes: _typeGroupsFromXTypeGroups(acceptedTypeGroups),
74+
),
75+
);
76+
return path == null ? null : Future<String>.value(path);
6977
}
7078

7179
@override
7280
Future<String?> getDirectoryPath({
7381
String? initialDirectory,
7482
String? confirmButtonText,
7583
}) async {
76-
final List<String?> paths = await _hostApi.showOpenDialog(
77-
SelectionOptions(
78-
allowMultiple: false,
79-
selectFolders: true,
80-
allowedTypes: <TypeGroup>[],
81-
),
82-
initialDirectory,
83-
confirmButtonText);
84-
return paths.isEmpty ? null : paths.first!;
84+
final String? path = _internalFilePicker.getDirectoryPath(
85+
initialDirectory: initialDirectory,
86+
confirmButtonText: confirmButtonText);
87+
return path == null ? null : Future<String>.value(path);
8588
}
8689
}
8790

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:win32/win32.dart';
2+
import 'dart_place.dart';
3+
4+
/// Exposes custom places.
5+
class CustomPlace {
6+
/// CustomPlace constructor.
7+
CustomPlace(this.item, this.place);
8+
9+
/// An IShellItem.
10+
IShellItem item;
11+
12+
/// A Place.
13+
Place place;
14+
}
15+
16+
/// An abstract of FileDialog, that allows user to interact with the file system.
17+
abstract class FileDialog {
18+
/// Sets a filter for the file types shown.
19+
///
20+
/// When using the Open dialog, the file types declared here are used to
21+
/// filter the view. When using the Save dialog, these values determine which
22+
/// file name extension is appended to the file name.
23+
///
24+
/// The first value is the "friendly" name which is shown to the user (e.g.
25+
/// `JPEG Files`); the second value is a filter, which may be a semicolon-
26+
/// separated list (for example `*.jpg;*.jpeg`).
27+
Map<String, String> filterSpecification = <String, String>{};
28+
29+
/// Set hWnd of dialog
30+
int hWndOwner = NULL;
31+
32+
/// Sets is save dialog option, this allows the user to select inixistent files.
33+
bool fileMustExist = false;
34+
35+
/// Clears the current filter specification, this way a new filter can be added.
36+
void clearFilterSpecification() {
37+
filterSpecification = <String, String>{};
38+
}
39+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import 'dart:ffi';
2+
3+
import 'package:ffi/ffi.dart';
4+
import 'package:win32/win32.dart';
5+
6+
/// FileOpenDialogAPI provider, it used to interact with an IFileOpenDialogInstance.
7+
class FileOpenDialogAPI {
8+
/// Sets dialog options.
9+
int setOptions(int options, IFileOpenDialog dialog) {
10+
return dialog.setOptions(options);
11+
}
12+
13+
/// Returns dialog options.
14+
int getOptions(Pointer<Uint32> ptrOptions, IFileOpenDialog dialog) {
15+
return dialog.getOptions(ptrOptions);
16+
}
17+
18+
/// Set confirmation button text on dialog.
19+
int setOkButtonLabel(String? confirmationText, IFileOpenDialog dialog) {
20+
return dialog.setOkButtonLabel(TEXT(confirmationText ?? 'Pick'));
21+
}
22+
23+
/// Sets allowed file type extensions.
24+
int setFileTypes(
25+
Map<String, String> filterSpecification, IFileOpenDialog dialog) {
26+
final Pointer<COMDLG_FILTERSPEC> registerFilterSpecification =
27+
calloc<COMDLG_FILTERSPEC>(filterSpecification.length);
28+
29+
int index = 0;
30+
for (final String key in filterSpecification.keys) {
31+
registerFilterSpecification[index]
32+
..pszName = TEXT(key)
33+
..pszSpec = TEXT(filterSpecification[key]!);
34+
index++;
35+
}
36+
37+
return dialog.setFileTypes(
38+
filterSpecification.length, registerFilterSpecification);
39+
}
40+
41+
/// Shows a dialog.
42+
int show(int hwndOwner, IFileOpenDialog dialog) {
43+
return dialog.show(hwndOwner);
44+
}
45+
46+
/// Release a dialog.
47+
int release(IFileOpenDialog dialog) {
48+
return dialog.release();
49+
}
50+
51+
/// Return a result from a dialog.
52+
int getResult(
53+
Pointer<Pointer<COMObject>> ptrCOMObject, IFileOpenDialog dialog) {
54+
return dialog.getResult(ptrCOMObject);
55+
}
56+
57+
/// Return results from a dialog, this should be used when selecting multiple items.
58+
int getResults(
59+
Pointer<Pointer<COMObject>> ptrCOMObject, IFileOpenDialog dialog) {
60+
return dialog.getResults(ptrCOMObject);
61+
}
62+
63+
/// Sets the initial directory for a dialog.
64+
int setFolder(Pointer<Pointer<COMObject>> ptrPath, IFileOpenDialog dialog) {
65+
return dialog.setFolder(ptrPath.value);
66+
}
67+
68+
/// Sets the file name for a dialog.
69+
int setFileName(String suggestedFileName, IFileOpenDialog dialog) {
70+
return dialog.setFileName(TEXT(suggestedFileName));
71+
}
72+
73+
/// Creates item from a given initial directory. This throws if the directory does not exist.
74+
int createItemFromParsingName(String initialDirectory, Pointer<GUID> ptrGuid,
75+
Pointer<Pointer<NativeType>> ptrPath) {
76+
return SHCreateItemFromParsingName(
77+
TEXT(initialDirectory), nullptr, ptrGuid, ptrPath);
78+
}
79+
}

0 commit comments

Comments
 (0)