gtk4/auto/
uri_launcher.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, 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    /// Collects the arguments that are needed to open a uri with an application.
15    ///
16    /// Depending on system configuration, user preferences and available APIs, this
17    /// may or may not show an app chooser dialog or launch the default application
18    /// right away.
19    ///
20    /// The operation is started with the [`launch()`][Self::launch()] function.
21    ///
22    /// To launch a file, use [`FileLauncher`][crate::FileLauncher].
23    ///
24    /// ## Properties
25    ///
26    ///
27    /// #### `uri`
28    ///  The uri to launch.
29    ///
30    /// Readable | Writeable
31    ///
32    /// # Implements
33    ///
34    /// [`trait@glib::ObjectExt`]
35    #[doc(alias = "GtkUriLauncher")]
36    pub struct UriLauncher(Object<ffi::GtkUriLauncher, ffi::GtkUriLauncherClass>);
37
38    match fn {
39        type_ => || ffi::gtk_uri_launcher_get_type(),
40    }
41}
42
43impl UriLauncher {
44    /// Creates a new [`UriLauncher`][crate::UriLauncher] object.
45    /// ## `uri`
46    /// the uri to open
47    ///
48    /// # Returns
49    ///
50    /// the new [`UriLauncher`][crate::UriLauncher]
51    #[doc(alias = "gtk_uri_launcher_new")]
52    pub fn new(uri: &str) -> UriLauncher {
53        assert_initialized_main_thread!();
54        unsafe { from_glib_full(ffi::gtk_uri_launcher_new(uri.to_glib_none().0)) }
55    }
56
57    // rustdoc-stripper-ignore-next
58    /// Creates a new builder-pattern struct instance to construct [`UriLauncher`] objects.
59    ///
60    /// This method returns an instance of [`UriLauncherBuilder`](crate::builders::UriLauncherBuilder) which can be used to create [`UriLauncher`] objects.
61    pub fn builder() -> UriLauncherBuilder {
62        UriLauncherBuilder::new()
63    }
64
65    /// Gets the uri that will be opened.
66    ///
67    /// # Returns
68    ///
69    /// the uri
70    #[doc(alias = "gtk_uri_launcher_get_uri")]
71    #[doc(alias = "get_uri")]
72    pub fn uri(&self) -> Option<glib::GString> {
73        unsafe { from_glib_none(ffi::gtk_uri_launcher_get_uri(self.to_glib_none().0)) }
74    }
75
76    /// Launches an application to open the uri.
77    ///
78    /// This may present an app chooser dialog to the user.
79    /// ## `parent`
80    /// the parent window
81    /// ## `cancellable`
82    /// a cancellable to cancel the operation
83    /// ## `callback`
84    /// a callback to call when the
85    ///   operation is complete
86    #[doc(alias = "gtk_uri_launcher_launch")]
87    pub fn launch<P: FnOnce(Result<(), glib::Error>) + 'static>(
88        &self,
89        parent: Option<&impl IsA<Window>>,
90        cancellable: Option<&impl IsA<gio::Cancellable>>,
91        callback: P,
92    ) {
93        let main_context = glib::MainContext::ref_thread_default();
94        let is_main_context_owner = main_context.is_owner();
95        let has_acquired_main_context = (!is_main_context_owner)
96            .then(|| main_context.acquire().ok())
97            .flatten();
98        assert!(
99            is_main_context_owner || has_acquired_main_context.is_some(),
100            "Async operations only allowed if the thread is owning the MainContext"
101        );
102
103        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
104            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
105        unsafe extern "C" fn launch_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
106            _source_object: *mut glib::gobject_ffi::GObject,
107            res: *mut gio::ffi::GAsyncResult,
108            user_data: glib::ffi::gpointer,
109        ) {
110            let mut error = std::ptr::null_mut();
111            let _ = ffi::gtk_uri_launcher_launch_finish(_source_object as *mut _, res, &mut error);
112            let result = if error.is_null() {
113                Ok(())
114            } else {
115                Err(from_glib_full(error))
116            };
117            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
118                Box_::from_raw(user_data as *mut _);
119            let callback: P = callback.into_inner();
120            callback(result);
121        }
122        let callback = launch_trampoline::<P>;
123        unsafe {
124            ffi::gtk_uri_launcher_launch(
125                self.to_glib_none().0,
126                parent.map(|p| p.as_ref()).to_glib_none().0,
127                cancellable.map(|p| p.as_ref()).to_glib_none().0,
128                Some(callback),
129                Box_::into_raw(user_data) as *mut _,
130            );
131        }
132    }
133
134    pub fn launch_future(
135        &self,
136        parent: Option<&(impl IsA<Window> + Clone + 'static)>,
137    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
138        let parent = parent.map(ToOwned::to_owned);
139        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
140            obj.launch(
141                parent.as_ref().map(::std::borrow::Borrow::borrow),
142                Some(cancellable),
143                move |res| {
144                    send.resolve(res);
145                },
146            );
147        }))
148    }
149
150    /// Sets the uri that will be opened.
151    /// ## `uri`
152    /// the uri
153    #[doc(alias = "gtk_uri_launcher_set_uri")]
154    #[doc(alias = "uri")]
155    pub fn set_uri(&self, uri: Option<&str>) {
156        unsafe {
157            ffi::gtk_uri_launcher_set_uri(self.to_glib_none().0, uri.to_glib_none().0);
158        }
159    }
160
161    #[cfg(feature = "v4_10")]
162    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
163    #[doc(alias = "uri")]
164    pub fn connect_uri_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
165        unsafe extern "C" fn notify_uri_trampoline<F: Fn(&UriLauncher) + 'static>(
166            this: *mut ffi::GtkUriLauncher,
167            _param_spec: glib::ffi::gpointer,
168            f: glib::ffi::gpointer,
169        ) {
170            let f: &F = &*(f as *const F);
171            f(&from_glib_borrow(this))
172        }
173        unsafe {
174            let f: Box_<F> = Box_::new(f);
175            connect_raw(
176                self.as_ptr() as *mut _,
177                b"notify::uri\0".as_ptr() as *const _,
178                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
179                    notify_uri_trampoline::<F> as *const (),
180                )),
181                Box_::into_raw(f),
182            )
183        }
184    }
185}
186
187#[cfg(feature = "v4_10")]
188#[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
189impl Default for UriLauncher {
190    fn default() -> Self {
191        glib::object::Object::new::<Self>()
192    }
193}
194
195// rustdoc-stripper-ignore-next
196/// A [builder-pattern] type to construct [`UriLauncher`] objects.
197///
198/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
199#[must_use = "The builder must be built to be used"]
200pub struct UriLauncherBuilder {
201    builder: glib::object::ObjectBuilder<'static, UriLauncher>,
202}
203
204impl UriLauncherBuilder {
205    fn new() -> Self {
206        Self {
207            builder: glib::object::Object::builder(),
208        }
209    }
210
211    /// The uri to launch.
212    #[cfg(feature = "v4_10")]
213    #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
214    pub fn uri(self, uri: impl Into<glib::GString>) -> Self {
215        Self {
216            builder: self.builder.property("uri", uri.into()),
217        }
218    }
219
220    // rustdoc-stripper-ignore-next
221    /// Build the [`UriLauncher`].
222    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
223    pub fn build(self) -> UriLauncher {
224        assert_initialized_main_thread!();
225        self.builder.build()
226    }
227}