[go: up one dir, main page]

gtk4/auto/
file_dialog.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, FileFilter, Window};
6use glib::{
7    prelude::*,
8    signal::{connect_raw, SignalHandlerId},
9    translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14    #[doc(alias = "GtkFileDialog")]
15    pub struct FileDialog(Object<ffi::GtkFileDialog, ffi::GtkFileDialogClass>);
16
17    match fn {
18        type_ => || ffi::gtk_file_dialog_get_type(),
19    }
20}
21
22impl FileDialog {
23    #[doc(alias = "gtk_file_dialog_new")]
24    pub fn new() -> FileDialog {
25        assert_initialized_main_thread!();
26        unsafe { from_glib_full(ffi::gtk_file_dialog_new()) }
27    }
28
29    // rustdoc-stripper-ignore-next
30    /// Creates a new builder-pattern struct instance to construct [`FileDialog`] objects.
31    ///
32    /// This method returns an instance of [`FileDialogBuilder`](crate::builders::FileDialogBuilder) which can be used to create [`FileDialog`] objects.
33    pub fn builder() -> FileDialogBuilder {
34        FileDialogBuilder::new()
35    }
36
37    #[doc(alias = "gtk_file_dialog_get_accept_label")]
38    #[doc(alias = "get_accept_label")]
39    #[doc(alias = "accept-label")]
40    pub fn accept_label(&self) -> Option<glib::GString> {
41        unsafe { from_glib_none(ffi::gtk_file_dialog_get_accept_label(self.to_glib_none().0)) }
42    }
43
44    #[doc(alias = "gtk_file_dialog_get_default_filter")]
45    #[doc(alias = "get_default_filter")]
46    #[doc(alias = "default-filter")]
47    pub fn default_filter(&self) -> Option<FileFilter> {
48        unsafe {
49            from_glib_none(ffi::gtk_file_dialog_get_default_filter(
50                self.to_glib_none().0,
51            ))
52        }
53    }
54
55    #[doc(alias = "gtk_file_dialog_get_filters")]
56    #[doc(alias = "get_filters")]
57    pub fn filters(&self) -> Option<gio::ListModel> {
58        unsafe { from_glib_none(ffi::gtk_file_dialog_get_filters(self.to_glib_none().0)) }
59    }
60
61    #[doc(alias = "gtk_file_dialog_get_initial_file")]
62    #[doc(alias = "get_initial_file")]
63    #[doc(alias = "initial-file")]
64    pub fn initial_file(&self) -> Option<gio::File> {
65        unsafe { from_glib_none(ffi::gtk_file_dialog_get_initial_file(self.to_glib_none().0)) }
66    }
67
68    #[doc(alias = "gtk_file_dialog_get_initial_folder")]
69    #[doc(alias = "get_initial_folder")]
70    #[doc(alias = "initial-folder")]
71    pub fn initial_folder(&self) -> Option<gio::File> {
72        unsafe {
73            from_glib_none(ffi::gtk_file_dialog_get_initial_folder(
74                self.to_glib_none().0,
75            ))
76        }
77    }
78
79    #[doc(alias = "gtk_file_dialog_get_initial_name")]
80    #[doc(alias = "get_initial_name")]
81    #[doc(alias = "initial-name")]
82    pub fn initial_name(&self) -> Option<glib::GString> {
83        unsafe { from_glib_none(ffi::gtk_file_dialog_get_initial_name(self.to_glib_none().0)) }
84    }
85
86    #[doc(alias = "gtk_file_dialog_get_modal")]
87    #[doc(alias = "get_modal")]
88    #[doc(alias = "modal")]
89    pub fn is_modal(&self) -> bool {
90        unsafe { from_glib(ffi::gtk_file_dialog_get_modal(self.to_glib_none().0)) }
91    }
92
93    #[doc(alias = "gtk_file_dialog_get_title")]
94    #[doc(alias = "get_title")]
95    pub fn title(&self) -> glib::GString {
96        unsafe { from_glib_none(ffi::gtk_file_dialog_get_title(self.to_glib_none().0)) }
97    }
98
99    #[doc(alias = "gtk_file_dialog_open")]
100    pub fn open<P: FnOnce(Result<gio::File, glib::Error>) + 'static>(
101        &self,
102        parent: Option<&impl IsA<Window>>,
103        cancellable: Option<&impl IsA<gio::Cancellable>>,
104        callback: P,
105    ) {
106        let main_context = glib::MainContext::ref_thread_default();
107        let is_main_context_owner = main_context.is_owner();
108        let has_acquired_main_context = (!is_main_context_owner)
109            .then(|| main_context.acquire().ok())
110            .flatten();
111        assert!(
112            is_main_context_owner || has_acquired_main_context.is_some(),
113            "Async operations only allowed if the thread is owning the MainContext"
114        );
115
116        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
117            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
118        unsafe extern "C" fn open_trampoline<
119            P: FnOnce(Result<gio::File, glib::Error>) + 'static,
120        >(
121            _source_object: *mut glib::gobject_ffi::GObject,
122            res: *mut gio::ffi::GAsyncResult,
123            user_data: glib::ffi::gpointer,
124        ) {
125            let mut error = std::ptr::null_mut();
126            let ret = ffi::gtk_file_dialog_open_finish(_source_object as *mut _, res, &mut error);
127            let result = if error.is_null() {
128                Ok(from_glib_full(ret))
129            } else {
130                Err(from_glib_full(error))
131            };
132            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
133                Box_::from_raw(user_data as *mut _);
134            let callback: P = callback.into_inner();
135            callback(result);
136        }
137        let callback = open_trampoline::<P>;
138        unsafe {
139            ffi::gtk_file_dialog_open(
140                self.to_glib_none().0,
141                parent.map(|p| p.as_ref()).to_glib_none().0,
142                cancellable.map(|p| p.as_ref()).to_glib_none().0,
143                Some(callback),
144                Box_::into_raw(user_data) as *mut _,
145            );
146        }
147    }
148
149    pub fn open_future(
150        &self,
151        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
152    ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::File, glib::Error>> + 'static>> {
153        let parent = parent.map(ToOwned::to_owned);
154        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
155            obj.open(
156                parent.as_ref().map(::std::borrow::Borrow::borrow),
157                Some(cancellable),
158                move |res| {
159                    send.resolve(res);
160                },
161            );
162        }))
163    }
164
165    #[doc(alias = "gtk_file_dialog_open_multiple")]
166    pub fn open_multiple<P: FnOnce(Result<gio::ListModel, glib::Error>) + 'static>(
167        &self,
168        parent: Option<&impl IsA<Window>>,
169        cancellable: Option<&impl IsA<gio::Cancellable>>,
170        callback: P,
171    ) {
172        let main_context = glib::MainContext::ref_thread_default();
173        let is_main_context_owner = main_context.is_owner();
174        let has_acquired_main_context = (!is_main_context_owner)
175            .then(|| main_context.acquire().ok())
176            .flatten();
177        assert!(
178            is_main_context_owner || has_acquired_main_context.is_some(),
179            "Async operations only allowed if the thread is owning the MainContext"
180        );
181
182        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
183            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
184        unsafe extern "C" fn open_multiple_trampoline<
185            P: FnOnce(Result<gio::ListModel, glib::Error>) + 'static,
186        >(
187            _source_object: *mut glib::gobject_ffi::GObject,
188            res: *mut gio::ffi::GAsyncResult,
189            user_data: glib::ffi::gpointer,
190        ) {
191            let mut error = std::ptr::null_mut();
192            let ret = ffi::gtk_file_dialog_open_multiple_finish(
193                _source_object as *mut _,
194                res,
195                &mut error,
196            );
197            let result = if error.is_null() {
198                Ok(from_glib_full(ret))
199            } else {
200                Err(from_glib_full(error))
201            };
202            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
203                Box_::from_raw(user_data as *mut _);
204            let callback: P = callback.into_inner();
205            callback(result);
206        }
207        let callback = open_multiple_trampoline::<P>;
208        unsafe {
209            ffi::gtk_file_dialog_open_multiple(
210                self.to_glib_none().0,
211                parent.map(|p| p.as_ref()).to_glib_none().0,
212                cancellable.map(|p| p.as_ref()).to_glib_none().0,
213                Some(callback),
214                Box_::into_raw(user_data) as *mut _,
215            );
216        }
217    }
218
219    pub fn open_multiple_future(
220        &self,
221        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
222    ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::ListModel, glib::Error>> + 'static>>
223    {
224        let parent = parent.map(ToOwned::to_owned);
225        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
226            obj.open_multiple(
227                parent.as_ref().map(::std::borrow::Borrow::borrow),
228                Some(cancellable),
229                move |res| {
230                    send.resolve(res);
231                },
232            );
233        }))
234    }
235
236    #[cfg(feature = "v4_18")]
237    #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
238    #[doc(alias = "gtk_file_dialog_open_multiple_text_files")]
239    pub fn open_multiple_text_files<
240        P: FnOnce(Result<(gio::ListModel, glib::GString), glib::Error>) + 'static,
241    >(
242        &self,
243        parent: Option<&impl IsA<Window>>,
244        cancellable: Option<&impl IsA<gio::Cancellable>>,
245        callback: P,
246    ) {
247        let main_context = glib::MainContext::ref_thread_default();
248        let is_main_context_owner = main_context.is_owner();
249        let has_acquired_main_context = (!is_main_context_owner)
250            .then(|| main_context.acquire().ok())
251            .flatten();
252        assert!(
253            is_main_context_owner || has_acquired_main_context.is_some(),
254            "Async operations only allowed if the thread is owning the MainContext"
255        );
256
257        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
258            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
259        unsafe extern "C" fn open_multiple_text_files_trampoline<
260            P: FnOnce(Result<(gio::ListModel, glib::GString), glib::Error>) + 'static,
261        >(
262            _source_object: *mut glib::gobject_ffi::GObject,
263            res: *mut gio::ffi::GAsyncResult,
264            user_data: glib::ffi::gpointer,
265        ) {
266            let mut error = std::ptr::null_mut();
267            let mut encoding = std::ptr::null();
268            let ret = ffi::gtk_file_dialog_open_multiple_text_files_finish(
269                _source_object as *mut _,
270                res,
271                &mut encoding,
272                &mut error,
273            );
274            let result = if error.is_null() {
275                Ok((from_glib_full(ret), from_glib_none(encoding)))
276            } else {
277                Err(from_glib_full(error))
278            };
279            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
280                Box_::from_raw(user_data as *mut _);
281            let callback: P = callback.into_inner();
282            callback(result);
283        }
284        let callback = open_multiple_text_files_trampoline::<P>;
285        unsafe {
286            ffi::gtk_file_dialog_open_multiple_text_files(
287                self.to_glib_none().0,
288                parent.map(|p| p.as_ref()).to_glib_none().0,
289                cancellable.map(|p| p.as_ref()).to_glib_none().0,
290                Some(callback),
291                Box_::into_raw(user_data) as *mut _,
292            );
293        }
294    }
295
296    #[cfg(feature = "v4_18")]
297    #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
298    pub fn open_multiple_text_files_future(
299        &self,
300        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
301    ) -> Pin<
302        Box_<
303            dyn std::future::Future<Output = Result<(gio::ListModel, glib::GString), glib::Error>>
304                + 'static,
305        >,
306    > {
307        let parent = parent.map(ToOwned::to_owned);
308        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
309            obj.open_multiple_text_files(
310                parent.as_ref().map(::std::borrow::Borrow::borrow),
311                Some(cancellable),
312                move |res| {
313                    send.resolve(res);
314                },
315            );
316        }))
317    }
318
319    #[cfg(feature = "v4_18")]
320    #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
321    #[doc(alias = "gtk_file_dialog_open_text_file")]
322    pub fn open_text_file<P: FnOnce(Result<(gio::File, glib::GString), glib::Error>) + 'static>(
323        &self,
324        parent: Option<&impl IsA<Window>>,
325        cancellable: Option<&impl IsA<gio::Cancellable>>,
326        callback: P,
327    ) {
328        let main_context = glib::MainContext::ref_thread_default();
329        let is_main_context_owner = main_context.is_owner();
330        let has_acquired_main_context = (!is_main_context_owner)
331            .then(|| main_context.acquire().ok())
332            .flatten();
333        assert!(
334            is_main_context_owner || has_acquired_main_context.is_some(),
335            "Async operations only allowed if the thread is owning the MainContext"
336        );
337
338        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
339            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
340        unsafe extern "C" fn open_text_file_trampoline<
341            P: FnOnce(Result<(gio::File, glib::GString), glib::Error>) + 'static,
342        >(
343            _source_object: *mut glib::gobject_ffi::GObject,
344            res: *mut gio::ffi::GAsyncResult,
345            user_data: glib::ffi::gpointer,
346        ) {
347            let mut error = std::ptr::null_mut();
348            let mut encoding = std::ptr::null();
349            let ret = ffi::gtk_file_dialog_open_text_file_finish(
350                _source_object as *mut _,
351                res,
352                &mut encoding,
353                &mut error,
354            );
355            let result = if error.is_null() {
356                Ok((from_glib_full(ret), from_glib_none(encoding)))
357            } else {
358                Err(from_glib_full(error))
359            };
360            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
361                Box_::from_raw(user_data as *mut _);
362            let callback: P = callback.into_inner();
363            callback(result);
364        }
365        let callback = open_text_file_trampoline::<P>;
366        unsafe {
367            ffi::gtk_file_dialog_open_text_file(
368                self.to_glib_none().0,
369                parent.map(|p| p.as_ref()).to_glib_none().0,
370                cancellable.map(|p| p.as_ref()).to_glib_none().0,
371                Some(callback),
372                Box_::into_raw(user_data) as *mut _,
373            );
374        }
375    }
376
377    #[cfg(feature = "v4_18")]
378    #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
379    pub fn open_text_file_future(
380        &self,
381        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
382    ) -> Pin<
383        Box_<
384            dyn std::future::Future<Output = Result<(gio::File, glib::GString), glib::Error>>
385                + 'static,
386        >,
387    > {
388        let parent = parent.map(ToOwned::to_owned);
389        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
390            obj.open_text_file(
391                parent.as_ref().map(::std::borrow::Borrow::borrow),
392                Some(cancellable),
393                move |res| {
394                    send.resolve(res);
395                },
396            );
397        }))
398    }
399
400    #[doc(alias = "gtk_file_dialog_save")]
401    pub fn save<P: FnOnce(Result<gio::File, glib::Error>) + 'static>(
402        &self,
403        parent: Option<&impl IsA<Window>>,
404        cancellable: Option<&impl IsA<gio::Cancellable>>,
405        callback: P,
406    ) {
407        let main_context = glib::MainContext::ref_thread_default();
408        let is_main_context_owner = main_context.is_owner();
409        let has_acquired_main_context = (!is_main_context_owner)
410            .then(|| main_context.acquire().ok())
411            .flatten();
412        assert!(
413            is_main_context_owner || has_acquired_main_context.is_some(),
414            "Async operations only allowed if the thread is owning the MainContext"
415        );
416
417        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
418            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
419        unsafe extern "C" fn save_trampoline<
420            P: FnOnce(Result<gio::File, glib::Error>) + 'static,
421        >(
422            _source_object: *mut glib::gobject_ffi::GObject,
423            res: *mut gio::ffi::GAsyncResult,
424            user_data: glib::ffi::gpointer,
425        ) {
426            let mut error = std::ptr::null_mut();
427            let ret = ffi::gtk_file_dialog_save_finish(_source_object as *mut _, res, &mut error);
428            let result = if error.is_null() {
429                Ok(from_glib_full(ret))
430            } else {
431                Err(from_glib_full(error))
432            };
433            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
434                Box_::from_raw(user_data as *mut _);
435            let callback: P = callback.into_inner();
436            callback(result);
437        }
438        let callback = save_trampoline::<P>;
439        unsafe {
440            ffi::gtk_file_dialog_save(
441                self.to_glib_none().0,
442                parent.map(|p| p.as_ref()).to_glib_none().0,
443                cancellable.map(|p| p.as_ref()).to_glib_none().0,
444                Some(callback),
445                Box_::into_raw(user_data) as *mut _,
446            );
447        }
448    }
449
450    pub fn save_future(
451        &self,
452        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
453    ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::File, glib::Error>> + 'static>> {
454        let parent = parent.map(ToOwned::to_owned);
455        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
456            obj.save(
457                parent.as_ref().map(::std::borrow::Borrow::borrow),
458                Some(cancellable),
459                move |res| {
460                    send.resolve(res);
461                },
462            );
463        }))
464    }
465
466    #[cfg(feature = "v4_18")]
467    #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
468    #[doc(alias = "gtk_file_dialog_save_text_file")]
469    pub fn save_text_file<
470        P: FnOnce(Result<(gio::File, glib::GString, glib::GString), glib::Error>) + 'static,
471    >(
472        &self,
473        parent: Option<&impl IsA<Window>>,
474        cancellable: Option<&impl IsA<gio::Cancellable>>,
475        callback: P,
476    ) {
477        let main_context = glib::MainContext::ref_thread_default();
478        let is_main_context_owner = main_context.is_owner();
479        let has_acquired_main_context = (!is_main_context_owner)
480            .then(|| main_context.acquire().ok())
481            .flatten();
482        assert!(
483            is_main_context_owner || has_acquired_main_context.is_some(),
484            "Async operations only allowed if the thread is owning the MainContext"
485        );
486
487        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
488            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
489        unsafe extern "C" fn save_text_file_trampoline<
490            P: FnOnce(Result<(gio::File, glib::GString, glib::GString), glib::Error>) + 'static,
491        >(
492            _source_object: *mut glib::gobject_ffi::GObject,
493            res: *mut gio::ffi::GAsyncResult,
494            user_data: glib::ffi::gpointer,
495        ) {
496            let mut error = std::ptr::null_mut();
497            let mut encoding = std::ptr::null();
498            let mut line_ending = std::ptr::null();
499            let ret = ffi::gtk_file_dialog_save_text_file_finish(
500                _source_object as *mut _,
501                res,
502                &mut encoding,
503                &mut line_ending,
504                &mut error,
505            );
506            let result = if error.is_null() {
507                Ok((
508                    from_glib_full(ret),
509                    from_glib_none(encoding),
510                    from_glib_none(line_ending),
511                ))
512            } else {
513                Err(from_glib_full(error))
514            };
515            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
516                Box_::from_raw(user_data as *mut _);
517            let callback: P = callback.into_inner();
518            callback(result);
519        }
520        let callback = save_text_file_trampoline::<P>;
521        unsafe {
522            ffi::gtk_file_dialog_save_text_file(
523                self.to_glib_none().0,
524                parent.map(|p| p.as_ref()).to_glib_none().0,
525                cancellable.map(|p| p.as_ref()).to_glib_none().0,
526                Some(callback),
527                Box_::into_raw(user_data) as *mut _,
528            );
529        }
530    }
531
532    #[cfg(feature = "v4_18")]
533    #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
534    pub fn save_text_file_future(
535        &self,
536        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
537    ) -> Pin<
538        Box_<
539            dyn std::future::Future<
540                    Output = Result<(gio::File, glib::GString, glib::GString), glib::Error>,
541                > + 'static,
542        >,
543    > {
544        let parent = parent.map(ToOwned::to_owned);
545        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
546            obj.save_text_file(
547                parent.as_ref().map(::std::borrow::Borrow::borrow),
548                Some(cancellable),
549                move |res| {
550                    send.resolve(res);
551                },
552            );
553        }))
554    }
555
556    #[doc(alias = "gtk_file_dialog_select_folder")]
557    pub fn select_folder<P: FnOnce(Result<gio::File, glib::Error>) + 'static>(
558        &self,
559        parent: Option<&impl IsA<Window>>,
560        cancellable: Option<&impl IsA<gio::Cancellable>>,
561        callback: P,
562    ) {
563        let main_context = glib::MainContext::ref_thread_default();
564        let is_main_context_owner = main_context.is_owner();
565        let has_acquired_main_context = (!is_main_context_owner)
566            .then(|| main_context.acquire().ok())
567            .flatten();
568        assert!(
569            is_main_context_owner || has_acquired_main_context.is_some(),
570            "Async operations only allowed if the thread is owning the MainContext"
571        );
572
573        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
574            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
575        unsafe extern "C" fn select_folder_trampoline<
576            P: FnOnce(Result<gio::File, glib::Error>) + 'static,
577        >(
578            _source_object: *mut glib::gobject_ffi::GObject,
579            res: *mut gio::ffi::GAsyncResult,
580            user_data: glib::ffi::gpointer,
581        ) {
582            let mut error = std::ptr::null_mut();
583            let ret = ffi::gtk_file_dialog_select_folder_finish(
584                _source_object as *mut _,
585                res,
586                &mut error,
587            );
588            let result = if error.is_null() {
589                Ok(from_glib_full(ret))
590            } else {
591                Err(from_glib_full(error))
592            };
593            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
594                Box_::from_raw(user_data as *mut _);
595            let callback: P = callback.into_inner();
596            callback(result);
597        }
598        let callback = select_folder_trampoline::<P>;
599        unsafe {
600            ffi::gtk_file_dialog_select_folder(
601                self.to_glib_none().0,
602                parent.map(|p| p.as_ref()).to_glib_none().0,
603                cancellable.map(|p| p.as_ref()).to_glib_none().0,
604                Some(callback),
605                Box_::into_raw(user_data) as *mut _,
606            );
607        }
608    }
609
610    pub fn select_folder_future(
611        &self,
612        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
613    ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::File, glib::Error>> + 'static>> {
614        let parent = parent.map(ToOwned::to_owned);
615        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
616            obj.select_folder(
617                parent.as_ref().map(::std::borrow::Borrow::borrow),
618                Some(cancellable),
619                move |res| {
620                    send.resolve(res);
621                },
622            );
623        }))
624    }
625
626    #[doc(alias = "gtk_file_dialog_select_multiple_folders")]
627    pub fn select_multiple_folders<P: FnOnce(Result<gio::ListModel, glib::Error>) + 'static>(
628        &self,
629        parent: Option<&impl IsA<Window>>,
630        cancellable: Option<&impl IsA<gio::Cancellable>>,
631        callback: P,
632    ) {
633        let main_context = glib::MainContext::ref_thread_default();
634        let is_main_context_owner = main_context.is_owner();
635        let has_acquired_main_context = (!is_main_context_owner)
636            .then(|| main_context.acquire().ok())
637            .flatten();
638        assert!(
639            is_main_context_owner || has_acquired_main_context.is_some(),
640            "Async operations only allowed if the thread is owning the MainContext"
641        );
642
643        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
644            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
645        unsafe extern "C" fn select_multiple_folders_trampoline<
646            P: FnOnce(Result<gio::ListModel, glib::Error>) + 'static,
647        >(
648            _source_object: *mut glib::gobject_ffi::GObject,
649            res: *mut gio::ffi::GAsyncResult,
650            user_data: glib::ffi::gpointer,
651        ) {
652            let mut error = std::ptr::null_mut();
653            let ret = ffi::gtk_file_dialog_select_multiple_folders_finish(
654                _source_object as *mut _,
655                res,
656                &mut error,
657            );
658            let result = if error.is_null() {
659                Ok(from_glib_full(ret))
660            } else {
661                Err(from_glib_full(error))
662            };
663            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
664                Box_::from_raw(user_data as *mut _);
665            let callback: P = callback.into_inner();
666            callback(result);
667        }
668        let callback = select_multiple_folders_trampoline::<P>;
669        unsafe {
670            ffi::gtk_file_dialog_select_multiple_folders(
671                self.to_glib_none().0,
672                parent.map(|p| p.as_ref()).to_glib_none().0,
673                cancellable.map(|p| p.as_ref()).to_glib_none().0,
674                Some(callback),
675                Box_::into_raw(user_data) as *mut _,
676            );
677        }
678    }
679
680    pub fn select_multiple_folders_future(
681        &self,
682        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
683    ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::ListModel, glib::Error>> + 'static>>
684    {
685        let parent = parent.map(ToOwned::to_owned);
686        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
687            obj.select_multiple_folders(
688                parent.as_ref().map(::std::borrow::Borrow::borrow),
689                Some(cancellable),
690                move |res| {
691                    send.resolve(res);
692                },
693            );
694        }))
695    }
696
697    #[doc(alias = "gtk_file_dialog_set_accept_label")]
698    #[doc(alias = "accept-label")]
699    pub fn set_accept_label(&self, accept_label: Option<&str>) {
700        unsafe {
701            ffi::gtk_file_dialog_set_accept_label(
702                self.to_glib_none().0,
703                accept_label.to_glib_none().0,
704            );
705        }
706    }
707
708    #[doc(alias = "gtk_file_dialog_set_default_filter")]
709    #[doc(alias = "default-filter")]
710    pub fn set_default_filter(&self, filter: Option<&FileFilter>) {
711        unsafe {
712            ffi::gtk_file_dialog_set_default_filter(self.to_glib_none().0, filter.to_glib_none().0);
713        }
714    }
715
716    #[doc(alias = "gtk_file_dialog_set_filters")]
717    #[doc(alias = "filters")]
718    pub fn set_filters(&self, filters: Option<&impl IsA<gio::ListModel>>) {
719        unsafe {
720            ffi::gtk_file_dialog_set_filters(
721                self.to_glib_none().0,
722                filters.map(|p| p.as_ref()).to_glib_none().0,
723            );
724        }
725    }
726
727    #[doc(alias = "gtk_file_dialog_set_initial_file")]
728    #[doc(alias = "initial-file")]
729    pub fn set_initial_file(&self, file: Option<&impl IsA<gio::File>>) {
730        unsafe {
731            ffi::gtk_file_dialog_set_initial_file(
732                self.to_glib_none().0,
733                file.map(|p| p.as_ref()).to_glib_none().0,
734            );
735        }
736    }
737
738    #[doc(alias = "gtk_file_dialog_set_initial_folder")]
739    #[doc(alias = "initial-folder")]
740    pub fn set_initial_folder(&self, folder: Option<&impl IsA<gio::File>>) {
741        unsafe {
742            ffi::gtk_file_dialog_set_initial_folder(
743                self.to_glib_none().0,
744                folder.map(|p| p.as_ref()).to_glib_none().0,
745            );
746        }
747    }
748
749    #[doc(alias = "gtk_file_dialog_set_initial_name")]
750    #[doc(alias = "initial-name")]
751    pub fn set_initial_name(&self, name: Option<&str>) {
752        unsafe {
753            ffi::gtk_file_dialog_set_initial_name(self.to_glib_none().0, name.to_glib_none().0);
754        }
755    }
756
757    #[doc(alias = "gtk_file_dialog_set_modal")]
758    #[doc(alias = "modal")]
759    pub fn set_modal(&self, modal: bool) {
760        unsafe {
761            ffi::gtk_file_dialog_set_modal(self.to_glib_none().0, modal.into_glib());
762        }
763    }
764
765    #[doc(alias = "gtk_file_dialog_set_title")]
766    #[doc(alias = "title")]
767    pub fn set_title(&self, title: &str) {
768        unsafe {
769            ffi::gtk_file_dialog_set_title(self.to_glib_none().0, title.to_glib_none().0);
770        }
771    }
772
773    #[cfg(feature = "v4_10")]
774    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
775    #[doc(alias = "accept-label")]
776    pub fn connect_accept_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
777        unsafe extern "C" fn notify_accept_label_trampoline<F: Fn(&FileDialog) + 'static>(
778            this: *mut ffi::GtkFileDialog,
779            _param_spec: glib::ffi::gpointer,
780            f: glib::ffi::gpointer,
781        ) {
782            let f: &F = &*(f as *const F);
783            f(&from_glib_borrow(this))
784        }
785        unsafe {
786            let f: Box_<F> = Box_::new(f);
787            connect_raw(
788                self.as_ptr() as *mut _,
789                c"notify::accept-label".as_ptr() as *const _,
790                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
791                    notify_accept_label_trampoline::<F> as *const (),
792                )),
793                Box_::into_raw(f),
794            )
795        }
796    }
797
798    #[cfg(feature = "v4_10")]
799    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
800    #[doc(alias = "default-filter")]
801    pub fn connect_default_filter_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
802        unsafe extern "C" fn notify_default_filter_trampoline<F: Fn(&FileDialog) + 'static>(
803            this: *mut ffi::GtkFileDialog,
804            _param_spec: glib::ffi::gpointer,
805            f: glib::ffi::gpointer,
806        ) {
807            let f: &F = &*(f as *const F);
808            f(&from_glib_borrow(this))
809        }
810        unsafe {
811            let f: Box_<F> = Box_::new(f);
812            connect_raw(
813                self.as_ptr() as *mut _,
814                c"notify::default-filter".as_ptr() as *const _,
815                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
816                    notify_default_filter_trampoline::<F> as *const (),
817                )),
818                Box_::into_raw(f),
819            )
820        }
821    }
822
823    #[cfg(feature = "v4_10")]
824    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
825    #[doc(alias = "filters")]
826    pub fn connect_filters_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
827        unsafe extern "C" fn notify_filters_trampoline<F: Fn(&FileDialog) + 'static>(
828            this: *mut ffi::GtkFileDialog,
829            _param_spec: glib::ffi::gpointer,
830            f: glib::ffi::gpointer,
831        ) {
832            let f: &F = &*(f as *const F);
833            f(&from_glib_borrow(this))
834        }
835        unsafe {
836            let f: Box_<F> = Box_::new(f);
837            connect_raw(
838                self.as_ptr() as *mut _,
839                c"notify::filters".as_ptr() as *const _,
840                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
841                    notify_filters_trampoline::<F> as *const (),
842                )),
843                Box_::into_raw(f),
844            )
845        }
846    }
847
848    #[cfg(feature = "v4_10")]
849    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
850    #[doc(alias = "initial-file")]
851    pub fn connect_initial_file_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
852        unsafe extern "C" fn notify_initial_file_trampoline<F: Fn(&FileDialog) + 'static>(
853            this: *mut ffi::GtkFileDialog,
854            _param_spec: glib::ffi::gpointer,
855            f: glib::ffi::gpointer,
856        ) {
857            let f: &F = &*(f as *const F);
858            f(&from_glib_borrow(this))
859        }
860        unsafe {
861            let f: Box_<F> = Box_::new(f);
862            connect_raw(
863                self.as_ptr() as *mut _,
864                c"notify::initial-file".as_ptr() as *const _,
865                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
866                    notify_initial_file_trampoline::<F> as *const (),
867                )),
868                Box_::into_raw(f),
869            )
870        }
871    }
872
873    #[cfg(feature = "v4_10")]
874    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
875    #[doc(alias = "initial-folder")]
876    pub fn connect_initial_folder_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
877        unsafe extern "C" fn notify_initial_folder_trampoline<F: Fn(&FileDialog) + 'static>(
878            this: *mut ffi::GtkFileDialog,
879            _param_spec: glib::ffi::gpointer,
880            f: glib::ffi::gpointer,
881        ) {
882            let f: &F = &*(f as *const F);
883            f(&from_glib_borrow(this))
884        }
885        unsafe {
886            let f: Box_<F> = Box_::new(f);
887            connect_raw(
888                self.as_ptr() as *mut _,
889                c"notify::initial-folder".as_ptr() as *const _,
890                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
891                    notify_initial_folder_trampoline::<F> as *const (),
892                )),
893                Box_::into_raw(f),
894            )
895        }
896    }
897
898    #[cfg(feature = "v4_10")]
899    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
900    #[doc(alias = "initial-name")]
901    pub fn connect_initial_name_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
902        unsafe extern "C" fn notify_initial_name_trampoline<F: Fn(&FileDialog) + 'static>(
903            this: *mut ffi::GtkFileDialog,
904            _param_spec: glib::ffi::gpointer,
905            f: glib::ffi::gpointer,
906        ) {
907            let f: &F = &*(f as *const F);
908            f(&from_glib_borrow(this))
909        }
910        unsafe {
911            let f: Box_<F> = Box_::new(f);
912            connect_raw(
913                self.as_ptr() as *mut _,
914                c"notify::initial-name".as_ptr() as *const _,
915                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
916                    notify_initial_name_trampoline::<F> as *const (),
917                )),
918                Box_::into_raw(f),
919            )
920        }
921    }
922
923    #[cfg(feature = "v4_10")]
924    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
925    #[doc(alias = "modal")]
926    pub fn connect_modal_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
927        unsafe extern "C" fn notify_modal_trampoline<F: Fn(&FileDialog) + 'static>(
928            this: *mut ffi::GtkFileDialog,
929            _param_spec: glib::ffi::gpointer,
930            f: glib::ffi::gpointer,
931        ) {
932            let f: &F = &*(f as *const F);
933            f(&from_glib_borrow(this))
934        }
935        unsafe {
936            let f: Box_<F> = Box_::new(f);
937            connect_raw(
938                self.as_ptr() as *mut _,
939                c"notify::modal".as_ptr() as *const _,
940                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
941                    notify_modal_trampoline::<F> as *const (),
942                )),
943                Box_::into_raw(f),
944            )
945        }
946    }
947
948    #[cfg(feature = "v4_10")]
949    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
950    #[doc(alias = "title")]
951    pub fn connect_title_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
952        unsafe extern "C" fn notify_title_trampoline<F: Fn(&FileDialog) + 'static>(
953            this: *mut ffi::GtkFileDialog,
954            _param_spec: glib::ffi::gpointer,
955            f: glib::ffi::gpointer,
956        ) {
957            let f: &F = &*(f as *const F);
958            f(&from_glib_borrow(this))
959        }
960        unsafe {
961            let f: Box_<F> = Box_::new(f);
962            connect_raw(
963                self.as_ptr() as *mut _,
964                c"notify::title".as_ptr() as *const _,
965                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
966                    notify_title_trampoline::<F> as *const (),
967                )),
968                Box_::into_raw(f),
969            )
970        }
971    }
972}
973
974#[cfg(feature = "v4_10")]
975#[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
976impl Default for FileDialog {
977    fn default() -> Self {
978        Self::new()
979    }
980}
981
982// rustdoc-stripper-ignore-next
983/// A [builder-pattern] type to construct [`FileDialog`] objects.
984///
985/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
986#[must_use = "The builder must be built to be used"]
987pub struct FileDialogBuilder {
988    builder: glib::object::ObjectBuilder<'static, FileDialog>,
989}
990
991impl FileDialogBuilder {
992    fn new() -> Self {
993        Self {
994            builder: glib::object::Object::builder(),
995        }
996    }
997
998    #[cfg(feature = "v4_10")]
999    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1000    pub fn accept_label(self, accept_label: impl Into<glib::GString>) -> Self {
1001        Self {
1002            builder: self.builder.property("accept-label", accept_label.into()),
1003        }
1004    }
1005
1006    #[cfg(feature = "v4_10")]
1007    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1008    pub fn default_filter(self, default_filter: &FileFilter) -> Self {
1009        Self {
1010            builder: self
1011                .builder
1012                .property("default-filter", default_filter.clone()),
1013        }
1014    }
1015
1016    #[cfg(feature = "v4_10")]
1017    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1018    pub fn filters(self, filters: &impl IsA<gio::ListModel>) -> Self {
1019        Self {
1020            builder: self.builder.property("filters", filters.clone().upcast()),
1021        }
1022    }
1023
1024    #[cfg(feature = "v4_10")]
1025    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1026    pub fn initial_file(self, initial_file: &impl IsA<gio::File>) -> Self {
1027        Self {
1028            builder: self
1029                .builder
1030                .property("initial-file", initial_file.clone().upcast()),
1031        }
1032    }
1033
1034    #[cfg(feature = "v4_10")]
1035    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1036    pub fn initial_folder(self, initial_folder: &impl IsA<gio::File>) -> Self {
1037        Self {
1038            builder: self
1039                .builder
1040                .property("initial-folder", initial_folder.clone().upcast()),
1041        }
1042    }
1043
1044    #[cfg(feature = "v4_10")]
1045    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1046    pub fn initial_name(self, initial_name: impl Into<glib::GString>) -> Self {
1047        Self {
1048            builder: self.builder.property("initial-name", initial_name.into()),
1049        }
1050    }
1051
1052    #[cfg(feature = "v4_10")]
1053    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1054    pub fn modal(self, modal: bool) -> Self {
1055        Self {
1056            builder: self.builder.property("modal", modal),
1057        }
1058    }
1059
1060    #[cfg(feature = "v4_10")]
1061    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
1062    pub fn title(self, title: impl Into<glib::GString>) -> Self {
1063        Self {
1064            builder: self.builder.property("title", title.into()),
1065        }
1066    }
1067
1068    // rustdoc-stripper-ignore-next
1069    /// Build the [`FileDialog`].
1070    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
1071    pub fn build(self) -> FileDialog {
1072        assert_initialized_main_thread!();
1073        self.builder.build()
1074    }
1075}