Skip to main content

gtk/auto/
file_chooser_native.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::{FileChooser, FileChooserAction, FileFilter, NativeDialog, Widget, Window, ffi};
6use glib::{
7    prelude::*,
8    signal::{SignalHandlerId, connect_raw},
9    translate::*,
10};
11use std::boxed::Box as Box_;
12
13glib::wrapper! {
14    /// [`FileChooserNative`][crate::FileChooserNative] is an abstraction of a dialog box suitable
15    /// for use with “File/Open” or “File/Save as” commands. By default, this
16    /// just uses a [`FileChooserDialog`][crate::FileChooserDialog] to implement the actual dialog.
17    /// However, on certain platforms, such as Windows and macOS, the native platform
18    /// file chooser is used instead. When the application is running in a
19    /// sandboxed environment without direct filesystem access (such as Flatpak),
20    /// [`FileChooserNative`][crate::FileChooserNative] may call the proper APIs (portals) to let the user
21    /// choose a file and make it available to the application.
22    ///
23    /// While the API of [`FileChooserNative`][crate::FileChooserNative] closely mirrors [`FileChooserDialog`][crate::FileChooserDialog], the main
24    /// difference is that there is no access to any [`Window`][crate::Window] or [`Widget`][crate::Widget] for the dialog.
25    /// This is required, as there may not be one in the case of a platform native dialog.
26    /// Showing, hiding and running the dialog is handled by the [`NativeDialog`][crate::NativeDialog] functions.
27    ///
28    /// ## Typical usage ## {`gtkfilechoosernative`-typical-usage}
29    ///
30    /// In the simplest of cases, you can the following code to use
31    /// [`FileChooserDialog`][crate::FileChooserDialog] to select a file for opening:
32    ///
33    ///
34    /// ```text
35    /// GtkFileChooserNative *native;
36    /// GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
37    /// gint res;
38    ///
39    /// native = gtk_file_chooser_native_new ("Open File",
40    ///                                       parent_window,
41    ///                                       action,
42    ///                                       "_Open",
43    ///                                       "_Cancel");
44    ///
45    /// res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
46    /// if (res == GTK_RESPONSE_ACCEPT)
47    ///   {
48    ///     char *filename;
49    ///     GtkFileChooser *chooser = GTK_FILE_CHOOSER (native);
50    ///     filename = gtk_file_chooser_get_filename (chooser);
51    ///     open_file (filename);
52    ///     g_free (filename);
53    ///   }
54    ///
55    /// g_object_unref (native);
56    /// ```
57    ///
58    /// To use a dialog for saving, you can use this:
59    ///
60    ///
61    /// ```text
62    /// GtkFileChooserNative *native;
63    /// GtkFileChooser *chooser;
64    /// GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
65    /// gint res;
66    ///
67    /// native = gtk_file_chooser_native_new ("Save File",
68    ///                                       parent_window,
69    ///                                       action,
70    ///                                       "_Save",
71    ///                                       "_Cancel");
72    /// chooser = GTK_FILE_CHOOSER (native);
73    ///
74    /// gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE);
75    ///
76    /// if (user_edited_a_new_document)
77    ///   gtk_file_chooser_set_current_name (chooser,
78    ///                                      _("Untitled document"));
79    /// else
80    ///   gtk_file_chooser_set_filename (chooser,
81    ///                                  existing_filename);
82    ///
83    /// res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
84    /// if (res == GTK_RESPONSE_ACCEPT)
85    ///   {
86    ///     char *filename;
87    ///
88    ///     filename = gtk_file_chooser_get_filename (chooser);
89    ///     save_to_file (filename);
90    ///     g_free (filename);
91    ///   }
92    ///
93    /// g_object_unref (native);
94    /// ```
95    ///
96    /// For more information on how to best set up a file dialog, see [`FileChooserDialog`][crate::FileChooserDialog].
97    ///
98    /// ## Response Codes ## {`gtkfilechooserdialognative`-responses}
99    ///
100    /// [`FileChooserNative`][crate::FileChooserNative] inherits from [`NativeDialog`][crate::NativeDialog], which means it
101    /// will return [`ResponseType::Accept`][crate::ResponseType::Accept] if the user accepted, and
102    /// [`ResponseType::Cancel`][crate::ResponseType::Cancel] if he pressed cancel. It can also return
103    /// [`ResponseType::DeleteEvent`][crate::ResponseType::DeleteEvent] if the window was unexpectedly closed.
104    ///
105    /// ## Differences from [`FileChooserDialog`][crate::FileChooserDialog] ## {`gtkfilechooserdialognative`-differences}
106    ///
107    /// There are a few things in the GtkFileChooser API that are not
108    /// possible to use with [`FileChooserNative`][crate::FileChooserNative], as such use would
109    /// prohibit the use of a native dialog.
110    ///
111    /// There is no support for the signals that are emitted when the user
112    /// navigates in the dialog, including:
113    /// * [`current-folder-changed`][struct@crate::FileChooser#current-folder-changed]
114    /// * [`selection-changed`][struct@crate::FileChooser#selection-changed]
115    /// * [`file-activated`][struct@crate::FileChooser#file-activated]
116    /// * [`confirm-overwrite`][struct@crate::FileChooser#confirm-overwrite]
117    ///
118    /// You can also not use the methods that directly control user navigation:
119    /// * [`FileChooserExt::unselect_filename()`][crate::prelude::FileChooserExt::unselect_filename()]
120    /// * [`FileChooserExt::select_all()`][crate::prelude::FileChooserExt::select_all()]
121    /// * [`FileChooserExt::unselect_all()`][crate::prelude::FileChooserExt::unselect_all()]
122    ///
123    /// If you need any of the above you will have to use [`FileChooserDialog`][crate::FileChooserDialog] directly.
124    ///
125    /// No operations that change the the dialog work while the dialog is
126    /// visible. Set all the properties that are required before showing the dialog.
127    ///
128    /// ## Win32 details ## {`gtkfilechooserdialognative`-win32}
129    ///
130    /// On windows the IFileDialog implementation (added in Windows Vista) is
131    /// used. It supports many of the features that [`FileChooserDialog`][crate::FileChooserDialog]
132    /// does, but there are some things it does not handle:
133    ///
134    /// * Extra widgets added with [`FileChooserExt::set_extra_widget()`][crate::prelude::FileChooserExt::set_extra_widget()].
135    ///
136    /// * Use of custom previews by connecting to [`update-preview`][struct@crate::FileChooser#update-preview].
137    ///
138    /// * Any [`FileFilter`][crate::FileFilter] added using a mimetype or custom filter.
139    ///
140    /// If any of these features are used the regular [`FileChooserDialog`][crate::FileChooserDialog]
141    /// will be used in place of the native one.
142    ///
143    /// ## Portal details ## {`gtkfilechooserdialognative`-portal}
144    ///
145    /// When the org.freedesktop.portal.FileChooser portal is available on the
146    /// session bus, it is used to bring up an out-of-process file chooser. Depending
147    /// on the kind of session the application is running in, this may or may not
148    /// be a GTK+ file chooser. In this situation, the following things are not
149    /// supported and will be silently ignored:
150    ///
151    /// * Extra widgets added with [`FileChooserExt::set_extra_widget()`][crate::prelude::FileChooserExt::set_extra_widget()].
152    ///
153    /// * Use of custom previews by connecting to [`update-preview`][struct@crate::FileChooser#update-preview].
154    ///
155    /// * Any [`FileFilter`][crate::FileFilter] added with a custom filter.
156    ///
157    /// ## macOS details ## {`gtkfilechooserdialognative`-macos}
158    ///
159    /// On macOS the NSSavePanel and NSOpenPanel classes are used to provide native
160    /// file chooser dialogs. Some features provided by [`FileChooserDialog`][crate::FileChooserDialog] are
161    /// not supported:
162    ///
163    /// * Extra widgets added with [`FileChooserExt::set_extra_widget()`][crate::prelude::FileChooserExt::set_extra_widget()], unless the
164    ///  widget is an instance of GtkLabel, in which case the label text will be used
165    ///  to set the NSSavePanel message instance property.
166    ///
167    /// * Use of custom previews by connecting to [`update-preview`][struct@crate::FileChooser#update-preview].
168    ///
169    /// * Any [`FileFilter`][crate::FileFilter] added with a custom filter.
170    ///
171    /// * Shortcut folders.
172    ///
173    /// ## Properties
174    ///
175    ///
176    /// #### `accept-label`
177    ///  The text used for the label on the accept button in the dialog, or
178    /// [`None`] to use the default text.
179    ///
180    /// Readable | Writable
181    ///
182    ///
183    /// #### `cancel-label`
184    ///  The text used for the label on the cancel button in the dialog, or
185    /// [`None`] to use the default text.
186    ///
187    /// Readable | Writable
188    /// <details><summary><h4>NativeDialog</h4></summary>
189    ///
190    ///
191    /// #### `modal`
192    ///  Whether the window should be modal with respect to its transient parent.
193    ///
194    /// Readable | Writable
195    ///
196    ///
197    /// #### `title`
198    ///  The title of the dialog window
199    ///
200    /// Readable | Writable
201    ///
202    ///
203    /// #### `transient-for`
204    ///  The transient parent of the dialog, or [`None`] for none.
205    ///
206    /// Readable | Writable | Construct
207    ///
208    ///
209    /// #### `visible`
210    ///  Whether the window is currenlty visible.
211    ///
212    /// Readable | Writable
213    /// </details>
214    /// <details><summary><h4>FileChooser</h4></summary>
215    ///
216    ///
217    /// #### `action`
218    ///  Readable | Writable
219    ///
220    ///
221    /// #### `create-folders`
222    ///  Whether a file chooser not in [`FileChooserAction::Open`][crate::FileChooserAction::Open] mode
223    /// will offer the user to create new folders.
224    ///
225    /// Readable | Writable
226    ///
227    ///
228    /// #### `do-overwrite-confirmation`
229    ///  Whether a file chooser in [`FileChooserAction::Save`][crate::FileChooserAction::Save] mode
230    /// will present an overwrite confirmation dialog if the user
231    /// selects a file name that already exists.
232    ///
233    /// Readable | Writable
234    ///
235    ///
236    /// #### `extra-widget`
237    ///  Readable | Writable
238    ///
239    ///
240    /// #### `filter`
241    ///  Readable | Writable
242    ///
243    ///
244    /// #### `local-only`
245    ///  Readable | Writable
246    ///
247    ///
248    /// #### `preview-widget`
249    ///  Readable | Writable
250    ///
251    ///
252    /// #### `preview-widget-active`
253    ///  Readable | Writable
254    ///
255    ///
256    /// #### `select-multiple`
257    ///  Readable | Writable
258    ///
259    ///
260    /// #### `show-hidden`
261    ///  Readable | Writable
262    ///
263    ///
264    /// #### `use-preview-label`
265    ///  Readable | Writable
266    /// </details>
267    ///
268    /// # Implements
269    ///
270    /// [`NativeDialogExt`][trait@crate::prelude::NativeDialogExt], [`trait@glib::ObjectExt`], [`FileChooserExt`][trait@crate::prelude::FileChooserExt], [`NativeDialogExtManual`][trait@crate::prelude::NativeDialogExtManual], [`FileChooserExtManual`][trait@crate::prelude::FileChooserExtManual]
271    #[doc(alias = "GtkFileChooserNative")]
272    pub struct FileChooserNative(Object<ffi::GtkFileChooserNative, ffi::GtkFileChooserNativeClass>) @extends NativeDialog, @implements FileChooser;
273
274    match fn {
275        type_ => || ffi::gtk_file_chooser_native_get_type(),
276    }
277}
278
279impl FileChooserNative {
280    /// Creates a new [`FileChooserNative`][crate::FileChooserNative].
281    /// ## `title`
282    /// Title of the native, or [`None`]
283    /// ## `parent`
284    /// Transient parent of the native, or [`None`]
285    /// ## `action`
286    /// Open or save mode for the dialog
287    /// ## `accept_label`
288    /// text to go in the accept button, or [`None`] for the default
289    /// ## `cancel_label`
290    /// text to go in the cancel button, or [`None`] for the default
291    ///
292    /// # Returns
293    ///
294    /// a new [`FileChooserNative`][crate::FileChooserNative]
295    #[doc(alias = "gtk_file_chooser_native_new")]
296    pub fn new(
297        title: Option<&str>,
298        parent: Option<&impl IsA<Window>>,
299        action: FileChooserAction,
300        accept_label: Option<&str>,
301        cancel_label: Option<&str>,
302    ) -> FileChooserNative {
303        assert_initialized_main_thread!();
304        unsafe {
305            from_glib_full(ffi::gtk_file_chooser_native_new(
306                title.to_glib_none().0,
307                parent.map(|p| p.as_ref()).to_glib_none().0,
308                action.into_glib(),
309                accept_label.to_glib_none().0,
310                cancel_label.to_glib_none().0,
311            ))
312        }
313    }
314
315    // rustdoc-stripper-ignore-next
316    /// Creates a new builder-pattern struct instance to construct [`FileChooserNative`] objects.
317    ///
318    /// This method returns an instance of [`FileChooserNativeBuilder`](crate::builders::FileChooserNativeBuilder) which can be used to create [`FileChooserNative`] objects.
319    pub fn builder() -> FileChooserNativeBuilder {
320        FileChooserNativeBuilder::new()
321    }
322
323    /// Retrieves the custom label text for the accept button.
324    ///
325    /// # Returns
326    ///
327    /// The custom label, or [`None`] for the default. This string
328    /// is owned by GTK+ and should not be modified or freed
329    #[doc(alias = "gtk_file_chooser_native_get_accept_label")]
330    #[doc(alias = "get_accept_label")]
331    #[doc(alias = "accept-label")]
332    pub fn accept_label(&self) -> Option<glib::GString> {
333        unsafe {
334            from_glib_none(ffi::gtk_file_chooser_native_get_accept_label(
335                self.to_glib_none().0,
336            ))
337        }
338    }
339
340    /// Retrieves the custom label text for the cancel button.
341    ///
342    /// # Returns
343    ///
344    /// The custom label, or [`None`] for the default. This string
345    /// is owned by GTK+ and should not be modified or freed
346    #[doc(alias = "gtk_file_chooser_native_get_cancel_label")]
347    #[doc(alias = "get_cancel_label")]
348    #[doc(alias = "cancel-label")]
349    pub fn cancel_label(&self) -> Option<glib::GString> {
350        unsafe {
351            from_glib_none(ffi::gtk_file_chooser_native_get_cancel_label(
352                self.to_glib_none().0,
353            ))
354        }
355    }
356
357    /// Sets the custom label text for the accept button.
358    ///
359    /// If characters in `label` are preceded by an underscore, they are underlined.
360    /// If you need a literal underscore character in a label, use “__” (two
361    /// underscores). The first underlined character represents a keyboard
362    /// accelerator called a mnemonic.
363    /// Pressing Alt and that key activates the button.
364    /// ## `accept_label`
365    /// custom label or [`None`] for the default
366    #[doc(alias = "gtk_file_chooser_native_set_accept_label")]
367    #[doc(alias = "accept-label")]
368    pub fn set_accept_label(&self, accept_label: Option<&str>) {
369        unsafe {
370            ffi::gtk_file_chooser_native_set_accept_label(
371                self.to_glib_none().0,
372                accept_label.to_glib_none().0,
373            );
374        }
375    }
376
377    /// Sets the custom label text for the cancel button.
378    ///
379    /// If characters in `label` are preceded by an underscore, they are underlined.
380    /// If you need a literal underscore character in a label, use “__” (two
381    /// underscores). The first underlined character represents a keyboard
382    /// accelerator called a mnemonic.
383    /// Pressing Alt and that key activates the button.
384    /// ## `cancel_label`
385    /// custom label or [`None`] for the default
386    #[doc(alias = "gtk_file_chooser_native_set_cancel_label")]
387    #[doc(alias = "cancel-label")]
388    pub fn set_cancel_label(&self, cancel_label: Option<&str>) {
389        unsafe {
390            ffi::gtk_file_chooser_native_set_cancel_label(
391                self.to_glib_none().0,
392                cancel_label.to_glib_none().0,
393            );
394        }
395    }
396
397    #[doc(alias = "accept-label")]
398    pub fn connect_accept_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
399        unsafe extern "C" fn notify_accept_label_trampoline<F: Fn(&FileChooserNative) + 'static>(
400            this: *mut ffi::GtkFileChooserNative,
401            _param_spec: glib::ffi::gpointer,
402            f: glib::ffi::gpointer,
403        ) {
404            unsafe {
405                let f: &F = &*(f as *const F);
406                f(&from_glib_borrow(this))
407            }
408        }
409        unsafe {
410            let f: Box_<F> = Box_::new(f);
411            connect_raw(
412                self.as_ptr() as *mut _,
413                c"notify::accept-label".as_ptr(),
414                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
415                    notify_accept_label_trampoline::<F> as *const (),
416                )),
417                Box_::into_raw(f),
418            )
419        }
420    }
421
422    #[doc(alias = "cancel-label")]
423    pub fn connect_cancel_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
424        unsafe extern "C" fn notify_cancel_label_trampoline<F: Fn(&FileChooserNative) + 'static>(
425            this: *mut ffi::GtkFileChooserNative,
426            _param_spec: glib::ffi::gpointer,
427            f: glib::ffi::gpointer,
428        ) {
429            unsafe {
430                let f: &F = &*(f as *const F);
431                f(&from_glib_borrow(this))
432            }
433        }
434        unsafe {
435            let f: Box_<F> = Box_::new(f);
436            connect_raw(
437                self.as_ptr() as *mut _,
438                c"notify::cancel-label".as_ptr(),
439                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
440                    notify_cancel_label_trampoline::<F> as *const (),
441                )),
442                Box_::into_raw(f),
443            )
444        }
445    }
446}
447
448impl Default for FileChooserNative {
449    fn default() -> Self {
450        glib::object::Object::new::<Self>()
451    }
452}
453
454// rustdoc-stripper-ignore-next
455/// A [builder-pattern] type to construct [`FileChooserNative`] objects.
456///
457/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
458#[must_use = "The builder must be built to be used"]
459pub struct FileChooserNativeBuilder {
460    builder: glib::object::ObjectBuilder<'static, FileChooserNative>,
461}
462
463impl FileChooserNativeBuilder {
464    fn new() -> Self {
465        Self {
466            builder: glib::object::Object::builder(),
467        }
468    }
469
470    /// The text used for the label on the accept button in the dialog, or
471    /// [`None`] to use the default text.
472    pub fn accept_label(self, accept_label: impl Into<glib::GString>) -> Self {
473        Self {
474            builder: self.builder.property("accept-label", accept_label.into()),
475        }
476    }
477
478    /// The text used for the label on the cancel button in the dialog, or
479    /// [`None`] to use the default text.
480    pub fn cancel_label(self, cancel_label: impl Into<glib::GString>) -> Self {
481        Self {
482            builder: self.builder.property("cancel-label", cancel_label.into()),
483        }
484    }
485
486    /// Whether the window should be modal with respect to its transient parent.
487    pub fn modal(self, modal: bool) -> Self {
488        Self {
489            builder: self.builder.property("modal", modal),
490        }
491    }
492
493    /// The title of the dialog window
494    pub fn title(self, title: impl Into<glib::GString>) -> Self {
495        Self {
496            builder: self.builder.property("title", title.into()),
497        }
498    }
499
500    /// The transient parent of the dialog, or [`None`] for none.
501    pub fn transient_for(self, transient_for: &impl IsA<Window>) -> Self {
502        Self {
503            builder: self
504                .builder
505                .property("transient-for", transient_for.clone().upcast()),
506        }
507    }
508
509    /// Whether the window is currenlty visible.
510    pub fn visible(self, visible: bool) -> Self {
511        Self {
512            builder: self.builder.property("visible", visible),
513        }
514    }
515
516    pub fn action(self, action: FileChooserAction) -> Self {
517        Self {
518            builder: self.builder.property("action", action),
519        }
520    }
521
522    /// Whether a file chooser not in [`FileChooserAction::Open`][crate::FileChooserAction::Open] mode
523    /// will offer the user to create new folders.
524    pub fn create_folders(self, create_folders: bool) -> Self {
525        Self {
526            builder: self.builder.property("create-folders", create_folders),
527        }
528    }
529
530    /// Whether a file chooser in [`FileChooserAction::Save`][crate::FileChooserAction::Save] mode
531    /// will present an overwrite confirmation dialog if the user
532    /// selects a file name that already exists.
533    pub fn do_overwrite_confirmation(self, do_overwrite_confirmation: bool) -> Self {
534        Self {
535            builder: self
536                .builder
537                .property("do-overwrite-confirmation", do_overwrite_confirmation),
538        }
539    }
540
541    pub fn extra_widget(self, extra_widget: &impl IsA<Widget>) -> Self {
542        Self {
543            builder: self
544                .builder
545                .property("extra-widget", extra_widget.clone().upcast()),
546        }
547    }
548
549    pub fn filter(self, filter: &FileFilter) -> Self {
550        Self {
551            builder: self.builder.property("filter", filter.clone()),
552        }
553    }
554
555    pub fn local_only(self, local_only: bool) -> Self {
556        Self {
557            builder: self.builder.property("local-only", local_only),
558        }
559    }
560
561    pub fn preview_widget(self, preview_widget: &impl IsA<Widget>) -> Self {
562        Self {
563            builder: self
564                .builder
565                .property("preview-widget", preview_widget.clone().upcast()),
566        }
567    }
568
569    pub fn preview_widget_active(self, preview_widget_active: bool) -> Self {
570        Self {
571            builder: self
572                .builder
573                .property("preview-widget-active", preview_widget_active),
574        }
575    }
576
577    pub fn select_multiple(self, select_multiple: bool) -> Self {
578        Self {
579            builder: self.builder.property("select-multiple", select_multiple),
580        }
581    }
582
583    pub fn show_hidden(self, show_hidden: bool) -> Self {
584        Self {
585            builder: self.builder.property("show-hidden", show_hidden),
586        }
587    }
588
589    pub fn use_preview_label(self, use_preview_label: bool) -> Self {
590        Self {
591            builder: self
592                .builder
593                .property("use-preview-label", use_preview_label),
594        }
595    }
596
597    // rustdoc-stripper-ignore-next
598    /// Build the [`FileChooserNative`].
599    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
600    pub fn build(self) -> FileChooserNative {
601        assert_initialized_main_thread!();
602        self.builder.build()
603    }
604}