FileSystemModel.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/HashMap.h>
  9. #include <LibCore/DateTime.h>
  10. #include <LibCore/FileWatcher.h>
  11. #include <LibGUI/Model.h>
  12. #include <string.h>
  13. #include <sys/stat.h>
  14. #include <time.h>
  15. namespace GUI {
  16. class FileSystemModel
  17. : public Model
  18. , public Weakable<FileSystemModel> {
  19. friend struct Node;
  20. public:
  21. enum Mode {
  22. Invalid,
  23. DirectoriesOnly,
  24. FilesAndDirectories
  25. };
  26. enum Column {
  27. Icon = 0,
  28. Name,
  29. Size,
  30. User,
  31. Group,
  32. Permissions,
  33. ModificationTime,
  34. Inode,
  35. SymlinkTarget,
  36. __Count,
  37. };
  38. struct Node {
  39. ~Node() = default;
  40. DeprecatedString name;
  41. DeprecatedString symlink_target;
  42. size_t size { 0 };
  43. mode_t mode { 0 };
  44. uid_t uid { 0 };
  45. gid_t gid { 0 };
  46. ino_t inode { 0 };
  47. time_t mtime { 0 };
  48. bool is_accessible_directory { false };
  49. size_t total_size { 0 };
  50. mutable RefPtr<Gfx::Bitmap> thumbnail;
  51. bool is_directory() const { return S_ISDIR(mode); }
  52. bool is_symlink_to_directory() const;
  53. bool is_executable() const { return mode & (S_IXUSR | S_IXGRP | S_IXOTH); }
  54. bool is_selected() const { return m_selected; }
  55. void set_selected(bool selected);
  56. bool has_error() const { return m_error != 0; }
  57. int error() const { return m_error; }
  58. char const* error_string() const { return strerror(m_error); }
  59. DeprecatedString full_path() const;
  60. private:
  61. friend class FileSystemModel;
  62. explicit Node(FileSystemModel& model)
  63. : m_model(model)
  64. {
  65. }
  66. FileSystemModel& m_model;
  67. Node* m_parent { nullptr };
  68. Vector<NonnullOwnPtr<Node>> m_children;
  69. bool m_has_traversed { false };
  70. bool m_selected { false };
  71. int m_error { 0 };
  72. bool m_parent_of_root { false };
  73. ModelIndex index(int column) const;
  74. void traverse_if_needed();
  75. void reify_if_needed();
  76. bool fetch_data(DeprecatedString const& full_path, bool is_root);
  77. OwnPtr<Node> create_child(DeprecatedString const& child_name);
  78. };
  79. static NonnullRefPtr<FileSystemModel> create(DeprecatedString root_path = "/", Mode mode = Mode::FilesAndDirectories)
  80. {
  81. return adopt_ref(*new FileSystemModel(root_path, mode));
  82. }
  83. virtual ~FileSystemModel() override = default;
  84. DeprecatedString root_path() const { return m_root_path; }
  85. void set_root_path(DeprecatedString);
  86. DeprecatedString full_path(ModelIndex const&) const;
  87. ModelIndex index(DeprecatedString path, int column) const;
  88. void update_node_on_selection(ModelIndex const&, bool const);
  89. ModelIndex m_previously_selected_index {};
  90. Node const& node(ModelIndex const& index) const;
  91. Function<void(int done, int total)> on_thumbnail_progress;
  92. Function<void()> on_complete;
  93. Function<void(int error, char const* error_string)> on_directory_change_error;
  94. Function<void(int error, char const* error_string)> on_rename_error;
  95. Function<void(DeprecatedString const& old_name, DeprecatedString const& new_name)> on_rename_successful;
  96. Function<void()> on_root_path_removed;
  97. virtual int tree_column() const override { return Column::Name; }
  98. virtual int row_count(ModelIndex const& = ModelIndex()) const override;
  99. virtual int column_count(ModelIndex const& = ModelIndex()) const override;
  100. virtual DeprecatedString column_name(int column) const override;
  101. virtual Variant data(ModelIndex const&, ModelRole = ModelRole::Display) const override;
  102. virtual ModelIndex parent_index(ModelIndex const&) const override;
  103. virtual ModelIndex index(int row, int column = 0, ModelIndex const& parent = ModelIndex()) const override;
  104. virtual StringView drag_data_type() const override { return "text/uri-list"sv; }
  105. virtual bool accepts_drag(ModelIndex const&, Vector<DeprecatedString> const& mime_types) const override;
  106. virtual bool is_column_sortable(int column_index) const override { return column_index != Column::Icon; }
  107. virtual bool is_editable(ModelIndex const&) const override;
  108. virtual bool is_searchable() const override { return true; }
  109. virtual void set_data(ModelIndex const&, Variant const&) override;
  110. virtual Vector<ModelIndex> matches(StringView, unsigned = MatchesFlag::AllMatching, ModelIndex const& = ModelIndex()) override;
  111. virtual void invalidate() override;
  112. static DeprecatedString timestamp_string(time_t timestamp)
  113. {
  114. return Core::DateTime::from_timestamp(timestamp).to_deprecated_string();
  115. }
  116. bool should_show_dotfiles() const { return m_should_show_dotfiles; }
  117. void set_should_show_dotfiles(bool);
  118. Optional<Vector<DeprecatedString>> allowed_file_extensions() const { return m_allowed_file_extensions; }
  119. void set_allowed_file_extensions(Optional<Vector<DeprecatedString>> const& allowed_file_extensions);
  120. private:
  121. FileSystemModel(DeprecatedString root_path, Mode);
  122. DeprecatedString name_for_uid(uid_t) const;
  123. DeprecatedString name_for_gid(gid_t) const;
  124. Optional<Node const&> node_for_path(DeprecatedString const&) const;
  125. HashMap<uid_t, DeprecatedString> m_user_names;
  126. HashMap<gid_t, DeprecatedString> m_group_names;
  127. bool fetch_thumbnail_for(Node const& node);
  128. GUI::Icon icon_for(Node const& node) const;
  129. void handle_file_event(Core::FileWatcherEvent const& event);
  130. DeprecatedString m_root_path;
  131. Mode m_mode { Invalid };
  132. OwnPtr<Node> m_root { nullptr };
  133. unsigned m_thumbnail_progress { 0 };
  134. unsigned m_thumbnail_progress_total { 0 };
  135. Optional<Vector<DeprecatedString>> m_allowed_file_extensions;
  136. bool m_should_show_dotfiles { false };
  137. RefPtr<Core::FileWatcher> m_file_watcher;
  138. };
  139. }