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")]
37 #[doc(alias = "gtk_list_store_new")]
38 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
39 #[allow(deprecated)]
40 pub fn new(column_types: &[Type]) -> Self {
41 assert_initialized_main_thread!();
42 unsafe {
43 let mut column_types = column_types
44 .iter()
45 .map(|t| t.into_glib())
46 .collect::<Vec<_>>();
47 from_glib_full(ffi::gtk_list_store_newv(
48 column_types.len() as c_int,
49 column_types.as_mut_ptr(),
50 ))
51 }
52 }
53
54 #[doc(alias = "gtk_list_store_insert_with_values")]
76 #[doc(alias = "gtk_list_store_insert_with_valuesv")]
77 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
78 #[allow(deprecated)]
79 pub fn insert_with_values(
80 &self,
81 position: Option<u32>,
82 columns_and_values: &[(u32, &dyn ToValue)],
83 ) -> TreeIter {
84 unsafe {
85 assert!(
86 position.unwrap_or(0) <= i32::MAX as u32,
87 "can't have more than {} rows",
88 i32::MAX
89 );
90 let n_columns =
91 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
92 as u32;
93 assert!(
94 columns_and_values.len() <= n_columns as usize,
95 "got values for {} columns but only {n_columns} columns exist",
96 columns_and_values.len(),
97 );
98 for (column, value) in columns_and_values {
99 assert!(
100 *column < n_columns,
101 "got column {column} which is higher than the number of columns {n_columns}",
102 );
103 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
104 self.upcast_ref::<TreeModel>().to_glib_none().0,
105 *column as c_int,
106 ));
107 assert!(
108 Value::type_transformable(value.value_type(), type_),
109 "column {column} is of type {type_} but found value of type {}",
110 value.value_type()
111 );
112 }
113
114 let columns = columns_and_values
115 .iter()
116 .map(|(c, _)| *c)
117 .collect::<Vec<_>>();
118 let values = columns_and_values
119 .iter()
120 .map(|(_, v)| v.to_value())
121 .collect::<Vec<_>>();
122
123 let mut iter = TreeIter::uninitialized();
124 ffi::gtk_list_store_insert_with_valuesv(
125 self.to_glib_none().0,
126 iter.to_glib_none_mut().0,
127 position.map_or(-1, |n| n as c_int),
128 mut_override(columns.as_ptr() as *const c_int),
129 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
130 columns.len() as c_int,
131 );
132 iter
133 }
134 }
135
136 #[doc(alias = "gtk_list_store_reorder")]
148 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
149 #[allow(deprecated)]
150 pub fn reorder(&self, new_order: &[u32]) {
151 unsafe {
152 let count = ffi::gtk_tree_model_iter_n_children(
153 self.upcast_ref::<TreeModel>().to_glib_none().0,
154 std::ptr::null_mut(),
155 );
156 let safe_count = count as usize == new_order.len();
157 debug_assert!(
158 safe_count,
159 "Incorrect `new_order` slice length. Expected `{count}`, found `{}`.",
160 new_order.len()
161 );
162 let safe_values = new_order.iter().max().map_or(true, |&max| {
163 let max = max as i32;
164 max >= 0 && max < count
165 });
166 debug_assert!(
167 safe_values,
168 "Some `new_order` slice values are out of range. Maximum safe value: \
169 `{}`. The slice contents: `{new_order:?}`",
170 count - 1,
171 );
172 if safe_count && safe_values {
173 ffi::gtk_list_store_reorder(
174 self.to_glib_none().0,
175 mut_override(new_order.as_ptr() as *const c_int),
176 );
177 }
178 }
179 }
180
181 #[doc(alias = "gtk_list_store_set")]
197 #[doc(alias = "gtk_list_store_set_valuesv")]
198 #[doc(alias = "gtk_list_store_set_valist")]
199 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
200 #[allow(deprecated)]
201 pub fn set(&self, iter: &TreeIter, columns_and_values: &[(u32, &dyn ToValue)]) {
202 unsafe {
203 let n_columns =
204 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
205 as u32;
206 assert!(
207 columns_and_values.len() <= n_columns as usize,
208 "got values for {} columns but only {n_columns} columns exist",
209 columns_and_values.len(),
210 );
211 for (column, value) in columns_and_values {
212 assert!(
213 *column < n_columns,
214 "got column {column} which is higher than the number of columns {n_columns}",
215 );
216 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
217 self.upcast_ref::<TreeModel>().to_glib_none().0,
218 *column as c_int,
219 ));
220 assert!(
221 Value::type_transformable(value.value_type(), type_),
222 "column {column} is of type {type_} but found value of type {}",
223 value.value_type()
224 );
225 }
226
227 let columns = columns_and_values
228 .iter()
229 .map(|(c, _)| *c)
230 .collect::<Vec<_>>();
231 let values = columns_and_values
232 .iter()
233 .map(|(_, v)| v.to_value())
234 .collect::<Vec<_>>();
235
236 ffi::gtk_list_store_set_valuesv(
237 self.to_glib_none().0,
238 mut_override(iter.to_glib_none().0),
239 mut_override(columns.as_ptr() as *const c_int),
240 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
241 columns.len() as c_int,
242 );
243 }
244 }
245
246 #[doc(alias = "gtk_list_store_set_column_types")]
261 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
262 #[allow(deprecated)]
263 pub fn set_column_types(&self, types: &[glib::Type]) {
264 unsafe {
265 let types_ptr: Vec<glib::ffi::GType> = types.iter().map(|t| t.into_glib()).collect();
266 ffi::gtk_list_store_set_column_types(
267 self.to_glib_none().0,
268 types.len() as i32,
269 mut_override(types_ptr.as_ptr()),
270 )
271 }
272 }
273
274 #[doc(alias = "gtk_list_store_set_value")]
288 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
289 #[allow(deprecated)]
290 pub fn set_value(&self, iter: &TreeIter, column: u32, value: &Value) {
291 unsafe {
292 let columns =
293 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
294 as u32;
295 assert!(
296 column < columns,
297 "got column {column} which is higher than the number of columns {columns}",
298 );
299
300 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
301 self.upcast_ref::<TreeModel>().to_glib_none().0,
302 column as c_int,
303 ));
304 assert!(
305 Value::type_transformable(value.type_(), type_),
306 "column {column} is of type {type_} but found value of type {}",
307 value.type_()
308 );
309
310 ffi::gtk_list_store_set_value(
311 self.to_glib_none().0,
312 mut_override(iter.to_glib_none().0),
313 column as c_int,
314 mut_override(value.to_glib_none().0),
315 );
316 }
317 }
318}