Try to use QSortFilterProxyModel via cxx-qt.
This may be easier if I just wrap a QAbstractItemModel in C++ and use cxx-qt to pull it into QML? That way I could do C++ pointer things in C++ and rust things in rust.
This commit is contained in:
parent
aa8590cd5c
commit
325cf285fc
@ -16,20 +16,23 @@ 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 {
|
||||
id: fs
|
||||
}
|
||||
anchors.fill: parent
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
boundsMovement: Flickable.StopAtBounds
|
||||
clip: true
|
||||
|
||||
Component.onCompleted: {
|
||||
FileSystem.setDirectory(root.rootDirectory)
|
||||
fs.setDirectory(root.rootDirectory)
|
||||
fileSystemTreeView.expandRecursively(0, -1)
|
||||
}
|
||||
|
||||
@ -122,13 +125,13 @@ Rectangle {
|
||||
text: qsTr("Set as root index")
|
||||
onTriggered: {
|
||||
console.log("Setting directory: " + treeDelegate.filePath)
|
||||
FileSystem.setDirectory(treeDelegate.filePath)
|
||||
FileSystemSortProxyModel.setDirectory(treeDelegate.filePath)
|
||||
}
|
||||
}
|
||||
Action {
|
||||
text: qsTr("Reset root index")
|
||||
onTriggered: {
|
||||
FileSystem.setDirectory("")
|
||||
FileSystemSortProxyModel.setDirectory("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,48 @@
|
||||
// SPDX-FileCopyrightText: 2026, Shaun Reed <shaunrd0@gmail.com>
|
||||
//
|
||||
// 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 std::pin::Pin;
|
||||
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!(<QtGui/QFileSystemModel>);
|
||||
type QFileSystemModel;
|
||||
|
||||
include!(<QSortFilterProxyModel>);
|
||||
type QSortFilterProxyModel;
|
||||
|
||||
include!(<QAbstractItemModel>);
|
||||
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,7 +50,37 @@ 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;
|
||||
|
||||
#[qinvokable]
|
||||
#[cxx_name = "setDirectory"]
|
||||
fn set_directory(self: Pin<&mut FileSystemSortProxyModel>, path: &QString) -> QModelIndex;
|
||||
}
|
||||
|
||||
// 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]
|
||||
#[cxx_name = "setRootPath"]
|
||||
fn set_root_path(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex;
|
||||
@ -36,24 +93,67 @@ pub mod qobject {
|
||||
#[qinvokable]
|
||||
#[cxx_name = "readFile"]
|
||||
fn read_file(self: &FileSystem, path: &QString) -> QString;
|
||||
|
||||
#[qinvokable]
|
||||
#[cxx_name = "setDirectory"]
|
||||
fn set_directory(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex;
|
||||
//
|
||||
// #[qinvokable]
|
||||
// #[cxx_name = "setDirectory"]
|
||||
// fn set_directory(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
false
|
||||
}
|
||||
|
||||
fn read_file(&self, path: &QString) -> QString {
|
||||
if let Some(inner) = unsafe { self.inner().as_ref() } {
|
||||
let pinned_inner = unsafe { Pin::new_unchecked(inner) };
|
||||
return pinned_inner.read_file(path)
|
||||
} else {
|
||||
panic!("Can't get inner()")
|
||||
}
|
||||
QString::default()
|
||||
}
|
||||
|
||||
// There will never be more than one column.
|
||||
fn column_count(&self, _index: &QModelIndex) -> i32 {
|
||||
1
|
||||
}
|
||||
|
||||
fn set_directory(self: Pin<&mut Self>, path: &QString) -> QModelIndex {
|
||||
if let Some(inner) = unsafe { self.inner().as_mut() } {
|
||||
let pinned_inner = unsafe { Pin::new_unchecked(inner) };
|
||||
return pinned_inner.set_directory(path)
|
||||
} else {
|
||||
panic!("Can't get inner()")
|
||||
}
|
||||
QModelIndex::default()
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user