Changeset View
Changeset View
Standalone View
Standalone View
src/dialogs/TagDialog.cpp
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Line(s) | |||||
44 | #include "TagGuesserDialog.h" | 44 | #include "TagGuesserDialog.h" | ||
45 | 45 | | |||
46 | #include <QLineEdit> | 46 | #include <QLineEdit> | ||
47 | #include <QMenu> | 47 | #include <QMenu> | ||
48 | #include <QTimer> | 48 | #include <QTimer> | ||
49 | 49 | | |||
50 | #include <KRun> | 50 | #include <KRun> | ||
51 | 51 | | |||
52 | #include <thread> | ||||
53 | | ||||
54 | | ||||
52 | namespace Meta { | 55 | namespace Meta { | ||
53 | namespace Field { | 56 | namespace Field { | ||
54 | const QString LABELS = "labels"; | 57 | const QString LABELS = "labels"; | ||
55 | const QString LYRICS = "lyrics"; | 58 | const QString LYRICS = "lyrics"; | ||
56 | const QString TYPE = "type"; | 59 | const QString TYPE = "type"; | ||
57 | const QString COLLECTION = "collection"; | 60 | const QString COLLECTION = "collection"; | ||
58 | const QString NOTE = "note"; | 61 | const QString NOTE = "note"; | ||
59 | } | 62 | } | ||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Line(s) | |||||
122 | } | 125 | } | ||
123 | 126 | | |||
124 | TagDialog::~TagDialog() | 127 | TagDialog::~TagDialog() | ||
125 | { | 128 | { | ||
126 | DEBUG_BLOCK | 129 | DEBUG_BLOCK | ||
127 | 130 | | |||
128 | Amarok::config( "TagDialog" ).writeEntry( "CurrentTab", ui->qTabWidget->currentIndex() ); | 131 | Amarok::config( "TagDialog" ).writeEntry( "CurrentTab", ui->qTabWidget->currentIndex() ); | ||
129 | 132 | | |||
130 | if( m_currentTrack && m_currentTrack->album() ) | 133 | if( m_currentAlbum ) | ||
131 | unsubscribeFrom( m_currentTrack->album() ); | 134 | unsubscribeFrom( m_currentAlbum ); | ||
132 | 135 | | |||
133 | delete ui; | 136 | delete ui; | ||
134 | } | 137 | } | ||
135 | 138 | | |||
136 | void | 139 | void | ||
137 | TagDialog::metadataChanged( Meta::AlbumPtr album ) | 140 | TagDialog::metadataChanged( Meta::AlbumPtr album ) | ||
138 | { | 141 | { | ||
139 | if( !m_currentTrack || !m_currentTrack->album() ) | 142 | if( m_currentAlbum ) | ||
140 | return; | 143 | return; | ||
141 | 144 | | |||
142 | // If the metadata of the current album has changed, reload the cover | 145 | // If the metadata of the current album has changed, reload the cover | ||
143 | if( album == m_currentTrack->album() ) | 146 | if( album == m_currentAlbum ) | ||
144 | updateCover(); | 147 | updateCover(); | ||
145 | 148 | | |||
146 | // TODO: if the lyrics changed: should we show a warning and ask the user | 149 | // TODO: if the lyrics changed: should we show a warning and ask the user | ||
147 | // if he wants to use the new lyrics? | 150 | // if he wants to use the new lyrics? | ||
148 | } | 151 | } | ||
149 | 152 | | |||
150 | 153 | | |||
151 | //////////////////////////////////////////////////////////////////////////////// | 154 | //////////////////////////////////////////////////////////////////////////////// | ||
▲ Show 20 Lines • Show All 450 Lines • ▼ Show 20 Line(s) | 604 | if( num < 0 || num >= m_tracks.count() ) | |||
602 | return; | 605 | return; | ||
603 | 606 | | |||
604 | if( m_currentTrack ) // even in multiple tracks mode we don't want to write back | 607 | if( m_currentTrack ) // even in multiple tracks mode we don't want to write back | ||
605 | setTagsToTrack(); | 608 | setTagsToTrack(); | ||
606 | 609 | | |||
607 | // there is a logical problem here. | 610 | // there is a logical problem here. | ||
608 | // if the track itself changes (e.g. because it get's a new album) | 611 | // if the track itself changes (e.g. because it get's a new album) | ||
609 | // then we don't re-subscribe | 612 | // then we don't re-subscribe | ||
610 | if( m_currentTrack && m_currentTrack->album() ) | 613 | if( m_currentAlbum ) | ||
611 | unsubscribeFrom( m_currentTrack->album() ); | 614 | unsubscribeFrom( m_currentAlbum ); | ||
612 | 615 | | |||
613 | m_currentTrack = m_tracks.at( num ); | 616 | m_currentTrack = m_tracks.at( num ); | ||
617 | m_currentAlbum = m_currentTrack->album(); | ||||
614 | m_currentTrackNum = num; | 618 | m_currentTrackNum = num; | ||
615 | 619 | | |||
616 | if( m_currentTrack && m_currentTrack->album() ) | 620 | if( m_currentAlbum ) | ||
617 | subscribeTo( m_currentTrack->album() ); | 621 | subscribeTo( m_currentAlbum ); | ||
618 | 622 | | |||
619 | setControlsAccessability(); | 623 | setControlsAccessability(); | ||
620 | updateButtons(); | 624 | updateButtons(); | ||
621 | setTagsToUi(); | 625 | setTagsToUi(); | ||
622 | } | 626 | } | ||
623 | 627 | | |||
624 | void | 628 | void | ||
625 | TagDialog::startDataQuery( Collections::QueryMaker::QueryType type, const QMetaMethod &signal, | 629 | TagDialog::startDataQuery( Collections::QueryMaker::QueryType type, const QMetaMethod &signal, | ||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 673 | { | |||
670 | return ( i == 0 ) | 674 | return ( i == 0 ) | ||
671 | ? i18nc( "The value for this tag is not known", "Unknown" ) | 675 | ? i18nc( "The value for this tag is not known", "Unknown" ) | ||
672 | : QString::number( i ); | 676 | : QString::number( i ); | ||
673 | } | 677 | } | ||
674 | 678 | | |||
675 | void | 679 | void | ||
676 | TagDialog::showCoverMenu( const QPoint &pos ) | 680 | TagDialog::showCoverMenu( const QPoint &pos ) | ||
677 | { | 681 | { | ||
678 | Meta::AlbumPtr album = m_currentTrack->album(); | 682 | if( !m_currentAlbum ) | ||
679 | if( !album ) | | |||
680 | return; // TODO: warning or something? | 683 | return; // TODO: warning or something? | ||
681 | 684 | | |||
682 | QAction *displayCoverAction = new DisplayCoverAction( this, album ); | 685 | QAction *displayCoverAction = new DisplayCoverAction( this, m_currentAlbum ); | ||
683 | QAction *unsetCoverAction = new UnsetCoverAction( this, album ); | 686 | QAction *unsetCoverAction = new UnsetCoverAction( this, m_currentAlbum ); | ||
684 | 687 | | |||
685 | if( !album->hasImage() ) | 688 | if( !m_currentAlbum->hasImage() ) | ||
686 | { | 689 | { | ||
687 | displayCoverAction->setEnabled( false ); | 690 | displayCoverAction->setEnabled( false ); | ||
688 | unsetCoverAction->setEnabled( false ); | 691 | unsetCoverAction->setEnabled( false ); | ||
689 | } | 692 | } | ||
690 | 693 | | |||
691 | QMenu *menu = new QMenu( this ); | 694 | QMenu *menu = new QMenu( this ); | ||
692 | menu->addAction( displayCoverAction ); | 695 | menu->addAction( displayCoverAction ); | ||
693 | menu->addAction( new FetchCoverAction( this, album ) ); | 696 | menu->addAction( new FetchCoverAction( this, m_currentAlbum ) ); | ||
694 | menu->addAction( new SetCustomCoverAction( this, album ) ); | 697 | menu->addAction( new SetCustomCoverAction( this, m_currentAlbum ) ); | ||
695 | menu->addAction( unsetCoverAction ); | 698 | menu->addAction( unsetCoverAction ); | ||
696 | 699 | | |||
697 | menu->exec( ui->pixmap_cover->mapToGlobal(pos) ); | 700 | menu->exec( ui->pixmap_cover->mapToGlobal(pos) ); | ||
698 | } | 701 | } | ||
699 | 702 | | |||
700 | void | 703 | void | ||
701 | TagDialog::setTagsToUi( const QVariantMap &tags ) | 704 | TagDialog::setTagsToUi( const QVariantMap &tags ) | ||
702 | { | 705 | { | ||
Show All 21 Lines | 724 | { | |||
724 | const QFontMetrics fnt = ui->trackArtistAlbumLabel->fontMetrics(); | 727 | const QFontMetrics fnt = ui->trackArtistAlbumLabel->fontMetrics(); | ||
725 | const int len = ui->trackArtistAlbumLabel->width(); | 728 | const int len = ui->trackArtistAlbumLabel->width(); | ||
726 | QString curTrackAlbName; | 729 | QString curTrackAlbName; | ||
727 | QString curArtistName; | 730 | QString curArtistName; | ||
728 | 731 | | |||
729 | QString curTrackName = fnt.elidedText( m_currentTrack->name().toHtmlEscaped(), Qt::ElideRight, len ); | 732 | QString curTrackName = fnt.elidedText( m_currentTrack->name().toHtmlEscaped(), Qt::ElideRight, len ); | ||
730 | QString curTrackPretName = fnt.elidedText( m_currentTrack->prettyName().toHtmlEscaped(), Qt::ElideRight, len ); | 733 | QString curTrackPretName = fnt.elidedText( m_currentTrack->prettyName().toHtmlEscaped(), Qt::ElideRight, len ); | ||
731 | 734 | | |||
732 | if( m_currentTrack->album() ) | 735 | if( m_currentAlbum ) | ||
733 | curTrackAlbName = fnt.elidedText( m_currentTrack->album()->name().toHtmlEscaped(), Qt::ElideRight, len ); | 736 | curTrackAlbName = fnt.elidedText( m_currentAlbum->name().toHtmlEscaped(), Qt::ElideRight, len ); | ||
734 | if( m_currentTrack->artist() ) | 737 | if( m_currentTrack->artist() ) | ||
735 | curArtistName = fnt.elidedText( m_currentTrack->artist()->name().toHtmlEscaped(), Qt::ElideRight, len ); | 738 | curArtistName = fnt.elidedText( m_currentTrack->artist()->name().toHtmlEscaped(), Qt::ElideRight, len ); | ||
736 | 739 | | |||
737 | 740 | | |||
738 | if( m_currentTrack->album() && m_currentTrack->album()->name().isEmpty() ) | 741 | if( m_currentAlbum && m_currentAlbum->name().isEmpty() ) | ||
739 | { | 742 | { | ||
740 | if( !m_currentTrack->name().isEmpty() ) | 743 | if( !m_currentTrack->name().isEmpty() ) | ||
741 | { | 744 | { | ||
742 | if( !m_currentTrack->artist()->name().isEmpty() ) | 745 | if( !m_currentTrack->artist()->name().isEmpty() ) | ||
743 | niceTitle = i18n( "<b>%1</b> by <b>%2</b>", curTrackName, curArtistName ); | 746 | niceTitle = i18n( "<b>%1</b> by <b>%2</b>", curTrackName, curArtistName ); | ||
744 | else | 747 | else | ||
745 | niceTitle = i18n( "<b>%1</b>", curTrackName ); | 748 | niceTitle = i18n( "<b>%1</b>", curTrackName ); | ||
746 | } | 749 | } | ||
747 | else | 750 | else | ||
748 | niceTitle = curTrackPretName; | 751 | niceTitle = curTrackPretName; | ||
749 | } | 752 | } | ||
750 | else if( m_currentTrack->album() ) | 753 | else if( m_currentAlbum ) | ||
751 | niceTitle = i18n( "<b>%1</b> by <b>%2</b> on <b>%3</b>" , curTrackName, curArtistName, curTrackAlbName ); | 754 | niceTitle = i18n( "<b>%1</b> by <b>%2</b> on <b>%3</b>" , curTrackName, curArtistName, curTrackAlbName ); | ||
752 | else if( m_currentTrack->artist() ) | 755 | else if( m_currentTrack->artist() ) | ||
753 | niceTitle = i18n( "<b>%1</b> by <b>%2</b>" , curTrackName, curArtistName ); | 756 | niceTitle = i18n( "<b>%1</b> by <b>%2</b>" , curTrackName, curArtistName ); | ||
754 | else | 757 | else | ||
755 | niceTitle = i18n( "<b>%1</b>" , curTrackName ); | 758 | niceTitle = i18n( "<b>%1</b>" , curTrackName ); | ||
756 | 759 | | |||
757 | ui->trackArtistAlbumLabel->setText( niceTitle ); | 760 | ui->trackArtistAlbumLabel->setText( niceTitle ); | ||
758 | } | 761 | } | ||
▲ Show 20 Lines • Show All 453 Lines • ▼ Show 20 Line(s) | |||||
1212 | TagDialog::updateCover() | 1215 | TagDialog::updateCover() | ||
1213 | { | 1216 | { | ||
1214 | DEBUG_BLOCK | 1217 | DEBUG_BLOCK | ||
1215 | 1218 | | |||
1216 | if( !m_currentTrack ) | 1219 | if( !m_currentTrack ) | ||
1217 | return; | 1220 | return; | ||
1218 | 1221 | | |||
1219 | // -- get the album | 1222 | // -- get the album | ||
1220 | Meta::AlbumPtr album = m_currentTrack->album(); | 1223 | Meta::AlbumPtr album = m_currentAlbum; | ||
1221 | if( !m_perTrack ) | 1224 | if( !m_perTrack ) | ||
1222 | { | 1225 | { | ||
1223 | foreach( Meta::TrackPtr track, m_tracks ) | 1226 | foreach( Meta::TrackPtr track, m_tracks ) | ||
1224 | { | 1227 | { | ||
1225 | if( track->album() != album ) | 1228 | if( track->album() != album ) | ||
1226 | album = 0; | 1229 | album = nullptr; | ||
1227 | } | 1230 | } | ||
1228 | } | 1231 | } | ||
1229 | 1232 | | |||
1230 | // -- set the ui | 1233 | // -- set the ui | ||
1231 | const int s = 100; // Image preview size | 1234 | const int s = 100; // Image preview size | ||
1232 | ui->pixmap_cover->setMinimumSize( s, s ); | 1235 | ui->pixmap_cover->setMinimumSize( s, s ); | ||
1233 | ui->pixmap_cover->setMaximumSize( s, s ); | 1236 | ui->pixmap_cover->setMaximumSize( s, s ); | ||
1234 | 1237 | | |||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | 1273 | #undef enableOrDisable | |||
1276 | ui->kLineEdit_Bpm->setClearButtonEnabled( editable ); | 1279 | ui->kLineEdit_Bpm->setClearButtonEnabled( editable ); | ||
1277 | 1280 | | |||
1278 | ui->qPlainTextEdit_comment->setEnabled( editable ); | 1281 | ui->qPlainTextEdit_comment->setEnabled( editable ); | ||
1279 | ui->pushButton_guessTags->setEnabled( m_perTrack && editable ); | 1282 | ui->pushButton_guessTags->setEnabled( m_perTrack && editable ); | ||
1280 | ui->pushButton_musicbrainz->setEnabled( editable ); | 1283 | ui->pushButton_musicbrainz->setEnabled( editable ); | ||
1281 | } | 1284 | } | ||
1282 | 1285 | | |||
1283 | void | 1286 | void | ||
1284 | TagDialog::saveLabels( Meta::TrackPtr track, const QStringList &labels ) | | |||
1285 | { | | |||
1286 | if( !track ) | | |||
1287 | return; | | |||
1288 | | ||||
1289 | QHash<QString, Meta::LabelPtr> labelMap; | | |||
1290 | foreach( const Meta::LabelPtr &label, track->labels() ) | | |||
1291 | { | | |||
1292 | labelMap.insert( label->name(), label ); | | |||
1293 | } | | |||
1294 | | ||||
1295 | // labels to remove | | |||
1296 | foreach( const QString &label, labelMap.keys().toSet() - labels.toSet() ) | | |||
1297 | { | | |||
1298 | track->removeLabel( labelMap.value( label ) ); | | |||
1299 | } | | |||
1300 | | ||||
1301 | // labels to add | | |||
1302 | foreach( const QString &label, labels.toSet() - labelMap.keys().toSet() ) | | |||
1303 | { | | |||
1304 | track->addLabel( label ); | | |||
1305 | } | | |||
1306 | } | | |||
1307 | | ||||
1308 | | ||||
1309 | void | | |||
1310 | TagDialog::saveTags() | 1287 | TagDialog::saveTags() | ||
1311 | { | 1288 | { | ||
1312 | setTagsToTrack(); | 1289 | setTagsToTrack(); | ||
1313 | 1290 | | |||
1314 | foreach( Meta::TrackPtr track, m_tracks ) | 1291 | for( auto &track : m_tracks ) | ||
1315 | { | 1292 | { | ||
1316 | QVariantMap data = m_storedTags[ track ]; | 1293 | QVariantMap data = m_storedTags[ track ]; | ||
1317 | //there is really no need to write to the file if only info m_stored in the db has changed | 1294 | //there is really no need to write to the file if only info m_stored in the db has changed | ||
1318 | if( !data.isEmpty() ) | 1295 | if( !data.isEmpty() ) | ||
1319 | { | 1296 | { | ||
1320 | debug() << "File info changed...."; | 1297 | debug() << "File info changed...."; | ||
1321 | 1298 | | |||
1299 | auto lambda = [=] () mutable | ||||
1300 | { | ||||
1322 | if( data.contains( Meta::Field::SCORE ) ) | 1301 | if( data.contains( Meta::Field::SCORE ) ) | ||
1323 | track->statistics()->setScore( data.value( Meta::Field::SCORE ).toInt() ); | 1302 | track->statistics()->setScore( data.value( Meta::Field::SCORE ).toInt() ); | ||
1324 | if( data.contains( Meta::Field::RATING ) ) | 1303 | if( data.contains( Meta::Field::RATING ) ) | ||
1325 | track->statistics()->setRating( data.value( Meta::Field::RATING ).toInt() ); | 1304 | track->statistics()->setRating( data.value( Meta::Field::RATING ).toInt() ); | ||
1326 | if( data.contains( Meta::Field::LYRICS ) ) | 1305 | if( data.contains( Meta::Field::LYRICS ) ) | ||
1327 | { | | |||
1328 | track->setCachedLyrics( data.value( Meta::Field::LYRICS ).toString() ); | 1306 | track->setCachedLyrics( data.value( Meta::Field::LYRICS ).toString() ); | ||
1329 | emit lyricsChanged( track->uidUrl() ); | | |||
1330 | } | | |||
1331 | 1307 | | |||
1332 | saveLabels( track, data.value( Meta::Field::LABELS ).toStringList() ); | 1308 | QStringList labels = data.value( Meta::Field::LABELS ).toStringList(); | ||
1309 | QHash<QString, Meta::LabelPtr> labelMap; | ||||
1310 | for( const auto &label : track->labels() ) | ||||
1311 | labelMap.insert( label->name(), label ); | ||||
1312 | | ||||
1313 | // labels to remove | ||||
1314 | for( const auto &label : labelMap.keys().toSet() - labels.toSet() ) | ||||
1315 | track->removeLabel( labelMap.value( label ) ); | ||||
1316 | | ||||
1317 | // labels to add | ||||
1318 | for( const auto &label : labels.toSet() - labelMap.keys().toSet() ) | ||||
1319 | track->addLabel( label ); | ||||
1333 | 1320 | | |||
1334 | Meta::TrackEditorPtr ec = track->editor(); | 1321 | Meta::TrackEditorPtr ec = track->editor(); | ||
1335 | if( !ec ) | 1322 | if( !ec ) | ||
1336 | { | 1323 | { | ||
1337 | debug() << "Track" << track->prettyUrl() << "does not have Meta::TrackEditor. Skipping."; | 1324 | debug() << "Track" << track->prettyUrl() << "does not have Meta::TrackEditor. Skipping."; | ||
1338 | continue; | 1325 | return; | ||
1339 | } | 1326 | } | ||
1340 | 1327 | | |||
1341 | ec->beginUpdate(); | 1328 | ec->beginUpdate(); | ||
1329 | | ||||
1342 | if( data.contains( Meta::Field::TITLE ) ) | 1330 | if( data.contains( Meta::Field::TITLE ) ) | ||
1343 | ec->setTitle( data.value( Meta::Field::TITLE ).toString() ); | 1331 | ec->setTitle( data.value( Meta::Field::TITLE ).toString() ); | ||
1344 | if( data.contains( Meta::Field::COMMENT ) ) | 1332 | if( data.contains( Meta::Field::COMMENT ) ) | ||
1345 | ec->setComment( data.value( Meta::Field::COMMENT ).toString() ); | 1333 | ec->setComment( data.value( Meta::Field::COMMENT ).toString() ); | ||
1346 | if( data.contains( Meta::Field::ARTIST ) ) | 1334 | if( data.contains( Meta::Field::ARTIST ) ) | ||
1347 | ec->setArtist( data.value( Meta::Field::ARTIST ).toString() ); | 1335 | ec->setArtist( data.value( Meta::Field::ARTIST ).toString() ); | ||
1348 | if( data.contains( Meta::Field::ALBUM ) ) | 1336 | if( data.contains( Meta::Field::ALBUM ) ) | ||
1349 | ec->setAlbum( data.value( Meta::Field::ALBUM ).toString() ); | 1337 | ec->setAlbum( data.value( Meta::Field::ALBUM ).toString() ); | ||
Show All 9 Lines | 1346 | if( data.contains( Meta::Field::DISCNUMBER ) ) | |||
1359 | ec->setDiscNumber( data.value( Meta::Field::DISCNUMBER ).toInt() ); | 1347 | ec->setDiscNumber( data.value( Meta::Field::DISCNUMBER ).toInt() ); | ||
1360 | if( data.contains( Meta::Field::BPM ) ) | 1348 | if( data.contains( Meta::Field::BPM ) ) | ||
1361 | ec->setBpm( data.value( Meta::Field::BPM ).toDouble() ); | 1349 | ec->setBpm( data.value( Meta::Field::BPM ).toDouble() ); | ||
1362 | if( data.contains( Meta::Field::ALBUMARTIST ) ) | 1350 | if( data.contains( Meta::Field::ALBUMARTIST ) ) | ||
1363 | ec->setAlbumArtist( data.value( Meta::Field::ALBUMARTIST ).toString() ); | 1351 | ec->setAlbumArtist( data.value( Meta::Field::ALBUMARTIST ).toString() ); | ||
1364 | 1352 | | |||
1365 | ec->endUpdate(); | 1353 | ec->endUpdate(); | ||
1366 | // note: the track should by itself emit a collectionUpdated signal if needed | 1354 | // note: the track should by itself emit a collectionUpdated signal if needed | ||
1355 | }; | ||||
1356 | std::thread thread( lambda ); | ||||
1357 | thread.detach(); | ||||
1367 | } | 1358 | } | ||
1368 | } | 1359 | } | ||
1369 | } | 1360 | } | ||
1370 | 1361 | | |||
1371 | void | 1362 | void | ||
1372 | TagDialog::selectOrInsertText( const QString &text, QComboBox *comboBox ) | 1363 | TagDialog::selectOrInsertText( const QString &text, QComboBox *comboBox ) | ||
1373 | { | 1364 | { | ||
1374 | int index = comboBox->findText( text ); | 1365 | int index = comboBox->findText( text ); | ||
Show All 40 Lines |