mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-21 18:37:58 +03:00
HackStudio: Add a 'Recent Projects' submenu in 'File'
This commit is contained in:
parent
dbfe385879
commit
7e7bfdac50
Notes:
sideshowbarker
2024-07-17 18:27:01 +09:00
Author: https://github.com/mrkct Commit: https://github.com/SerenityOS/serenity/commit/7e7bfdac50 Pull-request: https://github.com/SerenityOS/serenity/pull/12519 Reviewed-by: https://github.com/itamar8910 ✅
@ -23,6 +23,7 @@
|
|||||||
#include "ProjectDeclarations.h"
|
#include "ProjectDeclarations.h"
|
||||||
#include "TerminalWrapper.h"
|
#include "TerminalWrapper.h"
|
||||||
#include "ToDoEntries.h"
|
#include "ToDoEntries.h"
|
||||||
|
#include <AK/JsonParser.h>
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <Kernel/API/InodeWatcherEvent.h>
|
#include <Kernel/API/InodeWatcherEvent.h>
|
||||||
@ -192,6 +193,28 @@ void HackStudioWidget::on_action_tab_change()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<String> HackStudioWidget::read_recent_projects()
|
||||||
|
{
|
||||||
|
auto json = Config::read_string("HackStudio", "Global", "RecentProjects");
|
||||||
|
AK::JsonParser parser(json);
|
||||||
|
auto value_or_error = parser.parse();
|
||||||
|
if (value_or_error.is_error())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto value = value_or_error.release_value();
|
||||||
|
if (!value.is_array())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Vector<String> paths;
|
||||||
|
for (auto& json_value : value.as_array().values()) {
|
||||||
|
if (!json_value.is_string())
|
||||||
|
return {};
|
||||||
|
paths.append(json_value.as_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
void HackStudioWidget::open_project(const String& root_path)
|
void HackStudioWidget::open_project(const String& root_path)
|
||||||
{
|
{
|
||||||
if (warn_unsaved_changes("There are unsaved changes, do you want to save before closing current project?") == ContinueDecision::No)
|
if (warn_unsaved_changes("There are unsaved changes, do you want to save before closing current project?") == ContinueDecision::No)
|
||||||
@ -229,6 +252,15 @@ void HackStudioWidget::open_project(const String& root_path)
|
|||||||
LexicalPath::relative_path(absolute_old_path, m_project->root_path()),
|
LexicalPath::relative_path(absolute_old_path, m_project->root_path()),
|
||||||
LexicalPath::relative_path(absolute_new_path, m_project->root_path()));
|
LexicalPath::relative_path(absolute_new_path, m_project->root_path()));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto recent_projects = read_recent_projects();
|
||||||
|
recent_projects.remove_all_matching([&](auto& p) { return p == root_path; });
|
||||||
|
recent_projects.insert(0, root_path);
|
||||||
|
if (recent_projects.size() > recent_projects_history_size)
|
||||||
|
recent_projects.shrink(recent_projects_history_size);
|
||||||
|
|
||||||
|
Config::write_string("HackStudio", "Global", "RecentProjects", JsonArray(recent_projects).to_string());
|
||||||
|
update_recent_projects_submenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> HackStudioWidget::selected_file_paths() const
|
Vector<String> HackStudioWidget::selected_file_paths() const
|
||||||
@ -1142,11 +1174,36 @@ void HackStudioWidget::create_project_tab(GUI::Widget& parent)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HackStudioWidget::update_recent_projects_submenu()
|
||||||
|
{
|
||||||
|
if (!m_recent_projects_submenu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_recent_projects_submenu->remove_all_actions();
|
||||||
|
auto recent_projects = read_recent_projects();
|
||||||
|
|
||||||
|
if (recent_projects.size() <= 1) {
|
||||||
|
auto empty_action = GUI::Action::create("Empty...", [](auto&) {});
|
||||||
|
empty_action->set_enabled(false);
|
||||||
|
m_recent_projects_submenu->add_action(empty_action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < recent_projects.size(); i++) {
|
||||||
|
auto project_path = recent_projects[i];
|
||||||
|
m_recent_projects_submenu->add_action(GUI::Action::create(recent_projects[i], [this, project_path](auto&) {
|
||||||
|
open_project(project_path);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HackStudioWidget::create_file_menu(GUI::Window& window)
|
void HackStudioWidget::create_file_menu(GUI::Window& window)
|
||||||
{
|
{
|
||||||
auto& file_menu = window.add_menu("&File");
|
auto& file_menu = window.add_menu("&File");
|
||||||
file_menu.add_action(*m_new_project_action);
|
file_menu.add_action(*m_new_project_action);
|
||||||
file_menu.add_action(*m_open_action);
|
file_menu.add_action(*m_open_action);
|
||||||
|
m_recent_projects_submenu = &file_menu.add_submenu("Open Recent");
|
||||||
|
update_recent_projects_submenu();
|
||||||
file_menu.add_action(*m_save_action);
|
file_menu.add_action(*m_save_action);
|
||||||
file_menu.add_action(*m_save_as_action);
|
file_menu.add_action(*m_save_as_action);
|
||||||
file_menu.add_separator();
|
file_menu.add_separator();
|
||||||
|
@ -73,7 +73,11 @@ public:
|
|||||||
void for_each_open_file(Function<void(ProjectFile const&)>);
|
void for_each_open_file(Function<void(ProjectFile const&)>);
|
||||||
bool semantic_syntax_highlighting_is_enabled() const;
|
bool semantic_syntax_highlighting_is_enabled() const;
|
||||||
|
|
||||||
|
static Vector<String> read_recent_projects();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr size_t recent_projects_history_size = 15;
|
||||||
|
|
||||||
static String get_full_path_of_serenity_source(const String& file);
|
static String get_full_path_of_serenity_source(const String& file);
|
||||||
String get_absolute_path(String const&) const;
|
String get_absolute_path(String const&) const;
|
||||||
Vector<String> selected_file_paths() const;
|
Vector<String> selected_file_paths() const;
|
||||||
@ -128,6 +132,7 @@ private:
|
|||||||
void create_toolbar(GUI::Widget& parent);
|
void create_toolbar(GUI::Widget& parent);
|
||||||
void create_action_tab(GUI::Widget& parent);
|
void create_action_tab(GUI::Widget& parent);
|
||||||
void create_file_menu(GUI::Window&);
|
void create_file_menu(GUI::Window&);
|
||||||
|
void update_recent_projects_submenu();
|
||||||
void create_project_menu(GUI::Window&);
|
void create_project_menu(GUI::Window&);
|
||||||
void create_edit_menu(GUI::Window&);
|
void create_edit_menu(GUI::Window&);
|
||||||
void create_build_menu(GUI::Window&);
|
void create_build_menu(GUI::Window&);
|
||||||
@ -193,6 +198,7 @@ private:
|
|||||||
RefPtr<DisassemblyWidget> m_disassembly_widget;
|
RefPtr<DisassemblyWidget> m_disassembly_widget;
|
||||||
RefPtr<Threading::Thread> m_debugger_thread;
|
RefPtr<Threading::Thread> m_debugger_thread;
|
||||||
RefPtr<EditorWrapper> m_current_editor_in_execution;
|
RefPtr<EditorWrapper> m_current_editor_in_execution;
|
||||||
|
RefPtr<GUI::Menu> m_recent_projects_submenu { nullptr };
|
||||||
|
|
||||||
NonnullRefPtrVector<GUI::Action> m_new_file_actions;
|
NonnullRefPtrVector<GUI::Action> m_new_file_actions;
|
||||||
RefPtr<GUI::Action> m_new_plain_file_action;
|
RefPtr<GUI::Action> m_new_plain_file_action;
|
||||||
|
Loading…
Reference in New Issue
Block a user