Skip to main content

gtk/
file_chooser_dialog.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::FileChooserDialog;
4use crate::ResponseType;
5use crate::Widget;
6use crate::Window;
7use crate::{FileChooserAction, ffi};
8use glib::object::{Cast, IsA};
9use glib::translate::*;
10use libc::c_char;
11use std::ptr;
12
13impl FileChooserDialog {
14    // TODO: Keep the other constructor with buttons support as the only constructor (this one was
15    //       left for compatibility) and rename it to `new` for consistency.
16    /// Creates a new [`FileChooserDialog`][crate::FileChooserDialog]. This function is analogous to
17    /// `gtk_dialog_new_with_buttons()`.
18    /// ## `title`
19    /// Title of the dialog, or [`None`]
20    /// ## `parent`
21    /// Transient parent of the dialog, or [`None`]
22    /// ## `action`
23    /// Open or save mode for the dialog
24    /// ## `first_button_text`
25    /// stock ID or text to go in the first button, or [`None`]
26    ///
27    /// # Returns
28    ///
29    /// a new [`FileChooserDialog`][crate::FileChooserDialog]
30    #[doc(alias = "gtk_file_chooser_dialog_new")]
31    pub fn new<T: IsA<Window>>(
32        title: Option<&str>,
33        parent: Option<&T>,
34        action: FileChooserAction,
35    ) -> FileChooserDialog {
36        assert_initialized_main_thread!();
37        unsafe {
38            Widget::from_glib_none(ffi::gtk_file_chooser_dialog_new(
39                title.to_glib_none().0,
40                parent.map(|p| p.as_ref()).to_glib_none().0,
41                action.into_glib(),
42                ptr::null::<c_char>(),
43            ))
44            .unsafe_cast()
45        }
46    }
47
48    #[doc(alias = "gtk_file_chooser_dialog_new")]
49    pub fn with_buttons<T: IsA<Window>>(
50        title: Option<&str>,
51        parent: Option<&T>,
52        action: FileChooserAction,
53        buttons: &[(&str, ResponseType)],
54    ) -> FileChooserDialog {
55        assert_initialized_main_thread!();
56        unsafe {
57            Widget::from_glib_none(match buttons.len() {
58                0 => {
59                    ffi::gtk_file_chooser_dialog_new(
60                        title.to_glib_none().0,
61                        parent.map(|p| p.as_ref()).to_glib_none().0,
62                        action.into_glib(),
63                        ptr::null::<c_char>()
64                    )
65                },
66                1 => {
67                    ffi::gtk_file_chooser_dialog_new(
68                        title.to_glib_none().0,
69                        parent.map(|p| p.as_ref()).to_glib_none().0,
70                        action.into_glib(),
71                        buttons[0].0.to_glib_none().0,
72                        buttons[0].1.into_glib(),
73                        ptr::null::<c_char>(),
74                    )
75                },
76                2 => {
77                    ffi::gtk_file_chooser_dialog_new(
78                        title.to_glib_none().0,
79                        parent.map(|p| p.as_ref()).to_glib_none().0,
80                        action.into_glib(),
81                        buttons[0].0.to_glib_none().0,
82                        buttons[0].1.into_glib(),
83                        (buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
84                        buttons[1].1.into_glib(),
85                        ptr::null::<c_char>(),
86                    )
87                },
88                3 => {
89                    ffi::gtk_file_chooser_dialog_new(
90                        title.to_glib_none().0,
91                        parent.map(|p| p.as_ref()).to_glib_none().0,
92                        action.into_glib(),
93                        buttons[0].0.to_glib_none().0,
94                        buttons[0].1.into_glib(),
95                        (buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
96                        buttons[1].1.into_glib(),
97                        (buttons[2].0.to_glib_none() as Stash<*const c_char, str>).0,
98                        buttons[2].1.into_glib(),
99                        ptr::null::<c_char>(),
100                    )
101                },
102                _ => {
103                    // TODO: Support arbitrary number of buttons once variadic functions are supported.
104                    //       See: https://github.com/rust-lang/rust/issues/44930
105                    panic!("`FileChooserDialog::with_buttons` does not support 4+ buttons, received {}", buttons.len())
106                }
107            }).unsafe_cast()
108        }
109    }
110}