FileSystemModel.h 5.9 KB

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