[fractal/fractal-next] sidebar: Implement room filtering



commit f85a530ba1cedabeb1f20e03783e243401423c0e
Author: Veli Tasali <veli tasali gmail com>
Date:   Fri Apr 30 15:27:26 2021 +0300

    sidebar: Implement room filtering
    
    Filtering is done by lowercasing of the room name
    and of the filtering criterion.
    
    Closes https://gitlab.gnome.org/GNOME/fractal/-/issues/750.

 data/resources/ui/sidebar.ui   |  2 +-
 src/session/sidebar/sidebar.rs | 30 ++++++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 3 deletions(-)
---
diff --git a/data/resources/ui/sidebar.ui b/data/resources/ui/sidebar.ui
index ae7e0f49..e644a4ec 100644
--- a/data/resources/ui/sidebar.ui
+++ b/data/resources/ui/sidebar.ui
@@ -43,7 +43,7 @@
           <object class="GtkSearchBar" id="room_search">
             <property name="search-mode-enabled" bind-source="search_button" bind-property="active"/>
             <property name="child">
-              <object class="GtkSearchEntry"/>
+              <object class="GtkSearchEntry" id="room_search_entry"/>
             </property>
           </object>
         </child>
diff --git a/src/session/sidebar/sidebar.rs b/src/session/sidebar/sidebar.rs
index 5ddf2a9d..feba712c 100644
--- a/src/session/sidebar/sidebar.rs
+++ b/src/session/sidebar/sidebar.rs
@@ -21,6 +21,8 @@ mod imp {
         pub headerbar: TemplateChild<adw::HeaderBar>,
         #[template_child]
         pub listview: TemplateChild<gtk::ListView>,
+        #[template_child]
+        pub room_search_entry: TemplateChild<gtk::SearchEntry>,
     }
 
     #[glib::object_subclass]
@@ -115,8 +117,32 @@ impl Sidebar {
                 item.clone().downcast::<gio::ListModel>().ok()
             });
 
-            // TODO: set filter based on the text in the search entry
-            let filter_model = gtk::FilterListModel::new(Some(&tree_model), gtk::NONE_FILTER);
+            let room_expression = gtk::ClosureExpression::new(
+                String::static_type(),
+                |value| {
+                    Some(
+                        value[0]
+                            .get::<gtk::TreeListRow>()
+                            .unwrap()
+                            .item()
+                            .and_then(|o| o.downcast::<Room>().ok())
+                            .map_or(String::new(), |o| o.display_name())
+                            .to_value(),
+                    )
+                },
+                &[],
+            );
+            let filter = gtk::StringFilterBuilder::new()
+                .match_mode(gtk::StringFilterMatchMode::Substring)
+                .expression(&room_expression)
+                .ignore_case(true)
+                .build();
+            let filter_model = gtk::FilterListModel::new(Some(&tree_model), Some(&filter));
+            priv_
+                .room_search_entry
+                .bind_property("text", &filter, "search")
+                .flags(glib::BindingFlags::SYNC_CREATE)
+                .build();
 
             let selection = gtk::SingleSelection::new(Some(&filter_model));
             selection.connect_notify_local(Some("selected-item"), clone!(@weak self as obj => move |model, 
_| {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]