diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-23 21:13:08 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-23 21:13:08 +0200 |
commit | 2260190f398e5ae7b565c12ea662452f7916ba4b (patch) | |
tree | 8bb7bb62d2eee21ca3804625000c376be7627daa /DevTools | |
parent | 2d460b504f8fb95e23dbdc3c388ed892e0d37854 (diff) | |
download | serenity-2260190f398e5ae7b565c12ea662452f7916ba4b.zip |
HackStudio: Move "find in files" widget to its own file/class
Instead of clogging up main.cpp with find-in-files functionality,
put it in a FindInFilesWidget class in a separate file.
Diffstat (limited to 'DevTools')
-rw-r--r-- | DevTools/HackStudio/FindInFilesWidget.cpp | 90 | ||||
-rw-r--r-- | DevTools/HackStudio/FindInFilesWidget.h | 22 | ||||
-rw-r--r-- | DevTools/HackStudio/Makefile | 1 | ||||
-rw-r--r-- | DevTools/HackStudio/main.cpp | 88 |
4 files changed, 118 insertions, 83 deletions
diff --git a/DevTools/HackStudio/FindInFilesWidget.cpp b/DevTools/HackStudio/FindInFilesWidget.cpp new file mode 100644 index 0000000000..d5e7b77fad --- /dev/null +++ b/DevTools/HackStudio/FindInFilesWidget.cpp @@ -0,0 +1,90 @@ +#include "FindInFilesWidget.h" +#include "Project.h" +#include <LibGUI/GBoxLayout.h> +#include <LibGUI/GButton.h> +#include <LibGUI/GListView.h> +#include <LibGUI/GTextBox.h> + +extern void open_file(const String&); +extern OwnPtr<Project> g_project; + +struct FilenameAndLineNumber { + String filename; + int line_number { -1 }; +}; + +class SearchResultsModel final : public GModel { +public: + explicit SearchResultsModel(const Vector<FilenameAndLineNumber>&& matches) + : m_matches(move(matches)) + { + } + + virtual int row_count(const GModelIndex& = GModelIndex()) const override { return m_matches.size(); } + virtual int column_count(const GModelIndex& = GModelIndex()) const override { return 1; } + virtual GVariant data(const GModelIndex& index, Role role = Role::Display) const override + { + if (role == Role::Display) { + auto& match = m_matches.at(index.row()); + return String::format("%s:%d", match.filename.characters(), match.line_number); + } + return {}; + } + virtual void update() override {} + +private: + Vector<FilenameAndLineNumber> m_matches; +}; + +static RefPtr<SearchResultsModel> find_in_files(const StringView& text) +{ + Vector<FilenameAndLineNumber> matches; + g_project->for_each_text_file([&](auto& file) { + auto matches_in_file = file.find(text); + for (int match : matches_in_file) { + matches.append({ file.name(), match }); + } + }); + + return adopt(*new SearchResultsModel(move(matches))); +} + +FindInFilesWidget::FindInFilesWidget(GWidget* parent) + : GWidget(parent) +{ + set_layout(make<GBoxLayout>(Orientation::Vertical)); + m_textbox = GTextBox::construct(this); + m_textbox->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); + m_textbox->set_preferred_size(0, 20); + m_button = GButton::construct("Find in files", this); + m_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); + m_button->set_preferred_size(0, 20); + + m_result_view = GListView::construct(this); + + m_result_view->on_activation = [this](auto& index) { + auto match_string = m_result_view->model()->data(index).to_string(); + auto parts = match_string.split(':'); + ASSERT(parts.size() == 2); + bool ok; + int line_number = parts[1].to_int(ok); + ASSERT(ok); + open_file(parts[0]); + m_textbox->set_cursor(line_number - 1, 0); + m_textbox->set_focus(true); + }; + + m_button->on_click = [this](auto&) { + auto results_model = find_in_files(m_textbox->text()); + m_result_view->set_model(results_model); + }; + m_textbox->on_return_pressed = [this] { + m_button->click(); + }; +} + +void FindInFilesWidget::focus_textbox_and_select_all() +{ + m_textbox->select_all(); + m_textbox->set_focus(true); +} diff --git a/DevTools/HackStudio/FindInFilesWidget.h b/DevTools/HackStudio/FindInFilesWidget.h new file mode 100644 index 0000000000..c667ebd6a4 --- /dev/null +++ b/DevTools/HackStudio/FindInFilesWidget.h @@ -0,0 +1,22 @@ +#pragma once + +#include <LibGUI/GWidget.h> + +class GButton; +class GListView; +class GTextBox; + +class FindInFilesWidget final : public GWidget { + C_OBJECT(FindInFilesWidget) +public: + virtual ~FindInFilesWidget() override {} + + void focus_textbox_and_select_all(); + +private: + explicit FindInFilesWidget(GWidget* parent); + + RefPtr<GTextBox> m_textbox; + RefPtr<GButton> m_button; + RefPtr<GListView> m_result_view; +}; diff --git a/DevTools/HackStudio/Makefile b/DevTools/HackStudio/Makefile index 657c96beb4..c96a770342 100644 --- a/DevTools/HackStudio/Makefile +++ b/DevTools/HackStudio/Makefile @@ -4,6 +4,7 @@ OBJS = \ Project.o \ TextDocument.o \ TerminalWrapper.o \ + FindInFilesWidget.o \ main.o APP = HackStudio diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index 729d4e2c6b..4f82461468 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -1,11 +1,12 @@ +#include "FindInFilesWidget.h" #include "Project.h" #include "TerminalWrapper.h" #include <LibCore/CFile.h> #include <LibGUI/GAboutDialog.h> #include <LibGUI/GAction.h> #include <LibGUI/GApplication.h> -#include <LibGUI/GButton.h> #include <LibGUI/GBoxLayout.h> +#include <LibGUI/GButton.h> #include <LibGUI/GInputBox.h> #include <LibGUI/GListView.h> #include <LibGUI/GMenu.h> @@ -27,12 +28,10 @@ OwnPtr<Project> g_project; RefPtr<GWindow> g_window; RefPtr<GListView> g_project_list_view; RefPtr<GTextEditor> g_text_editor; -RefPtr<GTextBox> g_find_in_files_textbox; static void build(TerminalWrapper&); static void run(TerminalWrapper&); -static NonnullRefPtr<GWidget> build_find_in_files_widget(); -static void open_file(const String&); +void open_file(const String&); int main(int argc, char** argv) { @@ -75,7 +74,7 @@ int main(int argc, char** argv) auto tab_widget = GTabWidget::construct(inner_splitter); - auto find_in_files_widget = build_find_in_files_widget(); + auto find_in_files_widget = FindInFilesWidget::construct(nullptr); tab_widget->add_widget("Find in files", find_in_files_widget); auto terminal_wrapper = TerminalWrapper::construct(nullptr); @@ -116,8 +115,7 @@ int main(int argc, char** argv) auto edit_menu = make<GMenu>("Edit"); edit_menu->add_action(GAction::create("Find in files...", { Mod_Ctrl | Mod_Shift, Key_F }, [&](auto&) { tab_widget->set_active_widget(find_in_files_widget); - g_find_in_files_textbox->select_all(); - g_find_in_files_textbox->set_focus(true); + find_in_files_widget->focus_textbox_and_select_all(); })); menubar->add_menu(move(edit_menu)); @@ -156,82 +154,6 @@ void run(TerminalWrapper& wrapper) wrapper.run_command("make run"); } -struct FilenameAndLineNumber { - String filename; - int line_number { -1 }; -}; - -class SearchResultsModel final : public GModel { -public: - explicit SearchResultsModel(const Vector<FilenameAndLineNumber>&& matches) - : m_matches(move(matches)) - { - } - - virtual int row_count(const GModelIndex& = GModelIndex()) const override { return m_matches.size(); } - virtual int column_count(const GModelIndex& = GModelIndex()) const override { return 1; } - virtual GVariant data(const GModelIndex& index, Role role = Role::Display) const override - { - if (role == Role::Display) { - auto& match = m_matches.at(index.row()); - return String::format("%s:%d", match.filename.characters(), match.line_number); - } - return {}; - } - virtual void update() override {} - -private: - Vector<FilenameAndLineNumber> m_matches; -}; - -static RefPtr<SearchResultsModel> find_in_files(const StringView& text) -{ - Vector<FilenameAndLineNumber> matches; - g_project->for_each_text_file([&](auto& file) { - auto matches_in_file = file.find(text); - for (int match : matches_in_file) { - matches.append({ file.name(), match }); - } - }); - - return adopt(*new SearchResultsModel(move(matches))); -} - -NonnullRefPtr<GWidget> build_find_in_files_widget() -{ - auto widget = GWidget::construct(); - widget->set_layout(make<GBoxLayout>(Orientation::Vertical)); - g_find_in_files_textbox = GTextBox::construct(widget); - g_find_in_files_textbox->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); - g_find_in_files_textbox->set_preferred_size(0, 20); - auto button = GButton::construct("Find in files", widget); - button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); - button->set_preferred_size(0, 20); - - auto result_view = GListView::construct(widget); - - result_view->on_activation = [result_view](auto& index) { - auto match_string = result_view->model()->data(index).to_string(); - auto parts = match_string.split(':'); - ASSERT(parts.size() == 2); - bool ok; - int line_number = parts[1].to_int(ok); - ASSERT(ok); - open_file(parts[0]); - g_text_editor->set_cursor(line_number - 1, 0); - g_text_editor->set_focus(true); - }; - - button->on_click = [result_view = result_view.ptr()](auto&) { - auto results_model = find_in_files(g_find_in_files_textbox->text()); - result_view->set_model(results_model); - }; - g_find_in_files_textbox->on_return_pressed = [button = button.ptr()] { - button->click(); - }; - return widget; -} - void open_file(const String& filename) { auto file = CFile::construct(filename); |