Skip to content

Commit a378e6e

Browse files
committed
Add TypedListStore
1 parent 8b3286b commit a378e6e

File tree

8 files changed

+383
-40
lines changed

8 files changed

+383
-40
lines changed

src/container.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ use crate::{
22
distrobox::{ContainerInfo, ExportableApp, Status},
33
distrobox_task::DistroboxTask,
44
fakers::CommandRunner,
5+
gtk_utils::TypedListStore,
56
known_distros::{known_distro_by_image, KnownDistro},
67
query::Query,
78
root_store::RootStore,
89
fakers::Command
910
};
1011

1112
use gtk::{
12-
gio,
1313
glib::{derived_properties, BoxedAnyObject, Properties},
1414
};
1515

@@ -38,8 +38,8 @@ mod imp {
3838
pub image: RefCell<String>,
3939
#[property(get, set)]
4040
pub distro: RefCell<Option<KnownDistro>>,
41-
pub apps: Query<gio::ListStore, anyhow::Error>,
42-
pub binaries: Query<gio::ListStore, anyhow::Error>,
41+
pub apps: Query<TypedListStore<glib::BoxedAnyObject>, anyhow::Error>,
42+
pub binaries: Query<TypedListStore<glib::BoxedAnyObject>, anyhow::Error>,
4343
}
4444

