From 9129dbe0b992e7f1790aa98bf8401e8c6fd7180a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 26 Oct 2019 21:27:57 +0200 Subject: [PATCH] HackStudio: Implement adding a new file to the project You can now press Ctrl+N to create and add a new file to the project! --- DevTools/HackStudio/Project.cpp | 31 ++++++++++++++++++++++++++++--- DevTools/HackStudio/Project.h | 6 +++++- DevTools/HackStudio/main.cpp | 18 ++++++++++++++++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/DevTools/HackStudio/Project.cpp b/DevTools/HackStudio/Project.cpp index 9ef4f7e44c..0a3dacd0b7 100644 --- a/DevTools/HackStudio/Project.cpp +++ b/DevTools/HackStudio/Project.cpp @@ -24,13 +24,17 @@ public: } return {}; } - virtual void update() override {} + virtual void update() override + { + did_update(); + } private: Project& m_project; }; -Project::Project(Vector&& filenames) +Project::Project(const String& path, Vector&& filenames) + : m_path(path) { for (auto& filename : filenames) { m_files.append(TextDocument::construct_with_name(filename)); @@ -52,5 +56,26 @@ OwnPtr Project::load_from_file(const String& path) files.append(String::copy(line, Chomp)); } - return OwnPtr(new Project(move(files))); + return OwnPtr(new Project(path, move(files))); +} + +bool Project::add_file(const String& filename) +{ + auto project_file = CFile::construct(m_path); + if (!project_file->open(CFile::WriteOnly)) + return false; + + for (auto& file : m_files) { + // FIXME: Check for error here. CIODevice::printf() needs some work on error reporting. + project_file->printf("%s\n", file.name().characters()); + } + + project_file->printf("%s\n", filename.characters()); + + if (!project_file->close()) + return false; + + m_files.append(TextDocument::construct_with_name(filename)); + m_model->update(); + return true; } diff --git a/DevTools/HackStudio/Project.h b/DevTools/HackStudio/Project.h index 8233ac6cb2..d68b936e59 100644 --- a/DevTools/HackStudio/Project.h +++ b/DevTools/HackStudio/Project.h @@ -12,6 +12,8 @@ class Project { public: static OwnPtr load_from_file(const String& path); + [[nodiscard]] bool add_file(const String& filename); + GModel& model() { return *m_model; } template @@ -22,10 +24,12 @@ public: } } + private: friend class ProjectModel; - explicit Project(Vector&& files); + explicit Project(const String& path, Vector&& files); + String m_path; RefPtr m_model; NonnullRefPtrVector m_files; }; diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index 6f46e34261..07efdbf417 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -76,8 +76,22 @@ int main(int argc, char** argv) g_text_editor->set_line_wrapping_enabled(true); g_text_editor->set_automatic_indentation_enabled(true); - auto new_action = GAction::create("New", { Mod_Ctrl, Key_N }, GraphicsBitmap::load_from_file("/res/icons/16x16/new.png"), [&](const GAction&) { - // FIXME: Implement. + auto new_action = GAction::create("Add new file to project", { Mod_Ctrl, Key_N }, GraphicsBitmap::load_from_file("/res/icons/16x16/new.png"), [&](const GAction&) { + auto input_box = GInputBox::construct("Enter name of new file:", "Add new file to project", g_window); + if (input_box->exec() == GInputBox::ExecCancel) + return; + auto filename = input_box->text_value(); + auto file = CFile::construct(filename); + if (!file->open((CIODevice::OpenMode)(CIODevice::WriteOnly | CIODevice::MustBeNew))) { + GMessageBox::show(String::format("Failed to create '%s'", filename.characters()), "Error", GMessageBox::Type::Error, GMessageBox::InputType::OK, g_window); + return; + } + if (!g_project->add_file(filename)) { + GMessageBox::show(String::format("Failed to add '%s' to project", filename.characters()), "Error", GMessageBox::Type::Error, GMessageBox::InputType::OK, g_window); + // FIXME: Should we unlink the file here maybe? + return; + } + open_file(filename); }); auto open_action = GCommonActions::make_open_action([&](auto&) {