1use glib::{Type, Value, translate::*};
4use libc::c_int;
5
6use crate::{TreeIter, TreeModel, TreeStore, ffi, prelude::*};
7
8impl TreeStore {
9 #[doc(alias = "gtk_tree_store_newv")]
36 #[doc(alias = "gtk_tree_store_new")]
37 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
38 #[allow(deprecated)]
39 pub fn new(column_types: &[Type]) -> Self {
40 assert_initialized_main_thread!();
41 unsafe {
42 let mut column_types = column_types
43 .iter()
44 .map(|t| t.into_glib())
45 .collect::<Vec<_>>();
46 from_glib_full(ffi::gtk_tree_store_newv(
47 column_types.len() as c_int,
48 column_types.as_mut_ptr(),
49 ))
50 }
51 }
52
53 #[doc(alias = "gtk_tree_store_insert_with_values")]
76 #[doc(alias = "gtk_tree_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 parent: Option<&TreeIter>,
82 position: Option<u32>,
83 columns_and_values: &[(u32, &dyn ToValue)],
84 ) -> TreeIter {
85 unsafe {
86 assert!(
87 position.unwrap_or(0) <= i32::MAX as u32,
88 "can't have more than {} rows",
89 i32::MAX
90 );
91 let n_columns =
92 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
93 as u32;
94 assert!(
95 columns_and_values.len() <= n_columns as usize,
96 "got values for {} columns but only {n_columns} columns exist",
97 columns_and_values.len(),
98 );
99 for (column, value) in columns_and_values {
100 assert!(
101 *column < n_columns,
102 "got column {column} which is higher than the number of columns {n_columns}",
103 );
104 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
105 self.upcast_ref::<TreeModel>().to_glib_none().0,
106 *column as c_int,
107 ));
108 assert!(
109 Value::type_transformable(value.value_type(), type_),
110 "column {column} is of type {} but found value of type {type_}",
111 value.value_type()
112 );
113 }
114
115 let columns = columns_and_values
116 .iter()
117 .map(|(c, _)| *c)
118 .collect::<Vec<_>>();
119 let values = columns_and_values
120 .iter()
121 .map(|(_, v)| v.to_value())
122 .collect::<Vec<_>>();
123
124 let mut iter = TreeIter::uninitialized();
125 ffi::gtk_tree_store_insert_with_valuesv(
126 self.to_glib_none().0,
127 iter.to_glib_none_mut().0,
128 mut_override(parent.to_glib_none().0),
129 position.map_or(-1, |n| n as c_int),
130 mut_override(columns.as_ptr() as *const c_int),
131 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
132 columns.len() as c_int,
133 );
134 iter
135 }
136 }
137
138 #[doc(alias = "gtk_tree_store_reorder")]
153 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
154 #[allow(deprecated)]
155 pub fn reorder(&self, parent: &TreeIter, new_order: &[u32]) {
156 unsafe {
157 let count = ffi::gtk_tree_model_iter_n_children(
158 self.upcast_ref::<TreeModel>().to_glib_none().0,
159 mut_override(parent.to_glib_none().0),
160 );
161 let safe_count = count as usize == new_order.len();
162 debug_assert!(
163 safe_count,
164 "Incorrect `new_order` slice length. Expected `{count}`, found `{}`.",
165 new_order.len()
166 );
167 let safe_values = new_order.iter().max().is_none_or(|&max| {
168 let max = max as i32;
169 max >= 0 && max < count
170 });
171 debug_assert!(
172 safe_values,
173 "Some `new_order` slice values are out of range. Maximum safe value: \
174 `{}`. The slice contents: `{new_order:?}`",
175 count - 1,
176 );
177 if safe_count && safe_values {
178 ffi::gtk_tree_store_reorder(
179 self.to_glib_none().0,
180 mut_override(parent.to_glib_none().0),
181 mut_override(new_order.as_ptr() as *const c_int),
182 );
183 }
184 }
185 }
186
187 #[doc(alias = "gtk_tree_store_set")]
205 #[doc(alias = "gtk_tree_store_set_valuesv")]
206 #[doc(alias = "gtk_tree_store_set_valist")]
207 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
208 #[allow(deprecated)]
209 pub fn set(&self, iter: &TreeIter, columns_and_values: &[(u32, &dyn ToValue)]) {
210 unsafe {
211 let n_columns =
212 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
213 as u32;
214 assert!(
215 columns_and_values.len() <= n_columns as usize,
216 "got values for {} columns but only {n_columns} columns exist",
217 columns_and_values.len(),
218 );
219 for (column, value) in columns_and_values {
220 assert!(
221 *column < n_columns,
222 "got column {column} which is higher than the number of columns {n_columns}",
223 );
224 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
225 self.upcast_ref::<TreeModel>().to_glib_none().0,
226 *column as c_int,
227 ));
228 assert!(
229 Value::type_transformable(value.value_type(), type_),
230 "column {column} is of type {type_} but found value of type {}",
231 value.value_type()
232 );
233 }
234
235 let columns = columns_and_values
236 .iter()
237 .map(|(c, _)| *c)
238 .collect::<Vec<_>>();
239 let values = columns_and_values
240 .iter()
241 .map(|(_, v)| v.to_value())
242 .collect::<Vec<_>>();
243
244 ffi::gtk_tree_store_set_valuesv(
245 self.to_glib_none().0,
246 mut_override(iter.to_glib_none().0),
247 mut_override(columns.as_ptr() as *const c_int),
248 mut_override(values.as_ptr() as *const glib::gobject_ffi::GValue),
249 columns.len() as c_int,
250 );
251 }
252 }
253
254 #[doc(alias = "gtk_tree_store_set_column_types")]
270 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
271 #[allow(deprecated)]
272 pub fn set_column_types(&self, types: &[glib::Type]) {
273 unsafe {
274 let types_ptr: Vec<glib::ffi::GType> = types.iter().map(|t| t.into_glib()).collect();
275 ffi::gtk_tree_store_set_column_types(
276 self.to_glib_none().0,
277 types.len() as i32,
278 mut_override(types_ptr.as_ptr()),
279 )
280 }
281 }
282
283 #[doc(alias = "gtk_tree_store_set_value")]
298 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
299 #[allow(deprecated)]
300 pub fn set_value(&self, iter: &TreeIter, column: u32, value: &Value) {
301 unsafe {
302 let columns =
303 ffi::gtk_tree_model_get_n_columns(self.upcast_ref::<TreeModel>().to_glib_none().0)
304 as u32;
305 assert!(
306 column < columns,
307 "got column {column} which is higher than the number of columns {columns}",
308 );
309
310 let type_ = from_glib(ffi::gtk_tree_model_get_column_type(
311 self.upcast_ref::<TreeModel>().to_glib_none().0,
312 column as c_int,
313 ));
314 assert!(
315 Value::type_transformable(value.type_(), type_),
316 "column {column} is of type {type_} but found value of type {}",
317 value.type_()
318 );
319
320 ffi::gtk_tree_store_set_value(
321 self.to_glib_none().0,
322 mut_override(iter.to_glib_none().0),
323 column as c_int,
324 mut_override(value.to_glib_none().0),
325 );
326 }
327 }
328}