Skip to content
This repository was archived by the owner on Jun 8, 2021. It is now read-only.

Commit 06d9c44

Browse files
committed
Add support for file chooser buttons
This commit adds support for file chooser buttons. They are represented as a slice of tuples `(text, action)`. The original function uses varargs to support an arbitrary number of arguments. This implementation supports up to 3 buttons. **This is a breaking change.** See: https://developer.gnome.org/gtk3/stable/GtkFileChooserDialog.html#gtk-file-chooser-dialog-new Improve file chooser with buttons reliability Following the reviews in #602, this commit: - uses the `with_buttons` function instead of modifying `new` to keep backward compatibility. - saves the button texts in `Stash` objects to avoid invalid pointers - panics when the number of buttons is too high (instead of silently truncating the number of buttons) Remove doc comment for `FileChooserDialog::with_buttons` Remove local variables in `FileChooserDialog::with_buttons` This commit removes the Stash variables from `FileChooserDialog::with_buttons`, as requested in the PR #602 Fix formatting issue Keep `downcast_unchecked` method on the same line as the closing parenthesis of the chopped-down call to `Widget::from_glib_none`.
1 parent 42ad618 commit 06d9c44

File tree

1 file changed

+68
-6
lines changed

1 file changed

+68
-6
lines changed

src/file_chooser_dialog.rs

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,83 @@
55
use ffi;
66
use glib::translate::*;
77
use glib::object::{Downcast, IsA};
8+
use libc::c_char;
89
use std::ptr;
910
use FileChooserAction;
1011
use FileChooserDialog;
12+
use ResponseType;
1113
use Widget;
1214
use Window;
1315

1416
impl FileChooserDialog {
15-
pub fn new<T: IsA<Window>>(title: Option<&str>, parent: Option<&T>, action: FileChooserAction)
16-
-> FileChooserDialog {
17+
// TODO: Keep the other constructor with buttons support as the only constructor (this one was
18+
// left for compatibility) and rename it to `new` for consistency.
19+
pub fn new<T: IsA<Window>>(title: Option<&str>, parent: Option<&T>, action: FileChooserAction) -> FileChooserDialog {
1720
assert_initialized_main_thread!();
1821
unsafe {
19-
Widget::from_glib_none(
20-
ffi::gtk_file_chooser_dialog_new(title.to_glib_none().0, parent.to_glib_none().0,
21-
action.to_glib(), ptr::null_mut()))
22-
.downcast_unchecked()
22+
Widget::from_glib_none(ffi::gtk_file_chooser_dialog_new(
23+
title.to_glib_none().0,
24+
parent.to_glib_none().0,
25+
action.to_glib(),
26+
ptr::null::<c_char>()
27+
)).downcast_unchecked()
28+
}
29+
}
30+
31+
pub fn with_buttons<T: IsA<Window>>(title: Option<&str>, parent: Option<&T>, action: FileChooserAction, buttons: &[(&str, ResponseType)]) -> FileChooserDialog {
32+
assert_initialized_main_thread!();
33+
unsafe {
34+
Widget::from_glib_none(match buttons.len() {
35+
0 => {
36+
ffi::gtk_file_chooser_dialog_new(
37+
title.to_glib_none().0,
38+
parent.to_glib_none().0,
39+
action.to_glib(),
40+
ptr::null::<c_char>()
41+
)
42+
},
43+
1 => {
44+
ffi::gtk_file_chooser_dialog_new(
45+
title.to_glib_none().0,
46+
parent.to_glib_none().0,
47+
action.to_glib(),
48+
buttons[0].0.to_glib_none().0,
49+
buttons[0].1.to_glib(),
50+
ptr::null::<c_char>(),
51+
)
52+
},
53+
2 => {
54+
ffi::gtk_file_chooser_dialog_new(
55+
title.to_glib_none().0,
56+
parent.to_glib_none().0,
57+
action.to_glib(),
58+
buttons[0].0.to_glib_none().0,
59+
buttons[0].1.to_glib(),
60+
(buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
61+
buttons[1].1.to_glib(),
62+
ptr::null::<c_char>(),
63+
)
64+
},
65+
3 => {
66+
ffi::gtk_file_chooser_dialog_new(
67+
title.to_glib_none().0,
68+
parent.to_glib_none().0,
69+
action.to_glib(),
70+
buttons[0].0.to_glib_none().0,
71+
buttons[0].1.to_glib(),
72+
(buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
73+
buttons[1].1.to_glib(),
74+
(buttons[2].0.to_glib_none() as Stash<*const c_char, str>).0,
75+
buttons[2].1.to_glib(),
76+
ptr::null::<c_char>(),
77+
)
78+
},
79+
_ => {
80+
// TODO: Support arbitrary number of buttons once variadic functions are supported.
81+
// See: https://github.com/rust-lang/rust/issues/44930
82+
panic!(format!("`FileChooserDialog::with_buttons` does not support 4+ buttons, received {}", buttons.len()))
83+
}
84+
}).downcast_unchecked()
2385
}
2486
}
2587
}

0 commit comments

Comments
 (0)