game_list_p.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <atomic>
  6. #include <QRunnable>
  7. #include <QStandardItem>
  8. #include <QString>
  9. #include "citra_qt/util/util.h"
  10. #include "common/string_util.h"
  11. class GameListItem : public QStandardItem {
  12. public:
  13. GameListItem(): QStandardItem() {}
  14. GameListItem(const QString& string): QStandardItem(string) {}
  15. virtual ~GameListItem() override {}
  16. };
  17. /**
  18. * A specialization of GameListItem for path values.
  19. * This class ensures that for every full path value it holds, a correct string representation
  20. * of just the filename (with no extension) will be displayed to the user.
  21. */
  22. class GameListItemPath : public GameListItem {
  23. public:
  24. static const int FullPathRole = Qt::UserRole + 1;
  25. GameListItemPath(): GameListItem() {}
  26. GameListItemPath(const QString& game_path): GameListItem()
  27. {
  28. setData(game_path, FullPathRole);
  29. }
  30. void setData(const QVariant& value, int role) override
  31. {
  32. // By specializing setData for FullPathRole, we can ensure that the two string
  33. // representations of the data are always accurate and in the correct format.
  34. if (role == FullPathRole) {
  35. std::string filename;
  36. Common::SplitPath(value.toString().toStdString(), nullptr, &filename, nullptr);
  37. GameListItem::setData(QString::fromStdString(filename), Qt::DisplayRole);
  38. GameListItem::setData(value, FullPathRole);
  39. } else {
  40. GameListItem::setData(value, role);
  41. }
  42. }
  43. };
  44. /**
  45. * A specialization of GameListItem for size values.
  46. * This class ensures that for every numerical size value it holds (in bytes), a correct
  47. * human-readable string representation will be displayed to the user.
  48. */
  49. class GameListItemSize : public GameListItem {
  50. public:
  51. static const int SizeRole = Qt::UserRole + 1;
  52. GameListItemSize(): GameListItem() {}
  53. GameListItemSize(const qulonglong size_bytes): GameListItem()
  54. {
  55. setData(size_bytes, SizeRole);
  56. }
  57. void setData(const QVariant& value, int role) override
  58. {
  59. // By specializing setData for SizeRole, we can ensure that the numerical and string
  60. // representations of the data are always accurate and in the correct format.
  61. if (role == SizeRole) {
  62. qulonglong size_bytes = value.toULongLong();
  63. GameListItem::setData(ReadableByteSize(size_bytes), Qt::DisplayRole);
  64. GameListItem::setData(value, SizeRole);
  65. } else {
  66. GameListItem::setData(value, role);
  67. }
  68. }
  69. /**
  70. * This operator is, in practice, only used by the TreeView sorting systems.
  71. * Override it so that it will correctly sort by numerical value instead of by string representation.
  72. */
  73. bool operator<(const QStandardItem& other) const override
  74. {
  75. return data(SizeRole).toULongLong() < other.data(SizeRole).toULongLong();
  76. }
  77. };
  78. /**
  79. * Asynchronous worker object for populating the game list.
  80. * Communicates with other threads through Qt's signal/slot system.
  81. */
  82. class GameListWorker : public QObject, public QRunnable {
  83. Q_OBJECT
  84. public:
  85. GameListWorker(QString dir_path, bool deep_scan):
  86. QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {}
  87. public slots:
  88. /// Starts the processing of directory tree information.
  89. void run() override;
  90. /// Tells the worker that it should no longer continue processing. Thread-safe.
  91. void Cancel();
  92. signals:
  93. /**
  94. * The `EntryReady` signal is emitted once an entry has been prepared and is ready
  95. * to be added to the game list.
  96. * @param entry_items a list with `QStandardItem`s that make up the columns of the new entry.
  97. */
  98. void EntryReady(QList<QStandardItem*> entry_items);
  99. void Finished();
  100. private:
  101. QString dir_path;
  102. bool deep_scan;
  103. std::atomic_bool stop_processing;
  104. void AddFstEntriesToGameList(const std::string& dir_path, bool deep_scan);
  105. };