1use glib::{translate::*, Type, Value};
4use libc::c_int;
5
6use crate::{ffi, prelude::*, ListStore, TreeIter, TreeModel};
7
8impl ListStore {
9 #[doc(alias = "gtk_list_store_newv")]
10 #[doc(alias = "gtk_list_store_new")]
11 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
12 #[allow(deprecated)]
13 pub fn new(column_types: &[Type]) -> Self {
14 assert_initialized_main_thread!();
15 unsafe {
16 let mut column_types = column_types
17 .iter()
18 .map(|t| t.into_glib())
19 .collect::<Vec<_>>();
20 from_glib_full(ffi::gtk_list_store_newv(
21 column_types.len() as c_int,
22 column_types.as_mut_ptr(),
23 ))
24 }
25 }
26
27 #[doc(alias = "gtk_list_store_insert_with_values")]
28 #[doc(alias = "gtk_list_store_insert_with_valuesv")]
29 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
30 #[allow(deprecated)]
31 pub fn insert_with_values(
32 &self,
33 position: Option<u32>,
34 columns_and_values: &[(u32, &dyn ToValue)],
35 ) -> TreeIter {
36 unsafe {
37 assert!(
38 position.unwrap_or(0) <= i32::MAX as u32,
39 "can't have more than {} rows",
40 i32::MAX
41 );
42 let n_columns =
43 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
44 as u32;
45 assert!(
46 columns_and_values.len() <= n_columns as usize,
47 "got values for {} columns but only {n_columns} columns exist",
48 columns_and_values.len(),
49 );
50 for (column, value) in columns_and_values {
51 assert!(
52 *column < n_columns,
53 "got column {column} which is higher than the number of columns {n_columns}",
54 );
55 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
56 self.upcast_ref::<TreeModel>().to_glib_none().0,
57 *column as c_int,
58 ));
59 assert!(
60 Value::type_transformable(value.value_type(), type_),
61 "column {column} is of type {type_} but found value of type {}",
62 value.value_type()
63 );
64 }
65
66 let columns = columns_and_values
67 .iter()
68 .map(|(c, _)| *c)
69 .collect::<Vec<_>>();
70 let values = columns_and_values
71 .iter()
72 .map(|(_, v)| v.to_value())
73 .collect::<Vec<_>>();
74
75 let mut iter = TreeIter::uninitialized();
76 ffi::gtk_list_store_insert_with_valuesv(
77 self.to_glib_none().0,
78 iter.to_glib_none_mut().0,
79 position.map_or(-1, |n| n as c_int),
80 mut_override(columns.as_ptr() as *const c_int),
81 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
82 columns.len() as c_int,
83 );
84 iter
85 }
86 }
87
88 #[doc(alias = "gtk_list_store_reorder")]
89 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
90 #[allow(deprecated)]
91 pub fn reorder(&self, new_order: &[u32]) {
92 unsafe {
93 let count = ffi::gtk_tree_model_iter_n_children(
94 self.upcast_ref::<TreeModel>().to_glib_none().0,
95 std::ptr::null_mut(),
96 );
97 let safe_count = count as usize == new_order.len();
98 debug_assert!(
99 safe_count,
100 "Incorrect `new_order` slice length. Expected `{count}`, found `{}`.",
101 new_order.len()
102 );
103 let safe_values = new_order.iter().max().is_none_or(|&max| {
104 let max = max as i32;
105 max >= 0 && max < count
106 });
107 debug_assert!(
108 safe_values,
109 "Some `new_order` slice values are out of range. Maximum safe value: \
110 `{}`. The slice contents: `{new_order:?}`",
111 count - 1,
112 );
113 if safe_count && safe_values {
114 ffi::gtk_list_store_reorder(
115 self.to_glib_none().0,
116 mut_override(new_order.as_ptr() as *const c_int),
117 );
118 }
119 }
120 }
121
122 #[doc(alias = "gtk_list_store_set")]
123 #[doc(alias = "gtk_list_store_set_valuesv")]
124 #[doc(alias = "gtk_list_store_set_valist")]
125 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
126 #[allow(deprecated)]
127 pub fn set(&self, iter: &TreeIter, columns_and_values: &[(u32, &dyn ToValue)]) {
128 unsafe {
129 let n_columns =
130 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
131 as u32;
132 assert!(
133 columns_and_values.len() <= n_columns as usize,
134 "got values for {} columns but only {n_columns} columns exist",
135 columns_and_values.len(),
136 );
137 for (column, value) in columns_and_values {
138 assert!(
139 *column < n_columns,
140 "got column {column} which is higher than the number of columns {n_columns}",
141 );
142 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
143 self.upcast_ref::<TreeModel>().to_glib_none().0,
144 *column as c_int,
145 ));
146 assert!(
147 Value::type_transformable(value.value_type(), type_),
148 "column {column} is of type {type_} but found value of type {}",
149 value.value_type()
150 );
151 }
152
153 let columns = columns_and_values
154 .iter()
155 .map(|(c, _)| *c)
156 .collect::<Vec<_>>();
157 let values = columns_and_values
158 .iter()
159 .map(|(_, v)| v.to_value())
160 .collect::<Vec<_>>();
161
162 ffi::gtk_list_store_set_valuesv(
163 self.to_glib_none().0,
164 mut_override(iter.to_glib_none().0),
165 mut_override(columns.as_ptr() as *const c_int),
166 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
167 columns.len() as c_int,
168 );
169 }
170 }
171
172 #[doc(alias = "gtk_list_store_set_column_types")]
173 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
174 #[allow(deprecated)]
175 pub fn set_column_types(&self, types: &[glib::Type]) {
176 unsafe {
177 let types_ptr: Vec<glib::ffi::GType> = types.iter().map(|t| t.into_glib()).collect();
178 ffi::gtk_list_store_set_column_types(
179 self.to_glib_none().0,
180 types.len() as i32,
181 mut_override(types_ptr.as_ptr()),
182 )
183 }
184 }
185
186 #[doc(alias = "gtk_list_store_set_value")]
187 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
188 #[allow(deprecated)]
189 pub fn set_value(&self, iter: &TreeIter, column: u32, value: &Value) {
190 unsafe {
191 let columns =
192 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
193 as u32;
194 assert!(
195 column < columns,
196 "got column {column} which is higher than the number of columns {columns}",
197 );
198
199 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
200 self.upcast_ref::<TreeModel>().to_glib_none().0,
201 column as c_int,
202 ));
203 assert!(
204 Value::type_transformable(value.type_(), type_),
205 "column {column} is of type {type_} but found value of type {}",
206 value.type_()
207 );
208
209 ffi::gtk_list_store_set_value(
210 self.to_glib_none().0,
211 mut_override(iter.to_glib_none().0),
212 column as c_int,
213 mut_override(value.to_glib_none().0),
214 );
215 }
216 }
217}