1use std::ffi::CStr;
4
5use crate::ffi;
6use glib::{collections::StrV, translate::*, GStringPtr};
7
8glib::wrapper! {
9 #[doc(alias = "GtkRecentData")]
10 pub struct RecentData(BoxedInline<ffi::GtkRecentData>);
11
12 match fn {
13 init => |ptr| init_recent_data(ptr),
14 copy_into => |dest, src| copy_into_recent_data(dest, src),
15 clear => |ptr| clear_recent_data(ptr),
16 }
17}
18
19impl RecentData {
20 #[inline]
21 pub fn new(
22 display_name: Option<&str>,
23 description: Option<&str>,
24 mime_type: &str,
25 app_name: &str,
26 app_exec: &str,
27 groups: &[&str],
28 is_private: bool,
29 ) -> Self {
30 assert_initialized_main_thread!();
31 unsafe {
32 Self::unsafe_from(ffi::GtkRecentData {
33 display_name: display_name.to_glib_full(),
34 description: description.to_glib_full(),
35 mime_type: mime_type.to_glib_full(),
36 app_name: app_name.to_glib_full(),
37 app_exec: app_exec.to_glib_full(),
38 groups: groups.to_glib_full(),
39 is_private: is_private.into_glib(),
40 })
41 }
42 }
43
44 #[inline]
45 pub fn display_name(&self) -> Option<&str> {
46 unsafe {
47 if self.inner.display_name.is_null() {
48 None
49 } else {
50 CStr::from_ptr(self.inner.display_name).to_str().ok()
51 }
52 }
53 }
54
55 #[inline]
56 pub fn description(&self) -> Option<&str> {
57 unsafe {
58 if self.inner.description.is_null() {
59 None
60 } else {
61 CStr::from_ptr(self.inner.description).to_str().ok()
62 }
63 }
64 }
65
66 #[inline]
67 pub fn mime_type(&self) -> &str {
68 unsafe { CStr::from_ptr(self.inner.mime_type).to_str().unwrap() }
69 }
70
71 #[inline]
72 pub fn app_name(&self) -> &str {
73 unsafe { CStr::from_ptr(self.inner.app_name).to_str().unwrap() }
74 }
75
76 #[inline]
77 pub fn app_exec(&self) -> &str {
78 unsafe { CStr::from_ptr(self.inner.app_exec).to_str().unwrap() }
79 }
80
81 #[inline]
82 pub fn groups<'a>(&self) -> &'a [GStringPtr] {
83 unsafe { StrV::from_glib_borrow(self.inner.groups as *const _) }
84 }
85
86 #[inline]
87 pub fn is_private(&self) -> bool {
88 unsafe { from_glib(self.inner.is_private) }
89 }
90}
91
92unsafe fn init_recent_data(recent_data: *mut ffi::GtkRecentData) {
93 std::ptr::write(recent_data, std::mem::zeroed());
94}
95
96unsafe fn copy_into_recent_data(dest: *mut ffi::GtkRecentData, src: *const ffi::GtkRecentData) {
97 init_recent_data(dest);
98 (*dest).display_name = glib::ffi::g_strdup((*src).display_name);
99 (*dest).description = glib::ffi::g_strdup((*src).description);
100 (*dest).mime_type = glib::ffi::g_strdup((*src).mime_type);
101 (*dest).app_name = glib::ffi::g_strdup((*src).app_name);
102 (*dest).app_exec = glib::ffi::g_strdup((*src).app_exec);
103 (*dest).groups = glib::ffi::g_strdupv((*src).groups);
104 (*dest).is_private = (*src).is_private;
105}
106
107unsafe fn clear_recent_data(recent_data: *mut ffi::GtkRecentData) {
108 glib::ffi::g_free((*recent_data).display_name as *mut _);
109 glib::ffi::g_free((*recent_data).description as *mut _);
110 glib::ffi::g_free((*recent_data).mime_type as *mut _);
111 glib::ffi::g_free((*recent_data).app_name as *mut _);
112 glib::ffi::g_free((*recent_data).app_exec as *mut _);
113 glib::ffi::g_strfreev((*recent_data).groups as *mut _);
114}