start implementing model for koto artist
This commit is contained in:
parent
e3a00ab8ac
commit
ddfd17c67c
12 changed files with 267 additions and 34 deletions
|
@ -1,5 +1,5 @@
|
|||
find_package(Qt6 6.4 REQUIRED COMPONENTS Quick QuickControls2 Sql)
|
||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
find_package(ECM REQUIRED NO_MODULE)
|
||||
find_package(KF6Baloo)
|
||||
find_package(KF6FileMetaData)
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
@ -19,10 +19,15 @@ qt_add_executable(com.github.joshstrobl.koto
|
|||
datalake/cartographer.cpp
|
||||
datalake/database.cpp
|
||||
datalake/indexer.cpp
|
||||
datalake/models.cpp
|
||||
datalake/track.cpp
|
||||
datalake/cartographer.hpp
|
||||
datalake/structs.hpp
|
||||
main.cpp
|
||||
datalake/models.cpp
|
||||
)
|
||||
|
||||
target_include_directories(com.github.joshstrobl.koto PUBLIC datalake includes)
|
||||
ecm_add_qml_module(com.github.joshstrobl.koto URI "com.github.joshstrobl.koto" GENERATE_PLUGIN_SOURCE)
|
||||
|
||||
ecm_target_qml_sources(com.github.joshstrobl.koto
|
||||
|
|
|
@ -82,6 +82,10 @@ std::optional<int> KotoAlbum::getYear() {
|
|||
return this->year;
|
||||
}
|
||||
|
||||
int KotoAlbum::getYearQml() {
|
||||
return this->year.value_or(0);
|
||||
}
|
||||
|
||||
void KotoAlbum::removeTrack(KotoTrack* track) {
|
||||
this->tracks.removeOne(track);
|
||||
}
|
||||
|
|
|
@ -62,10 +62,18 @@ QString KotoArtist::getName() {
|
|||
return QString {this->name};
|
||||
}
|
||||
|
||||
QString KotoArtist::getPath() {
|
||||
return QString {this->path};
|
||||
}
|
||||
|
||||
QList<KotoTrack*> KotoArtist::getTracks() {
|
||||
return QList {this->tracks};
|
||||
}
|
||||
|
||||
QUuid KotoArtist::getUuid() {
|
||||
return this->uuid;
|
||||
}
|
||||
|
||||
void KotoArtist::removeAlbum(KotoAlbum* album) {
|
||||
this->albums.removeOne(album);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "cartographer.hpp"
|
||||
|
||||
Cartographer::Cartographer()
|
||||
: i_albums(QHash<QUuid, KotoAlbum*>()),
|
||||
i_artists(QHash<QUuid, KotoArtist*>()),
|
||||
#include <iostream>
|
||||
|
||||
Cartographer::Cartographer(QObject* parent)
|
||||
: QObject(parent),
|
||||
i_albums(QHash<QUuid, KotoAlbum*>()),
|
||||
i_artists_model(new KotoArtistModel(QList<KotoArtist*>())),
|
||||
i_artists_by_name(QHash<QString, KotoArtist*>()),
|
||||
i_tracks(QHash<QUuid, KotoTrack*>()) {}
|
||||
|
||||
|
@ -16,7 +19,7 @@ void Cartographer::addAlbum(KotoAlbum* album) {
|
|||
}
|
||||
|
||||
void Cartographer::addArtist(KotoArtist* artist) {
|
||||
this->i_artists.insert(artist->uuid, artist);
|
||||
this->i_artists_model->addArtist(artist);
|
||||
this->i_artists_by_name.insert(artist->getName(), artist);
|
||||
}
|
||||
|
||||
|
@ -29,17 +32,20 @@ std::optional<KotoAlbum*> Cartographer::getAlbum(QUuid uuid) {
|
|||
return album ? std::optional {album} : std::nullopt;
|
||||
}
|
||||
|
||||
QList<KotoAlbum*> Cartographer::getAlbums() {
|
||||
return this->i_albums.values();
|
||||
}
|
||||
|
||||
std::optional<KotoArtist*> Cartographer::getArtist(QUuid uuid) {
|
||||
auto artist = this->i_artists.value(uuid, nullptr);
|
||||
return artist ? std::optional {artist} : std::nullopt;
|
||||
for (auto artist : this->i_artists_model->getArtists()) {
|
||||
if (artist->uuid == uuid) { return std::optional {artist}; }
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
QList<KotoArtist*> Cartographer::getArtists() {
|
||||
return this->i_artists.values();
|
||||
return this->i_artists_model->getArtists();
|
||||
}
|
||||
|
||||
KotoArtistModel* Cartographer::getArtistsModel() {
|
||||
// if (this->i_artists_model == nullptr) { this->i_artists_model = new KotoArtistModel(this->i_artists); }
|
||||
return this->i_artists_model;
|
||||
}
|
||||
|
||||
std::optional<KotoArtist*> Cartographer::getArtist(QString name) {
|
||||
|
|
|
@ -1,21 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtQml/qqmlregistration.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlListProperty>
|
||||
#include <QString>
|
||||
#include <QUuid>
|
||||
#include <optional>
|
||||
|
||||
#include "structs.hpp"
|
||||
|
||||
class Cartographer {
|
||||
class Cartographer : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
// Q_PROPERTY(QQmlListProperty<KotoAlbum*> albums READ getAlbumsQml)
|
||||
Q_PROPERTY(KotoArtistModel* artists READ getArtistsModel)
|
||||
// Q_PROPERTY(QQmlListProperty<KotoTrack*> tracks READ getTracksQml)
|
||||
|
||||
public:
|
||||
Cartographer();
|
||||
Cartographer(QObject* parent = nullptr);
|
||||
static Cartographer& instance();
|
||||
static Cartographer* create() { return &instance(); }
|
||||
// static Cartographer* create(QQmlEngine* engine, QJSEngine*) {
|
||||
// engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership);
|
||||
// return &instance();
|
||||
// }
|
||||
|
||||
void addAlbum(KotoAlbum* album);
|
||||
void addArtist(KotoArtist* artist);
|
||||
void addTrack(KotoTrack* track);
|
||||
|
||||
// QQmlListProperty<KotoAlbum*> getAlbumsQml();
|
||||
KotoArtistModel* getArtistsModel();
|
||||
// QQmlListProperty<KotoTrack*> getTracksQml();
|
||||
|
||||
std::optional<KotoAlbum*> getAlbum(QUuid uuid);
|
||||
QList<KotoAlbum*> getAlbums();
|
||||
std::optional<KotoArtist*> getArtist(QUuid uuid);
|
||||
|
@ -26,7 +45,7 @@ class Cartographer {
|
|||
|
||||
private:
|
||||
QHash<QUuid, KotoAlbum*> i_albums;
|
||||
QHash<QUuid, KotoArtist*> i_artists;
|
||||
KotoArtistModel* i_artists_model;
|
||||
QHash<QString, KotoArtist*> i_artists_by_name;
|
||||
QHash<QUuid, KotoTrack*> i_tracks;
|
||||
};
|
||||
|
|
45
desktop/datalake/models.cpp
Normal file
45
desktop/datalake/models.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "structs.hpp"
|
||||
|
||||
KotoArtistModel::~KotoArtistModel() {
|
||||
this->beginResetModel();
|
||||
this->m_artists.clear();
|
||||
this->endResetModel();
|
||||
}
|
||||
|
||||
void KotoArtistModel::addArtist(KotoArtist* artist) {
|
||||
this->beginInsertRows(QModelIndex(), this->m_artists.count(), this->m_artists.count());
|
||||
this->m_artists.append(artist);
|
||||
this->endInsertRows();
|
||||
}
|
||||
|
||||
int KotoArtistModel::rowCount(const QModelIndex& parent) const {
|
||||
return this->m_artists.count();
|
||||
}
|
||||
|
||||
QVariant KotoArtistModel::data(const QModelIndex& index, int role) const {
|
||||
if (!index.isValid()) { return {}; }
|
||||
|
||||
if (index.row() >= this->m_artists.size()) { return {}; }
|
||||
|
||||
if (role == KotoArtistRoles::NameRole) {
|
||||
return this->m_artists.at(index.row())->getName();
|
||||
} else if (role == KotoArtistRoles::PathRole) {
|
||||
return this->m_artists.at(index.row())->getPath();
|
||||
} else if (role == KotoArtistRoles::UuidRole) {
|
||||
return this->m_artists.at(index.row())->uuid;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QList<KotoArtist*> KotoArtistModel::getArtists() {
|
||||
return this->m_artists;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> KotoArtistModel::roleNames() const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[NameRole] = QByteArrayLiteral("name");
|
||||
roles[PathRole] = QByteArrayLiteral("path");
|
||||
roles[UuidRole] = QByteArrayLiteral("uuid");
|
||||
return roles;
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
#include <QtQml/qqmlregistration.h>
|
||||
|
||||
#include <KFileMetaData/SimpleExtractionResult>
|
||||
#include <QAbstractListModel>
|
||||
#include <QFileInfo>
|
||||
#include <QList>
|
||||
#include <QSqlQuery>
|
||||
|
@ -8,14 +11,25 @@
|
|||
#include <QUuid>
|
||||
|
||||
class KotoArtist;
|
||||
class KotoArtistModel;
|
||||
class KotoAlbum;
|
||||
class KotoAlbumModel;
|
||||
class KotoTrack;
|
||||
class KotoTrackModel;
|
||||
|
||||
class KotoArtist : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged)
|
||||
Q_PROPERTY(QList<KotoAlbum*> albums READ getAlbums NOTIFY albumsChanged)
|
||||
Q_PROPERTY(QList<KotoTrack*> tracks READ getTracks NOTIFY tracksChanged)
|
||||
Q_PROPERTY(QUuid uuid READ getUuid)
|
||||
|
||||
class KotoArtist {
|
||||
public:
|
||||
KotoArtist();
|
||||
static KotoArtist* fromDb(const QSqlQuery& query, const QSqlRecord& record);
|
||||
~KotoArtist();
|
||||
virtual ~KotoArtist();
|
||||
|
||||
QUuid uuid;
|
||||
|
||||
|
@ -27,11 +41,18 @@ class KotoArtist {
|
|||
QString getName();
|
||||
QString getPath();
|
||||
QList<KotoTrack*> getTracks();
|
||||
QUuid getUuid();
|
||||
void removeAlbum(KotoAlbum* album);
|
||||
void removeTrack(KotoTrack* track);
|
||||
void setName(QString str);
|
||||
void setPath(QString str);
|
||||
|
||||
signals:
|
||||
void albumsChanged();
|
||||
void nameChanged();
|
||||
void pathChanged();
|
||||
void tracksChanged();
|
||||
|
||||
private:
|
||||
QString path;
|
||||
QString name;
|
||||
|
@ -40,11 +61,46 @@ class KotoArtist {
|
|||
QList<KotoTrack*> tracks;
|
||||
};
|
||||
|
||||
class KotoAlbum {
|
||||
class KotoArtistModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KotoArtistModel(const QList<KotoArtist*>& artists, QObject* parent = nullptr) : QAbstractListModel(parent), m_artists(artists) {}
|
||||
|
||||
void addArtist(KotoArtist* artist);
|
||||
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;
|
||||
virtual ~KotoArtistModel();
|
||||
|
||||
QList<KotoArtist*> getArtists();
|
||||
|
||||
enum KotoArtistRoles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
PathRole,
|
||||
UuidRole,
|
||||
};
|
||||
|
||||
private:
|
||||
QList<KotoArtist*> m_artists;
|
||||
};
|
||||
|
||||
class KotoAlbum : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
Q_PROPERTY(QString albumArtPath READ getAlbumArtPath WRITE setAlbumArtPath NOTIFY albumArtChanged)
|
||||
Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged)
|
||||
Q_PROPERTY(QList<QString> genres READ getGenres WRITE setGenres NOTIFY genresChanged)
|
||||
Q_PROPERTY(QString narrator READ getNarrator WRITE setNarrator NOTIFY narratorChanged)
|
||||
Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged)
|
||||
Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged)
|
||||
Q_PROPERTY(QList<KotoTrack*> tracks READ getTracks NOTIFY tracksChanged)
|
||||
Q_PROPERTY(int year READ getYearQml WRITE setYear NOTIFY yearChanged)
|
||||
|
||||
public:
|
||||
KotoAlbum();
|
||||
static KotoAlbum* fromDb(const QSqlQuery& query, const QSqlRecord& record);
|
||||
~KotoAlbum();
|
||||
virtual ~KotoAlbum();
|
||||
|
||||
QUuid uuid;
|
||||
QUuid artist_uuid;
|
||||
|
@ -58,6 +114,7 @@ class KotoAlbum {
|
|||
QString getTitle();
|
||||
QList<KotoTrack*> getTracks();
|
||||
std::optional<int> getYear();
|
||||
int getYearQml();
|
||||
|
||||
void addTrack(KotoTrack* track);
|
||||
void removeTrack(KotoTrack* track);
|
||||
|
@ -69,6 +126,16 @@ class KotoAlbum {
|
|||
void setTitle(QString str);
|
||||
void setYear(int num);
|
||||
|
||||
signals:
|
||||
void albumArtChanged();
|
||||
void descriptionChanged();
|
||||
void genresChanged();
|
||||
void narratorChanged();
|
||||
void pathChanged();
|
||||
void titleChanged();
|
||||
void tracksChanged();
|
||||
void yearChanged();
|
||||
|
||||
private:
|
||||
QString title;
|
||||
QString description;
|
||||
|
@ -82,18 +149,36 @@ class KotoAlbum {
|
|||
QString album_art_path;
|
||||
};
|
||||
|
||||
class KotoTrack {
|
||||
class KotoTrack : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
Q_PROPERTY(QString album_uuid READ getAlbumUuid NOTIFY albumChanged)
|
||||
Q_PROPERTY(QUuid artist_uuid READ getArtistUuid NOTIFY artistChanged)
|
||||
Q_PROPERTY(QUuid uuid READ getUuid)
|
||||
Q_PROPERTY(int discNumber READ getDiscNumber WRITE setDiscNumber NOTIFY discNumberChanged)
|
||||
Q_PROPERTY(int duration READ getDuration WRITE setDuration NOTIFY durationChanged)
|
||||
Q_PROPERTY(QStringList genres READ getGenres WRITE setGenres NOTIFY genresChanged)
|
||||
Q_PROPERTY(QString lyrics READ getLyrics WRITE setLyrics NOTIFY lyricsChanged)
|
||||
Q_PROPERTY(QString narrator READ getNarrator WRITE setNarrator NOTIFY narratorChanged)
|
||||
Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged)
|
||||
Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged)
|
||||
Q_PROPERTY(int trackNumber READ getTrackNumber WRITE setTrackNumber NOTIFY trackNumberChanged)
|
||||
Q_PROPERTY(int year READ getYear WRITE setYear NOTIFY yearChanged)
|
||||
|
||||
public:
|
||||
KotoTrack(); // No-op constructor
|
||||
static KotoTrack* fromDb(const QSqlQuery& query, const QSqlRecord& record);
|
||||
static KotoTrack* fromMetadata(const KFileMetaData::SimpleExtractionResult& metadata, const QFileInfo& info);
|
||||
~KotoTrack();
|
||||
virtual ~KotoTrack();
|
||||
|
||||
std::optional<QUuid> album_uuid;
|
||||
QUuid artist_uuid;
|
||||
QUuid uuid;
|
||||
|
||||
void commit();
|
||||
QString getAlbumUuid();
|
||||
QUuid getArtistUuid();
|
||||
int getDiscNumber();
|
||||
int getDuration();
|
||||
QStringList getGenres();
|
||||
QString getLyrics();
|
||||
|
@ -101,6 +186,7 @@ class KotoTrack {
|
|||
QString getPath();
|
||||
QString getTitle();
|
||||
int getTrackNumber();
|
||||
QUuid getUuid();
|
||||
int getYear();
|
||||
|
||||
void setAlbum(KotoAlbum* album);
|
||||
|
@ -115,6 +201,19 @@ class KotoTrack {
|
|||
void setTrackNumber(int num);
|
||||
void setYear(int num);
|
||||
|
||||
signals:
|
||||
void albumChanged();
|
||||
void artistChanged();
|
||||
void discNumberChanged();
|
||||
void durationChanged();
|
||||
void genresChanged();
|
||||
void lyricsChanged();
|
||||
void narratorChanged();
|
||||
void pathChanged();
|
||||
void titleChanged();
|
||||
void trackNumberChanged();
|
||||
void yearChanged();
|
||||
|
||||
private:
|
||||
int disc_number;
|
||||
int duration;
|
||||
|
|
|
@ -102,6 +102,19 @@ void KotoTrack::commit() {
|
|||
query.exec();
|
||||
}
|
||||
|
||||
QString KotoTrack::getAlbumUuid() {
|
||||
if (!this->album_uuid.has_value()) return this->album_uuid.value().toString();
|
||||
return {};
|
||||
}
|
||||
|
||||
QUuid KotoTrack::getArtistUuid() {
|
||||
return this->artist_uuid;
|
||||
}
|
||||
|
||||
int KotoTrack::getDiscNumber() {
|
||||
return this->disc_number;
|
||||
}
|
||||
|
||||
int KotoTrack::getDuration() {
|
||||
return this->duration;
|
||||
}
|
||||
|
@ -130,6 +143,10 @@ int KotoTrack::getTrackNumber() {
|
|||
return this->track_number;
|
||||
}
|
||||
|
||||
QUuid KotoTrack::getUuid() {
|
||||
return this->uuid;
|
||||
}
|
||||
|
||||
int KotoTrack::getYear() {
|
||||
return this->year;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,14 @@ int main(int argc, char* argv[]) {
|
|||
if (engine.rootObjects().isEmpty()) { return -1; }
|
||||
|
||||
std::thread([]() {
|
||||
Cartographer::create();
|
||||
// Cartographer::create();
|
||||
KotoConfig::create();
|
||||
KotoDatabase::create();
|
||||
|
||||
KotoDatabase::instance().connect();
|
||||
|
||||
std::cout << "???" << std::endl;
|
||||
|
||||
// If we needed to bootstrap, index all libraries, otherwise load the database
|
||||
if (KotoDatabase::instance().requiredBootstrap()) {
|
||||
indexAllLibraries();
|
||||
|
|
|
@ -3,10 +3,35 @@ import QtQuick.Controls as Controls
|
|||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Kirigami.Page {
|
||||
ColumnLayout {
|
||||
Controls.Label {
|
||||
text: qsTr("blah!")
|
||||
Kirigami.ScrollablePage {
|
||||
Component {
|
||||
id: listDelegate
|
||||
|
||||
Controls.ItemDelegate {
|
||||
required property string name
|
||||
|
||||
text: name
|
||||
width: ListView.view.width
|
||||
}
|
||||
}
|
||||
// ListModel {
|
||||
// id: blah
|
||||
//
|
||||
// ListElement {
|
||||
// name: "blah1"
|
||||
// }
|
||||
// ListElement {
|
||||
// name: "blah2"
|
||||
// }
|
||||
// ListElement {
|
||||
// name: "blah3"
|
||||
// }
|
||||
// }
|
||||
ListView {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
delegate: listDelegate
|
||||
//model: blah
|
||||
model: Cartographer.artists
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ Kirigami.GlobalDrawer {
|
|||
drawerOpen: !isMobile()
|
||||
edge: Qt.LeftEdge
|
||||
height: parent.height
|
||||
modal: isMobile()
|
||||
modal: false
|
||||
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
|
|
|
@ -9,11 +9,14 @@ Kirigami.Page {
|
|||
ColumnLayout {
|
||||
id: rootLayout
|
||||
|
||||
Layout.fillWidth: true
|
||||
anchors.fill: parent
|
||||
|
||||
Controls.StackView {
|
||||
id: rootStack
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
initialItem: HomePage {
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue