1#[cfg(feature = "futures")]
6#[cfg(any(feature = "v2_50", feature = "dox"))]
7use futures::future;
8use gio_sys;
9use glib::object::IsA;
10use glib::translate::*;
11use glib::GString;
12#[cfg(any(feature = "v2_50", feature = "dox"))]
13use glib_sys;
14#[cfg(any(feature = "v2_50", feature = "dox"))]
15use gobject_sys;
16use std;
17#[cfg(feature = "futures")]
18#[cfg(any(feature = "v2_50", feature = "dox"))]
19use std::boxed::Box as Box_;
20use std::fmt;
21use std::ptr;
22use AppInfoCreateFlags;
23use AppLaunchContext;
24#[cfg(any(feature = "v2_50", feature = "dox"))]
25use Cancellable;
26use Error;
27use File;
28use Icon;
29
30glib_wrapper! {
31 pub struct AppInfo(Interface<gio_sys::GAppInfo>);
32
33 match fn {
34 get_type => || gio_sys::g_app_info_get_type(),
35 }
36}
37
38impl AppInfo {
39 pub fn create_from_commandline<P: AsRef<std::ffi::OsStr>>(
40 commandline: P,
41 application_name: Option<&str>,
42 flags: AppInfoCreateFlags,
43 ) -> Result<AppInfo, Error> {
44 unsafe {
45 let mut error = ptr::null_mut();
46 let ret = gio_sys::g_app_info_create_from_commandline(
47 commandline.as_ref().to_glib_none().0,
48 application_name.to_glib_none().0,
49 flags.to_glib(),
50 &mut error,
51 );
52 if error.is_null() {
53 Ok(from_glib_full(ret))
54 } else {
55 Err(from_glib_full(error))
56 }
57 }
58 }
59
60 pub fn get_all() -> Vec<AppInfo> {
61 unsafe { FromGlibPtrContainer::from_glib_full(gio_sys::g_app_info_get_all()) }
62 }
63
64 pub fn get_all_for_type(content_type: &str) -> Vec<AppInfo> {
65 unsafe {
66 FromGlibPtrContainer::from_glib_full(gio_sys::g_app_info_get_all_for_type(
67 content_type.to_glib_none().0,
68 ))
69 }
70 }
71
72 pub fn get_default_for_type(content_type: &str, must_support_uris: bool) -> Option<AppInfo> {
73 unsafe {
74 from_glib_full(gio_sys::g_app_info_get_default_for_type(
75 content_type.to_glib_none().0,
76 must_support_uris.to_glib(),
77 ))
78 }
79 }
80
81 pub fn get_default_for_uri_scheme(uri_scheme: &str) -> Option<AppInfo> {
82 unsafe {
83 from_glib_full(gio_sys::g_app_info_get_default_for_uri_scheme(
84 uri_scheme.to_glib_none().0,
85 ))
86 }
87 }
88
89 pub fn get_fallback_for_type(content_type: &str) -> Vec<AppInfo> {
90 unsafe {
91 FromGlibPtrContainer::from_glib_full(gio_sys::g_app_info_get_fallback_for_type(
92 content_type.to_glib_none().0,
93 ))
94 }
95 }
96
97 pub fn get_recommended_for_type(content_type: &str) -> Vec<AppInfo> {
98 unsafe {
99 FromGlibPtrContainer::from_glib_full(gio_sys::g_app_info_get_recommended_for_type(
100 content_type.to_glib_none().0,
101 ))
102 }
103 }
104
105 pub fn launch_default_for_uri<P: IsA<AppLaunchContext>>(
106 uri: &str,
107 context: Option<&P>,
108 ) -> Result<(), Error> {
109 unsafe {
110 let mut error = ptr::null_mut();
111 let _ = gio_sys::g_app_info_launch_default_for_uri(
112 uri.to_glib_none().0,
113 context.map(|p| p.as_ref()).to_glib_none().0,
114 &mut error,
115 );
116 if error.is_null() {
117 Ok(())
118 } else {
119 Err(from_glib_full(error))
120 }
121 }
122 }
123
124 #[cfg(any(feature = "v2_50", feature = "dox"))]
125 pub fn launch_default_for_uri_async<
126 P: IsA<AppLaunchContext>,
127 Q: IsA<Cancellable>,
128 R: FnOnce(Result<(), Error>) + Send + 'static,
129 >(
130 uri: &str,
131 context: Option<&P>,
132 cancellable: Option<&Q>,
133 callback: R,
134 ) {
135 let user_data: Box<R> = Box::new(callback);
136 unsafe extern "C" fn launch_default_for_uri_async_trampoline<
137 R: FnOnce(Result<(), Error>) + Send + 'static,
138 >(
139 _source_object: *mut gobject_sys::GObject,
140 res: *mut gio_sys::GAsyncResult,
141 user_data: glib_sys::gpointer,
142 ) {
143 let mut error = ptr::null_mut();
144 let _ = gio_sys::g_app_info_launch_default_for_uri_finish(res, &mut error);
145 let result = if error.is_null() {
146 Ok(())
147 } else {
148 Err(from_glib_full(error))
149 };
150 let callback: Box<R> = Box::from_raw(user_data as *mut _);
151 callback(result);
152 }
153 let callback = launch_default_for_uri_async_trampoline::<R>;
154 unsafe {
155 gio_sys::g_app_info_launch_default_for_uri_async(
156 uri.to_glib_none().0,
157 context.map(|p| p.as_ref()).to_glib_none().0,
158 cancellable.map(|p| p.as_ref()).to_glib_none().0,
159 Some(callback),
160 Box::into_raw(user_data) as *mut _,
161 );
162 }
163 }
164
165 #[cfg(feature = "futures")]
166 #[cfg(any(feature = "v2_50", feature = "dox"))]
167 pub fn launch_default_for_uri_async_future<P: IsA<AppLaunchContext> + Clone + 'static>(
168 uri: &str,
169 context: Option<&P>,
170 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
171 use fragile::Fragile;
172 use GioFuture;
173
174 let uri = String::from(uri);
175 let context = context.map(ToOwned::to_owned);
176 GioFuture::new(&(), move |_obj, send| {
177 let cancellable = Cancellable::new();
178 let send = Fragile::new(send);
179 Self::launch_default_for_uri_async(
180 &uri,
181 context.as_ref().map(::std::borrow::Borrow::borrow),
182 Some(&cancellable),
183 move |res| {
184 let _ = send.into_inner().send(res);
185 },
186 );
187
188 cancellable
189 })
190 }
191
192 pub fn reset_type_associations(content_type: &str) {
193 unsafe {
194 gio_sys::g_app_info_reset_type_associations(content_type.to_glib_none().0);
195 }
196 }
197}
198
199pub const NONE_APP_INFO: Option<&AppInfo> = None;
200
201pub trait AppInfoExt: 'static {
202 fn add_supports_type(&self, content_type: &str) -> Result<(), Error>;
203
204 fn can_delete(&self) -> bool;
205
206 fn can_remove_supports_type(&self) -> bool;
207
208 fn delete(&self) -> bool;
209
210 fn dup(&self) -> Option<AppInfo>;
211
212 fn equal<P: IsA<AppInfo>>(&self, appinfo2: &P) -> bool;
213
214 fn get_commandline(&self) -> Option<std::path::PathBuf>;
215
216 fn get_description(&self) -> Option<GString>;
217
218 fn get_display_name(&self) -> Option<GString>;
219
220 fn get_executable(&self) -> Option<std::path::PathBuf>;
221
222 fn get_icon(&self) -> Option<Icon>;
223
224 fn get_id(&self) -> Option<GString>;
225
226 fn get_name(&self) -> Option<GString>;
227
228 fn get_supported_types(&self) -> Vec<GString>;
229
230 fn launch<P: IsA<AppLaunchContext>>(
231 &self,
232 files: &[File],
233 context: Option<&P>,
234 ) -> Result<(), Error>;
235
236 fn launch_uris<P: IsA<AppLaunchContext>>(
237 &self,
238 uris: &[&str],
239 context: Option<&P>,
240 ) -> Result<(), Error>;
241
242 fn remove_supports_type(&self, content_type: &str) -> Result<(), Error>;
243
244 fn set_as_default_for_extension<P: AsRef<std::path::Path>>(
245 &self,
246 extension: P,
247 ) -> Result<(), Error>;
248
249 fn set_as_default_for_type(&self, content_type: &str) -> Result<(), Error>;
250
251 fn set_as_last_used_for_type(&self, content_type: &str) -> Result<(), Error>;
252
253 fn should_show(&self) -> bool;
254
255 fn supports_files(&self) -> bool;
256
257 fn supports_uris(&self) -> bool;
258}
259
260impl<O: IsA<AppInfo>> AppInfoExt for O {
261 fn add_supports_type(&self, content_type: &str) -> Result<(), Error> {
262 unsafe {
263 let mut error = ptr::null_mut();
264 let _ = gio_sys::g_app_info_add_supports_type(
265 self.as_ref().to_glib_none().0,
266 content_type.to_glib_none().0,
267 &mut error,
268 );
269 if error.is_null() {
270 Ok(())
271 } else {
272 Err(from_glib_full(error))
273 }
274 }
275 }
276
277 fn can_delete(&self) -> bool {
278 unsafe {
279 from_glib(gio_sys::g_app_info_can_delete(
280 self.as_ref().to_glib_none().0,
281 ))
282 }
283 }
284
285 fn can_remove_supports_type(&self) -> bool {
286 unsafe {
287 from_glib(gio_sys::g_app_info_can_remove_supports_type(
288 self.as_ref().to_glib_none().0,
289 ))
290 }
291 }
292
293 fn delete(&self) -> bool {
294 unsafe { from_glib(gio_sys::g_app_info_delete(self.as_ref().to_glib_none().0)) }
295 }
296
297 fn dup(&self) -> Option<AppInfo> {
298 unsafe { from_glib_full(gio_sys::g_app_info_dup(self.as_ref().to_glib_none().0)) }
299 }
300
301 fn equal<P: IsA<AppInfo>>(&self, appinfo2: &P) -> bool {
302 unsafe {
303 from_glib(gio_sys::g_app_info_equal(
304 self.as_ref().to_glib_none().0,
305 appinfo2.as_ref().to_glib_none().0,
306 ))
307 }
308 }
309
310 fn get_commandline(&self) -> Option<std::path::PathBuf> {
311 unsafe {
312 from_glib_none(gio_sys::g_app_info_get_commandline(
313 self.as_ref().to_glib_none().0,
314 ))
315 }
316 }
317
318 fn get_description(&self) -> Option<GString> {
319 unsafe {
320 from_glib_none(gio_sys::g_app_info_get_description(
321 self.as_ref().to_glib_none().0,
322 ))
323 }
324 }
325
326 fn get_display_name(&self) -> Option<GString> {
327 unsafe {
328 from_glib_none(gio_sys::g_app_info_get_display_name(
329 self.as_ref().to_glib_none().0,
330 ))
331 }
332 }
333
334 fn get_executable(&self) -> Option<std::path::PathBuf> {
335 unsafe {
336 from_glib_none(gio_sys::g_app_info_get_executable(
337 self.as_ref().to_glib_none().0,
338 ))
339 }
340 }
341
342 fn get_icon(&self) -> Option<Icon> {
343 unsafe { from_glib_none(gio_sys::g_app_info_get_icon(self.as_ref().to_glib_none().0)) }
344 }
345
346 fn get_id(&self) -> Option<GString> {
347 unsafe { from_glib_none(gio_sys::g_app_info_get_id(self.as_ref().to_glib_none().0)) }
348 }
349
350 fn get_name(&self) -> Option<GString> {
351 unsafe { from_glib_none(gio_sys::g_app_info_get_name(self.as_ref().to_glib_none().0)) }
352 }
353
354 fn get_supported_types(&self) -> Vec<GString> {
355 unsafe {
356 FromGlibPtrContainer::from_glib_none(gio_sys::g_app_info_get_supported_types(
357 self.as_ref().to_glib_none().0,
358 ))
359 }
360 }
361
362 fn launch<P: IsA<AppLaunchContext>>(
363 &self,
364 files: &[File],
365 context: Option<&P>,
366 ) -> Result<(), Error> {
367 unsafe {
368 let mut error = ptr::null_mut();
369 let _ = gio_sys::g_app_info_launch(
370 self.as_ref().to_glib_none().0,
371 files.to_glib_none().0,
372 context.map(|p| p.as_ref()).to_glib_none().0,
373 &mut error,
374 );
375 if error.is_null() {
376 Ok(())
377 } else {
378 Err(from_glib_full(error))
379 }
380 }
381 }
382
383 fn launch_uris<P: IsA<AppLaunchContext>>(
384 &self,
385 uris: &[&str],
386 context: Option<&P>,
387 ) -> Result<(), Error> {
388 unsafe {
389 let mut error = ptr::null_mut();
390 let _ = gio_sys::g_app_info_launch_uris(
391 self.as_ref().to_glib_none().0,
392 uris.to_glib_none().0,
393 context.map(|p| p.as_ref()).to_glib_none().0,
394 &mut error,
395 );
396 if error.is_null() {
397 Ok(())
398 } else {
399 Err(from_glib_full(error))
400 }
401 }
402 }
403
404 fn remove_supports_type(&self, content_type: &str) -> Result<(), Error> {
405 unsafe {
406 let mut error = ptr::null_mut();
407 let _ = gio_sys::g_app_info_remove_supports_type(
408 self.as_ref().to_glib_none().0,
409 content_type.to_glib_none().0,
410 &mut error,
411 );
412 if error.is_null() {
413 Ok(())
414 } else {
415 Err(from_glib_full(error))
416 }
417 }
418 }
419
420 fn set_as_default_for_extension<P: AsRef<std::path::Path>>(
421 &self,
422 extension: P,
423 ) -> Result<(), Error> {
424 unsafe {
425 let mut error = ptr::null_mut();
426 let _ = gio_sys::g_app_info_set_as_default_for_extension(
427 self.as_ref().to_glib_none().0,
428 extension.as_ref().to_glib_none().0,
429 &mut error,
430 );
431 if error.is_null() {
432 Ok(())
433 } else {
434 Err(from_glib_full(error))
435 }
436 }
437 }
438
439 fn set_as_default_for_type(&self, content_type: &str) -> Result<(), Error> {
440 unsafe {
441 let mut error = ptr::null_mut();
442 let _ = gio_sys::g_app_info_set_as_default_for_type(
443 self.as_ref().to_glib_none().0,
444 content_type.to_glib_none().0,
445 &mut error,
446 );
447 if error.is_null() {
448 Ok(())
449 } else {
450 Err(from_glib_full(error))
451 }
452 }
453 }
454
455 fn set_as_last_used_for_type(&self, content_type: &str) -> Result<(), Error> {
456 unsafe {
457 let mut error = ptr::null_mut();
458 let _ = gio_sys::g_app_info_set_as_last_used_for_type(
459 self.as_ref().to_glib_none().0,
460 content_type.to_glib_none().0,
461 &mut error,
462 );
463 if error.is_null() {
464 Ok(())
465 } else {
466 Err(from_glib_full(error))
467 }
468 }
469 }
470
471 fn should_show(&self) -> bool {
472 unsafe {
473 from_glib(gio_sys::g_app_info_should_show(
474 self.as_ref().to_glib_none().0,
475 ))
476 }
477 }
478
479 fn supports_files(&self) -> bool {
480 unsafe {
481 from_glib(gio_sys::g_app_info_supports_files(
482 self.as_ref().to_glib_none().0,
483 ))
484 }
485 }
486
487 fn supports_uris(&self) -> bool {
488 unsafe {
489 from_glib(gio_sys::g_app_info_supports_uris(
490 self.as_ref().to_glib_none().0,
491 ))
492 }
493 }
494}
495
496impl fmt::Display for AppInfo {
497 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
498 write!(f, "AppInfo")
499 }
500}