mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-22 13:48:13 +03:00
parent
e7bd8c5920
commit
2326bcd399
6
.changes/file-dialog-refactor.md
Normal file
6
.changes/file-dialog-refactor.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-api": minor
|
||||
"api": minor
|
||||
---
|
||||
|
||||
The file dialog API now uses [rfd](https://github.com/PolyMeilex/rfd). The filter option is now an array of `{ name: string, extensions: string[] }`.
|
@ -1,16 +1,21 @@
|
||||
import { invoke } from './tauri'
|
||||
|
||||
export interface DialogFilter {
|
||||
name: string
|
||||
extensions: string[]
|
||||
}
|
||||
|
||||
export interface OpenDialogOptions {
|
||||
filter?: string
|
||||
filters?: DialogFilter[]
|
||||
defaultPath?: string
|
||||
multiple?: boolean
|
||||
directory?: boolean
|
||||
}
|
||||
|
||||
export type SaveDialogOptions = Pick<
|
||||
OpenDialogOptions,
|
||||
'filter' | 'defaultPath'
|
||||
>
|
||||
export interface SaveDialogOptions {
|
||||
filters?: DialogFilter[]
|
||||
defaultPath?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @name openDialog
|
||||
|
@ -27,7 +27,7 @@ tar = "0.4"
|
||||
flate2 = "1.0"
|
||||
thiserror = "1.0.23"
|
||||
rand = "0.8"
|
||||
nfd = "0.0.4"
|
||||
rfd = "0.2.1"
|
||||
tinyfiledialogs = "3.3"
|
||||
reqwest = { version = "0.11", features = [ "json", "multipart" ] }
|
||||
bytes = { version = "1", features = ["serde"] }
|
||||
|
@ -1,10 +1,52 @@
|
||||
use std::path::Path;
|
||||
|
||||
pub use nfd::Response;
|
||||
use nfd::{open_dialog, DialogType};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use rfd::FileDialog;
|
||||
use tinyfiledialogs::{message_box_ok, message_box_yes_no, MessageBoxIcon, YesNo};
|
||||
|
||||
/// The file dialog builder.
|
||||
/// Constructs file picker dialogs that can select single/multiple files or directories.
|
||||
#[derive(Default)]
|
||||
pub struct FileDialogBuilder(FileDialog);
|
||||
|
||||
impl FileDialogBuilder {
|
||||
/// Gets the default file dialog builder.
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
/// Add file extension filter. Takes in the name of the filter, and list of extensions
|
||||
pub fn add_filter(mut self, name: impl AsRef<str>, extensions: &[&str]) -> Self {
|
||||
self.0 = self.0.add_filter(name.as_ref(), extensions);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set starting directory of the dialog.
|
||||
pub fn set_directory<P: AsRef<Path>>(mut self, directory: P) -> Self {
|
||||
self.0 = self.0.set_directory(&directory);
|
||||
self
|
||||
}
|
||||
|
||||
/// Pick one file.
|
||||
pub fn pick_file(self) -> Option<PathBuf> {
|
||||
self.0.pick_file()
|
||||
}
|
||||
|
||||
/// Pick multiple files.
|
||||
pub fn pick_files(self) -> Option<Vec<PathBuf>> {
|
||||
self.0.pick_files()
|
||||
}
|
||||
|
||||
/// Pick one folder.
|
||||
pub fn pick_folder(self) -> Option<PathBuf> {
|
||||
self.0.pick_folder()
|
||||
}
|
||||
|
||||
/// Opens save file dialog.
|
||||
pub fn save_file(self) -> Option<PathBuf> {
|
||||
self.0.save_file()
|
||||
}
|
||||
}
|
||||
|
||||
/// Response for the ask dialog
|
||||
pub enum AskResponse {
|
||||
/// User confirmed.
|
||||
@ -30,52 +72,3 @@ pub fn ask(title: impl AsRef<str>, message: impl AsRef<str>) -> AskResponse {
|
||||
pub fn message(title: impl AsRef<str>, message: impl AsRef<str>) {
|
||||
message_box_ok(title.as_ref(), message.as_ref(), MessageBoxIcon::Info);
|
||||
}
|
||||
|
||||
fn open_dialog_internal(
|
||||
dialog_type: DialogType,
|
||||
filter: Option<impl AsRef<str>>,
|
||||
default_path: Option<impl AsRef<Path>>,
|
||||
) -> crate::Result<Response> {
|
||||
let response = open_dialog(
|
||||
filter.map(|s| s.as_ref().to_string()).as_deref(),
|
||||
default_path
|
||||
.map(|s| s.as_ref().to_string_lossy().to_string())
|
||||
.as_deref(),
|
||||
dialog_type,
|
||||
)
|
||||
.map_err(|e| crate::Error::Dialog(e.to_string()))?;
|
||||
match response {
|
||||
Response::Cancel => Err(crate::Error::DialogCancelled),
|
||||
_ => Ok(response),
|
||||
}
|
||||
}
|
||||
|
||||
/// Open single select file dialog
|
||||
pub fn select(
|
||||
filter_list: Option<impl AsRef<str>>,
|
||||
default_path: Option<impl AsRef<Path>>,
|
||||
) -> crate::Result<Response> {
|
||||
open_dialog_internal(DialogType::SingleFile, filter_list, default_path)
|
||||
}
|
||||
|
||||
/// Open multiple select file dialog
|
||||
pub fn select_multiple(
|
||||
filter_list: Option<impl AsRef<str>>,
|
||||
default_path: Option<impl AsRef<Path>>,
|
||||
) -> crate::Result<Response> {
|
||||
open_dialog_internal(DialogType::MultipleFiles, filter_list, default_path)
|
||||
}
|
||||
|
||||
/// Open save dialog
|
||||
pub fn save_file(
|
||||
filter_list: Option<impl AsRef<str>>,
|
||||
default_path: Option<impl AsRef<Path>>,
|
||||
) -> crate::Result<Response> {
|
||||
open_dialog_internal(DialogType::SaveFile, filter_list, default_path)
|
||||
}
|
||||
|
||||
/// Open pick folder dialog
|
||||
pub fn pick_folder(default_path: Option<impl AsRef<Path>>) -> crate::Result<Response> {
|
||||
let filter: Option<String> = None;
|
||||
open_dialog_internal(DialogType::PickFolder, filter, default_path)
|
||||
}
|
||||
|
38
tauri/examples/api/src-tauri/Cargo.lock
generated
38
tauri/examples/api/src-tauri/Cargo.lock
generated
@ -852,12 +852,6 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
|
||||
[[package]]
|
||||
name = "gdk"
|
||||
version = "0.13.2"
|
||||
@ -1636,15 +1630,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nfd"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.18.0"
|
||||
@ -2329,6 +2314,27 @@ dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3de7c6d5eab0f6b212d1b5a376639d91061bbfbdc2d7c7c5214063bd6ce99581"
|
||||
dependencies = [
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"dispatch",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk-sys",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"objc",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "runas"
|
||||
version = "0.2.1"
|
||||
@ -2750,11 +2756,11 @@ dependencies = [
|
||||
"either",
|
||||
"flate2",
|
||||
"http",
|
||||
"nfd",
|
||||
"notify-rust",
|
||||
"once_cell",
|
||||
"rand 0.8.3",
|
||||
"reqwest",
|
||||
"rfd",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -27,42 +27,58 @@
|
||||
|
||||
function openDialog() {
|
||||
open({
|
||||
defaultPath: defaultPath,
|
||||
filter: filter,
|
||||
multiple: multiple,
|
||||
directory: directory
|
||||
defaultPath,
|
||||
filters: filter ? [{
|
||||
name: 'Tauri Example',
|
||||
extensions: filter.split(',').map(f => f.trim())
|
||||
}] : [],
|
||||
multiple,
|
||||
directory
|
||||
}).then(function (res) {
|
||||
var pathToRead = res
|
||||
var isFile = pathToRead.match(/\S+\.\S+$/g)
|
||||
readBinaryFile(pathToRead).then(function (response) {
|
||||
if (isFile) {
|
||||
if (pathToRead.includes('.png') || pathToRead.includes('.jpg')) {
|
||||
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
||||
var src = 'data:image/png;base64,' + base64
|
||||
onMessage('<img src="' + src + '"></img>')
|
||||
})
|
||||
if (Array.isArray(res)) {
|
||||
onMessage(res)
|
||||
} else {
|
||||
var pathToRead = res
|
||||
var isFile = pathToRead.match(/\S+\.\S+$/g)
|
||||
readBinaryFile(pathToRead).then(function (response) {
|
||||
if (isFile) {
|
||||
if (pathToRead.includes('.png') || pathToRead.includes('.jpg')) {
|
||||
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
||||
var src = 'data:image/png;base64,' + base64
|
||||
onMessage('<img src="' + src + '"></img>')
|
||||
})
|
||||
} else {
|
||||
onMessage(res)
|
||||
}
|
||||
} else {
|
||||
onMessage(res)
|
||||
}
|
||||
} else {
|
||||
onMessage(res)
|
||||
}
|
||||
}).catch(onMessage(res))
|
||||
}).catch(onMessage(res))
|
||||
}
|
||||
}).catch(onMessage)
|
||||
}
|
||||
|
||||
function saveDialog() {
|
||||
save({
|
||||
defaultPath: defaultPath,
|
||||
filter: filter,
|
||||
defaultPath,
|
||||
filters: filter ? [{
|
||||
name: 'Tauri Example',
|
||||
extensions: filter.split(',').map(f => f.trim())
|
||||
}] : [],
|
||||
}).then(onMessage).catch(onMessage)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dialog-filter {
|
||||
width: 260px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="margin-top: 24px">
|
||||
<input id="dialog-default-path" placeholder="Default path" bind:value={defaultPath} />
|
||||
<input id="dialog-filter" placeholder="Extensions filter" bind:value={filter} />
|
||||
<input id="dialog-filter" placeholder="Extensions filter, comma-separated" bind:value={filter} />
|
||||
<div>
|
||||
<input type="checkbox" id="dialog-multiple" bind:checked={multiple} />
|
||||
<label for="dialog-multiple">Multiple</label>
|
||||
|
2
tauri/examples/communication/dist/__tauri.js
vendored
2
tauri/examples/communication/dist/__tauri.js
vendored
File diff suppressed because one or more lines are too long
47
tauri/examples/communication/dist/dialog.js
vendored
47
tauri/examples/communication/dist/dialog.js
vendored
@ -7,31 +7,37 @@ document.getElementById("open-dialog").addEventListener("click", function () {
|
||||
window.__TAURI__.dialog
|
||||
.open({
|
||||
defaultPath: defaultPathInput.value || null,
|
||||
filter: filterInput.value || null,
|
||||
filters: filterInput.value ? [{
|
||||
name: 'Tauri Example',
|
||||
extensions: filterInput.value.split(',').map(f => f.trim())
|
||||
}] : [],
|
||||
multiple: multipleInput.checked,
|
||||
directory: directoryInput.checked,
|
||||
})
|
||||
.then(function (res) {
|
||||
console.log(res);
|
||||
var pathToRead = res;
|
||||
var isFile = pathToRead.match(/\S+\.\S+$/g);
|
||||
window.__TAURI__.fs
|
||||
.readBinaryFile(pathToRead)
|
||||
.then(function (response) {
|
||||
if (isFile) {
|
||||
if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) {
|
||||
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
||||
var src = "data:image/png;base64," + base64;
|
||||
registerResponse('<img src="' + src + '"></img>');
|
||||
});
|
||||
if (Array.isArray(res)) {
|
||||
registerResponse(res);
|
||||
} else {
|
||||
var pathToRead = res;
|
||||
var isFile = pathToRead.match(/\S+\.\S+$/g);
|
||||
window.__TAURI__.fs
|
||||
.readBinaryFile(pathToRead)
|
||||
.then(function (response) {
|
||||
if (isFile) {
|
||||
if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) {
|
||||
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
||||
var src = "data:image/png;base64," + base64;
|
||||
registerResponse('<img src="' + src + '"></img>');
|
||||
});
|
||||
} else {
|
||||
registerResponse(res);
|
||||
}
|
||||
} else {
|
||||
registerResponse(res);
|
||||
}
|
||||
} else {
|
||||
registerResponse(res);
|
||||
}
|
||||
})
|
||||
.catch(registerResponse(res));
|
||||
})
|
||||
.catch(registerResponse(res));
|
||||
}
|
||||
})
|
||||
.catch(registerResponse);
|
||||
});
|
||||
@ -40,7 +46,10 @@ document.getElementById("save-dialog").addEventListener("click", function () {
|
||||
window.__TAURI__.dialog
|
||||
.save({
|
||||
defaultPath: defaultPathInput.value || null,
|
||||
filter: filterInput.value || null,
|
||||
filters: filterInput.value ? [{
|
||||
name: 'Tauri Example',
|
||||
extensions: filterInput.value.split(',').map(f => f.trim())
|
||||
}] : [],
|
||||
})
|
||||
.then(registerResponse)
|
||||
.catch(registerResponse);
|
||||
|
38
tauri/examples/communication/src-tauri/Cargo.lock
generated
38
tauri/examples/communication/src-tauri/Cargo.lock
generated
@ -852,12 +852,6 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
|
||||
[[package]]
|
||||
name = "gdk"
|
||||
version = "0.13.2"
|
||||
@ -1636,15 +1630,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nfd"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.18.0"
|
||||
@ -2329,6 +2314,27 @@ dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3de7c6d5eab0f6b212d1b5a376639d91061bbfbdc2d7c7c5214063bd6ce99581"
|
||||
dependencies = [
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"dispatch",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk-sys",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"objc",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "runas"
|
||||
version = "0.2.1"
|
||||
@ -2750,11 +2756,11 @@ dependencies = [
|
||||
"either",
|
||||
"flate2",
|
||||
"http",
|
||||
"nfd",
|
||||
"notify-rust",
|
||||
"once_cell",
|
||||
"rand 0.8.3",
|
||||
"reqwest",
|
||||
"rfd",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
2
tauri/examples/multiwindow/dist/__tauri.js
vendored
2
tauri/examples/multiwindow/dist/__tauri.js
vendored
File diff suppressed because one or more lines are too long
38
tauri/examples/multiwindow/src-tauri/Cargo.lock
generated
38
tauri/examples/multiwindow/src-tauri/Cargo.lock
generated
@ -807,12 +807,6 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
|
||||
[[package]]
|
||||
name = "gdk"
|
||||
version = "0.13.2"
|
||||
@ -1591,15 +1585,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nfd"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.18.0"
|
||||
@ -2278,6 +2263,27 @@ dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3de7c6d5eab0f6b212d1b5a376639d91061bbfbdc2d7c7c5214063bd6ce99581"
|
||||
dependencies = [
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"dispatch",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk-sys",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"objc",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "runas"
|
||||
version = "0.2.1"
|
||||
@ -2692,11 +2698,11 @@ dependencies = [
|
||||
"either",
|
||||
"flate2",
|
||||
"http",
|
||||
"nfd",
|
||||
"notify-rust",
|
||||
"once_cell",
|
||||
"rand 0.8.3",
|
||||
"reqwest",
|
||||
"rfd",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -1,18 +1,25 @@
|
||||
use crate::api::dialog::{
|
||||
ask as ask_dialog, message as message_dialog, pick_folder, save_file, select, select_multiple,
|
||||
AskResponse, Response,
|
||||
ask as ask_dialog, message as message_dialog, AskResponse, FileDialogBuilder,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value as JsonValue;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DialogFilter {
|
||||
name: String,
|
||||
extensions: Vec<String>,
|
||||
}
|
||||
|
||||
/// The options for the open dialog API.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OpenDialogOptions {
|
||||
/// The initial path of the dialog.
|
||||
pub filter: Option<String>,
|
||||
/// The filters of the dialog.
|
||||
#[serde(default)]
|
||||
pub filters: Vec<DialogFilter>,
|
||||
/// Whether the dialog allows multiple selection or not.
|
||||
#[serde(default)]
|
||||
pub multiple: bool,
|
||||
@ -27,8 +34,9 @@ pub struct OpenDialogOptions {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SaveDialogOptions {
|
||||
/// The initial path of the dialog.
|
||||
pub filter: Option<String>,
|
||||
/// The filters of the dialog.
|
||||
#[serde(default)]
|
||||
pub filters: Vec<DialogFilter>,
|
||||
/// The initial path of the dialog.
|
||||
pub default_path: Option<PathBuf>,
|
||||
}
|
||||
@ -59,13 +67,13 @@ impl Cmd {
|
||||
match self {
|
||||
Self::OpenDialog { options } => {
|
||||
#[cfg(open_dialog)]
|
||||
return open(options).and_then(super::to_value);
|
||||
return open(options);
|
||||
#[cfg(not(open_dialog))]
|
||||
Err(crate::Error::ApiNotAllowlisted("title".to_string()));
|
||||
}
|
||||
Self::SaveDialog { options } => {
|
||||
#[cfg(save_dialog)]
|
||||
return save(options).and_then(super::to_value);
|
||||
return save(options);
|
||||
#[cfg(not(save_dialog))]
|
||||
Err(crate::Error::ApiNotAllowlisted("saveDialog".to_string()));
|
||||
}
|
||||
@ -97,36 +105,40 @@ impl Cmd {
|
||||
}
|
||||
}
|
||||
|
||||
/// maps a dialog response to a JS value to eval
|
||||
#[cfg(any(open_dialog, save_dialog))]
|
||||
fn map_response(response: Response) -> JsonValue {
|
||||
match response {
|
||||
Response::Okay(path) => path.into(),
|
||||
Response::OkayMultiple(paths) => paths.into(),
|
||||
Response::Cancel => JsonValue::Null,
|
||||
}
|
||||
}
|
||||
|
||||
/// Shows an open dialog.
|
||||
#[cfg(open_dialog)]
|
||||
pub fn open(options: OpenDialogOptions) -> crate::Result<JsonValue> {
|
||||
let response = if options.multiple {
|
||||
select_multiple(options.filter, options.default_path)
|
||||
} else if options.directory {
|
||||
pick_folder(options.default_path)
|
||||
let mut dialog_builder = FileDialogBuilder::new();
|
||||
if let Some(default_path) = options.default_path {
|
||||
dialog_builder = dialog_builder.set_directory(default_path);
|
||||
}
|
||||
for filter in options.filters {
|
||||
let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
|
||||
dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
|
||||
}
|
||||
let response = if options.directory {
|
||||
serde_json::to_value(dialog_builder.pick_folder())?
|
||||
} else if options.multiple {
|
||||
serde_json::to_value(dialog_builder.pick_files())?
|
||||
} else {
|
||||
select(options.filter, options.default_path)
|
||||
serde_json::to_value(dialog_builder.pick_file())?
|
||||
};
|
||||
let res = response.map(map_response)?;
|
||||
Ok(res)
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
/// Shows a save dialog.
|
||||
#[cfg(save_dialog)]
|
||||
pub fn save(options: SaveDialogOptions) -> crate::Result<JsonValue> {
|
||||
save_file(options.filter, options.default_path)
|
||||
.map(map_response)
|
||||
.map_err(Into::into)
|
||||
let mut dialog_builder = FileDialogBuilder::new();
|
||||
if let Some(default_path) = options.default_path {
|
||||
dialog_builder = dialog_builder.set_directory(default_path);
|
||||
}
|
||||
for filter in options.filters {
|
||||
let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
|
||||
dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
|
||||
}
|
||||
let response = dialog_builder.save_file();
|
||||
Ok(serde_json::to_value(response)?)
|
||||
}
|
||||
|
||||
/// Shows a dialog with a yes/no question.
|
||||
|
Loading…
Reference in New Issue
Block a user