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

Commit 90558cd

Browse files
author
Juan Ángel Dausa
committed
* Migrate get directory path.
* 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 90558cd

31 files changed

+1639
-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._dartFileSelectorAPI]) {
13+
_dartFileSelectorAPI = _dartFileSelectorAPI ?? DartFileSelectorAPI();
14+
_api = _dartFileSelectorAPI!;
15+
}
16+
17+
late DartFileSelectorAPI _api;
18+
late DartFileSelectorAPI? _dartFileSelectorAPI;
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 = _api.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 = _api.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 = _api.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 = _api.getDirectoryPath(
85+
initialDirectory: initialDirectory,
86+
confirmButtonText: confirmButtonText);
87+
return path == null ? null : Future<String>.value(path);
8588
}
8689
}
8790

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

0 commit comments

Comments
 (0)