Skip to content

Commit

Permalink
Merge pull request #1248 from miguelpruivo/feature/#989-prompt-to-con…
Browse files Browse the repository at this point in the history
…firm-overwrite-if-file-already-exists

#989: save file on Windows: prompt user for confirmation when selecting an already existing file
  • Loading branch information
miguelpruivo committed Apr 4, 2023
2 parents acb4deb + a314b5b commit b060f04
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 30 deletions.
1 change: 0 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
steps:
- uses: actions/checkout@v3

- uses: subosito/flutter-action@v1
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.2.7
### Desktop (Windows)
Fixes the behavior of the `saveFile()` dialog on Windows. Now, when the user selects an already existing file, then Windows prompts the user to confirm overwriting this file. This change makes the dialog behave the same on all desktop platforms (macOS, Linux, and Windows). Previously, Windows would not have asked the user for confirmation ([#989](https://github.com/miguelpruivo/flutter_file_picker/issues/989)).

## 5.2.6
### Web
- Increase time to wait on js result
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ If you have any feature that you want to see in this package, please feel free t

| API | Android | iOS | Linux | macOS | Windows | Web |
| --------------------- | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ |
| clearTemporaryFiles() | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: |
| getDirectoryPath() | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| pickFiles() | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| saveFile() | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| clearTemporaryFiles() | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
| getDirectoryPath() | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
| pickFiles() | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| saveFile() | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |

See the [API section of the File Picker Wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/api) or the [official API reference on pub.dev](https://pub.dev/documentation/file_picker/latest/file_picker/FilePicker-class.html) for further details.

Expand Down
56 changes: 32 additions & 24 deletions lib/src/windows/file_picker_windows.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ class FilePickerWindows extends FilePicker {
final comdlg32 = DynamicLibrary.open('comdlg32.dll');

final getOpenFileNameW =
comdlg32.lookupFunction<GetOpenFileNameW, GetOpenFileNameWDart>(
'GetOpenFileNameW');
comdlg32.lookupFunction<GetOpenFileNameW, GetOpenFileNameWDart>(
'GetOpenFileNameW');

final Pointer<OPENFILENAMEW> openFileNameW = _instantiateOpenFileNameW(
allowMultiple: allowMultiple,
Expand Down Expand Up @@ -184,13 +184,15 @@ class FilePickerWindows extends FilePicker {
await Isolate.spawn(
_callSaveFile,
_OpenSaveFileArgs(
port: port.sendPort,
fileName: fileName,
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
type: type,
allowedExtensions: allowedExtensions,
lockParentWindow: lockParentWindow));
port: port.sendPort,
fileName: fileName,
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
type: type,
allowedExtensions: allowedExtensions,
lockParentWindow: lockParentWindow,
confirmOverwrite: true,
));
return (await port.first) as String?;
}

Expand All @@ -205,8 +207,8 @@ class FilePickerWindows extends FilePicker {
final comdlg32 = DynamicLibrary.open('comdlg32.dll');

final getSaveFileNameW =
comdlg32.lookupFunction<GetSaveFileNameW, GetSaveFileNameWDart>(
'GetSaveFileNameW');
comdlg32.lookupFunction<GetSaveFileNameW, GetSaveFileNameWDart>(
'GetSaveFileNameW');

final Pointer<OPENFILENAMEW> openFileNameW = _instantiateOpenFileNameW(
allowedExtensions: allowedExtensions,
Expand Down Expand Up @@ -310,6 +312,7 @@ class FilePickerWindows extends FilePicker {
List<String>? allowedExtensions,
FileType type = FileType.any,
bool lockParentWindow = false,
bool confirmOverwrite = false,
}) {
final lpstrFileBufferSize = 8192 * maximumPathLength;
final Pointer<OPENFILENAMEW> openFileNameW = calloc<OPENFILENAMEW>();
Expand All @@ -333,6 +336,10 @@ class FilePickerWindows extends FilePicker {
openFileNameW.ref.flags |= ofnAllowMultiSelect;
}

if (confirmOverwrite) {
openFileNameW.ref.flags |= ofnOverwritePrompt;
}

if (defaultFileName != null) {
validateFileName(defaultFileName);

Expand Down Expand Up @@ -373,7 +380,6 @@ class FilePickerWindows extends FilePicker {
calloc.free(openFileNameW);
}


static void _callPickFiles(_OpenSaveFileArgs args) {
final impl = FilePickerWindows();
args.port.send(impl._pickFiles(
Expand All @@ -396,7 +402,6 @@ class FilePickerWindows extends FilePicker {
allowedExtensions: args.allowedExtensions,
lockParentWindow: args.lockParentWindow));
}

}

class _OpenSaveFileArgs {
Expand All @@ -409,15 +414,18 @@ class _OpenSaveFileArgs {
final bool allowCompression;
final bool allowMultiple;
final bool lockParentWindow;

_OpenSaveFileArgs(
{required this.port,
this.dialogTitle,
this.fileName,
this.initialDirectory,
this.type = FileType.any,
this.allowedExtensions,
this.allowCompression = true,
this.allowMultiple = false,
this.lockParentWindow = false});
final bool confirmOverwrite;

_OpenSaveFileArgs({
required this.port,
this.dialogTitle,
this.fileName,
this.initialDirectory,
this.type = FileType.any,
this.allowedExtensions,
this.allowCompression = true,
this.allowMultiple = false,
this.lockParentWindow = false,
this.confirmOverwrite = false,
});
}
3 changes: 3 additions & 0 deletions lib/src/windows/file_picker_windows_ffi_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,6 @@ const ofnFileMustExist = 0x00001000;

/// Hides the Read Only check box.
const ofnHideReadOnly = 0x00000004;

/// Causes the Save As dialog box to generate a message box if the selected file already exists. The user must confirm whether to overwrite the file.
const ofnOverwritePrompt = 0x00000002;
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: A package that allows you to use a native file explorer to pick sin
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
repository: https://github.com/miguelpruivo/flutter_file_picker
issue_tracker: https://github.com/miguelpruivo/flutter_file_picker/issues
version: 5.2.6
version: 5.2.7

dependencies:
flutter:
Expand Down

0 comments on commit b060f04

Please sign in to comment.