1use gio_sys;
6use glib;
7use glib::object::Cast;
8use glib::object::IsA;
9use glib::signal::connect_raw;
10use glib::signal::SignalHandlerId;
11use glib::translate::*;
12use glib_sys;
13use libc;
14use std::boxed::Box as Box_;
15use std::fmt;
16use std::mem::transmute;
17use MenuAttributeIter;
18use MenuLinkIter;
19
20glib_wrapper! {
21 pub struct MenuModel(Object<gio_sys::GMenuModel, gio_sys::GMenuModelClass, MenuModelClass>);
22
23 match fn {
24 get_type => || gio_sys::g_menu_model_get_type(),
25 }
26}
27
28pub const NONE_MENU_MODEL: Option<&MenuModel> = None;
29
30pub trait MenuModelExt: 'static {
31 fn get_item_attribute_value(
34 &self,
35 item_index: i32,
36 attribute: &str,
37 expected_type: Option<&glib::VariantTy>,
38 ) -> Option<glib::Variant>;
39
40 fn get_item_link(&self, item_index: i32, link: &str) -> Option<MenuModel>;
41
42 fn get_n_items(&self) -> i32;
43
44 fn is_mutable(&self) -> bool;
45
46 fn items_changed(&self, position: i32, removed: i32, added: i32);
47
48 fn iterate_item_attributes(&self, item_index: i32) -> Option<MenuAttributeIter>;
49
50 fn iterate_item_links(&self, item_index: i32) -> Option<MenuLinkIter>;
51
52 fn connect_items_changed<F: Fn(&Self, i32, i32, i32) + 'static>(&self, f: F)
53 -> SignalHandlerId;
54}
55
56impl<O: IsA<MenuModel>> MenuModelExt for O {
57 fn get_item_attribute_value(
62 &self,
63 item_index: i32,
64 attribute: &str,
65 expected_type: Option<&glib::VariantTy>,
66 ) -> Option<glib::Variant> {
67 unsafe {
68 from_glib_full(gio_sys::g_menu_model_get_item_attribute_value(
69 self.as_ref().to_glib_none().0,
70 item_index,
71 attribute.to_glib_none().0,
72 expected_type.to_glib_none().0,
73 ))
74 }
75 }
76
77 fn get_item_link(&self, item_index: i32, link: &str) -> Option<MenuModel> {
78 unsafe {
79 from_glib_full(gio_sys::g_menu_model_get_item_link(
80 self.as_ref().to_glib_none().0,
81 item_index,
82 link.to_glib_none().0,
83 ))
84 }
85 }
86
87 fn get_n_items(&self) -> i32 {
88 unsafe { gio_sys::g_menu_model_get_n_items(self.as_ref().to_glib_none().0) }
89 }
90
91 fn is_mutable(&self) -> bool {
92 unsafe {
93 from_glib(gio_sys::g_menu_model_is_mutable(
94 self.as_ref().to_glib_none().0,
95 ))
96 }
97 }
98
99 fn items_changed(&self, position: i32, removed: i32, added: i32) {
100 unsafe {
101 gio_sys::g_menu_model_items_changed(
102 self.as_ref().to_glib_none().0,
103 position,
104 removed,
105 added,
106 );
107 }
108 }
109
110 fn iterate_item_attributes(&self, item_index: i32) -> Option<MenuAttributeIter> {
111 unsafe {
112 from_glib_full(gio_sys::g_menu_model_iterate_item_attributes(
113 self.as_ref().to_glib_none().0,
114 item_index,
115 ))
116 }
117 }
118
119 fn iterate_item_links(&self, item_index: i32) -> Option<MenuLinkIter> {
120 unsafe {
121 from_glib_full(gio_sys::g_menu_model_iterate_item_links(
122 self.as_ref().to_glib_none().0,
123 item_index,
124 ))
125 }
126 }
127
128 fn connect_items_changed<F: Fn(&Self, i32, i32, i32) + 'static>(
129 &self,
130 f: F,
131 ) -> SignalHandlerId {
132 unsafe extern "C" fn items_changed_trampoline<P, F: Fn(&P, i32, i32, i32) + 'static>(
133 this: *mut gio_sys::GMenuModel,
134 position: libc::c_int,
135 removed: libc::c_int,
136 added: libc::c_int,
137 f: glib_sys::gpointer,
138 ) where
139 P: IsA<MenuModel>,
140 {
141 let f: &F = &*(f as *const F);
142 f(
143 &MenuModel::from_glib_borrow(this).unsafe_cast(),
144 position,
145 removed,
146 added,
147 )
148 }
149 unsafe {
150 let f: Box_<F> = Box_::new(f);
151 connect_raw(
152 self.as_ptr() as *mut _,
153 b"items-changed\0".as_ptr() as *const _,
154 Some(transmute(items_changed_trampoline::<Self, F> as usize)),
155 Box_::into_raw(f),
156 )
157 }
158 }
159}
160
161impl fmt::Display for MenuModel {
162 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 write!(f, "MenuModel")
164 }
165}