File indexing completed on 2024-05-05 04:50:33
0001 /* 0002 SPDX-FileCopyrightText: 2020 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 0004 SPDX-License-Identifier: LGPL-3.0-or-later 0005 */ 0006 0007 #include "editabletrackmetadatamodel.h" 0008 0009 #include <KLocalizedString> 0010 0011 0012 EditableTrackMetadataModel::EditableTrackMetadataModel(QObject *parent) 0013 : TrackMetadataModel(parent) 0014 { 0015 } 0016 0017 QVariant EditableTrackMetadataModel::data(const QModelIndex &index, int role) const 0018 { 0019 auto result = QVariant{}; 0020 0021 const auto currentKey = trackKey(index.row()); 0022 0023 switch (role) 0024 { 0025 case ReadOnlyRole: 0026 switch (currentKey) 0027 { 0028 case DataTypes::TitleRole: 0029 result = false; 0030 break; 0031 case DataTypes::ResourceRole: 0032 switch (allTrackData().elementType()) 0033 { 0034 case ElisaUtils::Track: 0035 result = true; 0036 break; 0037 case ElisaUtils::Radio: 0038 result = false; 0039 break; 0040 case ElisaUtils::PlayList: 0041 result = false; 0042 break; 0043 case ElisaUtils::Album: 0044 case ElisaUtils::Artist: 0045 case ElisaUtils::Composer: 0046 case ElisaUtils::Container: 0047 case ElisaUtils::FileName: 0048 case ElisaUtils::Genre: 0049 case ElisaUtils::Lyricist: 0050 case ElisaUtils::Unknown: 0051 result = true; 0052 break; 0053 } 0054 break; 0055 case DataTypes::ImageUrlRole: 0056 case DataTypes::ArtistRole: 0057 case DataTypes::AlbumRole: 0058 case DataTypes::AlbumArtistRole: 0059 case DataTypes::TrackNumberRole: 0060 case DataTypes::DiscNumberRole: 0061 case DataTypes::RatingRole: 0062 case DataTypes::GenreRole: 0063 case DataTypes::LyricistRole: 0064 case DataTypes::ComposerRole: 0065 case DataTypes::CommentRole: 0066 case DataTypes::YearRole: 0067 case DataTypes::LyricsRole: 0068 result = false; 0069 break; 0070 case DataTypes::LastPlayDate: 0071 case DataTypes::PlayCounter: 0072 case DataTypes::DurationRole: 0073 case DataTypes::SampleRateRole: 0074 case DataTypes::BitRateRole: 0075 case DataTypes::ChannelsRole: 0076 case DataTypes::FirstPlayDate: 0077 result = true; 0078 break; 0079 case DataTypes::SecondaryTextRole: 0080 case DataTypes::ShadowForImageRole: 0081 case DataTypes::ChildModelRole: 0082 case DataTypes::StringDurationRole: 0083 case DataTypes::IsValidAlbumArtistRole: 0084 case DataTypes::AllArtistsRole: 0085 case DataTypes::HighestTrackRating: 0086 case DataTypes::IdRole: 0087 case DataTypes::ParentIdRole: 0088 case DataTypes::DatabaseIdRole: 0089 case DataTypes::IsSingleDiscAlbumRole: 0090 case DataTypes::ContainerDataRole: 0091 case DataTypes::IsPartialDataRole: 0092 case DataTypes::AlbumIdRole: 0093 case DataTypes::HasEmbeddedCover: 0094 case DataTypes::FileModificationTime: 0095 case DataTypes::ElementTypeRole: 0096 case DataTypes::FullDataRole: 0097 case DataTypes::IsDirectoryRole: 0098 case DataTypes::IsPlayListRole: 0099 case DataTypes::FilePathRole: 0100 case DataTypes::HasChildrenRole: 0101 case DataTypes::MultipleImageUrlsRole: 0102 break; 0103 } 0104 break; 0105 case RemovableFieldRole: 0106 switch (allTrackData().elementType()) 0107 { 0108 case ElisaUtils::Track: 0109 switch (currentKey) 0110 { 0111 case DataTypes::TitleRole: 0112 case DataTypes::BitRateRole: 0113 case DataTypes::ChannelsRole: 0114 case DataTypes::ArtistRole: 0115 case DataTypes::AlbumRole: 0116 case DataTypes::AlbumArtistRole: 0117 case DataTypes::TrackNumberRole: 0118 case DataTypes::DiscNumberRole: 0119 case DataTypes::RatingRole: 0120 case DataTypes::GenreRole: 0121 case DataTypes::LyricistRole: 0122 case DataTypes::ComposerRole: 0123 case DataTypes::CommentRole: 0124 case DataTypes::YearRole: 0125 case DataTypes::LyricsRole: 0126 case DataTypes::SampleRateRole: 0127 result = true; 0128 break; 0129 case DataTypes::LastPlayDate: 0130 case DataTypes::PlayCounter: 0131 case DataTypes::ImageUrlRole: 0132 case DataTypes::DurationRole: 0133 case DataTypes::SecondaryTextRole: 0134 case DataTypes::ShadowForImageRole: 0135 case DataTypes::ChildModelRole: 0136 case DataTypes::StringDurationRole: 0137 case DataTypes::IsValidAlbumArtistRole: 0138 case DataTypes::AllArtistsRole: 0139 case DataTypes::HighestTrackRating: 0140 case DataTypes::IdRole: 0141 case DataTypes::ParentIdRole: 0142 case DataTypes::DatabaseIdRole: 0143 case DataTypes::IsSingleDiscAlbumRole: 0144 case DataTypes::ContainerDataRole: 0145 case DataTypes::IsPartialDataRole: 0146 case DataTypes::AlbumIdRole: 0147 case DataTypes::HasEmbeddedCover: 0148 case DataTypes::FileModificationTime: 0149 case DataTypes::FirstPlayDate: 0150 case DataTypes::ElementTypeRole: 0151 case DataTypes::FullDataRole: 0152 case DataTypes::IsDirectoryRole: 0153 case DataTypes::IsPlayListRole: 0154 case DataTypes::FilePathRole: 0155 case DataTypes::ResourceRole: 0156 case DataTypes::HasChildrenRole: 0157 case DataTypes::MultipleImageUrlsRole: 0158 result = false; 0159 break; 0160 } 0161 break; 0162 case ElisaUtils::Radio: 0163 case ElisaUtils::Album: 0164 case ElisaUtils::Artist: 0165 case ElisaUtils::Composer: 0166 case ElisaUtils::Container: 0167 case ElisaUtils::FileName: 0168 case ElisaUtils::Genre: 0169 case ElisaUtils::Lyricist: 0170 case ElisaUtils::Unknown: 0171 case ElisaUtils::PlayList: 0172 result = false; 0173 break; 0174 } 0175 break; 0176 default: 0177 result = TrackMetadataModel::data(index, role); 0178 } 0179 0180 return result; 0181 } 0182 0183 QHash<int, QByteArray> EditableTrackMetadataModel::roleNames() const 0184 { 0185 auto names = TrackMetadataModel::roleNames(); 0186 0187 names[EditableColumnRoles::ReadOnlyRole] = "isReadOnly"; 0188 names[EditableColumnRoles::RemovableFieldRole] = "isRemovable"; 0189 0190 return names; 0191 } 0192 0193 bool EditableTrackMetadataModel::setData(const QModelIndex &index, const QVariant &value, int role) 0194 { 0195 auto result = TrackMetadataModel::setData(index, value, role); 0196 0197 if (result) { 0198 modelHasBeenModified(); 0199 validData(); 0200 } 0201 0202 return result; 0203 } 0204 0205 void EditableTrackMetadataModel::saveData() 0206 { 0207 saveChanges(); 0208 mIsNewRadio = false; 0209 mIsDirty = false; 0210 Q_EMIT isDirtyChanged(); 0211 0212 auto newTrackData = allTrackData(); 0213 0214 newTrackData[DataTypes::ResourceRole] = QUrl::fromUserInput(newTrackData[DataTypes::ResourceRole].toString()); 0215 0216 QString imageUrl = dataFromType(DataTypes::ImageUrlRole).toString(); 0217 if (!imageUrl.isEmpty() 0218 && !imageUrl.startsWith(QStringLiteral("http://")) 0219 && !imageUrl.startsWith(QStringLiteral("https://")) 0220 && !imageUrl.startsWith(QStringLiteral("file://"))) { 0221 newTrackData[DataTypes::ImageUrlRole] = QUrl::fromUserInput(QStringLiteral("file:/").append(imageUrl)); 0222 } 0223 0224 Q_EMIT saveTrackModified({newTrackData}, {}); 0225 } 0226 0227 void EditableTrackMetadataModel::resetData() 0228 { 0229 undoChanges(); 0230 mIsDirty = false; 0231 Q_EMIT isDirtyChanged(); 0232 } 0233 0234 void EditableTrackMetadataModel::deleteRadio() 0235 { 0236 auto &track = displayedTrackData(); 0237 if (track[DataTypes::DatabaseIdRole].toULongLong()) { 0238 Q_EMIT deleteRadioData(track[DataTypes::DatabaseIdRole].toULongLong()); 0239 } 0240 } 0241 0242 void EditableTrackMetadataModel::removeData(int index) 0243 { 0244 beginRemoveRows({}, index, index); 0245 removeDataByIndex(index); 0246 endRemoveRows(); 0247 0248 modelHasBeenModified(); 0249 0250 validData(); 0251 0252 updateExtraMetadata(); 0253 } 0254 0255 void EditableTrackMetadataModel::addData(const QString &name) 0256 { 0257 beginInsertRows({}, rowCount(), rowCount()); 0258 addDataByName(name); 0259 endInsertRows(); 0260 0261 modelHasBeenModified(); 0262 validData(); 0263 0264 updateExtraMetadata(); 0265 } 0266 0267 void EditableTrackMetadataModel::fillDataFromTrackData(const TrackMetadataModel::TrackDataType &trackData) 0268 { 0269 if (mIsNewRadio) { 0270 return; 0271 } 0272 0273 TrackMetadataModel::fillDataFromTrackData(trackData); 0274 0275 updateExtraMetadata(); 0276 } 0277 0278 void EditableTrackMetadataModel::filterDataFromTrackData() 0279 { 0280 TrackMetadataModel::filterDataFromTrackData(); 0281 validData(); 0282 } 0283 0284 void EditableTrackMetadataModel::fillLyricsDataFromTrack() 0285 { 0286 TrackMetadataModel::fillLyricsDataFromTrack(); 0287 validData(); 0288 0289 updateExtraMetadata(); 0290 } 0291 0292 void EditableTrackMetadataModel::fillDataForNewRadio() 0293 { 0294 mIsNewRadio = true; 0295 TrackMetadataModel::fillDataForNewRadio(); 0296 } 0297 0298 void EditableTrackMetadataModel::initialize(MusicListenersManager *newManager, DatabaseInterface *trackDatabase) 0299 { 0300 TrackMetadataModel::initialize(newManager, trackDatabase); 0301 0302 connect(this, &EditableTrackMetadataModel::saveTrackModified, 0303 &modelDataLoader(), &ModelDataLoader::trackHasBeenModified); 0304 connect(this, &EditableTrackMetadataModel::deleteRadioData, 0305 &modelDataLoader(), &ModelDataLoader::removeRadio); 0306 } 0307 0308 void EditableTrackMetadataModel::validData() 0309 { 0310 bool newValidState = true; 0311 0312 const auto &resourceData = dataFromType(TrackDataType::key_type::ResourceRole); 0313 if (resourceData.canConvert<QUrl>()) { 0314 const auto resourceUrl = resourceData.toUrl(); 0315 0316 newValidState = !resourceUrl.scheme().isEmpty() && resourceUrl.isValid() && !resourceUrl.isRelative(); 0317 } else { 0318 newValidState = false; 0319 } 0320 0321 if (!newValidState) { 0322 mErrorMessage = i18nc("@info:status Error message when track URL is invalid", "Invalid URL."); 0323 Q_EMIT errorMessageChanged(); 0324 } 0325 0326 if (newValidState) { 0327 const auto &titleData = dataFromType(TrackDataType::key_type::TitleRole); 0328 0329 newValidState = newValidState && !titleData.toString().isEmpty(); 0330 0331 if (!newValidState) { 0332 mErrorMessage = i18nc("@info:status Error message when track title is empty", "Empty title."); 0333 Q_EMIT errorMessageChanged(); 0334 } 0335 } 0336 0337 if (mIsDataValid != newValidState) { 0338 mIsDataValid = newValidState; 0339 0340 Q_EMIT isDataValidChanged(); 0341 } 0342 } 0343 0344 void EditableTrackMetadataModel::updateExtraMetadata() 0345 { 0346 mExtraMetadata.clear(); 0347 for(auto metadataRole : {DataTypes::TitleRole, DataTypes::ArtistRole, 0348 DataTypes::AlbumRole, DataTypes::AlbumArtistRole, DataTypes::TrackNumberRole, 0349 DataTypes::DiscNumberRole, DataTypes::RatingRole, DataTypes::GenreRole, 0350 DataTypes::LyricistRole, DataTypes::ComposerRole, DataTypes::CommentRole, 0351 DataTypes::YearRole, DataTypes::ChannelsRole, DataTypes::BitRateRole, 0352 DataTypes::SampleRateRole, DataTypes::LyricsRole}) { 0353 if (!metadataExists(metadataRole)) { 0354 mExtraMetadata.push_back(nameFromRole(metadataRole)); 0355 } 0356 } 0357 0358 Q_EMIT extraMetadataChanged(); 0359 } 0360 0361 void EditableTrackMetadataModel::modelHasBeenModified() 0362 { 0363 if (!mIsDirty) { 0364 mIsDirty = true; 0365 Q_EMIT isDirtyChanged(); 0366 } 0367 } 0368 0369 0370 #include "moc_editabletrackmetadatamodel.cpp"