gtk4/
tree_sortable.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{fmt, mem};
4
5use glib::translate::*;
6
7use crate::{ffi, prelude::*, Ordering, SortType, TreeIter, TreeModel, TreeSortable};
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
10#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
11#[allow(deprecated)]
12pub enum SortColumn {
13    #[doc(alias = "GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID")]
14    Default,
15    Index(u32),
16}
17
18#[doc(hidden)]
19impl IntoGlib for SortColumn {
20    type GlibType = i32;
21
22    #[inline]
23    fn into_glib(self) -> i32 {
24        match self {
25            SortColumn::Default => ffi::GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
26            SortColumn::Index(x) => {
27                assert!(x <= i32::MAX as u32, "column index is too big");
28                x as i32
29            }
30        }
31    }
32}
33
34#[doc(hidden)]
35impl FromGlib<i32> for SortColumn {
36    #[inline]
37    unsafe fn from_glib(val: i32) -> Self {
38        skip_assert_initialized!();
39        match val {
40            ffi::GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID => Self::Default,
41            x => {
42                assert!(x >= 0, "invalid column index");
43                Self::Index(x as u32)
44            }
45        }
46    }
47}
48
49impl fmt::Display for SortColumn {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        write!(
52            f,
53            "SortColumn::{}",
54            match *self {
55                SortColumn::Default => "Default",
56                SortColumn::Index(_) => "Index",
57            }
58        )
59    }
60}
61
62// rustdoc-stripper-ignore-next
63/// Trait containing manually implemented methods of
64/// [`TreeSortable`](crate::TreeSortable).
65#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
66#[allow(deprecated)]
67pub trait TreeSortableExtManual: IsA<TreeSortable> + 'static {
68    /// Sets the default comparison function used when sorting to be @sort_func.
69    /// If the current sort column id of @self is
70    /// `GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID`, then the model will sort using
71    /// this function.
72    ///
73    /// If @sort_func is [`None`], then there will be no default comparison function.
74    /// This means that once the model  has been sorted, it can’t go back to the
75    /// default state. In this case, when the current sort column id of @self
76    /// is `GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID`, the model will be unsorted.
77    ///
78    /// # Deprecated since 4.10
79    ///
80    /// ## `sort_func`
81    /// The comparison function
82    #[doc(alias = "gtk_tree_sortable_set_default_sort_func")]
83    fn set_default_sort_func<F>(&self, sort_func: F)
84    where
85        F: Fn(&Self, &TreeIter, &TreeIter) -> Ordering + 'static,
86    {
87        unsafe {
88            ffi::gtk_tree_sortable_set_default_sort_func(
89                self.as_ref().to_glib_none().0,
90                Some(trampoline::<Self, F>),
91                into_raw(sort_func),
92                Some(destroy_closure::<Self, F>),
93            )
94        }
95    }
96    /// Sets the comparison function used when sorting to be @sort_func. If the
97    /// current sort column id of @self is the same as @sort_column_id, then
98    /// the model will sort using this function.
99    ///
100    /// # Deprecated since 4.10
101    ///
102    /// ## `sort_column_id`
103    /// the sort column id to set the function for
104    /// ## `sort_func`
105    /// The comparison function
106    #[doc(alias = "gtk_tree_sortable_set_sort_func")]
107    fn set_sort_func<F>(&self, sort_column_id: SortColumn, sort_func: F)
108    where
109        F: Fn(&Self, &TreeIter, &TreeIter) -> Ordering + 'static,
110    {
111        unsafe {
112            ffi::gtk_tree_sortable_set_sort_func(
113                self.as_ref().to_glib_none().0,
114                sort_column_id.into_glib(),
115                Some(trampoline::<Self, F>),
116                into_raw(sort_func),
117                Some(destroy_closure::<Self, F>),
118            )
119        }
120    }
121    /// Fills in @sort_column_id and @order with the current sort column and the
122    /// order. It returns [`true`] unless the @sort_column_id is
123    /// `GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID` or
124    /// `GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID`.
125    ///
126    /// # Deprecated since 4.10
127    ///
128    ///
129    /// # Returns
130    ///
131    /// [`true`] if the sort column is not one of the special sort
132    ///   column ids.
133    ///
134    /// ## `sort_column_id`
135    /// The sort column id to be filled in
136    ///
137    /// ## `order`
138    /// The [`SortType`][crate::SortType] to be filled in
139    #[doc(alias = "gtk_tree_sortable_get_sort_column_id")]
140    #[doc(alias = "get_sort_column_id")]
141    fn sort_column_id(&self) -> Option<(SortColumn, SortType)> {
142        unsafe {
143            let mut sort_column_id = mem::MaybeUninit::uninit();
144            let mut order = mem::MaybeUninit::uninit();
145            ffi::gtk_tree_sortable_get_sort_column_id(
146                self.as_ref().to_glib_none().0,
147                sort_column_id.as_mut_ptr(),
148                order.as_mut_ptr(),
149            );
150            let sort_column_id = sort_column_id.assume_init();
151            if sort_column_id != ffi::GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID {
152                Some((from_glib(sort_column_id), from_glib(order.assume_init())))
153            } else {
154                None
155            }
156        }
157    }
158    /// Sets the current sort column to be @sort_column_id. The @self will
159    /// resort itself to reflect this change, after emitting a
160    /// `GtkTreeSortable::sort-column-changed` signal. @sort_column_id may either be
161    /// a regular column id, or one of the following special values:
162    ///
163    /// - `GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID`: the default sort function
164    ///   will be used, if it is set
165    ///
166    /// - `GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID`: no sorting will occur
167    ///
168    /// # Deprecated since 4.10
169    ///
170    /// ## `sort_column_id`
171    /// the sort column id to set
172    /// ## `order`
173    /// The sort order of the column
174    #[doc(alias = "gtk_tree_sortable_set_sort_column_id")]
175    fn set_sort_column_id(&self, sort_column_id: SortColumn, order: SortType) {
176        unsafe {
177            ffi::gtk_tree_sortable_set_sort_column_id(
178                self.as_ref().to_glib_none().0,
179                sort_column_id.into_glib(),
180                order.into_glib(),
181            );
182        }
183    }
184    #[doc(alias = "gtk_tree_sortable_set_sort_column_id")]
185    fn set_unsorted(&self) {
186        unsafe {
187            ffi::gtk_tree_sortable_set_sort_column_id(
188                self.as_ref().to_glib_none().0,
189                ffi::GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
190                SortType::Ascending.into_glib(),
191            );
192        }
193    }
194}
195
196unsafe extern "C" fn trampoline<T, F: Fn(&T, &TreeIter, &TreeIter) -> Ordering>(
197    this: *mut ffi::GtkTreeModel,
198    iter: *mut ffi::GtkTreeIter,
199    iter2: *mut ffi::GtkTreeIter,
200    f: glib::ffi::gpointer,
201) -> i32
202where
203    T: IsA<TreeSortable>,
204{
205    let f: &F = &*(f as *const F);
206    f(
207        &TreeModel::from_glib_none(this).unsafe_cast(),
208        &from_glib_borrow(iter),
209        &from_glib_borrow(iter2),
210    )
211    .into_glib()
212}
213
214unsafe extern "C" fn destroy_closure<T, F: Fn(&T, &TreeIter, &TreeIter) -> Ordering>(
215    ptr: glib::ffi::gpointer,
216) {
217    let _ = Box::<F>::from_raw(ptr as *mut _);
218}
219
220fn into_raw<F, T>(func: F) -> glib::ffi::gpointer
221where
222    F: Fn(&T, &TreeIter, &TreeIter) -> Ordering + 'static,
223{
224    skip_assert_initialized!();
225    let func: Box<F> = Box::new(func);
226    Box::into_raw(func) as glib::ffi::gpointer
227}
228
229impl<O: IsA<TreeSortable>> TreeSortableExtManual for O {}