FileSystemModel.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. bool can_delete_or_move() const;
  60. DeprecatedString full_path() const;
  61. private:
  62. friend class FileSystemModel;
  63. explicit Node(FileSystemModel& model)
  64. : m_model(model)
  65. {
  66. }
  67. FileSystemModel& m_model;
  68. Node* m_parent { nullptr };
  69. Vector<NonnullOwnPtr<Node>> m_children;
  70. mutable Optional<bool> m_can_delete_or_move;
  71. bool m_has_traversed { false };
  72. bool m_selected { false };
  73. int m_error { 0 };
  74. bool m_parent_of_root { false };
  75. ModelIndex index(int column) const;
  76. void traverse_if_needed();
  77. void reify_if_needed();
  78. bool fetch_data(DeprecatedString const& full_path, bool is_root);
  79. OwnPtr<Node> create_child(DeprecatedString const& child_name);
  80. };
  81. static NonnullRefPtr<FileSystemModel> create(DeprecatedString root_path = "/", Mode mode = Mode::FilesAndDirectories)
  82. {
  83. return adopt_ref(*new FileSystemModel(root_path, mode));
  84. }
  85. virtual ~FileSystemModel() override = default;
  86. DeprecatedString root_path() const { return m_root_path; }
  87. void set_root_path(DeprecatedString);
  88. DeprecatedString full_path(ModelIndex const&) const;
  89. ModelIndex index(DeprecatedString path, int column) const;
  90. void update_node_on_selection(ModelIndex const&, bool const);
  91. ModelIndex m_previously_selected_index {};
  92. Node const& node(ModelIndex const& index) const;
  93. Function<void(int done, int total)> on_thumbnail_progress;
  94. Function<void()> on_complete;
  95. Function<void(int error, char const* error_string)> on_directory_change_error;
  96. Function<void(int error, char const* error_string)> on_rename_error;
  97. Function<void(DeprecatedString const& old_name, DeprecatedString const& new_name)> on_rename_successful;
  98. Function<void()> on_root_path_removed;
  99. virtual int tree_column() const override { return Column::Name; }
  100. virtual int row_count(ModelIndex const& = ModelIndex()) const override;
  101. virtual int column_count(ModelIndex const& = ModelIndex()) const override;
  102. virtual DeprecatedString column_name(int column) const override;
  103. virtual Variant data(ModelIndex const&, ModelRole = ModelRole::Display) const override;
  104. virtual ModelIndex parent_index(ModelIndex const&) const override;
  105. virtual ModelIndex index(int row, int column = 0, ModelIndex const& parent = ModelIndex()) const override;
  106. virtual StringView drag_data_type() const override { return "text/uri-list"sv; }
  107. virtual bool accepts_drag(ModelIndex const&, Vector<DeprecatedString> const& mime_types) const override;
  108. virtual bool is_column_sortable(int column_index) const override { return column_index != Column::Icon; }
  109. virtual bool is_editable(ModelIndex const&) const override;
  110. virtual bool is_searchable() const override { return true; }
  111. virtual void set_data(ModelIndex const&, Variant const&) override;
  112. virtual Vector<ModelIndex> matches(StringView, unsigned = MatchesFlag::AllMatching, ModelIndex const& = ModelIndex()) override;
  113. virtual void invalidate() override;
  114. static DeprecatedString timestamp_string(time_t timestamp)
  115. {
  116. return Core::DateTime::from_timestamp(timestamp).to_deprecated_string();
  117. }
  118. bool should_show_dotfiles() const { return m_should_show_dotfiles; }
  119. void set_should_show_dotfiles(bool);
  120. Optional<Vector<DeprecatedString>> allowed_file_extensions() const { return m_allowed_file_extensions; }
  121. void set_allowed_file_extensions(Optional<Vector<DeprecatedString>> const& allowed_file_extensions);
  122. private:
  123. FileSystemModel(DeprecatedString root_path, Mode);
  124. DeprecatedString name_for_uid(uid_t) const;
  125. DeprecatedString name_for_gid(gid_t) const;
  126. Optional<Node const&> node_for_path(DeprecatedString const&) const;
  127. HashMap<uid_t, DeprecatedString> m_user_names;
  128. HashMap<gid_t, DeprecatedString> m_group_names;
  129. bool fetch_thumbnail_for(Node const& node);
  130. GUI::Icon icon_for(Node const& node) const;
  131. void handle_file_event(Core::FileWatcherEvent const& event);
  132. DeprecatedString m_root_path;
  133. Mode m_mode { Invalid };
  134. OwnPtr<Node> m_root { nullptr };
  135. unsigned m_thumbnail_progress { 0 };
  136. unsigned m_thumbnail_progress_total { 0 };
  137. Optional<Vector<DeprecatedString>> m_allowed_file_extensions;
  138. bool m_should_show_dotfiles { false };
  139. RefPtr<Core::FileWatcher> m_file_watcher;
  140. };
  141. }