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