diff --git a/qml/ClideTreeView.qml b/qml/ClideTreeView.qml index 49ca563..84c5484 100644 --- a/qml/ClideTreeView.qml +++ b/qml/ClideTreeView.qml @@ -16,13 +16,14 @@ Rectangle { signal fileClicked(string filePath) + // https://doc.qt.io/qt-6/qml-qtquick-treeview.html TreeView { id: fileSystemTreeView anchors.margins: 15 property int lastIndex: -1 - model: FileSystem + model: FileSystemSortProxyModel anchors.fill: parent boundsBehavior: Flickable.StopAtBounds boundsMovement: Flickable.StopAtBounds diff --git a/src/gui/filesystem.rs b/src/gui/filesystem.rs index ffac3bf..4d7d097 100644 --- a/src/gui/filesystem.rs +++ b/src/gui/filesystem.rs @@ -1,21 +1,47 @@ // SPDX-FileCopyrightText: 2026, Shaun Reed // // SPDX-License-Identifier: GNU General Public License v3.0 or later +use crate::gui::filesystem::qobject::{QAbstractItemModel}; +use cxx_qt_lib::{QModelIndex, QString}; +use dirs; +use log::warn; +use std::io::BufRead; +use std::{fs}; +use syntect::easy::HighlightFile; +use syntect::highlighting::ThemeSet; +use syntect::html::{ + IncludeBackground, append_highlighted_html_for_styled_line, start_highlighted_html_snippet, +}; +use syntect::parsing::SyntaxSet; #[cxx_qt::bridge] pub mod qobject { + // Import Qt Types from C++ unsafe extern "C++" { - // Import Qt Types from C++ include!("cxx-qt-lib/qstring.h"); type QString = cxx_qt_lib::QString; + include!("cxx-qt-lib/qmodelindex.h"); type QModelIndex = cxx_qt_lib::QModelIndex; + include!(); type QFileSystemModel; + + include!(); + type QSortFilterProxyModel; + + include!(); + type QAbstractItemModel; } + // Export QML classes from Rust unsafe extern "RustQt" { - // Export QML Types from Rust + #[qobject] + #[qml_element] + #[base = QSortFilterProxyModel] + #[qproperty(*mut FileSystem, inner)] + type FileSystemSortProxyModel = super::FileSystemSortProxyModelImpl; + #[qobject] #[base = QFileSystemModel] #[qml_element] @@ -23,6 +49,40 @@ pub mod qobject { #[qproperty(QString, file_path, cxx_name = "filePath")] #[qproperty(QModelIndex, root_index, cxx_name = "rootIndex")] type FileSystem = super::FileSystemImpl; + } + + // Export QSortFilterProxyModel functions from Rust + // https://doc.qt.io/qt-6/qsortfilterproxymodel.html + unsafe extern "RustQt" { + #[inherit] + #[cxx_name = "setSourceModel"] + unsafe fn set_source_model( + self: Pin<&mut FileSystemSortProxyModel>, + source: *mut QAbstractItemModel, + ); + + #[cxx_override] + #[cxx_name = "filterAcceptsRow"] + const fn filter_accepts_row( + self: &FileSystemSortProxyModel, + source_row: i32, + source_parent: &QModelIndex, + ) -> bool; + } + + // Custom initialization logic. + impl cxx_qt::Initialize for FileSystemSortProxyModel {} + + // Export QFileSystemModel functions from Rust + // https://doc.qt.io/qt-6/qfilesystemmodel.html + unsafe extern "RustQt" { + #[inherit] + fn index( + self: Pin<&mut FileSystem>, + row: i32, + col: i32, + parent: &QModelIndex, + ) -> QModelIndex; #[inherit] #[cxx_name = "setRootPath"] @@ -43,17 +103,35 @@ pub mod qobject { } } -use cxx_qt_lib::{QModelIndex, QString}; -use dirs; -use log::warn; -use std::fs; -use std::io::BufRead; -use syntect::easy::HighlightFile; -use syntect::highlighting::ThemeSet; -use syntect::html::{ - IncludeBackground, append_highlighted_html_for_styled_line, start_highlighted_html_snippet, -}; -use syntect::parsing::SyntaxSet; +pub struct FileSystemSortProxyModelImpl { + inner: *mut qobject::FileSystem, +} + +impl Default for FileSystemSortProxyModelImpl { + fn default() -> Self { + let model = Self { + inner: std::ptr::null_mut(), + }; + model + } +} + +impl qobject::FileSystemSortProxyModel { + pub const fn filter_accepts_row(&self, _source_row: i32, _source_parent: &QModelIndex) -> bool { + true + } +} + +impl cxx_qt::Initialize for qobject::FileSystemSortProxyModel { + fn initialize(self: core::pin::Pin<&mut Self>) { + let mut fs = FileSystemImpl::default(); + unsafe { + let model: *mut FileSystemImpl = std::ptr::from_mut(&mut fs); + let m: *mut QAbstractItemModel = model as *mut QAbstractItemModel; + self.set_source_model(m); + } + } +} // TODO: Impleent a provider for QFileSystemModel::setIconProvider for icons. pub struct FileSystemImpl {