GFileSystemModel.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #pragma once
  2. #include <AK/HashMap.h>
  3. #include <AK/NonnullOwnPtrVector.h>
  4. #include <LibCore/CNotifier.h>
  5. #include <LibGUI/GModel.h>
  6. #include <sys/stat.h>
  7. #include <time.h>
  8. class GFileSystemModel : public GModel
  9. , public Weakable<GFileSystemModel> {
  10. friend struct Node;
  11. public:
  12. enum Mode {
  13. Invalid,
  14. DirectoriesOnly,
  15. FilesAndDirectories
  16. };
  17. enum Column {
  18. Icon = 0,
  19. Name,
  20. Size,
  21. Owner,
  22. Group,
  23. Permissions,
  24. ModificationTime,
  25. Inode,
  26. __Count,
  27. };
  28. struct Node {
  29. ~Node() { close(m_watch_fd); }
  30. String name;
  31. size_t size { 0 };
  32. mode_t mode { 0 };
  33. uid_t uid { 0 };
  34. gid_t gid { 0 };
  35. ino_t inode { 0 };
  36. time_t mtime { 0 };
  37. size_t total_size { 0 };
  38. mutable RefPtr<GraphicsBitmap> thumbnail;
  39. bool is_directory() const { return S_ISDIR(mode); }
  40. bool is_executable() const { return mode & S_IXUSR; }
  41. String full_path(const GFileSystemModel&) const;
  42. private:
  43. friend class GFileSystemModel;
  44. Node* parent { nullptr };
  45. NonnullOwnPtrVector<Node> children;
  46. bool has_traversed { false };
  47. int m_watch_fd { -1 };
  48. RefPtr<CNotifier> m_notifier;
  49. GModelIndex index(const GFileSystemModel&, int column) const;
  50. void traverse_if_needed(const GFileSystemModel&);
  51. void reify_if_needed(const GFileSystemModel&);
  52. bool fetch_data_using_lstat(const String& full_path);
  53. };
  54. static NonnullRefPtr<GFileSystemModel> create(const StringView& root_path = "/", Mode mode = Mode::FilesAndDirectories)
  55. {
  56. return adopt(*new GFileSystemModel(root_path, mode));
  57. }
  58. virtual ~GFileSystemModel() override;
  59. String root_path() const { return m_root_path; }
  60. void set_root_path(const StringView&);
  61. String full_path(const GModelIndex&) const;
  62. GModelIndex index(const StringView& path, int column) const;
  63. const Node& node(const GModelIndex& index) const;
  64. GIcon icon_for_file(const mode_t mode, const String& name) const;
  65. Function<void(int done, int total)> on_thumbnail_progress;
  66. Function<void()> on_root_path_change;
  67. virtual int tree_column() const { return Column::Name; }
  68. virtual int row_count(const GModelIndex& = GModelIndex()) const override;
  69. virtual int column_count(const GModelIndex& = GModelIndex()) const override;
  70. virtual String column_name(int column) const override;
  71. virtual ColumnMetadata column_metadata(int column) const override;
  72. virtual GVariant data(const GModelIndex&, Role = Role::Display) const override;
  73. virtual void update() override;
  74. virtual GModelIndex parent_index(const GModelIndex&) const override;
  75. virtual GModelIndex index(int row, int column = 0, const GModelIndex& parent = GModelIndex()) const override;
  76. static String timestamp_string(time_t timestamp)
  77. {
  78. auto* tm = localtime(&timestamp);
  79. return String::format("%4u-%02u-%02u %02u:%02u:%02u",
  80. tm->tm_year + 1900,
  81. tm->tm_mon + 1,
  82. tm->tm_mday,
  83. tm->tm_hour,
  84. tm->tm_min,
  85. tm->tm_sec);
  86. }
  87. private:
  88. GFileSystemModel(const StringView& root_path, Mode);
  89. String name_for_uid(uid_t) const;
  90. String name_for_gid(gid_t) const;
  91. HashMap<uid_t, String> m_user_names;
  92. HashMap<gid_t, String> m_group_names;
  93. bool fetch_thumbnail_for(const Node& node);
  94. GIcon icon_for(const Node& node) const;
  95. String m_root_path;
  96. Mode m_mode { Invalid };
  97. OwnPtr<Node> m_root { nullptr };
  98. GIcon m_directory_icon;
  99. GIcon m_file_icon;
  100. GIcon m_symlink_icon;
  101. GIcon m_socket_icon;
  102. GIcon m_executable_icon;
  103. GIcon m_filetype_image_icon;
  104. GIcon m_filetype_sound_icon;
  105. GIcon m_filetype_html_icon;
  106. unsigned m_thumbnail_progress { 0 };
  107. unsigned m_thumbnail_progress_total { 0 };
  108. };