4545
impl Default for Container {
@@ -52,10 +52,10 @@ mod imp {
5252
image: RefCell::new(String::new()),
5353
distro: RefCell::new(None),
5454
apps: Query::new("apps".into(), || async {
55-
Ok(gio::ListStore::new::<BoxedAnyObject>())
55+
Ok(TypedListStore::new())
5656
}),
5757
binaries: Query::new("binaries".into(), || async {
58-
Ok(gio::ListStore::new::<BoxedAnyObject>())
58+
Ok(TypedListStore::new())
5959
}),
6060
}
6161
}
@@ -106,8 +106,7 @@ impl Container {
106106
.list_apps(&this.name())
107107
.await?;
108108

109-
let mut apps_list = gio::ListStore::new::<BoxedAnyObject>();
110-
apps_list.extend(apps.into_iter().map(BoxedAnyObject::new));
109+
let apps_list: TypedListStore<BoxedAnyObject> = TypedListStore::from_iter(apps.into_iter().map(BoxedAnyObject::new));
111110

112111
// Listing the apps starts the container, we need to update its status
113112
this.root_store().load_containers();
@@ -125,8 +124,7 @@ impl Container {
125124
.get_exported_binaries(&this.name())
126125
.await?;
127126

128-
let mut binaries_list = gio::ListStore::new::<BoxedAnyObject>();
129-
binaries_list.extend(binaries.into_iter().map(BoxedAnyObject::new));
127+
let binaries_list: TypedListStore<BoxedAnyObject> = TypedListStore::from_iter(binaries.into_iter().map(BoxedAnyObject::new));
130128

131129
// Listing the binaries starts the container, we need to update its status
132130
this.root_store().load_containers();
@@ -137,11 +135,11 @@ impl Container {
137135
this
138136
}
139137

140-
pub fn apps(&self) -> Query<gio::ListStore, anyhow::Error> {
138+
pub fn apps(&self) -> Query<TypedListStore<BoxedAnyObject>, anyhow::Error> {
141139
self.imp().apps.clone()
142140
}
143141

144-
pub fn binaries(&self) -> Query<gio::ListStore, anyhow::Error> {
142+
pub fn binaries(&self) -> Query<TypedListStore<BoxedAnyObject>, anyhow::Error> {
145143
self.imp().binaries.clone()
146144
}
147145

src/dialogs/exportable_apps_dialog.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use gtk::{gio, glib, pango};
55

66
use crate::container::Container;
77
use crate::distrobox::{ExportableApp, ExportableBinary};
8-
use crate::gtk_utils::reaction;
8+
use crate::gtk_utils::{reaction, TypedListStore};
99
use crate::fakers::Command;
1010

1111
use std::cell::RefCell;
@@ -227,8 +227,8 @@ impl ExportableAppsDialog {
227227
});
228228

229229
let this_clone = this.clone();
230-
let render_apps = move |apps_data: &gio::ListStore| {
231-
let n_apps = apps_data.n_items();
230+
let render_apps = move |apps_data: &TypedListStore<BoxedAnyObject>| {
231+
let n_apps = apps_data.len();
232232

233233
// Update description based on whether there are apps
234234
if n_apps == 0 {
@@ -242,7 +242,7 @@ impl ExportableAppsDialog {
242242
this_clone
243243
.imp()
244244
.list_box
245-
.bind_model(Some(apps_data), move |obj| {
245+
.bind_model(Some(apps_data.inner()), move |obj| {
246246
let app = obj
247247
.downcast_ref::<BoxedAnyObject>()
248248
.map(|obj| obj.borrow::<ExportableApp>())
@@ -252,8 +252,8 @@ impl ExportableAppsDialog {
252252
};
253253

254254
let this_clone = this.clone();
255-
let render_binaries = move |binaries_data: &gio::ListStore| {
256-
let n_binaries = binaries_data.n_items();
255+
let render_binaries = move |binaries_data: &TypedListStore<BoxedAnyObject>| {
256+
let n_binaries = binaries_data.len();
257257

258258
// Update description based on whether there are binaries
259259
if n_binaries == 0 {
@@ -267,7 +267,7 @@ impl ExportableAppsDialog {
267267
this_clone
268268
.imp()
269269
.binaries_list_box
270-
.bind_model(Some(binaries_data), move |obj| {
270+
.bind_model(Some(binaries_data.inner()), move |obj| {
271271
let binary = obj
272272
.downcast_ref::<BoxedAnyObject>()
273273
.map(|obj| obj.borrow::<ExportableBinary>())

src/dialogs/task_manager_dialog.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ mod imp {
6868
let this = self.obj().clone();
6969
let root_store = self.obj().root_store();
7070
self.list_box
71-
.bind_model(Some(&root_store.tasks()), move |obj| {
71+
.bind_model(Some(root_store.tasks().inner()), move |obj| {
7272
let task = obj.downcast_ref::<DistroboxTask>().unwrap();
7373
this.build_row(task).upcast()
7474
});
@@ -102,13 +102,13 @@ mod imp {
102102
"Manage Tasks",
103103
));
104104
let this = self.obj().clone();
105-
if root_store.tasks().n_items() == 0 {
105+
if root_store.tasks().len() == 0 {
106106
this.imp().stack.set_visible_child_name("empty");
107107
} else {
108108
this.imp().stack.set_visible_child_name("list");
109109
}
110110
root_store
111-
.tasks()
111+
.tasks().inner()
112112
.connect_items_changed(move |tasks, _, _, _| {
113113
dbg!(tasks.n_items());
114114
if tasks.n_items() == 0 {
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use std::collections::HashMap;
22
use std::hash::Hash;
33

44
use gtk::prelude::*;
5-
use gtk::{gio, glib};
5+
use gtk::glib;
6+
mod typed_list_store;
7+
pub use typed_list_store::TypedListStore;
68

79
pub fn reconcile_properties<T: IsA<glib::Object>>(dest: &T, src: &T, properties: &[&str]) {
810
for prop in dest.list_properties() {
@@ -19,15 +21,14 @@ pub fn reconcile_properties<T: IsA<glib::Object>>(dest: &T, src: &T, properties:
1921
}
2022
}
2123
pub fn reconcile_list_by_key<T: IsA<glib::Object>, K: Hash + std::cmp::Eq>(
22-
list: gio::ListStore,
24+
list: &TypedListStore<T>,
2325
other: &[T],
2426
key_fn: impl Fn(&T) -> K,
2527
properties: &[&str],
2628
) {
2729
let mut other_map: HashMap<K, (&T, bool)> =
2830
other.iter().map(|v| (key_fn(v), (v, false))).collect();
2931
list.retain(|item| {
30-
let item = item.downcast_ref().unwrap();
3132
let key = key_fn(item);
3233
if let Some(other) = other_map.get_mut(&key) {
3334
reconcile_properties(item, other.0, properties);

0 commit comments

Comments
 (0)