Materialize source-scoped artist aggregates and FTS, then expose exact keyset pages and bounded A-Z metadata for the existing Artists rail. Query the selected artist's albums through the indexed credit relationship with an independent bounded model, generation cancellation, artwork updates, and per-surface legacy fallback. cx
91 lines
3.3 KiB
C++
91 lines
3.3 KiB
C++
#ifndef QBZ_LOCAL_ALBUMS_MODEL_H
|
|
#define QBZ_LOCAL_ALBUMS_MODEL_H
|
|
|
|
#include <QtCore/QAbstractListModel>
|
|
#include <QtCore/QHash>
|
|
#include <QtCore/QList>
|
|
#include <QtCore/QVariantMap>
|
|
|
|
class LocalAlbumsModel final : public QAbstractListModel
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(int generation READ generation NOTIFY generationChanged)
|
|
Q_PROPERTY(qint64 totalCount READ totalCount NOTIFY totalCountChanged)
|
|
Q_PROPERTY(qint64 albumTotal READ albumTotal NOTIFY albumTotalChanged)
|
|
Q_PROPERTY(int residentAlbums READ residentAlbums NOTIFY residentAlbumsChanged)
|
|
Q_PROPERTY(qint64 evictions READ evictions NOTIFY evictionsChanged)
|
|
Q_PROPERTY(qint64 selectedCount READ selectedCount NOTIFY selectedCountChanged)
|
|
|
|
public:
|
|
enum Role { ModelDataRole = Qt::UserRole + 1 };
|
|
|
|
explicit LocalAlbumsModel(QObject *parent = nullptr);
|
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
QHash<int, QByteArray> roleNames() const override;
|
|
|
|
int generation() const { return m_generation; }
|
|
qint64 totalCount() const { return m_totalCount; }
|
|
qint64 albumTotal() const { return m_albumTotal; }
|
|
int residentAlbums() const { return m_residentAlbums; }
|
|
qint64 evictions() const { return m_evictions; }
|
|
qint64 selectedCount() const { return m_selectedCount; }
|
|
|
|
Q_INVOKABLE QVariantMap rowAt(qint64 row) const;
|
|
Q_INVOKABLE void setArtwork(const QString &artKey, const QString &path);
|
|
|
|
void resetQuery(int generation, qint64 totalCount, qint64 albumTotal);
|
|
bool applyPage(int generation, int page, const QByteArray &json);
|
|
void setSelection(int generation, const QByteArray &json, qint64 selectedCount);
|
|
|
|
signals:
|
|
void generationChanged();
|
|
void totalCountChanged();
|
|
void albumTotalChanged();
|
|
void residentAlbumsChanged();
|
|
void evictionsChanged();
|
|
void selectedCountChanged();
|
|
void pageMiss(int page, int generation);
|
|
|
|
private:
|
|
struct Entry {
|
|
QVariantMap values;
|
|
QStringList artKeys;
|
|
int albumCount = 0;
|
|
};
|
|
using Page = QList<Entry>;
|
|
|
|
static constexpr int PageEntries = 100;
|
|
static constexpr int MaxResidentAlbums = 2000;
|
|
|
|
QVariantMap modelData(qint64 row) const;
|
|
void requestPage(int page, bool prefetch = false) const;
|
|
void touch(int page) const;
|
|
bool selected(qint64 row) const;
|
|
void evictIfNeeded();
|
|
|
|
int m_generation = 0;
|
|
qint64 m_totalCount = 0;
|
|
qint64 m_albumTotal = 0;
|
|
QHash<int, Page> m_pages;
|
|
mutable QList<int> m_lru;
|
|
mutable QHash<int, bool> m_pending;
|
|
int m_residentAlbums = 0;
|
|
qint64 m_evictions = 0;
|
|
bool m_selectAll = false;
|
|
QList<QPair<qint64, qint64>> m_selectionRanges;
|
|
qint64 m_selectedCount = 0;
|
|
};
|
|
|
|
extern "C" {
|
|
void qbz_local_albums_register_qml_type();
|
|
void qbz_local_albums_reset(int generation, qint64 totalCount, qint64 albumTotal);
|
|
bool qbz_local_albums_apply_page(int generation, int page, const char *json);
|
|
void qbz_local_albums_set_selection(int generation, const char *json, qint64 selectedCount);
|
|
void qbz_local_artist_albums_reset(int generation, qint64 totalCount, qint64 albumTotal);
|
|
bool qbz_local_artist_albums_apply_page(int generation, int page, const char *json);
|
|
}
|
|
|
|
#endif // QBZ_LOCAL_ALBUMS_MODEL_H
|