Commit 67042c8f authored by Matthieu Gallien's avatar Matthieu Gallien

add support for fetching lyrics in TrackMetaDataModel and display it

CCBUG: 401969
parent 0e9abefe
......@@ -21,9 +21,20 @@
#include <KI18n/KLocalizedString>
#include <QtConcurrent/QtConcurrentRun>
TrackMetadataModel::TrackMetadataModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&mLyricsValueWatcher, &QFutureWatcher<QString>::finished,
this, &TrackMetadataModel::lyricsValueIsReady);
}
TrackMetadataModel::~TrackMetadataModel()
{
if (mLyricsValueWatcher.isRunning() && !mLyricsValueWatcher.isFinished()) {
mLyricsValueWatcher.waitForFinished();
}
}
int TrackMetadataModel::rowCount(const QModelIndex &parent) const
......@@ -103,6 +114,9 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
case DatabaseInterface::PlayCounter:
result = i18nc("Play counter label for track metadata view", "Play count");
break;
case DatabaseInterface::LyricsRole:
result = i18nc("Lyrics label for track metadata view", "Lyrics");
break;
case DatabaseInterface::SecondaryTextRole:
case DatabaseInterface::ImageUrlRole:
case DatabaseInterface::ShadowForImageRole:
......@@ -171,6 +185,9 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
case DatabaseInterface::PlayCounter:
result = IntegerEntry;
break;
case DatabaseInterface::LyricsRole:
result = LongTextEntry;
break;
case DatabaseInterface::DurationRole:
case DatabaseInterface::SampleRateRole:
case DatabaseInterface::BitRateRole:
......@@ -273,6 +290,8 @@ void TrackMetadataModel::fillDataFromTrackData(const TrackMetadataModel::TrackDa
filterDataFromTrackData();
endResetModel();
fetchLyrics();
mCoverImage = trackData[DatabaseInterface::ImageUrlRole].toUrl();
Q_EMIT coverUrlChanged();
......@@ -306,6 +325,17 @@ TrackMetadataModel::TrackDataType::mapped_type TrackMetadataModel::dataFromType(
return mFullData[metaData];
}
void TrackMetadataModel::lyricsValueIsReady()
{
if (!mLyricsValueWatcher.result().isEmpty()) {
beginInsertRows({}, mTrackData.size(), mTrackData.size());
mTrackKeys.push_back(DatabaseInterface::LyricsRole);
mTrackData[DatabaseInterface::LyricsRole] = mLyricsValueWatcher.result();
mFullData[DatabaseInterface::LyricsRole] = mLyricsValueWatcher.result();
endInsertRows();
}
}
void TrackMetadataModel::initialize(MusicListenersManager *newManager, DatabaseInterface *trackDatabase)
{
mManager = newManager;
......@@ -331,6 +361,19 @@ void TrackMetadataModel::initialize(MusicListenersManager *newManager, DatabaseI
this, &TrackMetadataModel::trackData);
}
void TrackMetadataModel::fetchLyrics()
{
auto lyricicsValue = QtConcurrent::run(QThreadPool::globalInstance(), [=]() {
auto trackData = mFileScanner.scanOneFile(mFullData[DatabaseInterface::ResourceRole].toUrl(), mMimeDatabase);
if (!trackData.lyrics().isEmpty()) {
return trackData.lyrics();
}
return QString{};
});
mLyricsValueWatcher.setFuture(lyricicsValue);
}
void TrackMetadataModel::initializeByTrackId(qulonglong databaseId)
{
Q_EMIT needDataByDatabaseId(ElisaUtils::Track, databaseId);
......
......@@ -23,9 +23,12 @@
#include "elisautils.h"
#include "databaseinterface.h"
#include "modeldataloader.h"
#include "filescanner.h"
#include <QUrl>
#include <QAbstractListModel>
#include <QMimeDatabase>
#include <QFutureWatcher>
class MusicListenersManager;
......@@ -60,6 +63,7 @@ public:
IntegerEntry,
RatingEntry,
DateEntry,
LongTextEntry,
};
Q_ENUM(ItemType)
......@@ -68,6 +72,8 @@ public:
explicit TrackMetadataModel(QObject *parent = nullptr);
~TrackMetadataModel() override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
......@@ -117,11 +123,17 @@ protected:
TrackDataType::mapped_type dataFromType(TrackDataType::key_type metaData) const;
private Q_SLOTS:
void lyricsValueIsReady();
private:
void initialize(MusicListenersManager *newManager,
DatabaseInterface *trackDatabase);
void fetchLyrics();
TrackDataType mFullData;
TrackDataType mTrackData;
......@@ -136,6 +148,12 @@ private:
MusicListenersManager *mManager = nullptr;
FileScanner mFileScanner;
QMimeDatabase mMimeDatabase;
QFutureWatcher<QString> mLyricsValueWatcher;
};
#endif // TRACKMETADATAMODEL_H
......@@ -144,17 +144,27 @@ FocusScope {
elide: Text.ElideRight
}
Repeater {
ListView {
id: trackData
Layout.fillWidth: true
Layout.fillHeight: true
ScrollBar.vertical: ScrollBar {
id: scrollBar
}
boundsBehavior: Flickable.StopAtBounds
clip: true
spacing: 0
model: metaDataModel
delegate: MetaDataDelegate {
width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width
}
}
Item {
Layout.fillHeight: true
}
Row {
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
Layout.topMargin: elisaTheme.layoutVerticalMargin
......
......@@ -87,6 +87,7 @@ Window {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: 2 * elisaTheme.layoutHorizontalMargin
focus: true
......@@ -96,7 +97,6 @@ Window {
boundsBehavior: Flickable.StopAtBounds
clip: true
ScrollHelper {
id: scrollHelper
flickable: trackData
......@@ -104,7 +104,9 @@ Window {
}
model: realModel
delegate: metadataDelegate
delegate: MetaDataDelegate {
width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width
}
}
}
......@@ -148,79 +150,6 @@ Window {
}
}
Component {
id: metadataDelegate
RowLayout {
id: delegateRow
spacing: 0
width: scrollBar.visible ? trackData.width - scrollBar.width : trackData.width
Label {
id: metaDataLabels
text: i18nc('name of a property for the track metadata detailled view', '%1:', model.name)
color: myPalette.text
horizontalAlignment: Text.AlignRight
Layout.preferredWidth: 0.8 * elisaTheme.coverImageSize
Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
}
Loader {
active: model.type === TrackMetadataModel.TextEntry || model.type === TrackMetadataModel.IntegerEntry
Layout.fillWidth: true
sourceComponent: LabelWithToolTip {
text: model.display
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
anchors.fill: parent
}
}
Loader {
active: model.type === TrackMetadataModel.DateEntry
Layout.fillWidth: true
sourceComponent: LabelWithToolTip {
text: rawDate.toLocaleDateString()
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
anchors.fill: parent
property date rawDate: new Date(model.display)
}
}
Loader {
active: model.type === TrackMetadataModel.RatingEntry
Layout.fillWidth: true
sourceComponent: RatingStar {
starRating: model.display
starSize: elisaTheme.ratingStarSize
readOnly: true
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
}
}
}
}
}
Connections {
target: elisa
......
......@@ -25,13 +25,12 @@ RowLayout {
id: delegateRow
spacing: 0
width: topItem.width
height: metaDataLabelMetric.height * 1.5
height: (model.type === TrackMetadataModel.LongTextEntry ? longTextDisplayLoader.height : metaDataLabelMetric.height) + (elisaTheme.layoutVerticalMargin / 2)
TextMetrics {
id: metaDataLabelMetric
text: model.name
text: 'Metadata Name'
font.weight: Font.Bold
}
......@@ -45,16 +44,20 @@ RowLayout {
horizontalAlignment: Text.AlignLeft
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: 0.8 * elisaTheme.coverImageSize
Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin * 2 : 0
Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin * 2 : 0
}
Loader {
id: textDisplayLoader
active: model.type === TrackMetadataModel.TextEntry || model.type === TrackMetadataModel.IntegerEntry
visible: model.type === TrackMetadataModel.TextEntry || model.type === TrackMetadataModel.IntegerEntry
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
sourceComponent: LabelWithToolTip {
text: model.display
......@@ -66,11 +69,34 @@ RowLayout {
}
}
Loader {
id: longTextDisplayLoader
active: model.type === TrackMetadataModel.LongTextEntry
visible: model.type === TrackMetadataModel.LongTextEntry
Layout.fillWidth: true
Layout.maximumWidth: delegateRow.width - (0.8 * elisaTheme.coverImageSize + elisaTheme.layoutHorizontalMargin * 2)
Layout.alignment: Qt.AlignTop
sourceComponent: Label {
text: model.display
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
anchors.fill: parent
wrapMode: Text.WordWrap
}
}
Loader {
active: model.type === TrackMetadataModel.DateEntry
visible: model.type === TrackMetadataModel.DateEntry
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
sourceComponent: LabelWithToolTip {
text: rawDate.toLocaleDateString()
......@@ -89,6 +115,7 @@ RowLayout {
visible: model.type === TrackMetadataModel.RatingEntry
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
sourceComponent: RatingStar {
starRating: model.display
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment