gtk/
file_chooser_dialog.rs

1// Copyright 2013-2016, The Gtk-rs Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use glib::object::{Cast, IsA};
6use glib::translate::*;
7use gtk_sys;
8use libc::c_char;
9use std::ptr;
10use FileChooserAction;
11use FileChooserDialog;
12use ResponseType;
13use Widget;
14use Window;
15
16impl 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>>(
20        title: Option<&str>,
21        parent: Option<&T>,
22        action: FileChooserAction,
23    ) -> FileChooserDialog {
24        assert_initialized_main_thread!();
25        unsafe {
26            Widget::from_glib_none(gtk_sys::gtk_file_chooser_dialog_new(
27                title.to_glib_none().0,
28                parent.map(|p| p.as_ref()).to_glib_none().0,
29                action.to_glib(),
30                ptr::null::<c_char>(),
31            ))
32            .unsafe_cast()
33        }
34    }
35
36    pub fn with_buttons<T: IsA<Window>>(
37        title: Option<&str>,
38        parent: Option<&T>,
39        action: FileChooserAction,
40        buttons: &[(&str, ResponseType)],
41    ) -> FileChooserDialog {
42        assert_initialized_main_thread!();
43        unsafe {
44            Widget::from_glib_none(match buttons.len() {
45                0 => {
46                    gtk_sys::gtk_file_chooser_dialog_new(
47                        title.to_glib_none().0,
48                        parent.map(|p| p.as_ref()).to_glib_none().0,
49                        action.to_glib(),
50                        ptr::null::<c_char>()
51                    )
52                },
53                1 => {
54                    gtk_sys::gtk_file_chooser_dialog_new(
55                        title.to_glib_none().0,
56                        parent.map(|p| p.as_ref()).to_glib_none().0,
57                        action.to_glib(),
58                        buttons[0].0.to_glib_none().0,
59                        buttons[0].1.to_glib(),
60                        ptr::null::<c_char>(),
61                    )
62                },
63                2 => {
64                    gtk_sys::gtk_file_chooser_dialog_new(
65                        title.to_glib_none().0,
66                        parent.map(|p| p.as_ref()).to_glib_none().0,
67                        action.to_glib(),
68                        buttons[0].0.to_glib_none().0,
69                        buttons[0].1.to_glib(),
70                        (buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
71                        buttons[1].1.to_glib(),
72                        ptr::null::<c_char>(),
73                    )
74                },
75                3 => {
76                    gtk_sys::gtk_file_chooser_dialog_new(
77                        title.to_glib_none().0,
78                        parent.map(|p| p.as_ref()).to_glib_none().0,
79                        action.to_glib(),
80                        buttons[0].0.to_glib_none().0,
81                        buttons[0].1.to_glib(),
82                        (buttons[1].0.to_glib_none() as Stash<*const c_char, str>).0,
83                        buttons[1].1.to_glib(),
84                        (buttons[2].0.to_glib_none() as Stash<*const c_char, str>).0,
85                        buttons[2].1.to_glib(),
86                        ptr::null::<c_char>(),
87                    )
88                },
89                _ => {
90                    // TODO: Support arbitrary number of buttons once variadic functions are supported.
91                    //       See: https://github.com/rust-lang/rust/issues/44930
92                    panic!(format!("`FileChooserDialog::with_buttons` does not support 4+ buttons, received {}", buttons.len()))
93                }
94            }).unsafe_cast()
95        }
96    }
97}