From d292d42b65e562aab6b73016580161bb1fc16ecd Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 2 Nov 2025 18:36:45 +0100 Subject: [PATCH] update_file, add multiple files, display sizes --- src/mainwindow.cc | 57 +++++++++++++++++---------------------- src/mainwindow.h | 3 ++- src/mainwindow.ui | 13 ++++++--- src/vault.cc | 69 ++++++++++++++++++++++++++++++++++++++++++++--- src/vault.h | 1 + 5 files changed, 103 insertions(+), 40 deletions(-) diff --git a/src/mainwindow.cc b/src/mainwindow.cc index d4da126..fd495d0 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -1,6 +1,8 @@ #include "mainwindow.h" +#include #include #include +#include #include #include @@ -16,7 +18,7 @@ MainWindow::MainWindow(QWidget *parent) return; } - m_vault = Vault(path.toStdString()); + m_vault = std::make_unique(path.toStdString()); reload_fs_tree(); }); @@ -28,7 +30,7 @@ MainWindow::MainWindow(QWidget *parent) return; } - m_vault = Vault(path.toStdString()); + m_vault = std::make_unique(path.toStdString()); reload_fs_tree(); }); @@ -40,39 +42,22 @@ MainWindow::MainWindow(QWidget *parent) connect(ui->fsTreeWidget, &QTreeWidget::customContextMenuRequested, this, &MainWindow::file_context_menu); - connect(ui->actionAddFile, &QAction::triggered, this, [this]() { + connect(ui->actionAddFiles, &QAction::triggered, this, [this]() { if (!m_vault) { return; } - QString path = QFileDialog::getOpenFileName(this, "Choose a file to add"); - if (path.isEmpty()) { - return; + QStringList paths = + QFileDialog::getOpenFileNames(this, "Choose files to add"); + for (const auto &path : paths) { + std::ifstream file(path.toStdString(), std::ios::binary); + + std::string content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + + m_vault->write_file(path_to_filename(path.toStdString()), content); } - std::ifstream file(path.toStdString(), std::ios::binary); - - std::string content((std::istreambuf_iterator(file)), - std::istreambuf_iterator()); - - m_vault->write_file(path_to_filename(path.toStdString()), content); - - reload_fs_tree(); - }); - - connect(ui->actionCreateFile, &QAction::triggered, this, [this]() { - if (!m_vault) { - return; - } - - QString path = - QInputDialog::getText(this, "Create File", "Where to create the file"); - if (path.isEmpty()) { - return; - } - - m_vault->write_file(path.toStdString(), ""); - reload_fs_tree(); }); } @@ -84,7 +69,9 @@ void MainWindow::reload_fs_tree() { for (const auto &header : headers) { auto *item = new QTreeWidgetItem(ui->fsTreeWidget); item->setText(0, QString::fromStdString(header.name)); + item->setText(1, QString::number(header.size)); } + ui->fsTreeWidget->resizeColumnToContents(0); } void MainWindow::preview_file(const std::string &filename) { @@ -107,9 +94,15 @@ void MainWindow::edit_file(const std::string &filename) { } temp_file.flush(); - // TODO: xdg-open or something - std::system(("kwrite " + temp_file.fileName()).toStdString().c_str()); - // TODO: write back + QDesktopServices::openUrl(QUrl::fromLocalFile(temp_file.fileName())); + QMessageBox::information(this, "Edit", + "Please edit the file in the opened editor and " + "save it. Click OK when done."); + + temp_file.seek(0); + QTextStream in(&temp_file); + m_vault->update_file(filename, in.readAll().toStdString()); + reload_fs_tree(); } else { qWarning() << "File to edit not found"; } diff --git a/src/mainwindow.h b/src/mainwindow.h index f058d29..1f5c7ca 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -3,6 +3,7 @@ #include "ui_mainwindow.h" #include "vault.h" #include +#include class MainWindow : public QMainWindow { Q_OBJECT @@ -13,7 +14,7 @@ public: private: Ui::MainWindow *ui; - std::optional m_vault; + std::unique_ptr m_vault; void reload_fs_tree(); void preview_file(const std::string &filename); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 3a4a89a..2d953ab 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -20,11 +20,19 @@ Qt::ContextMenuPolicy::CustomContextMenu + + false + Name + + + Size + + @@ -52,8 +60,7 @@ Files - - + @@ -68,7 +75,7 @@ Open - + Add diff --git a/src/vault.cc b/src/vault.cc index 6248084..ccd7bfd 100644 --- a/src/vault.cc +++ b/src/vault.cc @@ -1,6 +1,7 @@ #include "vault.h" #include "common.h" #include +#include #include Vault::Vault(std::string path) : m_path(std::move(path)) { @@ -78,15 +79,75 @@ std::optional Vault::read_file(const std::string &filename) { return std::nullopt; } -void Vault::write_file(const std::string &name, const std::string &content) { +void Vault::write_file(const std::string &filename, + const std::string &content) { m_file.clear(); m_file.seekp(0, std::ios::end); - u64 name_size = name.size(); + u64 filename_size = filename.size(); u64 content_size = content.size(); - m_file.write(reinterpret_cast(&name_size), sizeof(u64)); - m_file.write(name.data(), static_cast(name_size)); + m_file.write(reinterpret_cast(&filename_size), sizeof(u64)); + m_file.write(filename.data(), static_cast(filename_size)); m_file.write(reinterpret_cast(&content_size), sizeof(u64)); m_file.write(content.data(), static_cast(content_size)); m_file.flush(); } + +void Vault::update_file(const std::string &filename, + const std::string &content) { + m_file.clear(); + m_file.seekg(AFTER_HEADER_OFFSET, std::ios::beg); + + i64 entry_start = -1; + u64 entry_total_size = 0; + + while (true) { + i64 current_pos = m_file.tellg(); + + u64 name_size = 0; + if (!m_file.read(reinterpret_cast(&name_size), sizeof(u64))) { + break; + } + + std::string name; + name.resize(name_size); + m_file.read(name.data(), static_cast(name_size)); + + u64 content_size = 0; + m_file.read(reinterpret_cast(&content_size), sizeof(u64)); + + if (name == filename) { + entry_start = current_pos; + entry_total_size = sizeof(u64) + name_size + sizeof(u64) + content_size; + m_file.seekg(static_cast(content_size), std::ios::cur); + break; + } + + m_file.seekg(static_cast(content_size), std::ios::cur); + } + + if (entry_start != -1) { + i64 entry_end = entry_start + static_cast(entry_total_size); + + m_file.clear(); + m_file.seekg(entry_end, std::ios::beg); + std::string remaining; + remaining.assign(std::istreambuf_iterator(m_file), + std::istreambuf_iterator()); + + m_file.clear(); + m_file.seekp(entry_start, std::ios::beg); + m_file.write(remaining.data(), static_cast(remaining.size())); + + i64 new_size = entry_start + static_cast(remaining.size()); + m_file.flush(); + m_file.close(); + + std::filesystem::resize_file(m_path, new_size); + + m_file.open(m_path, std::ios::in | std::ios::out | std::ios::binary); + ASSERT(m_file.good()); + } + + write_file(filename, content); +} \ No newline at end of file diff --git a/src/vault.h b/src/vault.h index 4351f5c..9a3ffc5 100644 --- a/src/vault.h +++ b/src/vault.h @@ -20,6 +20,7 @@ public: std::vector read_file_headers(); std::optional read_file(const std::string &name); void write_file(const std::string &name, const std::string &content); + void update_file(const std::string &name, const std::string &content); private: std::string m_path;