Commit 819bf2b3 authored by Matthieu Gallien's avatar Matthieu Gallien 🎵
Browse files

allow addition of new metadata fields from a list of fields not existing

manage the list of undefined fields and allow the user to add one from
them

factor existing code to allow reuse
parent f64bed95
......@@ -212,11 +212,7 @@ bool EditableTrackMetadataModel::setData(const QModelIndex &index, const QVarian
auto result = TrackMetadataModel::setData(index, value, role);
if (result) {
if (!mIsDirty) {
mIsDirty = true;
Q_EMIT isDirtyChanged();
}
modelHasBeenModified();
validData();
}
......@@ -258,12 +254,11 @@ void EditableTrackMetadataModel::removeData(int index)
removeDataByIndex(index);
endRemoveRows();
if (!mIsDirty) {
mIsDirty = true;
Q_EMIT isDirtyChanged();
}
modelHasBeenModified();
validData();
updateExtraMetadata();
}
void EditableTrackMetadataModel::addData(const QString &name)
......@@ -272,12 +267,10 @@ void EditableTrackMetadataModel::addData(const QString &name)
addDataByName(name);
endInsertRows();
if (!mIsDirty) {
mIsDirty = true;
Q_EMIT isDirtyChanged();
}
modelHasBeenModified();
validData();
updateExtraMetadata();
}
void EditableTrackMetadataModel::fillDataFromTrackData(const TrackMetadataModel::TrackDataType &trackData,
......@@ -288,6 +281,8 @@ void EditableTrackMetadataModel::fillDataFromTrackData(const TrackMetadataModel:
}
TrackMetadataModel::fillDataFromTrackData(trackData, fieldsForTrack);
updateExtraMetadata();
}
void EditableTrackMetadataModel::filterDataFromTrackData()
......@@ -354,5 +349,30 @@ void EditableTrackMetadataModel::validData()
}
}
void EditableTrackMetadataModel::updateExtraMetadata()
{
mExtraMetadata.clear();
for(auto metadataRole : {DataTypes::TitleRole, DataTypes::ArtistRole,
DataTypes::AlbumRole, DataTypes::AlbumArtistRole, DataTypes::TrackNumberRole,
DataTypes::DiscNumberRole, DataTypes::RatingRole, DataTypes::GenreRole,
DataTypes::LyricistRole, DataTypes::ComposerRole, DataTypes::CommentRole,
DataTypes::YearRole, DataTypes::ChannelsRole, DataTypes::BitRateRole,
DataTypes::SampleRateRole, DataTypes::LyricsRole}) {
if (!metadataExists(metadataRole)) {
mExtraMetadata.push_back(nameFromRole(metadataRole));
}
}
Q_EMIT extraMetadataChanged();
}
void EditableTrackMetadataModel::modelHasBeenModified()
{
if (!mIsDirty) {
mIsDirty = true;
Q_EMIT isDirtyChanged();
}
}
#include "moc_editabletrackmetadatamodel.cpp"
......@@ -27,6 +27,10 @@ class ELISALIB_EXPORT EditableTrackMetadataModel : public TrackMetadataModel
READ isDirty
NOTIFY isDirtyChanged)
Q_PROPERTY(QStringList extraMetadata
READ extraMetadata
NOTIFY extraMetadataChanged)
public:
enum EditableColumnRoles
{
......@@ -60,6 +64,11 @@ public:
QHash<int, QByteArray> roleNames() const override;
QStringList extraMetadata() const
{
return mExtraMetadata;
}
Q_SIGNALS:
void isDataValidChanged();
......@@ -71,6 +80,8 @@ Q_SIGNALS:
void deleteRadioData(qulonglong radioId);
void extraMetadataChanged();
public Q_SLOTS:
void saveData();
......@@ -98,6 +109,10 @@ private:
void validData();
void updateExtraMetadata();
void modelHasBeenModified();
bool mIsNewRadio = false;
bool mIsDataValid = false;
......@@ -105,6 +120,8 @@ private:
bool mIsDirty = false;
QString mErrorMessage;
QStringList mExtraMetadata;
};
......
......@@ -12,6 +12,8 @@
#include <QtConcurrent>
#include <algorithm>
TrackMetadataModel::TrackMetadataModel(QObject *parent)
: QAbstractListModel(parent)
{
......@@ -102,96 +104,7 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
}
break;
case ItemNameRole:
switch (currentKey)
{
case DataTypes::TitleRole:
result = i18nc("Track title for track metadata view", "Title");
break;
case DataTypes::DurationRole:
result = i18nc("Duration label for track metadata view", "Duration");
break;
case DataTypes::ArtistRole:
result = i18nc("Track artist for track metadata view", "Artist");
break;
case DataTypes::AlbumRole:
result = i18nc("Album name for track metadata view", "Album");
break;
case DataTypes::AlbumArtistRole:
result = i18nc("Album artist for track metadata view", "Album Artist");
break;
case DataTypes::TrackNumberRole:
result = i18nc("Track number for track metadata view", "Track Number");
break;
case DataTypes::DiscNumberRole:
result = i18nc("Disc number for track metadata view", "Disc Number");
break;
case DataTypes::RatingRole:
result = i18nc("Rating label for information panel", "Rating");
break;
case DataTypes::GenreRole:
result = i18nc("Genre label for track metadata view", "Genre");
break;
case DataTypes::LyricistRole:
result = i18nc("Lyricist label for track metadata view", "Lyricist");
break;
case DataTypes::ComposerRole:
result = i18nc("Composer name for track metadata view", "Composer");
break;
case DataTypes::CommentRole:
result = i18nc("Comment label for track metadata view", "Comment");
break;
case DataTypes::YearRole:
result = i18nc("Year label for track metadata view", "Year");
break;
case DataTypes::ChannelsRole:
result = i18nc("Channels label for track metadata view", "Channels");
break;
case DataTypes::BitRateRole:
result = i18nc("Bit rate label for track metadata view", "Bit Rate");
break;
case DataTypes::SampleRateRole:
result = i18nc("Sample Rate label for track metadata view", "Sample Rate");
break;
case DataTypes::LastPlayDate:
result = i18nc("Last play date label for track metadata view", "Last played");
break;
case DataTypes::PlayCounter:
result = i18nc("Play counter label for track metadata view", "Play count");
break;
case DataTypes::LyricsRole:
result = i18nc("Lyrics label for track metadata view", "Lyrics");
break;
case DataTypes::ResourceRole:
result = i18nc("Radio HTTP address for radio metadata view", "Stream Http Address");
break;
case DataTypes::ImageUrlRole:
result = i18nc("Image address for radio metadata view", "Image Address");
break;
case DataTypes::SecondaryTextRole:
case DataTypes::ShadowForImageRole:
case DataTypes::ChildModelRole:
case DataTypes::StringDurationRole:
case DataTypes::IsValidAlbumArtistRole:
case DataTypes::AllArtistsRole:
case DataTypes::HighestTrackRating:
case DataTypes::IdRole:
case DataTypes::ParentIdRole:
case DataTypes::DatabaseIdRole:
case DataTypes::IsSingleDiscAlbumRole:
case DataTypes::ContainerDataRole:
case DataTypes::IsPartialDataRole:
case DataTypes::AlbumIdRole:
case DataTypes::HasEmbeddedCover:
case DataTypes::FileModificationTime:
case DataTypes::FirstPlayDate:
case DataTypes::PlayFrequency:
case DataTypes::ElementTypeRole:
case DataTypes::FullDataRole:
case DataTypes::IsDirectoryRole:
case DataTypes::IsPlayListRole:
case DataTypes::FilePathRole:
break;
}
result = nameFromRole(currentKey);
break;
case ItemTypeRole:
switch (currentKey)
......@@ -563,6 +476,109 @@ void TrackMetadataModel::addDataByName(const QString &name)
mTrackKeys.push_back(newRole);
}
QString TrackMetadataModel::nameFromRole(DataTypes::ColumnsRoles role)
{
auto result = QString{};
switch (role)
{
case DataTypes::TitleRole:
result = i18nc("Track title for track metadata view", "Title");
break;
case DataTypes::DurationRole:
result = i18nc("Duration label for track metadata view", "Duration");
break;
case DataTypes::ArtistRole:
result = i18nc("Track artist for track metadata view", "Artist");
break;
case DataTypes::AlbumRole:
result = i18nc("Album name for track metadata view", "Album");
break;
case DataTypes::AlbumArtistRole:
result = i18nc("Album artist for track metadata view", "Album Artist");
break;
case DataTypes::TrackNumberRole:
result = i18nc("Track number for track metadata view", "Track Number");
break;
case DataTypes::DiscNumberRole:
result = i18nc("Disc number for track metadata view", "Disc Number");
break;
case DataTypes::RatingRole:
result = i18nc("Rating label for information panel", "Rating");
break;
case DataTypes::GenreRole:
result = i18nc("Genre label for track metadata view", "Genre");
break;
case DataTypes::LyricistRole:
result = i18nc("Lyricist label for track metadata view", "Lyricist");
break;
case DataTypes::ComposerRole:
result = i18nc("Composer name for track metadata view", "Composer");
break;
case DataTypes::CommentRole:
result = i18nc("Comment label for track metadata view", "Comment");
break;
case DataTypes::YearRole:
result = i18nc("Year label for track metadata view", "Year");
break;
case DataTypes::ChannelsRole:
result = i18nc("Channels label for track metadata view", "Channels");
break;
case DataTypes::BitRateRole:
result = i18nc("Bit rate label for track metadata view", "Bit Rate");
break;
case DataTypes::SampleRateRole:
result = i18nc("Sample Rate label for track metadata view", "Sample Rate");
break;
case DataTypes::LastPlayDate:
result = i18nc("Last play date label for track metadata view", "Last played");
break;
case DataTypes::FirstPlayDate:
result = i18nc("First play date label for track metadata view", "First played");
break;
case DataTypes::PlayCounter:
result = i18nc("Play counter label for track metadata view", "Play count");
break;
case DataTypes::LyricsRole:
result = i18nc("Lyrics label for track metadata view", "Lyrics");
break;
case DataTypes::ResourceRole:
result = i18nc("Radio HTTP address for radio metadata view", "Stream Http Address");
break;
case DataTypes::ImageUrlRole:
result = i18nc("Image address for radio metadata view", "Image Address");
break;
case DataTypes::SecondaryTextRole:
case DataTypes::ShadowForImageRole:
case DataTypes::ChildModelRole:
case DataTypes::StringDurationRole:
case DataTypes::IsValidAlbumArtistRole:
case DataTypes::AllArtistsRole:
case DataTypes::HighestTrackRating:
case DataTypes::IdRole:
case DataTypes::ParentIdRole:
case DataTypes::DatabaseIdRole:
case DataTypes::IsSingleDiscAlbumRole:
case DataTypes::ContainerDataRole:
case DataTypes::IsPartialDataRole:
case DataTypes::AlbumIdRole:
case DataTypes::HasEmbeddedCover:
case DataTypes::FileModificationTime:
case DataTypes::PlayFrequency:
case DataTypes::ElementTypeRole:
case DataTypes::FullDataRole:
case DataTypes::IsDirectoryRole:
case DataTypes::IsPlayListRole:
case DataTypes::FilePathRole:
break;
}
return result;
}
bool TrackMetadataModel::metadataExists(DataTypes::ColumnsRoles metadataRole) const
{
return std::find(mTrackKeys.begin(), mTrackKeys.end(), metadataRole) != mTrackKeys.end();
}
void TrackMetadataModel::fetchLyrics()
{
auto lyricicsValue = QtConcurrent::run(QThreadPool::globalInstance(), [=]() {
......
......@@ -156,6 +156,10 @@ protected:
void addDataByName(const QString &name);
static QString nameFromRole(DataTypes::ColumnsRoles role);
bool metadataExists(DataTypes::ColumnsRoles metadataRole) const;
private Q_SLOTS:
void lyricsValueIsReady();
......
......@@ -104,7 +104,7 @@ Window {
id: metaDataDelegate
MetaDataDelegate {
width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width
width: trackData.width
index: model.index
name: model.name
......@@ -117,7 +117,7 @@ Window {
id: editableMetaDataDelegate
EditableMetaDataDelegate {
width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width
width: trackData.width
index: model.index
name: model.name
......@@ -133,55 +133,40 @@ Window {
delegate: ((dialogStates.state === 'readWrite' || dialogStates.state === 'readWriteAndDirty' ||
dialogStates.state === 'create' || dialogStates.state === 'createAndDirty') && !realModel.isReadOnly) ? editableMetaDataDelegate: metaDataDelegate
}
footer: RowLayout {
width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width
spacing: 0
visible: (dialogStates.state === 'readWrite' || dialogStates.state === 'readWriteAndDirty' ||
dialogStates.state === 'create' || dialogStates.state === 'createAndDirty') && !realModel.isReadOnly
ComboBox {
id: selectedField
textRole: "text"
valueRole: "text"
model: [
{ text: i18nc("Track title for track metadata view", "Title" ) },
{ text: i18nc("Track artist for track metadata view", "Artist") },
{ text: i18nc("Album name for track metadata view", "Album") },
{ text: i18nc("Album artist for track metadata view", "Album Artist") },
{ text: i18nc("Track number for track metadata view", "Track Number") },
{ text: i18nc("Disc number for track metadata view", "Disc Number") },
{ text: i18nc("Rating label for information panel", "Rating") },
{ text: i18nc("Genre label for track metadata view", "Genre") },
{ text: i18nc("Lyricist label for track metadata view", "Lyricist") },
{ text: i18nc("Composer name for track metadata view", "Composer") },
{ text: i18nc("Comment label for track metadata view", "Comment") },
{ text: i18nc("Year label for track metadata view", "Year") },
{ text: i18nc("Channels label for track metadata view", "Channels") },
{ text: i18nc("Bit rate label for track metadata view", "Bit Rate") },
{ text: i18nc("Sample Rate label for track metadata view", "Sample Rate") },
{ text: i18nc("Lyrics label for track metadata view", "Lyrics") },
]
}
footer: RowLayout {
width: trackData.width
Item {
Layout.fillWidth: true
}
spacing: 0
visible: (dialogStates.state === 'readWrite' || dialogStates.state === 'readWriteAndDirty' ||
dialogStates.state === 'create' || dialogStates.state === 'createAndDirty') && !realModel.isReadOnly
Item {
Layout.fillWidth: true
}
Button {
Layout.fillHeight: true
Layout.preferredWidth: height
ComboBox {
id: selectedField
flat: true
display: AbstractButton.IconOnly
icon.name: 'list-add'
textRole: "modelData"
valueRole: "modelData"
onClicked: realModel.addData(selectedField.currentValue)
model: realModel.extraMetadata
Layout.rightMargin: Kirigami.Units.smallSpacing * 2
}
Button {
Layout.fillHeight: true
Layout.preferredWidth: height
flat: true
display: AbstractButton.IconOnly
icon.name: 'list-add'
onClicked: realModel.addData(selectedField.currentValue)
}
}
}
}
......
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