diff --git a/src/databaseinterface.cpp b/src/databaseinterface.cpp --- a/src/databaseinterface.cpp +++ b/src/databaseinterface.cpp @@ -2841,16 +2841,16 @@ const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Radios` (" "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " "`HttpAddress` VARCHAR(255) NOT NULL, " - "`Priority` INTEGER NOT NULL, " + "`ImageAddress` VARCHAR(255) NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " "`Rating` INTEGER NOT NULL DEFAULT 0, " "`Genre` VARCHAR(55), " "`Comment` VARCHAR(255), " "UNIQUE (" "`HttpAddress`" "), " "UNIQUE (" - "`Priority`, `Title`, `HttpAddress`" + "`Title`, `HttpAddress`" ") " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`))" )); @@ -2868,15 +2868,16 @@ //Find webradios (french): https://doc.ubuntu-fr.org/liste_radio_france //English: https://www.radio.fr/language/english (to get the link play a radio and look for streamUrl in the html elements page). - const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO `Radios` (`HttpAddress`, `Priority`, `Title`) " - "SELECT 'http://classicrock.stream.ouifm.fr/ouifm3.mp3', 1, 'OuiFM_Classic_Rock' UNION ALL " - "SELECT 'http://rock70s.stream.ouifm.fr/ouifmseventies.mp3', 1, 'OuiFM_70s' UNION ALL " - "SELECT 'http://jazzradio.ice.infomaniak.ch/jazzradio-high.mp3', 2 , 'Jazz_Radio' UNION ALL " - "SELECT 'http://cdn.nrjaudio.fm/audio1/fr/30601/mp3_128.mp3?origine=playerweb', 1, 'Nostalgie' UNION ALL " - "SELECT 'https://scdn.nrjaudio.fm/audio1/fr/30713/aac_64.mp3?origine=playerweb', 1, 'Nostalgie Johnny' UNION ALL " - "SELECT 'http://sc-classrock.1.fm:8200', 1, 'Classic rock replay' UNION ALL " - "SELECT 'http://agnes.torontocast.com:8151/stream', 1, 'Instrumentals Forever' UNION ALL " - "SELECT 'https://stream.laut.fm/jahfari', 1, 'Jahfari'" + const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO `Radios` (`HttpAddress`, `ImageAddress`, `Title`) " + "SELECT 'http://classicrock.stream.ouifm.fr/ouifm3.mp3', '', 'OuiFM_Classic_Rock' UNION ALL " + "SELECT 'http://rock70s.stream.ouifm.fr/ouifmseventies.mp3', '', 'OuiFM_70s' UNION ALL " + "SELECT 'http://jazzradio.ice.infomaniak.ch/jazzradio-high.mp3', '' , 'Jazz_Radio' UNION ALL " + "SELECT 'http://cdn.nrjaudio.fm/audio1/fr/30601/mp3_128.mp3?origine=playerweb', '', 'Nostalgie' UNION ALL " + "SELECT 'https://scdn.nrjaudio.fm/audio1/fr/30713/aac_64.mp3?origine=playerweb', '', 'Nostalgie Johnny' UNION ALL " + "SELECT 'http://sc-classrock.1.fm:8200', '', 'Classic rock replay' UNION ALL " + "SELECT 'http://agnes.torontocast.com:8151/stream', '', 'Instrumentals Forever' UNION ALL " + "SELECT 'https://stream.laut.fm/jahfari', '', 'Jahfari' UNION ALL " + "SELECT 'https://chai5she.cdn.dvmr.fr/francemusique-lofi.mp3', 'https://static.radio.fr/images/broadcasts/07/f7/3366/c44.png', 'France Musique'" )); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << createSchemaQuery.lastQuery(); @@ -3629,6 +3630,7 @@ "radios.`ID`, " "radios.`Title`, " "radios.`HttpAddress`, " + "radios.`ImageAddress`, " "radios.`Rating`, " "trackGenre.`Name`, " "radios.`Comment` " @@ -4447,6 +4449,7 @@ "radios.`ID`, " "radios.`Title`, " "radios.`HttpAddress`, " + "radios.`ImageAddress`, " "radios.`Rating`, " "trackGenre.`Name`, " "radios.`Comment` " @@ -5117,14 +5120,14 @@ "`httpAddress`, " "`Comment`, " "`Rating`, " - "`Priority`) " + "`ImageAddress`) " "VALUES " "(" ":title, " ":httpAddress, " ":comment, " ":trackRating," - "1)"); + ":imageAddress)"); auto result = prepareQuery(d->mInsertRadioQuery, insertRadioQueryText); @@ -5156,7 +5159,8 @@ "`HttpAddress` = :httpAddress, " "`Title` = :title, " "`Comment` = :comment, " - "`Rating` = :trackRating " + "`Rating` = :trackRating, " + "`ImageAddress` = :imageAddress " "WHERE " "`ID` = :radioId"); @@ -6401,11 +6405,12 @@ result[TrackDataType::key_type::ArtistRole] = trackRecord.value(1); result[TrackDataType::key_type::ResourceRole] = trackRecord.value(2); - result[TrackDataType::key_type::RatingRole] = trackRecord.value(3); + result[TrackDataType::key_type::ImageUrlRole] = trackRecord.value(3); + result[TrackDataType::key_type::RatingRole] = trackRecord.value(4); if (!trackRecord.value(4).isNull()) { - result[TrackDataType::key_type::GenreRole] = trackRecord.value(4); + result[TrackDataType::key_type::GenreRole] = trackRecord.value(5); } - result[TrackDataType::key_type::CommentRole] = trackRecord.value(5); + result[TrackDataType::key_type::CommentRole] = trackRecord.value(6); result[TrackDataType::key_type::ElementTypeRole] = ElisaUtils::Radio; return result; @@ -6811,6 +6816,7 @@ query.bindValue(QStringLiteral(":title"), oneTrack.title()); query.bindValue(QStringLiteral(":comment"), oneTrack.comment()); query.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); + query.bindValue(QStringLiteral(":imageAddress"), oneTrack.albumCover()); auto result = execQuery(query); diff --git a/src/models/datamodel.h b/src/models/datamodel.h --- a/src/models/datamodel.h +++ b/src/models/datamodel.h @@ -143,6 +143,8 @@ ElisaUtils::PlayListEntryType modelType, ElisaUtils::FilterType filter, const QString &genre, const QString &artist, qulonglong databaseId); + void resetAlbumImage(qulonglong databaseId); + private Q_SLOTS: void cleanedDatabase(); diff --git a/src/models/datamodel.cpp b/src/models/datamodel.cpp --- a/src/models/datamodel.cpp +++ b/src/models/datamodel.cpp @@ -831,6 +831,15 @@ Q_EMIT dataChanged(index(albumIndex, 0), index(albumIndex, 0)); } +void DataModel::resetAlbumImage(qulonglong databaseId) +{ + DataModel::ListTrackDataType *mAllData = d->mModelType == ElisaUtils::Radio ? &d->mAllRadiosData: &d->mAllTrackData; + auto trackIndex = indexFromId(databaseId); + (*mAllData)[trackIndex][DatabaseInterface::ImageUrlRole] = QUrl(QStringLiteral("image://icon/media-optical-audio")); + + Q_EMIT dataChanged(index(trackIndex, 0), index(trackIndex, 0)); +} + void DataModel::cleanedDatabase() { beginResetModel(); diff --git a/src/models/trackmetadatamodel.h b/src/models/trackmetadatamodel.h --- a/src/models/trackmetadatamodel.h +++ b/src/models/trackmetadatamodel.h @@ -133,6 +133,8 @@ void setManager(MusicListenersManager *newManager); + void resetCoverUrl(); + void setDatabase(DatabaseInterface *trackDatabase); void saveData(); diff --git a/src/models/trackmetadatamodel.cpp b/src/models/trackmetadatamodel.cpp --- a/src/models/trackmetadatamodel.cpp +++ b/src/models/trackmetadatamodel.cpp @@ -165,8 +165,10 @@ case DatabaseInterface::ResourceRole: result = i18nc("Radio HTTP address for radio metadata view", "Stream Http Address"); break; - case DatabaseInterface::SecondaryTextRole: case DatabaseInterface::ImageUrlRole: + result = i18nc("Image address for radio metadata view", "Image Address"); + break; + case DatabaseInterface::SecondaryTextRole: case DatabaseInterface::ShadowForImageRole: case DatabaseInterface::ChildModelRole: case DatabaseInterface::StringDurationRole: @@ -195,6 +197,7 @@ result = TextEntry; break; case DatabaseInterface::ResourceRole: + case DatabaseInterface::ImageUrlRole: result = TextEntry; break; case DatabaseInterface::ArtistRole: @@ -244,7 +247,6 @@ case DatabaseInterface::BitRateRole: case DatabaseInterface::ChannelsRole: case DatabaseInterface::SecondaryTextRole: - case DatabaseInterface::ImageUrlRole: case DatabaseInterface::ShadowForImageRole: case DatabaseInterface::ChildModelRole: case DatabaseInterface::StringDurationRole: @@ -529,6 +531,12 @@ initialize(newManager, nullptr); } +void TrackMetadataModel::resetCoverUrl() +{ + mCoverImage = QUrl(QStringLiteral("image://icon/media-optical-audio")); + Q_EMIT coverUrlChanged(); +} + void TrackMetadataModel::setDatabase(DatabaseInterface *trackDatabase) { initialize(nullptr, trackDatabase); @@ -554,7 +562,8 @@ } const QList fieldsForTrack({DatabaseInterface::TitleRole, DatabaseInterface::ResourceRole, - DatabaseInterface::CommentRole, DatabaseInterface::DatabaseIdRole}); + DatabaseInterface::CommentRole, DatabaseInterface::ImageUrlRole, + DatabaseInterface::DatabaseIdRole}); fillDataFromTrackData(radiosData, fieldsForTrack); } diff --git a/src/qml/DataListView.qml b/src/qml/DataListView.qml --- a/src/qml/DataListView.qml +++ b/src/qml/DataListView.qml @@ -44,11 +44,12 @@ { "initialDatabaseId": databaseId, "modelType": modelType, - "showImage": false, + "showImage": true, "showTrackFileName": false, "showDeleteButton": databaseId !== -1, "showApplyButton": true, "editableMetadata": true, + "widthIndex": 4.5, }); } else { metadataLoader.setSource("MediaTrackMetadataView.qml", @@ -128,6 +129,10 @@ onCallOpenMetaDataView: { openMetaDataView(databaseId) } + + onResetAlbumImage: { + realModel.resetAlbumImage(databaseId) + } } } @@ -172,6 +177,10 @@ onCallOpenMetaDataView: { openMetaDataView(databaseId) } + + onResetAlbumImage: { + realModel.resetAlbumImage(databaseId) + } } } diff --git a/src/qml/ListBrowserDelegate.qml b/src/qml/ListBrowserDelegate.qml --- a/src/qml/ListBrowserDelegate.qml +++ b/src/qml/ListBrowserDelegate.qml @@ -45,6 +45,7 @@ signal enqueue(var databaseId, var name) signal replaceAndPlay(var databaseId, var name) signal callOpenMetaDataView(var databaseId) + signal resetAlbumImage(var databaseId) Accessible.role: Accessible.ListItem Accessible.name: title @@ -187,6 +188,12 @@ color: myPalette.shadow } + + onStatusChanged: { + if (coverImageElement.status == Image.Error) { + resetAlbumImage(databaseId) + } + } } } diff --git a/src/qml/MediaTrackMetadataView.qml b/src/qml/MediaTrackMetadataView.qml --- a/src/qml/MediaTrackMetadataView.qml +++ b/src/qml/MediaTrackMetadataView.qml @@ -35,6 +35,7 @@ property alias showTrackFileName: fileNameRow.visible property alias showDeleteButton: deleteButtonBox.visible property alias showApplyButton: applyButton.visible + property double widthIndex: 2.8 signal rejected() @@ -55,7 +56,7 @@ color: myPalette.window minimumHeight: elisaTheme.coverImageSize * 1.8 - minimumWidth: elisaTheme.coverImageSize * 2.8 + minimumWidth: elisaTheme.coverImageSize * trackMetadata.widthIndex ColumnLayout { anchors.fill: parent @@ -88,6 +89,12 @@ Layout.minimumWidth: elisaTheme.coverImageSize Layout.maximumHeight: elisaTheme.coverImageSize Layout.maximumWidth: elisaTheme.coverImageSize + + onStatusChanged: { + if (metadataImage.status == Image.Error) { + realModel.resetCoverUrl() + } + } } ListView {