From 1546eb1028de0c9b167e93838aa3ea945bdb54bd Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sun, 30 Mar 2025 13:50:23 -0400 Subject: [PATCH] Add FileSystem Rust module. --- qml/ClideEditor.qml | 7 ++++++ qml/ClideProjectView.qml | 2 ++ src/filesystem.rs | 53 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/filesystem.rs diff --git a/qml/ClideEditor.qml b/qml/ClideEditor.qml index 26eea2e..bde3318 100644 --- a/qml/ClideEditor.qml +++ b/qml/ClideEditor.qml @@ -5,10 +5,16 @@ import QtQuick.Layouts import clide.module 1.0 SplitView { + id: root Layout.fillHeight: true Layout.fillWidth: true orientation: Qt.Vertical + // The path to the file to show in the text editor. + // This is updated by a signal caught within ClideProjectView. + // Initialized by the Default trait for the Rust QML singleton FileSystem. + required property string filePath; + // Customized handle to drag between the Editor and the Console. handle: Rectangle { border.color: SplitHandle.pressed ? RustColors.pressed : SplitHandle.hovered ? RustColors.hovered : RustColors.gutter @@ -102,6 +108,7 @@ SplitView { // selectionColor: RustColors.editor_highlight textFormat: Qt.AutoText wrapMode: TextArea.Wrap + text: FileSystem.readFile(root.filePath) background: Rectangle { color: RustColors.editor_background diff --git a/qml/ClideProjectView.qml b/qml/ClideProjectView.qml index 5ceab61..eead520 100644 --- a/qml/ClideProjectView.qml +++ b/qml/ClideProjectView.qml @@ -51,5 +51,7 @@ SplitView { } } ClideEditor { + // Initialize using the Default trait in Rust QML singleton FileSystem. + filePath: FileSystem.filePath } } diff --git a/src/filesystem.rs b/src/filesystem.rs new file mode 100644 index 0000000..ecc9fcd --- /dev/null +++ b/src/filesystem.rs @@ -0,0 +1,53 @@ +#[cxx_qt::bridge] +pub mod qobject { + 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; + } + + unsafe extern "RustQt" { + // Export QML Types from Rust + #[qobject] + #[qml_element] + #[qml_singleton] + #[qproperty(QString, file_path, cxx_name = "filePath")] + type FileSystem = super::FileSystemImpl; + + #[qinvokable] + #[cxx_name = "readFile"] + fn read_file(self: &FileSystem, path: &QString) -> QString; + } +} + +use cxx_qt_lib::{QModelIndex, QString}; +use std::fs; +pub struct FileSystemImpl { + file_path: QString, + model_index: QModelIndex, +} + +// Default is explicit to make the editor open this source file initially. +impl Default for FileSystemImpl { + fn default() -> Self { + Self { + file_path: QString::from(file!()), + model_index: Default::default(), + } + } +} + +impl qobject::FileSystem { + fn read_file(&self, path: &QString) -> QString { + if path.is_empty() { + return QString::default(); + } + // TODO: What if the file is binary or something horrible? + QString::from( + fs::read_to_string(path.to_string()) + .expect(format!("Failed to read file {}", path).as_str()), + ) + } +}