[go: up one dir, main page]

gtk4/
recent_data.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use 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}