Commit eb209bf8 authored by Jerome Guidon's avatar Jerome Guidon Committed by Matthieu Gallien
Browse files

Radios: add support for images

Summary:
Album images where disabled for radios. This patch adds support for images in the radio view. A field has been added to EditableMetaData to allow the user to choose the image he wants for a radio. It can be a local file or an url.

Linked to: T7567

Reviewers: #elisa, mgallien, ngraham, astippich

Reviewed By: #elisa, astippich

Subscribers: ndavis, astippich, ngraham, mgallien

Differential Revision: https://phabricator.kde.org/D23859
parent 91abe0d3
......@@ -2821,16 +2821,6 @@ void DatabaseInterface::upgradeDatabaseV13()
qCInfo(orgKdeElisaDatabase) << "finished update to v13 of database schema";
}
void DatabaseInterface::upgradeDatabaseV15()
{
}
void DatabaseInterface::upgradeDatabaseV16()
{
}
void DatabaseInterface::upgradeDatabaseV14()
{
qCInfo(orgKdeElisaDatabase) << "begin update to v14 of database schema";
......@@ -2932,6 +2922,141 @@ void DatabaseInterface::upgradeDatabaseV14()
qCInfo(orgKdeElisaDatabase) << "finished update to v14 of database schema";
}
void DatabaseInterface::upgradeDatabaseV15()
{
qCInfo(orgKdeElisaDatabase) << "begin update to v15 of database schema";
{
QSqlQuery createSchemaQuery(d->mTracksDatabase);
const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV15` (`Version` INTEGER PRIMARY KEY NOT NULL)"));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError();
Q_EMIT databaseError();
}
}
{
QSqlQuery disableForeignKeys(d->mTracksDatabase);
auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF"));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << disableForeignKeys.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << disableForeignKeys.lastError();
Q_EMIT databaseError();
}
}
d->mTracksDatabase.transaction();
{
QSqlQuery createSchemaQuery(d->mTracksDatabase);
const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `RadiosNew` ("
"`ID` INTEGER PRIMARY KEY AUTOINCREMENT, "
"`HttpAddress` VARCHAR(255) 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 ("
"`Title`, `HttpAddress`"
") "
"CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`))"
));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError();
Q_EMIT databaseError();
}
}
{
QSqlQuery createSchemaQuery(d->mTracksDatabase);
const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO RadiosNew SELECT ID, HttpAddress, '', Title, Rating, Genre, Comment FROM Radios"));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError();
Q_EMIT databaseError();
}
}
{
QSqlQuery createSchemaQuery(d->mTracksDatabase);
const auto &result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Radios`"));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError();
Q_EMIT databaseError();
}
}
{
QSqlQuery createSchemaQuery(d->mTracksDatabase);
const auto &result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `RadiosNew` RENAME TO `Radios`"));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError();
Q_EMIT databaseError();
}
}
{
QSqlQuery createSchemaQuery(d->mTracksDatabase);
const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO `Radios` (`HttpAddress`, `ImageAddress`, `Title`) "
"SELECT 'https://chai5she.cdn.dvmr.fr/francemusique-lofi.mp3', 'https://static.radio.fr/images/broadcasts/07/f7/3366/c44.png', 'France Musique'"
));
if (!result) {
qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << createSchemaQuery.lastQuery();
qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << createSchemaQuery.lastError();
Q_EMIT databaseError();
}
}
d->mTracksDatabase.commit();
{
QSqlQuery enableForeignKeys(d->mTracksDatabase);
auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON"));
if (!result) {
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << enableForeignKeys.lastQuery();
qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << enableForeignKeys.lastError();
Q_EMIT databaseError();
}
}
qCInfo(orgKdeElisaDatabase) << "finished update to v15 of database schema";
}
void DatabaseInterface::upgradeDatabaseV16()
{
}
void DatabaseInterface::checkDatabaseSchema()
{
checkAlbumsTableSchema();
......@@ -3830,6 +3955,7 @@ void DatabaseInterface::initRequest()
"radios.`ID`, "
"radios.`Title`, "
"radios.`HttpAddress`, "
"radios.`ImageAddress`, "
"radios.`Rating`, "
"trackGenre.`Name`, "
"radios.`Comment` "
......@@ -4761,6 +4887,7 @@ void DatabaseInterface::initRequest()
"radios.`ID`, "
"radios.`Title`, "
"radios.`HttpAddress`, "
"radios.`ImageAddress`, "
"radios.`Rating`, "
"trackGenre.`Name`, "
"radios.`Comment` "
......@@ -5431,14 +5558,14 @@ void DatabaseInterface::initRequest()
"`httpAddress`, "
"`Comment`, "
"`Rating`, "
"`Priority`) "
"`ImageAddress`) "
"VALUES "
"("
":title, "
":httpAddress, "
":comment, "
":trackRating,"
"1)");
":imageAddress)");
auto result = prepareQuery(d->mInsertRadioQuery, insertRadioQueryText);
......@@ -5470,7 +5597,8 @@ void DatabaseInterface::initRequest()
"`HttpAddress` = :httpAddress, "
"`Title` = :title, "
"`Comment` = :comment, "
"`Rating` = :trackRating "
"`Rating` = :trackRating, "
"`ImageAddress` = :imageAddress "
"WHERE "
"`ID` = :radioId");
......@@ -6729,16 +6857,15 @@ DataTypes::TrackDataType DatabaseInterface::buildRadioDataFromDatabaseRecord(con
result[DataTypes::TrackDataType::key_type::DatabaseIdRole] = trackRecord.value(0);
result[DataTypes::TrackDataType::key_type::TitleRole] = trackRecord.value(1);
result[DataTypes::TrackDataType::key_type::AlbumRole] = i18n("Radios");
result[DataTypes::TrackDataType::key_type::ArtistRole] = trackRecord.value(1);
result[DataTypes::TrackDataType::key_type::ResourceRole] = trackRecord.value(2);
result[DataTypes::TrackDataType::key_type::RatingRole] = trackRecord.value(3);
if (!trackRecord.value(4).isNull()) {
result[DataTypes::TrackDataType::key_type::GenreRole] = trackRecord.value(4);
result[DataTypes::TrackDataType::key_type::ImageUrlRole] = trackRecord.value(3);
result[DataTypes::TrackDataType::key_type::RatingRole] = trackRecord.value(4);
if (!trackRecord.value(5).isNull()) {
result[DataTypes::TrackDataType::key_type::GenreRole] = trackRecord.value(5);
}
result[DataTypes::TrackDataType::key_type::CommentRole] = trackRecord.value(5);
result[DataTypes::TrackDataType::key_type::CommentRole] = trackRecord.value(6);
result[DataTypes::TrackDataType::key_type::ElementTypeRole] = ElisaUtils::Radio;
return result;
......@@ -7144,6 +7271,7 @@ void DatabaseInterface::insertRadio(const DataTypes::TrackDataType &oneTrack)
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);
......
......@@ -165,8 +165,10 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
case DataTypes::ResourceRole:
result = i18nc("Radio HTTP address for radio metadata view", "Stream Http Address");
break;
case DataTypes::SecondaryTextRole:
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:
......@@ -174,7 +176,6 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
case DataTypes::AllArtistsRole:
case DataTypes::HighestTrackRating:
case DataTypes::IdRole:
case DataTypes::ParentIdRole:
case DataTypes::DatabaseIdRole:
case DataTypes::IsSingleDiscAlbumRole:
case DataTypes::ContainerDataRole:
......@@ -195,6 +196,7 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
result = TextEntry;
break;
case DataTypes::ResourceRole:
case DataTypes::ImageUrlRole:
result = TextEntry;
break;
case DataTypes::ArtistRole:
......@@ -244,7 +246,6 @@ QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const
case DataTypes::BitRateRole:
case DataTypes::ChannelsRole:
case DataTypes::SecondaryTextRole:
case DataTypes::ImageUrlRole:
case DataTypes::ShadowForImageRole:
case DataTypes::ChildModelRole:
case DataTypes::StringDurationRole:
......@@ -500,6 +501,7 @@ void TrackMetadataModel::fillDataForNewRadio()
DataTypes::TitleRole,
DataTypes::ResourceRole,
DataTypes::CommentRole,
DataTypes::ImageUrlRole,
DataTypes::DatabaseIdRole
}) {
......@@ -539,6 +541,14 @@ void TrackMetadataModel::setDatabase(DatabaseInterface *trackDatabase)
void TrackMetadataModel::saveData()
{
QString imageUrl = mTrackData[DataTypes::ImageUrlRole].toString();
if (!imageUrl.isEmpty()
&& !imageUrl.startsWith(QStringLiteral("http://"))
&& !imageUrl.startsWith(QStringLiteral("https://"))
&& !imageUrl.startsWith(QStringLiteral("file://"))) {
mTrackData[DataTypes::ImageUrlRole] = QStringLiteral("file:/").append(imageUrl);
}
Q_EMIT saveRadioData(mTrackData);
}
......@@ -557,7 +567,8 @@ void TrackMetadataModel::radioData(const TrackDataType &radiosData)
}
const QList<DataTypes::ColumnsRoles> fieldsForTrack({DataTypes::TitleRole, DataTypes::ResourceRole,
DataTypes::CommentRole, DataTypes::DatabaseIdRole});
DataTypes::CommentRole, DataTypes::ImageUrlRole,
DataTypes::DatabaseIdRole});
fillDataFromTrackData(radiosData, fieldsForTrack);
}
......
......@@ -45,11 +45,12 @@ FocusScope {
"initialDatabaseId": databaseId,
"fileName": url,
"modelType": viewHeader.modelType,
"showImage": false,
"showImage": true,
"showTrackFileName": false,
"showDeleteButton": databaseId !== -1,
"showApplyButton": true,
"editableMetadata": true,
"widthIndex": 4.5,
});
} else {
metadataLoader.setSource("MediaTrackMetadataView.qml",
......
......@@ -164,6 +164,12 @@ FocusScope {
color: myPalette.shadow
}
onStatusChanged: {
if (coverImageElement.status === Image.Error) {
source = 'image://icon/media-optical-audio'
}
}
}
}
......@@ -313,6 +319,16 @@ FocusScope {
}
}
Connections {
target: mediaTrack
onImageUrlChanged: {
if (coverImageElement.source !== imageUrl) {
coverImageElement.source = (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage))
}
}
}
states: [
State {
name: 'notSelected'
......
......@@ -35,6 +35,7 @@ Window {
property alias showTrackFileName: fileNameRow.visible
property alias showDeleteButton: deleteButtonBox.visible
property alias showApplyButton: applyButton.visible
property double widthIndex: 2.8
signal rejected()
......@@ -56,7 +57,7 @@ Window {
color: myPalette.window
minimumHeight: elisaTheme.coverImageSize * 1.8
minimumWidth: elisaTheme.coverImageSize * 2.8
minimumWidth: elisaTheme.coverImageSize * trackMetadata.widthIndex
ColumnLayout {
anchors.fill: parent
......@@ -89,6 +90,12 @@ Window {
Layout.minimumWidth: elisaTheme.coverImageSize
Layout.maximumHeight: elisaTheme.coverImageSize
Layout.maximumWidth: elisaTheme.coverImageSize
onStatusChanged: {
if (metadataImage.status === Image.Error) {
source = Qt.resolvedUrl(elisaTheme.defaultAlbumImage)
}
}
}
ListView {
......@@ -230,6 +237,14 @@ Window {
}
}
Connections {
target: realModel
onCoverUrlChanged: {
metadataImage.source = realModel.coverUrl
}
}
Component.onCompleted: {
if (elisa.musicManager) {
if (initialDatabaseId === -1) {
......
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