Serenity Operating System
at master 190 lines 6.1 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/URL.h> 10#include <AK/Vector.h> 11#include <LibConfig/Listener.h> 12#include <LibDesktop/Launcher.h> 13#include <LibGUI/Action.h> 14#include <LibGUI/ColumnsView.h> 15#include <LibGUI/FileSystemModel.h> 16#include <LibGUI/IconView.h> 17#include <LibGUI/StackWidget.h> 18#include <LibGUI/TableView.h> 19#include <fcntl.h> 20#include <sys/stat.h> 21 22namespace FileManager { 23 24void spawn_terminal(DeprecatedString const& directory); 25 26class LauncherHandler : public RefCounted<LauncherHandler> { 27public: 28 LauncherHandler(NonnullRefPtr<Desktop::Launcher::Details> const& details) 29 : m_details(details) 30 { 31 } 32 33 NonnullRefPtr<GUI::Action> create_launch_action(Function<void(LauncherHandler const&)>); 34 Desktop::Launcher::Details const& details() const { return *m_details; } 35 36private: 37 NonnullRefPtr<Desktop::Launcher::Details> m_details; 38}; 39 40class DirectoryView final 41 : public GUI::StackWidget 42 , private GUI::ModelClient 43 , public Config::Listener { 44 C_OBJECT(DirectoryView); 45 46public: 47 enum class Mode { 48 Desktop, 49 Normal, 50 }; 51 52 virtual ~DirectoryView() override; 53 54 bool open(DeprecatedString const& path); 55 DeprecatedString path() const { return model().root_path(); } 56 void open_parent_directory(); 57 void open_previous_directory(); 58 void open_next_directory(); 59 int path_history_size() const { return m_path_history.size(); } 60 int path_history_position() const { return m_path_history_position; } 61 static RefPtr<LauncherHandler> get_default_launch_handler(Vector<NonnullRefPtr<LauncherHandler>> const& handlers); 62 static Vector<NonnullRefPtr<LauncherHandler>> get_launch_handlers(URL const& url); 63 static Vector<NonnullRefPtr<LauncherHandler>> get_launch_handlers(DeprecatedString const& path); 64 65 void refresh(); 66 67 void launch(URL const&, LauncherHandler const&) const; 68 69 Function<void(StringView path, bool can_read_in_path, bool can_write_in_path)> on_path_change; 70 Function<void(GUI::AbstractView&)> on_selection_change; 71 Function<void(GUI::ModelIndex const&, GUI::ContextMenuEvent const&)> on_context_menu_request; 72 Function<void(StringView)> on_status_message; 73 Function<void(int done, int total)> on_thumbnail_progress; 74 Function<void()> on_accepted_drop; 75 76 enum ViewMode { 77 Invalid, 78 Table, 79 Columns, 80 Icon 81 }; 82 void set_view_mode(ViewMode); 83 ViewMode view_mode() const { return m_view_mode; } 84 85 void set_view_mode_from_string(DeprecatedString const&); 86 87 GUI::AbstractView& current_view() 88 { 89 switch (m_view_mode) { 90 case ViewMode::Table: 91 return *m_table_view; 92 case ViewMode::Columns: 93 return *m_columns_view; 94 case ViewMode::Icon: 95 return *m_icon_view; 96 default: 97 VERIFY_NOT_REACHED(); 98 } 99 } 100 101 GUI::AbstractView const& current_view() const 102 { 103 return const_cast<DirectoryView*>(this)->current_view(); 104 } 105 106 template<typename Callback> 107 void for_each_view_implementation(Callback callback) 108 { 109 if (m_icon_view) 110 callback(*m_icon_view); 111 if (m_table_view) 112 callback(*m_table_view); 113 if (m_columns_view) 114 callback(*m_columns_view); 115 } 116 117 void set_should_show_dotfiles(bool); 118 119 GUI::FileSystemModel::Node const& node(GUI::ModelIndex const&) const; 120 121 bool is_desktop() const { return m_mode == Mode::Desktop; } 122 123 Vector<DeprecatedString> selected_file_paths() const; 124 125 GUI::Action& mkdir_action() { return *m_mkdir_action; } 126 GUI::Action& touch_action() { return *m_touch_action; } 127 GUI::Action& open_terminal_action() { return *m_open_terminal_action; } 128 GUI::Action& delete_action() { return *m_delete_action; } 129 GUI::Action& force_delete_action() { return *m_force_delete_action; } 130 GUI::Action& rename_action() { return *m_rename_action; } 131 GUI::Action& view_as_icons_action() { return *m_view_as_icons_action; } 132 GUI::Action& view_as_table_action() { return *m_view_as_table_action; } 133 GUI::Action& view_as_columns_action() { return *m_view_as_columns_action; } 134 135 // ^Config::Listener 136 virtual void config_string_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value) override; 137 138private: 139 explicit DirectoryView(Mode); 140 141 GUI::FileSystemModel const& model() const { return *m_model; } 142 GUI::FileSystemModel& model() { return *m_model; } 143 144 void handle_selection_change(); 145 void handle_drop(GUI::ModelIndex const&, GUI::DropEvent const&); 146 void do_delete(bool should_confirm); 147 148 // ^GUI::ModelClient 149 virtual void model_did_update(unsigned) override; 150 151 void setup_actions(); 152 void setup_model(); 153 void setup_icon_view(); 154 void setup_columns_view(); 155 void setup_table_view(); 156 157 void handle_activation(GUI::ModelIndex const&); 158 159 void set_status_message(StringView); 160 void update_statusbar(); 161 bool can_modify_current_selection(); 162 163 Mode m_mode { Mode::Normal }; 164 ViewMode m_view_mode { Invalid }; 165 166 NonnullRefPtr<GUI::FileSystemModel> m_model; 167 NonnullRefPtr<GUI::SortingProxyModel> m_sorting_model; 168 size_t m_path_history_position { 0 }; 169 Vector<DeprecatedString> m_path_history; 170 void add_path_to_history(DeprecatedString); 171 172 RefPtr<GUI::Label> m_error_label; 173 174 RefPtr<GUI::TableView> m_table_view; 175 RefPtr<GUI::IconView> m_icon_view; 176 RefPtr<GUI::ColumnsView> m_columns_view; 177 178 RefPtr<GUI::Action> m_mkdir_action; 179 RefPtr<GUI::Action> m_touch_action; 180 RefPtr<GUI::Action> m_open_terminal_action; 181 RefPtr<GUI::Action> m_delete_action; 182 RefPtr<GUI::Action> m_force_delete_action; 183 RefPtr<GUI::Action> m_rename_action; 184 185 RefPtr<GUI::Action> m_view_as_table_action; 186 RefPtr<GUI::Action> m_view_as_icons_action; 187 RefPtr<GUI::Action> m_view_as_columns_action; 188}; 189 190}