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

Commit

Permalink
Add support for file chooser buttons
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
demurgos committed Dec 11, 2017
1 parent 42ad618 commit 06d9c44
Showing 1 changed file with 68 additions and 6 deletions.
74 changes: 68 additions & 6 deletions src/file_chooser_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,83 @@
use ffi;
use glib::translate::*;
use glib::object::{Downcast, IsA};
use libc::c_char;
use std::ptr;
use FileChooserAction;
use FileChooserDialog;
use ResponseType;
use Widget;
use Window;

impl FileChooserDialog {
pub fn new<T: IsA<Window>>(title: Option<&str>, parent: Option<&T>, action: FileChooserAction)
-> FileChooserDialog {
// TODO: Keep the other constructor with buttons support as the only constructor (this one was
// left for compatibility) and rename it to `new` for consistency.
pub fn new<T: IsA<Window>>(title: Option<&str>, parent: Option<&T>, action: FileChooserAction) -> FileChooserDialog {
assert_initialized_main_thread!();
unsafe {
Widget::from_glib_none(
ffi::gtk_file_chooser_dialog_new(title.to_glib_none().0, parent.to_glib_none().0,
action.to_glib(), ptr::null_mut()))
.downcast_unchecked()
Widget::from_glib_none(ffi::gtk_file_chooser_dialog_new(
title.to_glib_none().0,
parent.to_glib_none().0,
action.to_glib(),
ptr::null::<c_char>()
)).downcast_unchecked()
}
}

pub fn with_buttons<T: IsA<Window>>(title: Option<&str>, parent: Option<&T>, action: FileChooserAction, buttons: &[(&str, ResponseType)]) -> FileChooserDialog {
assert_initialized_main_thread!();
unsafe {
Widget::from_glib_none(match buttons.len() {
0 => {
ffi::gtk_file_chooser_dialog_new(
title.to_glib_none().0,
parent.to_glib_none().0,
action.to_glib(),
ptr::null::<c_char>()
)
},
1 => {
ffi::gtk_file_chooser_dialog_new(
title.to_glib_none().0,
parent.to_glib_none().0,
action.to_glib(),
buttons[0].0.to_glib_none().0,
buttons[0].1.to_glib(),
ptr::null::<c_char>(),
)
},
2 => {
ffi::gtk_file_chooser_dialog_new(
title.to_glib_none().0,
parent.to_glib_none().0,
action.to_glib(),
buttons[0].0.to_glib_none().0,
buttons[0].1.to_glib(),
(buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
buttons[1].1.to_glib(),
ptr::null::<c_char>(),
)
},
3 => {
ffi::gtk_file_chooser_dialog_new(
title.to_glib_none().0,
parent.to_glib_none().0,
action.to_glib(),
buttons[0].0.to_glib_none().0,
buttons[0].1.to_glib(),
(buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
buttons[1].1.to_glib(),
(buttons[2].0.to_glib_none() as Stash<*const c_char, str>).0,
buttons[2].1.to_glib(),
ptr::null::<c_char>(),
)
},
_ => {
// TODO: Support arbitrary number of buttons once variadic functions are supported.
// See: https://github.com/rust-lang/rust/issues/44930
panic!(format!("`FileChooserDialog::with_buttons` does not support 4+ buttons, received {}", buttons.len()))
}
}).downcast_unchecked()
}
}
}

0 comments on commit 06d9c44

Please sign in to comment.