From f197099346375308411e5289891656c82ea97160 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Fri, 13 Sep 2024 14:01:06 -0500 Subject: [PATCH] library is showing items and searching is working again --- src/qml/presenter/Library.qml | 21 ++++++----- src/qml/presenter/LibraryItem.qml | 61 ++++++++++++++++--------------- src/qml/presenter/MainWindow.qml | 20 ++++++++-- src/rust/songs/song_model.rs | 47 +++++++++++++++++++++++- 4 files changed, 106 insertions(+), 43 deletions(-) diff --git a/src/qml/presenter/Library.qml b/src/qml/presenter/Library.qml index 2baff8b..ffc5196 100644 --- a/src/qml/presenter/Library.qml +++ b/src/qml/presenter/Library.qml @@ -34,8 +34,8 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.preferredHeight: parent.height - 280 - proxyModel: songProxyModel - innerModel: songProxyModel.songModel + proxyModel: songModel + innerModel: songModel libraryType: "song" headerLabel: "Songs" itemIcon: "folder-music-symbolic" @@ -53,7 +53,10 @@ Item { songProxyModel.deleteSongs(rows) }) - Component.onCompleted: selectedLibrary = "song"; + Component.onCompleted: { + selectedLibrary = "song"; + console.log("PRINTER SONGS: " + songModel.count); + } } Presenter.LibraryItem { @@ -61,8 +64,8 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.preferredHeight: parent.height - 280 - proxyModel: videoProxyModel - innerModel: videoProxyModel.videoModel + proxyModel: videoModel + innerModel: videoModel libraryType: "video" headerLabel: "Videos" itemIcon: "folder-videos-symbolic" @@ -87,8 +90,8 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.preferredHeight: parent.height - 280 - proxyModel: imageProxyModel - innerModel: imageProxyModel.imageModel + proxyModel: imageModel + innerModel: imageModel libraryType: "image" headerLabel: "Images" itemIcon: "folder-pictures-symbolic" @@ -108,8 +111,8 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.preferredHeight: parent.height - 280 - proxyModel: presProxyModel - innerModel: presProxyModel.presentationModel + proxyModel: presentationModel + innerModel: presentationModel libraryType: "presentation" headerLabel: "Presentations" itemIcon: "x-office-presentation-symbolic" diff --git a/src/qml/presenter/LibraryItem.qml b/src/qml/presenter/LibraryItem.qml index 78e1aa4..d2cdd69 100644 --- a/src/qml/presenter/LibraryItem.qml +++ b/src/qml/presenter/LibraryItem.qml @@ -155,7 +155,9 @@ ColumnLayout { id: searchField height: parent.height width: parent.width - 40 - onAccepted: proxyModel.setFilterRegularExpression(searchField.text) + onAccepted: { + innerModel.search(text); + } background: Presenter.TextBackground { control: searchField } @@ -177,11 +179,11 @@ ColumnLayout { Layout.fillWidth: true Layout.alignment: Qt.AlignTop id: libraryList - model: proxyModel + model: innerModel clip: true ItemSelectionModel { id: selectionModel - model: proxyModel + model: innerModel onSelectionChanged: { /* showPassiveNotification("deslected: " + deselected); */ /* showPassiveNotification("selected: " + selected); */ @@ -222,18 +224,30 @@ ColumnLayout { Item { implicitWidth: ListView.view.width height: selectedLibrary == libraryType ? 50 : 0 + property bool rightMenu: false + property bool selected: selectionModel.hasSelection && selectionModel.currentIndex == innerModel.index(index, 0) + property bool fileValidation: { + if (filePath) + fileHelper.validate(filePath) + else + false + } + + Rectangle { + id: itemBackground + color: Kirigami.Theme.backgroundColor + anchors.fill: parent + + Binding on color { + when: dragHandler.containsMouse || selected + value: Kirigami.Theme.highlightColor + } + + } + Controls.ItemDelegate { id: listItem - property bool rightMenu: false - property bool selected: selectionModel.isSelected(proxyModel.idx(index)) - property bool fileValidation: { - if (filePath) - fileHelper.validate(filePath) - else - false - } - implicitWidth: libraryList.width height: selectedLibrary == libraryType ? 50 : 0 text: title @@ -251,17 +265,6 @@ ColumnLayout { icon.width: Kirigami.Units.gridUnit icon.height: Kirigami.Units.gridUnit /* supportsMouseEvents: false */ - /* background: Rectangle { */ - /* color: Kirigami.Theme.backgroundColor */ - /* fill: parent */ - /* } */ - /* Binding on backgroundColor { */ - /* when: dragHandler.containsMouse || */ - /* (selectionModel.hasSelection && */ - /* selectionModel.isSelected(proxyModel.idx(index))) */ - /* value: Kirigami.Theme.highlightColor */ - /* } */ - /* textColor: { */ /* if (selectedLibrary == "song") */ /* Kirigami.Theme.textColor; */ @@ -348,7 +351,7 @@ ColumnLayout { onClicked: { if (mouse.button === Qt.RightButton) { if(selectionModel.selectedIndexes.length <= 1) - selectionModel.select(proxyModel.idx(index), + selectionModel.select(innerModel.index(index), ItemSelectionModel.ClearAndSelect); rightClickMenu.popup() } @@ -356,19 +359,19 @@ ColumnLayout { (mouse.modifiers === Qt.ShiftModifier)) { if (libraryList.currentIndex < index) { for (let i = libraryList.currentIndex; i <= index; i++) { - selectionModel.select(proxyModel.idx(i), + selectionModel.select(innerModel.index(i), ItemSelectionModel.Select); } } else { for (let i = index; i <= libraryList.currentIndex; i++) { - selectionModel.select(proxyModel.idx(i), + selectionModel.select(innerModel.index(i), ItemSelectionModel.Select); } } console.log(selectionModel.selectedIndexes); } else { - selectionModel.select(proxyModel.idx(index), + selectionModel.select(innerModel.index(index), ItemSelectionModel.ClearAndSelect); libraryList.currentIndex = index; } @@ -420,13 +423,13 @@ ColumnLayout { if (row > currentRow) { for (var i = currentRow; i <= row; i++) { - let idx = proxyModel.idx(i); + let idx = innerModel.idx(i); selectionModel.select(idx, ItemSelectionModel.Select); } } else { for (var i = row; i <= currentRow; i++) { - let idx = proxyModel.idx(i); + let idx = innerModel.idx(i); selectionModel.select(idx, ItemSelectionModel.Select); } } diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index 80dad90..087ca31 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -179,10 +179,22 @@ Controls.Page { /* ImageProxyModel { id: imageProxyModel } */ /* PresentationProxyModel { id: presProxyModel } */ /* VideoProxyModel { id: videoProxyModel } */ - SongModel { id: songModel } - VideoModel { id: videoModel } - PresentationModel { id: presentationModel } - ImageModel { id: imageModel } + SongModel { + id: songModel + Component.onCompleted: setup(); + } + VideoModel { + id: videoModel + Component.onCompleted: setup(); + } + PresentationModel { + id: presentationModel + Component.onCompleted: setup(); + } + ImageModel { + id: imageModel + Component.onCompleted: setup(); + } ServiceThing { id: serviceThing } FileHelper { id: fileHelper } /* SlideHelper { id: slideHelper } */ diff --git a/src/rust/songs/song_model.rs b/src/rust/songs/song_model.rs index 1417c2a..319f40d 100644 --- a/src/rust/songs/song_model.rs +++ b/src/rust/songs/song_model.rs @@ -160,6 +160,8 @@ pub mod song_model { index: i32, updated_audio: QString, ) -> bool; + #[qinvokable] + fn search(self: Pin<&mut SongModel>, search_term: QString); } impl cxx_qt::Threading for SongModel {} @@ -249,7 +251,8 @@ use diesel::sqlite::SqliteConnection; use diesel::{delete, insert_into, prelude::*, update}; use std::collections::HashMap; use std::pin::Pin; -use tracing::{debug, error}; +use std::slice::Iter; +use tracing::{debug, debug_span, error, info, instrument}; use self::song_model::{ QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32, @@ -290,6 +293,7 @@ pub struct SongModelRust { count: i32, highest_id: i32, songs: Vec, + inner_songs: Vec, } impl song_model::SongModel { @@ -351,6 +355,7 @@ impl song_model::SongModel { println!("--------------------------------------"); println!("{:?}", self.as_mut().songs); println!("--------------------------------------"); + self.as_mut().rust_mut().inner_songs = self.songs.clone(); } pub fn remove_item(mut self: Pin<&mut Self>, index: i32) -> bool { @@ -1053,6 +1058,25 @@ impl song_model::SongModel { QStringList::from(&lyric_list) } + fn search(mut self: Pin<&mut Self>, search_term: QString) { + let search_term = search_term.to_string().to_lowercase(); + debug!(search_term); + let searched_songs: Vec = self + .inner_songs + .iter() + .filter(|song| { + song.title.to_lowercase().contains(&search_term) + }) + .cloned() + .collect(); + debug!(search = ?&searched_songs); + unsafe { + self.as_mut().begin_reset_model(); + self.as_mut().rust_mut().songs = searched_songs; + self.as_mut().end_reset_model(); + } + } + fn get_role(&self, role: SongRoles) -> i32 { match role { SongRoles::Id => 0, @@ -1179,3 +1203,24 @@ impl song_model::SongModel { cnt } } + +impl song_model::SongRoles { + fn iter() -> Iter<'static, SongRoles> { + static SONGROLES: [SongRoles; 13] = [ + SongRoles::Id, + SongRoles::Title, + SongRoles::Lyrics, + SongRoles::Author, + SongRoles::Ccli, + SongRoles::Audio, + SongRoles::VerseOrder, + SongRoles::Background, + SongRoles::BackgroundType, + SongRoles::HorizontalTextAlignment, + SongRoles::VerticalTextAlignment, + SongRoles::Font, + SongRoles::FontSize, + ]; + SONGROLES.iter() + } +}