[go: up one dir, main page]

gtk4/
tree_store.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use 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}