1use glib::object::Cast;
6use glib::object::IsA;
7use glib::signal::connect_raw;
8use glib::signal::SignalHandlerId;
9use glib::translate::*;
10use glib::GString;
11use glib::StaticType;
12use glib::ToValue;
13use glib::Value;
14use glib_sys;
15use gobject_sys;
16use gtk_sys;
17use std::boxed::Box as Box_;
18use std::fmt;
19use std::mem::transmute;
20use FileChooser;
21#[cfg(any(feature = "v3_20", feature = "dox"))]
22use FileChooserAction;
23use NativeDialog;
24#[cfg(any(feature = "v3_20", feature = "dox"))]
25use Window;
26
27glib_wrapper! {
28 pub struct FileChooserNative(Object<gtk_sys::GtkFileChooserNative, gtk_sys::GtkFileChooserNativeClass, FileChooserNativeClass>) @extends NativeDialog, @implements FileChooser;
29
30 match fn {
31 get_type => || gtk_sys::gtk_file_chooser_native_get_type(),
32 }
33}
34
35impl FileChooserNative {
36 #[cfg(any(feature = "v3_20", feature = "dox"))]
37 pub fn new<P: IsA<Window>>(
38 title: Option<&str>,
39 parent: Option<&P>,
40 action: FileChooserAction,
41 accept_label: Option<&str>,
42 cancel_label: Option<&str>,
43 ) -> FileChooserNative {
44 assert_initialized_main_thread!();
45 unsafe {
46 from_glib_full(gtk_sys::gtk_file_chooser_native_new(
47 title.to_glib_none().0,
48 parent.map(|p| p.as_ref()).to_glib_none().0,
49 action.to_glib(),
50 accept_label.to_glib_none().0,
51 cancel_label.to_glib_none().0,
52 ))
53 }
54 }
55}
56
57pub struct FileChooserNativeBuilder {
58 accept_label: Option<String>,
59 cancel_label: Option<String>,
60 #[cfg(any(feature = "v3_20", feature = "dox"))]
61 modal: Option<bool>,
62 #[cfg(any(feature = "v3_20", feature = "dox"))]
63 title: Option<String>,
64 #[cfg(any(feature = "v3_20", feature = "dox"))]
65 transient_for: Option<Window>,
66 #[cfg(any(feature = "v3_20", feature = "dox"))]
67 visible: Option<bool>,
68}
69
70impl FileChooserNativeBuilder {
71 pub fn new() -> Self {
72 Self {
73 accept_label: None,
74 cancel_label: None,
75 #[cfg(any(feature = "v3_20", feature = "dox"))]
76 modal: None,
77 #[cfg(any(feature = "v3_20", feature = "dox"))]
78 title: None,
79 #[cfg(any(feature = "v3_20", feature = "dox"))]
80 transient_for: None,
81 #[cfg(any(feature = "v3_20", feature = "dox"))]
82 visible: None,
83 }
84 }
85
86 pub fn build(self) -> FileChooserNative {
87 let mut properties: Vec<(&str, &dyn ToValue)> = vec![];
88 if let Some(ref accept_label) = self.accept_label {
89 properties.push(("accept-label", accept_label));
90 }
91 if let Some(ref cancel_label) = self.cancel_label {
92 properties.push(("cancel-label", cancel_label));
93 }
94 #[cfg(any(feature = "v3_20", feature = "dox"))]
95 {
96 if let Some(ref modal) = self.modal {
97 properties.push(("modal", modal));
98 }
99 }
100 #[cfg(any(feature = "v3_20", feature = "dox"))]
101 {
102 if let Some(ref title) = self.title {
103 properties.push(("title", title));
104 }
105 }
106 #[cfg(any(feature = "v3_20", feature = "dox"))]
107 {
108 if let Some(ref transient_for) = self.transient_for {
109 properties.push(("transient-for", transient_for));
110 }
111 }
112 #[cfg(any(feature = "v3_20", feature = "dox"))]
113 {
114 if let Some(ref visible) = self.visible {
115 properties.push(("visible", visible));
116 }
117 }
118 glib::Object::new(FileChooserNative::static_type(), &properties)
119 .expect("object new")
120 .downcast()
121 .expect("downcast")
122 }
123
124 pub fn accept_label(mut self, accept_label: &str) -> Self {
125 self.accept_label = Some(accept_label.to_string());
126 self
127 }
128
129 pub fn cancel_label(mut self, cancel_label: &str) -> Self {
130 self.cancel_label = Some(cancel_label.to_string());
131 self
132 }
133
134 #[cfg(any(feature = "v3_20", feature = "dox"))]
135 pub fn modal(mut self, modal: bool) -> Self {
136 self.modal = Some(modal);
137 self
138 }
139
140 #[cfg(any(feature = "v3_20", feature = "dox"))]
141 pub fn title(mut self, title: &str) -> Self {
142 self.title = Some(title.to_string());
143 self
144 }
145
146 #[cfg(any(feature = "v3_20", feature = "dox"))]
147 pub fn transient_for(mut self, transient_for: &Window) -> Self {
148 self.transient_for = Some(transient_for.clone());
149 self
150 }
151
152 #[cfg(any(feature = "v3_20", feature = "dox"))]
153 pub fn visible(mut self, visible: bool) -> Self {
154 self.visible = Some(visible);
155 self
156 }
157}
158
159pub const NONE_FILE_CHOOSER_NATIVE: Option<&FileChooserNative> = None;
160
161pub trait FileChooserNativeExt: 'static {
162 #[cfg(any(feature = "v3_20", feature = "dox"))]
163 fn get_accept_label(&self) -> Option<GString>;
164
165 #[cfg(any(feature = "v3_20", feature = "dox"))]
166 fn get_cancel_label(&self) -> Option<GString>;
167
168 #[cfg(any(feature = "v3_20", feature = "dox"))]
169 fn set_accept_label(&self, accept_label: Option<&str>);
170
171 #[cfg(any(feature = "v3_20", feature = "dox"))]
172 fn set_cancel_label(&self, cancel_label: Option<&str>);
173
174 fn get_property_accept_label(&self) -> Option<GString>;
175
176 fn set_property_accept_label(&self, accept_label: Option<&str>);
177
178 fn get_property_cancel_label(&self) -> Option<GString>;
179
180 fn set_property_cancel_label(&self, cancel_label: Option<&str>);
181
182 fn connect_property_accept_label_notify<F: Fn(&Self) + 'static>(&self, f: F)
183 -> SignalHandlerId;
184
185 fn connect_property_cancel_label_notify<F: Fn(&Self) + 'static>(&self, f: F)
186 -> SignalHandlerId;
187}
188
189impl<O: IsA<FileChooserNative>> FileChooserNativeExt for O {
190 #[cfg(any(feature = "v3_20", feature = "dox"))]
191 fn get_accept_label(&self) -> Option<GString> {
192 unsafe {
193 from_glib_none(gtk_sys::gtk_file_chooser_native_get_accept_label(
194 self.as_ref().to_glib_none().0,
195 ))
196 }
197 }
198
199 #[cfg(any(feature = "v3_20", feature = "dox"))]
200 fn get_cancel_label(&self) -> Option<GString> {
201 unsafe {
202 from_glib_none(gtk_sys::gtk_file_chooser_native_get_cancel_label(
203 self.as_ref().to_glib_none().0,
204 ))
205 }
206 }
207
208 #[cfg(any(feature = "v3_20", feature = "dox"))]
209 fn set_accept_label(&self, accept_label: Option<&str>) {
210 unsafe {
211 gtk_sys::gtk_file_chooser_native_set_accept_label(
212 self.as_ref().to_glib_none().0,
213 accept_label.to_glib_none().0,
214 );
215 }
216 }
217
218 #[cfg(any(feature = "v3_20", feature = "dox"))]
219 fn set_cancel_label(&self, cancel_label: Option<&str>) {
220 unsafe {
221 gtk_sys::gtk_file_chooser_native_set_cancel_label(
222 self.as_ref().to_glib_none().0,
223 cancel_label.to_glib_none().0,
224 );
225 }
226 }
227
228 fn get_property_accept_label(&self) -> Option<GString> {
229 unsafe {
230 let mut value = Value::from_type(<GString as StaticType>::static_type());
231 gobject_sys::g_object_get_property(
232 self.to_glib_none().0 as *mut gobject_sys::GObject,
233 b"accept-label\0".as_ptr() as *const _,
234 value.to_glib_none_mut().0,
235 );
236 value.get()
237 }
238 }
239
240 fn set_property_accept_label(&self, accept_label: Option<&str>) {
241 unsafe {
242 gobject_sys::g_object_set_property(
243 self.to_glib_none().0 as *mut gobject_sys::GObject,
244 b"accept-label\0".as_ptr() as *const _,
245 Value::from(accept_label).to_glib_none().0,
246 );
247 }
248 }
249
250 fn get_property_cancel_label(&self) -> Option<GString> {
251 unsafe {
252 let mut value = Value::from_type(<GString as StaticType>::static_type());
253 gobject_sys::g_object_get_property(
254 self.to_glib_none().0 as *mut gobject_sys::GObject,
255 b"cancel-label\0".as_ptr() as *const _,
256 value.to_glib_none_mut().0,
257 );
258 value.get()
259 }
260 }
261
262 fn set_property_cancel_label(&self, cancel_label: Option<&str>) {
263 unsafe {
264 gobject_sys::g_object_set_property(
265 self.to_glib_none().0 as *mut gobject_sys::GObject,
266 b"cancel-label\0".as_ptr() as *const _,
267 Value::from(cancel_label).to_glib_none().0,
268 );
269 }
270 }
271
272 fn connect_property_accept_label_notify<F: Fn(&Self) + 'static>(
273 &self,
274 f: F,
275 ) -> SignalHandlerId {
276 unsafe extern "C" fn notify_accept_label_trampoline<P, F: Fn(&P) + 'static>(
277 this: *mut gtk_sys::GtkFileChooserNative,
278 _param_spec: glib_sys::gpointer,
279 f: glib_sys::gpointer,
280 ) where
281 P: IsA<FileChooserNative>,
282 {
283 let f: &F = &*(f as *const F);
284 f(&FileChooserNative::from_glib_borrow(this).unsafe_cast())
285 }
286 unsafe {
287 let f: Box_<F> = Box_::new(f);
288 connect_raw(
289 self.as_ptr() as *mut _,
290 b"notify::accept-label\0".as_ptr() as *const _,
291 Some(transmute(
292 notify_accept_label_trampoline::<Self, F> as usize,
293 )),
294 Box_::into_raw(f),
295 )
296 }
297 }
298
299 fn connect_property_cancel_label_notify<F: Fn(&Self) + 'static>(
300 &self,
301 f: F,
302 ) -> SignalHandlerId {
303 unsafe extern "C" fn notify_cancel_label_trampoline<P, F: Fn(&P) + 'static>(
304 this: *mut gtk_sys::GtkFileChooserNative,
305 _param_spec: glib_sys::gpointer,
306 f: glib_sys::gpointer,
307 ) where
308 P: IsA<FileChooserNative>,
309 {
310 let f: &F = &*(f as *const F);
311 f(&FileChooserNative::from_glib_borrow(this).unsafe_cast())
312 }
313 unsafe {
314 let f: Box_<F> = Box_::new(f);
315 connect_raw(
316 self.as_ptr() as *mut _,
317 b"notify::cancel-label\0".as_ptr() as *const _,
318 Some(transmute(
319 notify_cancel_label_trampoline::<Self, F> as usize,
320 )),
321 Box_::into_raw(f),
322 )
323 }
324 }
325}
326
327impl fmt::Display for FileChooserNative {
328 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
329 write!(f, "FileChooserNative")
330 }
331}