aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui/pages/modplatform/ResourceModel.h
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/ui/pages/modplatform/ResourceModel.h')
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.h101
1 files changed, 101 insertions, 0 deletions
diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h
new file mode 100644
index 00000000..af0e9f55
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ResourceModel.h
@@ -0,0 +1,101 @@
+#pragma once
+
+#include <optional>
+
+#include <QAbstractListModel>
+
+#include "QObjectPtr.h"
+#include "modplatform/ResourceAPI.h"
+#include "tasks/ConcurrentTask.h"
+
+class NetJob;
+class ResourcePage;
+class ResourceAPI;
+
+namespace ModPlatform {
+struct IndexedPack;
+}
+
+
+class ResourceModel : public QAbstractListModel {
+ Q_OBJECT
+
+ public:
+ ResourceModel(ResourcePage* parent, ResourceAPI* api);
+ ~ResourceModel() override;
+
+ [[nodiscard]] auto data(const QModelIndex&, int role) const -> QVariant override;
+ bool setData(const QModelIndex& index, const QVariant& value, int role) override;
+
+ [[nodiscard]] auto debugName() const -> QString;
+
+ [[nodiscard]] inline int rowCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : m_packs.size(); }
+ [[nodiscard]] inline int columnCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : 1; };
+ [[nodiscard]] inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
+
+ inline void addActiveJob(Task::Ptr ptr) { m_current_job.addTask(ptr); if (!m_current_job.isRunning()) m_current_job.start(); }
+ inline Task const& activeJob() { return m_current_job; }
+
+ public slots:
+ void fetchMore(const QModelIndex& parent) override;
+ [[nodiscard]] inline bool canFetchMore(const QModelIndex& parent) const override
+ {
+ return parent.isValid() ? false : m_search_state == SearchState::CanFetchMore;
+ }
+
+ void setSearchTerm(QString term) { m_search_term = term; }
+
+ virtual ResourceAPI::SearchArgs createSearchArguments() = 0;
+ virtual ResourceAPI::SearchCallbacks createSearchCallbacks() = 0;
+
+ virtual ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) = 0;
+ virtual ResourceAPI::VersionSearchCallbacks createVersionsCallbacks(QModelIndex&) = 0;
+
+ virtual ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) = 0;
+ virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) = 0;
+
+ /** Requests the API for more entries. */
+ virtual void search();
+
+ /** Applies any processing / extra requests needed to fully load the specified entry's information. */
+ virtual void loadEntry(QModelIndex&);
+
+ /** Schedule a refresh, clearing the current state. */
+ void refresh();
+
+ /** Gets the icon at the URL for the given index. If it's not fetched yet, fetch it and update when fisinhed. */
+ std::optional<QIcon> getIcon(QModelIndex&, const QUrl&);
+
+ protected:
+ /** Resets the model's data. */
+ void clearData();
+
+ [[nodiscard]] bool isPackSelected(const ModPlatform::IndexedPack&) const;
+
+ protected:
+ /* Basic search parameters */
+ enum class SearchState { None, CanFetchMore, ResetRequested, Finished } m_search_state = SearchState::None;
+ int m_next_search_offset = 0;
+ QString m_search_term;
+
+ std::unique_ptr<ResourceAPI> m_api;
+
+ ConcurrentTask m_current_job;
+
+ shared_qobject_ptr<NetJob> m_current_icon_job;
+ QSet<QUrl> m_currently_running_icon_actions;
+ QSet<QUrl> m_failed_icon_actions;
+
+ ResourcePage* m_associated_page = nullptr;
+
+ QList<ModPlatform::IndexedPack> m_packs;
+
+ // HACK: We need this to prevent callbacks from calling the model after it has already been deleted.
+ // This leaks a tiny bit of memory per time the user has opened a resource dialog. How to make this better?
+ static QHash<ResourceModel*, bool> s_running_models;
+
+ private:
+ /* Default search request callbacks */
+ void searchRequestFailed(QString reason, int network_error_code);
+ void searchRequestAborted();
+};