gui #17

Open
shaunrd0 wants to merge 11 commits from gui into main
2 changed files with 21 additions and 124 deletions
Showing only changes of commit c70bba16e4 - Show all commits

View File

@ -16,23 +16,20 @@ Rectangle {
signal fileClicked(string filePath) signal fileClicked(string filePath)
// https://doc.qt.io/qt-6/qml-qtquick-treeview.html
TreeView { TreeView {
id: fileSystemTreeView id: fileSystemTreeView
anchors.margins: 15 anchors.margins: 15
property int lastIndex: -1 property int lastIndex: -1
model: FileSystemSortProxyModel { model: FileSystem
id: fs
}
anchors.fill: parent anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
boundsMovement: Flickable.StopAtBounds boundsMovement: Flickable.StopAtBounds
clip: true clip: true
Component.onCompleted: { Component.onCompleted: {
fs.setDirectory(root.rootDirectory) FileSystem.setDirectory(root.rootDirectory)
fileSystemTreeView.expandRecursively(0, -1) fileSystemTreeView.expandRecursively(0, -1)
} }
@ -125,13 +122,13 @@ Rectangle {
text: qsTr("Set as root index") text: qsTr("Set as root index")
onTriggered: { onTriggered: {
console.log("Setting directory: " + treeDelegate.filePath) console.log("Setting directory: " + treeDelegate.filePath)
FileSystemSortProxyModel.setDirectory(treeDelegate.filePath) FileSystem.setDirectory(treeDelegate.filePath)
} }
} }
Action { Action {
text: qsTr("Reset root index") text: qsTr("Reset root index")
onTriggered: { onTriggered: {
FileSystemSortProxyModel.setDirectory("") FileSystem.setDirectory("")
} }
} }
} }

View File

@ -1,48 +1,21 @@
// SPDX-FileCopyrightText: 2026, Shaun Reed <shaunrd0@gmail.com> // SPDX-FileCopyrightText: 2026, Shaun Reed <shaunrd0@gmail.com>
// //
// SPDX-License-Identifier: GNU General Public License v3.0 or later // 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] #[cxx_qt::bridge]
pub mod qobject { pub mod qobject {
// Import Qt Types from C++
unsafe extern "C++" { unsafe extern "C++" {
// Import Qt Types from C++
include!("cxx-qt-lib/qstring.h"); include!("cxx-qt-lib/qstring.h");
type QString = cxx_qt_lib::QString; type QString = cxx_qt_lib::QString;
include!("cxx-qt-lib/qmodelindex.h"); include!("cxx-qt-lib/qmodelindex.h");
type QModelIndex = cxx_qt_lib::QModelIndex; type QModelIndex = cxx_qt_lib::QModelIndex;
include!(<QtGui/QFileSystemModel>); include!(<QtGui/QFileSystemModel>);
type QFileSystemModel; type QFileSystemModel;
include!(<QSortFilterProxyModel>);
type QSortFilterProxyModel;
include!(<QAbstractItemModel>);
type QAbstractItemModel;
} }
// Export QML classes from Rust
unsafe extern "RustQt" { unsafe extern "RustQt" {
#[qobject] // Export QML Types from Rust
#[qml_element]
#[base = QSortFilterProxyModel]
#[qproperty(*mut FileSystem, inner)]
type FileSystemSortProxyModel = super::FileSystemSortProxyModelImpl;
#[qobject] #[qobject]
#[base = QFileSystemModel] #[base = QFileSystemModel]
#[qml_element] #[qml_element]
@ -50,37 +23,7 @@ pub mod qobject {
#[qproperty(QString, file_path, cxx_name = "filePath")] #[qproperty(QString, file_path, cxx_name = "filePath")]
#[qproperty(QModelIndex, root_index, cxx_name = "rootIndex")] #[qproperty(QModelIndex, root_index, cxx_name = "rootIndex")]
type FileSystem = super::FileSystemImpl; 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] #[inherit]
#[cxx_name = "setRootPath"] #[cxx_name = "setRootPath"]
fn set_root_path(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex; fn set_root_path(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex;
@ -93,67 +36,24 @@ pub mod qobject {
#[qinvokable] #[qinvokable]
#[cxx_name = "readFile"] #[cxx_name = "readFile"]
fn read_file(self: &FileSystem, path: &QString) -> QString; fn read_file(self: &FileSystem, path: &QString) -> QString;
//
// #[qinvokable] #[qinvokable]
// #[cxx_name = "setDirectory"] #[cxx_name = "setDirectory"]
// fn set_directory(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex; fn set_directory(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex;
} }
} }
pub struct FileSystemSortProxyModelImpl { use cxx_qt_lib::{QModelIndex, QString};
inner: *mut qobject::FileSystem, use dirs;
} use log::warn;
use std::fs;
impl Default for FileSystemSortProxyModelImpl { use std::io::BufRead;
fn default() -> Self { use syntect::easy::HighlightFile;
let model = Self { use syntect::highlighting::ThemeSet;
inner: std::ptr::null_mut(), use syntect::html::{
}; IncludeBackground, append_highlighted_html_for_styled_line, start_highlighted_html_snippet,
model };
} use syntect::parsing::SyntaxSet;
}
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. // TODO: Impleent a provider for QFileSystemModel::setIconProvider for icons.
pub struct FileSystemImpl { pub struct FileSystemImpl {