authenticator/models/
accounts.rs

1use gtk::{gio, glib, prelude::*, subclass::prelude::*};
2
3use super::account::Account;
4
5mod imp {
6    use std::cell::RefCell;
7
8    use super::*;
9
10    #[derive(Default)]
11    pub struct AccountsModel(pub RefCell<Vec<Account>>);
12
13    #[glib::object_subclass]
14    impl ObjectSubclass for AccountsModel {
15        const NAME: &'static str = "AccountsModel";
16        type Type = super::AccountsModel;
17        type Interfaces = (gio::ListModel,);
18    }
19
20    impl ObjectImpl for AccountsModel {}
21    impl ListModelImpl for AccountsModel {
22        fn item_type(&self) -> glib::Type {
23            Account::static_type()
24        }
25        fn n_items(&self) -> u32 {
26            self.0.borrow().len() as u32
27        }
28        fn item(&self, position: u32) -> Option<glib::Object> {
29            self.0
30                .borrow()
31                .get(position as usize)
32                .map(|o| o.clone().upcast::<glib::Object>())
33        }
34    }
35}
36
37glib::wrapper! {
38    pub struct AccountsModel(ObjectSubclass<imp::AccountsModel>)
39        @implements gio::ListModel;
40}
41
42impl AccountsModel {
43    pub fn append(&self, account: &Account) {
44        let pos = {
45            let mut data = self.imp().0.borrow_mut();
46            data.push(account.clone());
47            (data.len() - 1) as u32
48        };
49        self.items_changed(pos, 0, 1);
50    }
51
52    pub fn splice(&self, accounts: &[Account]) {
53        let len = accounts.len();
54        let pos = {
55            let mut data = self.imp().0.borrow_mut();
56            let pos = data.len();
57            data.extend_from_slice(accounts);
58            pos as u32
59        };
60        self.items_changed(pos, 0, len as u32);
61    }
62
63    pub fn remove(&self, pos: u32) {
64        self.imp().0.borrow_mut().remove(pos as usize);
65        self.items_changed(pos, 1, 0);
66    }
67
68    pub fn find_by_id(&self, id: u32) -> Option<Account> {
69        for pos in 0..self.n_items() {
70            let account = self.item(pos).and_downcast::<Account>().unwrap();
71            if account.id() == id {
72                return Some(account);
73            }
74        }
75        None
76    }
77
78    pub fn find_position_by_id(&self, id: u32) -> Option<u32> {
79        for pos in 0..self.n_items() {
80            let obj = self.item(pos)?;
81            let account = obj.downcast_ref::<Account>().unwrap();
82            if account.id() == id {
83                return Some(pos);
84            }
85        }
86        None
87    }
88}
89
90impl Default for AccountsModel {
91    fn default() -> Self {
92        glib::Object::new()
93    }
94}