1use glib::{Type, Value, translate::*};
4use libc::c_int;
5
6use crate::{ListStore, TreeIter, TreeModel, ffi, prelude::*};
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")]
145 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
146 #[allow(deprecated)]
147 pub fn reorder(&self, new_order: &[u32]) {
148 unsafe {
149 let count = ffi::gtk_tree_model_iter_n_children(
150 self.upcast_ref::<TreeModel>().to_glib_none().0,
151 std::ptr::null_mut(),
152 );
153 let safe_count = count as usize == new_order.len();
154 debug_assert!(
155 safe_count,
156 "Incorrect `new_order` slice length. Expected `{count}`, found `{}`.",
157 new_order.len()
158 );
159 let safe_values = new_order.iter().max().is_none_or(|&max| {
160 let max = max as i32;
161 max >= 0 && max < count
162 });
163 debug_assert!(
164 safe_values,
165 "Some `new_order` slice values are out of range. Maximum safe value: \
166 `{}`. The slice contents: `{new_order:?}`",
167 count - 1,
168 );
169 if safe_count && safe_values {
170 ffi::gtk_list_store_reorder(
171 self.to_glib_none().0,
172 mut_override(new_order.as_ptr() as *const c_int),
173 );
174 }
175 }
176 }
177
178 #[doc(alias = "gtk_list_store_set")]
190 #[doc(alias = "gtk_list_store_set_valuesv")]
191 #[doc(alias = "gtk_list_store_set_valist")]
192 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
193 #[allow(deprecated)]
194 pub fn set(&self, iter: &TreeIter, columns_and_values: &[(u32, &dyn ToValue)]) {
195 unsafe {
196 let n_columns =
197 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
198 as u32;
199 assert!(
200 columns_and_values.len() <= n_columns as usize,
201 "got values for {} columns but only {n_columns} columns exist",
202 columns_and_values.len(),
203 );
204 for (column, value) in columns_and_values {
205 assert!(
206 *column < n_columns,
207 "got column {column} which is higher than the number of columns {n_columns}",
208 );
209 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
210 self.upcast_ref::<TreeModel>().to_glib_none().0,
211 *column as c_int,
212 ));
213 assert!(
214 Value::type_transformable(value.value_type(), type_),
215 "column {column} is of type {type_} but found value of type {}",
216 value.value_type()
217 );
218 }
219
220 let columns = columns_and_values
221 .iter()
222 .map(|(c, _)| *c)
223 .collect::<Vec<_>>();
224 let values = columns_and_values
225 .iter()
226 .map(|(_, v)| v.to_value())
227 .collect::<Vec<_>>();
228
229 ffi::gtk_list_store_set_valuesv(
230 self.to_glib_none().0,
231 mut_override(iter.to_glib_none().0),
232 mut_override(columns.as_ptr() as *const c_int),
233 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
234 columns.len() as c_int,
235 );
236 }
237 }
238
239 #[doc(alias = "gtk_list_store_set_column_types")]
254 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
255 #[allow(deprecated)]
256 pub fn set_column_types(&self, types: &[glib::Type]) {
257 unsafe {
258 let types_ptr: Vec<glib::ffi::GType> = types.iter().map(|t| t.into_glib()).collect();
259 ffi::gtk_list_store_set_column_types(
260 self.to_glib_none().0,
261 types.len() as i32,
262 mut_override(types_ptr.as_ptr()),
263 )
264 }
265 }
266
267 #[doc(alias = "gtk_list_store_set_value")]
281 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
282 #[allow(deprecated)]
283 pub fn set_value(&self, iter: &TreeIter, column: u32, value: &Value) {
284 unsafe {
285 let columns =
286 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
287 as u32;
288 assert!(
289 column < columns,
290 "got column {column} which is higher than the number of columns {columns}",
291 );
292
293 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
294 self.upcast_ref::<TreeModel>().to_glib_none().0,
295 column as c_int,
296 ));
297 assert!(
298 Value::type_transformable(value.type_(), type_),
299 "column {column} is of type {type_} but found value of type {}",
300 value.type_()
301 );
302
303 ffi::gtk_list_store_set_value(
304 self.to_glib_none().0,
305 mut_override(iter.to_glib_none().0),
306 column as c_int,
307 mut_override(value.to_glib_none().0),
308 );
309 }
310 }
311}