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};
6use glib::{
7    prelude::*,
8    signal::{connect_raw, SignalHandlerId},
9    translate::*,
10};
11use std::{boxed::Box as Box_, fmt, mem::transmute};
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 | Writeable
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 | Writeable
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 | Writeable
195    ///
196    ///
197    /// #### `title`
198    ///  The title of the dialog window
199    ///
200    /// Readable | Writeable
201    ///
202    ///
203    /// #### `transient-for`
204    ///  The transient parent of the dialog, or [`None`] for none.
205    ///
206    /// Readable | Writeable | Construct
207    ///
208    ///
209    /// #### `visible`
210    ///  Whether the window is currenlty visible.
211    ///
212    /// Readable | Writeable
213    /// </details>
214    /// <details><summary><h4>FileChooser</h4></summary>
215    ///
216    ///
217    /// #### `action`
218    ///  Readable | Writeable
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 | Writeable
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 | Writeable
234    ///
235    ///
236    /// #### `extra-widget`
237    ///  Readable | Writeable
238    ///
239    ///
240    /// #### `filter`
241    ///  Readable | Writeable
242    ///
243    ///
244    /// #### `local-only`
245    ///  Readable | Writeable
246    ///
247    ///
248    /// #### `preview-widget`
249    ///  Readable | Writeable
250    ///
251    ///
252    /// #### `preview-widget-active`
253    ///  Readable | Writeable
254    ///
255    ///
256    /// #### `select-multiple`
257    ///  Readable | Writeable
258    ///
259    ///
260    /// #### `show-hidden`
261    ///  Readable | Writeable
262    ///
263    ///
264    /// #### `use-preview-label`
265    ///  Readable | Writeable
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    pub fn accept_label(&self) -> Option<glib::GString> {
332        unsafe {
333            from_glib_none(ffi::gtk_file_chooser_native_get_accept_label(
334                self.to_glib_none().0,
335            ))
336        }
337    }
338
339    /// Retrieves the custom label text for the cancel button.
340    ///
341    /// # Returns
342    ///
343    /// The custom label, or [`None`] for the default. This string
344    /// is owned by GTK+ and should not be modified or freed
345    #[doc(alias = "gtk_file_chooser_native_get_cancel_label")]
346    #[doc(alias = "get_cancel_label")]
347    pub fn cancel_label(&self) -> Option<glib::GString> {
348        unsafe {
349            from_glib_none(ffi::gtk_file_chooser_native_get_cancel_label(
350                self.to_glib_none().0,
351            ))
352        }
353    }
354
355    /// Sets the custom label text for the accept button.
356    ///
357    /// If characters in `label` are preceded by an underscore, they are underlined.
358    /// If you need a literal underscore character in a label, use “__” (two
359    /// underscores). The first underlined character represents a keyboard
360    /// accelerator called a mnemonic.
361    /// Pressing Alt and that key activates the button.
362    /// ## `accept_label`
363    /// custom label or [`None`] for the default
364    #[doc(alias = "gtk_file_chooser_native_set_accept_label")]
365    pub fn set_accept_label(&self, accept_label: Option<&str>) {
366        unsafe {
367            ffi::gtk_file_chooser_native_set_accept_label(
368                self.to_glib_none().0,
369                accept_label.to_glib_none().0,
370            );
371        }
372    }
373
374    /// Sets the custom label text for the cancel button.
375    ///
376    /// If characters in `label` are preceded by an underscore, they are underlined.
377    /// If you need a literal underscore character in a label, use “__” (two
378    /// underscores). The first underlined character represents a keyboard
379    /// accelerator called a mnemonic.
380    /// Pressing Alt and that key activates the button.
381    /// ## `cancel_label`
382    /// custom label or [`None`] for the default
383    #[doc(alias = "gtk_file_chooser_native_set_cancel_label")]
384    pub fn set_cancel_label(&self, cancel_label: Option<&str>) {
385        unsafe {
386            ffi::gtk_file_chooser_native_set_cancel_label(
387                self.to_glib_none().0,
388                cancel_label.to_glib_none().0,
389            );
390        }
391    }
392
393    #[doc(alias = "accept-label")]
394    pub fn connect_accept_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
395        unsafe extern "C" fn notify_accept_label_trampoline<F: Fn(&FileChooserNative) + 'static>(
396            this: *mut ffi::GtkFileChooserNative,
397            _param_spec: glib::ffi::gpointer,
398            f: glib::ffi::gpointer,
399        ) {
400            let f: &F = &*(f as *const F);
401            f(&from_glib_borrow(this))
402        }
403        unsafe {
404            let f: Box_<F> = Box_::new(f);
405            connect_raw(
406                self.as_ptr() as *mut _,
407                b"notify::accept-label\0".as_ptr() as *const _,
408                Some(transmute::<_, unsafe extern "C" fn()>(
409                    notify_accept_label_trampoline::<F> as *const (),
410                )),
411                Box_::into_raw(f),
412            )
413        }
414    }
415
416    #[doc(alias = "cancel-label")]
417    pub fn connect_cancel_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
418        unsafe extern "C" fn notify_cancel_label_trampoline<F: Fn(&FileChooserNative) + 'static>(
419            this: *mut ffi::GtkFileChooserNative,
420            _param_spec: glib::ffi::gpointer,
421            f: glib::ffi::gpointer,
422        ) {
423            let f: &F = &*(f as *const F);
424            f(&from_glib_borrow(this))
425        }
426        unsafe {
427            let f: Box_<F> = Box_::new(f);
428            connect_raw(
429                self.as_ptr() as *mut _,
430                b"notify::cancel-label\0".as_ptr() as *const _,
431                Some(transmute::<_, unsafe extern "C" fn()>(
432                    notify_cancel_label_trampoline::<F> as *const (),
433                )),
434                Box_::into_raw(f),
435            )
436        }
437    }
438}
439
440impl Default for FileChooserNative {
441    fn default() -> Self {
442        glib::object::Object::new::<Self>()
443    }
444}
445
446// rustdoc-stripper-ignore-next
447/// A [builder-pattern] type to construct [`FileChooserNative`] objects.
448///
449/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
450#[must_use = "The builder must be built to be used"]
451pub struct FileChooserNativeBuilder {
452    builder: glib::object::ObjectBuilder<'static, FileChooserNative>,
453}
454
455impl FileChooserNativeBuilder {
456    fn new() -> Self {
457        Self {
458            builder: glib::object::Object::builder(),
459        }
460    }
461
462    /// The text used for the label on the accept button in the dialog, or
463    /// [`None`] to use the default text.
464    pub fn accept_label(self, accept_label: impl Into<glib::GString>) -> Self {
465        Self {
466            builder: self.builder.property("accept-label", accept_label.into()),
467        }
468    }
469
470    /// The text used for the label on the cancel button in the dialog, or
471    /// [`None`] to use the default text.
472    pub fn cancel_label(self, cancel_label: impl Into<glib::GString>) -> Self {
473        Self {
474            builder: self.builder.property("cancel-label", cancel_label.into()),
475        }
476    }
477
478    /// Whether the window should be modal with respect to its transient parent.
479    pub fn modal(self, modal: bool) -> Self {
480        Self {
481            builder: self.builder.property("modal", modal),
482        }
483    }
484
485    /// The title of the dialog window
486    pub fn title(self, title: impl Into<glib::GString>) -> Self {
487        Self {
488            builder: self.builder.property("title", title.into()),
489        }
490    }
491
492    /// The transient parent of the dialog, or [`None`] for none.
493    pub fn transient_for(self, transient_for: &impl IsA<Window>) -> Self {
494        Self {
495            builder: self
496                .builder
497                .property("transient-for", transient_for.clone().upcast()),
498        }
499    }
500
501    /// Whether the window is currenlty visible.
502    pub fn visible(self, visible: bool) -> Self {
503        Self {
504            builder: self.builder.property("visible", visible),
505        }
506    }
507
508    pub fn action(self, action: FileChooserAction) -> Self {
509        Self {
510            builder: self.builder.property("action", action),
511        }
512    }
513
514    /// Whether a file chooser not in [`FileChooserAction::Open`][crate::FileChooserAction::Open] mode
515    /// will offer the user to create new folders.
516    pub fn create_folders(self, create_folders: bool) -> Self {
517        Self {
518            builder: self.builder.property("create-folders", create_folders),
519        }
520    }
521
522    /// Whether a file chooser in [`FileChooserAction::Save`][crate::FileChooserAction::Save] mode
523    /// will present an overwrite confirmation dialog if the user
524    /// selects a file name that already exists.
525    pub fn do_overwrite_confirmation(self, do_overwrite_confirmation: bool) -> Self {
526        Self {
527            builder: self
528                .builder
529                .property("do-overwrite-confirmation", do_overwrite_confirmation),
530        }
531    }
532
533    pub fn extra_widget(self, extra_widget: &impl IsA<Widget>) -> Self {
534        Self {
535            builder: self
536                .builder
537                .property("extra-widget", extra_widget.clone().upcast()),
538        }
539    }
540
541    pub fn filter(self, filter: &FileFilter) -> Self {
542        Self {
543            builder: self.builder.property("filter", filter.clone()),
544        }
545    }
546
547    pub fn local_only(self, local_only: bool) -> Self {
548        Self {
549            builder: self.builder.property("local-only", local_only),
550        }
551    }
552
553    pub fn preview_widget(self, preview_widget: &impl IsA<Widget>) -> Self {
554        Self {
555            builder: self
556                .builder
557                .property("preview-widget", preview_widget.clone().upcast()),
558        }
559    }
560
561    pub fn preview_widget_active(self, preview_widget_active: bool) -> Self {
562        Self {
563            builder: self
564                .builder
565                .property("preview-widget-active", preview_widget_active),
566        }
567    }
568
569    pub fn select_multiple(self, select_multiple: bool) -> Self {
570        Self {
571            builder: self.builder.property("select-multiple", select_multiple),
572        }
573    }
574
575    pub fn show_hidden(self, show_hidden: bool) -> Self {
576        Self {
577            builder: self.builder.property("show-hidden", show_hidden),
578        }
579    }
580
581    pub fn use_preview_label(self, use_preview_label: bool) -> Self {
582        Self {
583            builder: self
584                .builder
585                .property("use-preview-label", use_preview_label),
586        }
587    }
588
589    // rustdoc-stripper-ignore-next
590    /// Build the [`FileChooserNative`].
591    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
592    pub fn build(self) -> FileChooserNative {
593        self.builder.build()
594    }
595}
596
597impl fmt::Display for FileChooserNative {
598    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
599        f.write_str("FileChooserNative")
600    }
601}