aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-12-10 18:46:44 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-12-10 19:56:32 +0100
commit89afcb4844dd484f0c9cdfef7e5ff8d751647c43 (patch)
treef23e994a66ec562685ca44caa6ba939de34acdf1
parent7d1a146003117694e9d970b0cf08c514ffad1c6e (diff)
downloaddialog-rs-file-selection.tar.gz
dialog-rs-file-selection.tar.bz2
Add Open/Save mode to the file selection dialogfile-selection
This patch adds the option to set a FileSelectionMode, either Open or Save. Not all backends might support this – currently, only zenity and kdialog do. Per default, the Open mode is used (as before).
-rw-r--r--examples/file_selection.rs10
-rw-r--r--src/backends/kdialog.rs10
-rw-r--r--src/backends/zenity.rs9
-rw-r--r--src/lib.rs27
4 files changed, 50 insertions, 6 deletions
diff --git a/examples/file_selection.rs b/examples/file_selection.rs
index 5436742..5d2d860 100644
--- a/examples/file_selection.rs
+++ b/examples/file_selection.rs
@@ -5,9 +5,17 @@ use dialog::DialogBox;
fn main() -> dialog::Result<()> {
let choice = dialog::FileSelection::new("Please select a file")
- .title("File Chooser Example")
+ .title("File Chooser Example (Open)")
.path("/etc")
.show()?;
println!("The user chose: {:?}", choice);
+
+ let choice = dialog::FileSelection::new("Please select a file")
+ .title("File Chooser Example (Save)")
+ .mode(dialog::FileSelectionMode::Save)
+ .path("/etc")
+ .show()?;
+ println!("The user chose: {:?}", choice);
+
Ok(())
}
diff --git a/src/backends/kdialog.rs b/src/backends/kdialog.rs
index e556ddf..21928f8 100644
--- a/src/backends/kdialog.rs
+++ b/src/backends/kdialog.rs
@@ -4,7 +4,9 @@
use std::process;
-use crate::{Choice, Error, FileSelection, Input, Message, Password, Question, Result};
+use crate::{
+ Choice, Error, FileSelection, FileSelectionMode, Input, Message, Password, Question, Result,
+};
/// Subprocess exit codes
///
@@ -139,7 +141,11 @@ impl super::Backend for KDialog {
fn show_file_selection(&self, file_selection: &FileSelection) -> Result<Option<String>> {
let dir = file_selection.path_to_string().ok_or("path not valid")?;
- let args = vec!["--getopenfilename", &dir];
+ let option = match file_selection.mode {
+ FileSelectionMode::Open => "--getopenfilename",
+ FileSelectionMode::Save => "--getsavefilename",
+ };
+ let args = vec![option, &dir];
self.execute(args, &file_selection.title)
.and_then(get_stdout)
}
diff --git a/src/backends/zenity.rs b/src/backends/zenity.rs
index 4ee7785..ac0f98f 100644
--- a/src/backends/zenity.rs
+++ b/src/backends/zenity.rs
@@ -3,7 +3,9 @@
use std::process;
-use crate::{Choice, Error, FileSelection, Input, Message, Password, Question, Result};
+use crate::{
+ Choice, Error, FileSelection, FileSelectionMode, Input, Message, Password, Question, Result,
+};
/// The `zenity` backend.
///
@@ -166,7 +168,10 @@ impl super::Backend for Zenity {
fn show_file_selection(&self, file_selection: &FileSelection) -> Result<Option<String>> {
let dir = file_selection.path_to_string().ok_or("path not valid")?;
- let args = vec!["--file-selection", "--filename", &dir];
+ let mut args = vec!["--file-selection", "--filename", &dir];
+ if file_selection.mode == FileSelectionMode::Save {
+ args.push("--save");
+ }
self.execute(args, &file_selection.title)
.and_then(get_stdout)
}
diff --git a/src/lib.rs b/src/lib.rs
index da2a259..aa19105 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -348,11 +348,24 @@ impl DialogBox for Question {
}
}
+/// The type of a file selection dialog.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum FileSelectionMode {
+ /// An Open File dialog, meaning that the user can only select an existing file.
+ Open,
+ /// A Save File dialog, meaning that the user is allowed to select a non-existing file.
+ Save,
+}
+
/// A file chooser dialog box.
///
-/// This dialog box opens a file chooser with an optional title in the specified path. If the path
+/// This dialog box opens a file choser with an optional title in the specified path. If the path
/// is not specified, it defaults to the user’s home directory.
///
+/// The backends might support multiple operation modes, for example open or save dialogs. You can
+/// select a mode using the [`FileSelectionMode`][] enum, though the backend might ignore the mode
+/// and just display a simple file dialog. Per default, the mode is set to `Open`.
+///
/// # Example
///
/// ```no_run
@@ -365,10 +378,13 @@ impl DialogBox for Question {
/// .expect("Could not display dialog box");
/// println!("The user chose: {:?}", choice);
/// ```
+///
+/// [`FileSelectionMode`]: enum.FileSelectionMode.html
pub struct FileSelection {
text: String,
title: Option<String>,
path: Option<PathBuf>,
+ mode: FileSelectionMode,
}
impl FileSelection {
@@ -378,6 +394,7 @@ impl FileSelection {
text: text.into(),
title: None,
path: dirs::home_dir(),
+ mode: FileSelectionMode::Open,
}
}
@@ -409,6 +426,14 @@ impl FileSelection {
_ => None,
}
}
+
+ /// Sets the operation mode of the file chooser.
+ ///
+ /// This method returns a reference to `self` to enable chaining.
+ pub fn mode(&mut self, mode: FileSelectionMode) -> &mut FileSelection {
+ self.mode = mode;
+ self
+ }
}
impl DialogBox for FileSelection {