update_file, add multiple files, display sizes

This commit is contained in:
2025-11-02 18:36:45 +01:00
parent 3922456171
commit d292d42b65
5 changed files with 103 additions and 40 deletions

View File

@@ -1,6 +1,8 @@
#include "mainwindow.h"
#include <QDesktopServices>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QTemporaryFile>
#include <iostream>
@@ -16,7 +18,7 @@ MainWindow::MainWindow(QWidget *parent)
return;
}
m_vault = Vault(path.toStdString());
m_vault = std::make_unique<Vault>(path.toStdString());
reload_fs_tree();
});
@@ -28,7 +30,7 @@ MainWindow::MainWindow(QWidget *parent)
return;
}
m_vault = Vault(path.toStdString());
m_vault = std::make_unique<Vault>(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<char>(file)),
std::istreambuf_iterator<char>());
m_vault->write_file(path_to_filename(path.toStdString()), content);
}
std::ifstream file(path.toStdString(), std::ios::binary);
std::string content((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
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";
}

View File

@@ -3,6 +3,7 @@
#include "ui_mainwindow.h"
#include "vault.h"
#include <QMainWindow>
#include <memory>
class MainWindow : public QMainWindow {
Q_OBJECT
@@ -13,7 +14,7 @@ public:
private:
Ui::MainWindow *ui;
std::optional<Vault> m_vault;
std::unique_ptr<Vault> m_vault;
void reload_fs_tree();
void preview_file(const std::string &filename);

View File

@@ -20,11 +20,19 @@
<property name="contextMenuPolicy">
<enum>Qt::ContextMenuPolicy::CustomContextMenu</enum>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Size</string>
</property>
</column>
</widget>
</item>
<item>
@@ -52,8 +60,7 @@
<property name="title">
<string>Files</string>
</property>
<addaction name="actionCreateFile"/>
<addaction name="actionAddFile"/>
<addaction name="actionAddFiles"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuFiles"/>
@@ -68,7 +75,7 @@
<string>Open</string>
</property>
</action>
<action name="actionAddFile">
<action name="actionAddFiles">
<property name="text">
<string>Add</string>
</property>

View File

@@ -1,6 +1,7 @@
#include "vault.h"
#include "common.h"
#include <array>
#include <filesystem>
#include <iostream>
Vault::Vault(std::string path) : m_path(std::move(path)) {
@@ -78,15 +79,75 @@ std::optional<std::string> 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<const char *>(&name_size), sizeof(u64));
m_file.write(name.data(), static_cast<i64>(name_size));
m_file.write(reinterpret_cast<const char *>(&filename_size), sizeof(u64));
m_file.write(filename.data(), static_cast<i64>(filename_size));
m_file.write(reinterpret_cast<const char *>(&content_size), sizeof(u64));
m_file.write(content.data(), static_cast<i64>(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<char *>(&name_size), sizeof(u64))) {
break;
}
std::string name;
name.resize(name_size);
m_file.read(name.data(), static_cast<i64>(name_size));
u64 content_size = 0;
m_file.read(reinterpret_cast<char *>(&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<i64>(content_size), std::ios::cur);
break;
}
m_file.seekg(static_cast<i64>(content_size), std::ios::cur);
}
if (entry_start != -1) {
i64 entry_end = entry_start + static_cast<i64>(entry_total_size);
m_file.clear();
m_file.seekg(entry_end, std::ios::beg);
std::string remaining;
remaining.assign(std::istreambuf_iterator<char>(m_file),
std::istreambuf_iterator<char>());
m_file.clear();
m_file.seekp(entry_start, std::ios::beg);
m_file.write(remaining.data(), static_cast<i64>(remaining.size()));
i64 new_size = entry_start + static_cast<i64>(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);
}

View File

@@ -20,6 +20,7 @@ public:
std::vector<FileHeader> read_file_headers();
std::optional<std::string> 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;