diff --git a/autotests/filescannertest.cpp b/autotests/filescannertest.cpp index df4aabfa..4965c14c 100644 --- a/autotests/filescannertest.cpp +++ b/autotests/filescannertest.cpp @@ -1,144 +1,144 @@ /* * Copyright 2018 Alexander Stippich * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "musicaudiotrack.h" #include "filescanner.h" #include "config-upnp-qt.h" #include #include #include #include #include #include #include #include class FileScannerTest: public QObject { Q_OBJECT public: QString createTrackUrl(QString subpath) { return QStringLiteral(LOCAL_FILE_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/cover_art") + subpath; } QList mTestTracksForDirectory = { createTrackUrl(QStringLiteral("/artist1/album1/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist1/album2/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist1/album3/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist2/album1/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist2/album2/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist2/album3/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist3/album1/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist3/album2/not_existing.ogg")), createTrackUrl(QStringLiteral("/artist3/album3/not_existing.ogg")), }; QList mTestTracksForMetaData = { createTrackUrl(QStringLiteral("/artist4/test.ogg")), createTrackUrl(QStringLiteral("/artist4/test.flac")), createTrackUrl(QStringLiteral("/artist4/test.mp3")), }; private Q_SLOTS: void initTestCase() { } void testFileMetaDataScan() { QMimeDatabase mimeDb; FileScanner fileScanner; auto scannedTrack = fileScanner.scanOneFile(QUrl::fromLocalFile(QStringLiteral(LOCAL_FILE_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/music/test.ogg")), mimeDb); QCOMPARE(scannedTrack.title(), QStringLiteral("Title")); QCOMPARE(scannedTrack.genre(), QStringLiteral("Genre")); - QCOMPARE(scannedTrack.albumName(), QStringLiteral("Test")); + QCOMPARE(scannedTrack.album(), QStringLiteral("Test")); QCOMPARE(scannedTrack.artist(), QStringLiteral("Artist")); } void testFindCoverInDirectory() { FileScanner fileScanner; QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(0)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(1)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(2)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(3)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(4)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(5)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(6)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(7)).isEmpty()); QVERIFY(!fileScanner.searchForCoverFile(mTestTracksForDirectory.at(8)).isEmpty()); } void loadCoverFromMetaData() { FileScanner fileScanner; QVERIFY(fileScanner.checkEmbeddedCoverImage(mTestTracksForMetaData.at(0))); QVERIFY(fileScanner.checkEmbeddedCoverImage(mTestTracksForMetaData.at(1))); QVERIFY(fileScanner.checkEmbeddedCoverImage(mTestTracksForMetaData.at(2))); } void benchmarkFileScan() { QMimeDatabase mimeDb; FileScanner fileScanner; QBENCHMARK { for (int i = 0; i < 100; i++) { auto scannedTrack = fileScanner.scanOneFile(QUrl::fromLocalFile(QStringLiteral(LOCAL_FILE_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/music/test.ogg")), mimeDb); auto scannedTrack2 = fileScanner.scanOneFile(QUrl::fromLocalFile(QStringLiteral(LOCAL_FILE_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/music/testMultiple.ogg")), mimeDb); auto scannedTrack3 = fileScanner.scanOneFile(QUrl::fromLocalFile(QStringLiteral(LOCAL_FILE_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/music/testMany.ogg")), mimeDb); } } } void benchmarkCoverInDirectory() { FileScanner fileScanner; QBENCHMARK { fileScanner.searchForCoverFile(mTestTracksForDirectory.at(0)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(1)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(2)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(3)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(4)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(5)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(6)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(7)); fileScanner.searchForCoverFile(mTestTracksForDirectory.at(8)); } } void benchmarkCoverFromMetadata() { FileScanner fileScanner; QBENCHMARK { fileScanner.checkEmbeddedCoverImage(mTestTracksForMetaData.at(0)); fileScanner.checkEmbeddedCoverImage(mTestTracksForMetaData.at(1)); fileScanner.checkEmbeddedCoverImage(mTestTracksForMetaData.at(2)); } } }; QTEST_GUILESS_MAIN(FileScannerTest) #include "filescannertest.moc" diff --git a/autotests/manageaudioplayertest.h b/autotests/manageaudioplayertest.h index 28b0b4cc..e3f2fbe7 100644 --- a/autotests/manageaudioplayertest.h +++ b/autotests/manageaudioplayertest.h @@ -1,96 +1,95 @@ /* * Copyright 2016 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef MANAGEAUDIOPLAYERTEST_H #define MANAGEAUDIOPLAYERTEST_H #include class ManageAudioPlayerTest : public QObject { Q_OBJECT public: enum ColumnsRoles { IsValidRole = Qt::UserRole + 1, TitleRole = IsValidRole + 1, DurationRole = TitleRole + 1, - MilliSecondsDurationRole = DurationRole + 1, - CreatorRole = MilliSecondsDurationRole + 1, + CreatorRole = DurationRole + 1, ArtistRole = CreatorRole + 1, AlbumRole = ArtistRole + 1, TrackNumberRole = AlbumRole + 1, RatingRole = TrackNumberRole + 1, ImageRole = RatingRole + 1, ResourceRole = ImageRole + 1, CountRole = ResourceRole + 1, IsPlayingRole = CountRole + 1, }; Q_ENUM(ColumnsRoles) explicit ManageAudioPlayerTest(QObject *parent = nullptr); Q_SIGNALS: private Q_SLOTS: void initTestCase(); void simpleInitialCase(); void noPlayCase(); void skipNextTrack(); void skipNextTrackWithRandomPlay(); void skipPreviousTrack(); void playTrackAndskipNextTrack(); void playTrackAndskipPreviousTrack(); void skipNextTrackAndPlayTrack(); void skipPreviousTrackAndPlayTrack(); void playLastCase(); void playSingleTrack(); void playRestoredTrack(); void testRestoreSettingsAutomaticPlay(); void testRestoreSettingsNoAutomaticPlay(); void testRestoreSettingsAutomaticPlayAndPosition(); void playTrackPauseAndSkipNextTrack(); void testRestoreSettingsNoPlayWrongTrack(); void testRestorePlayListAndSettingsAutomaticPlay(); void playSingleAndClearPlayListTrack(); }; #endif // MANAGEAUDIOPLAYERTEST_H diff --git a/autotests/manageheaderbartest.h b/autotests/manageheaderbartest.h index 6517add8..5bdd9289 100644 --- a/autotests/manageheaderbartest.h +++ b/autotests/manageheaderbartest.h @@ -1,74 +1,73 @@ /* * Copyright 2016 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef MANAGEHEADERBARTEST_H #define MANAGEHEADERBARTEST_H #include #include "databasetestdata.h" #include "musicaudiotrack.h" #include #include #include #include class ManageHeaderBarTest : public QObject, public DatabaseTestData { Q_OBJECT public: enum ColumnsRoles { IsValidRole = Qt::UserRole + 1, TitleRole = IsValidRole + 1, DurationRole = TitleRole + 1, - MilliSecondsDurationRole = DurationRole + 1, - CreatorRole = MilliSecondsDurationRole + 1, + CreatorRole = DurationRole + 1, ArtistRole = CreatorRole + 1, AlbumRole = ArtistRole + 1, TrackNumberRole = AlbumRole + 1, RatingRole = TrackNumberRole + 1, ImageRole = RatingRole + 1, AlbumIdRole = ImageRole + 1, ResourceRole = AlbumIdRole + 1, CountRole = ResourceRole + 1, IsPlayingRole = CountRole + 1, }; Q_ENUM(ColumnsRoles) explicit ManageHeaderBarTest(QObject *parent = nullptr); Q_SIGNALS: private Q_SLOTS: void initTestCase(); void simpleInitialCase(); void setCurrentTrackWithInvalidData(); void setCurrentTrackWithData(); }; #endif // MANAGEHEADERBARTEST_H diff --git a/autotests/mediaplaylisttest.cpp b/autotests/mediaplaylisttest.cpp index 3b090157..9aaf3b94 100644 --- a/autotests/mediaplaylisttest.cpp +++ b/autotests/mediaplaylisttest.cpp @@ -1,7223 +1,7223 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mediaplaylisttest.h" #include "mediaplaylisttestconfig.h" #include "mediaplaylist.h" #include "databaseinterface.h" #include "musicaudiotrack.h" #include "trackslistener.h" #include "config-upnp-qt.h" #include #include #include #include #include #include #include MediaPlayListTest::MediaPlayListTest(QObject *parent) : QObject(parent) { } void MediaPlayListTest::initTestCase() { qRegisterMetaType>("QHash"); qRegisterMetaType>>("QHash>"); qRegisterMetaType>("QVector"); qRegisterMetaType>("QHash"); qRegisterMetaType("PlayListEntryType"); } void MediaPlayListTest::simpleInitialCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto newTrackID = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track6"), QStringLiteral("artist1 and artist2"), QStringLiteral("album2"), 6, 1); myPlayList.enqueue({newTrackID, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); } void MediaPlayListTest::enqueueAlbumCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1"), QStringLiteral("/")), QStringLiteral("album2")}, ElisaUtils::Album); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); } void MediaPlayListTest::clearPlayListCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy tracksCountChangedSpy(&myPlayList, &MediaPlayList::tracksCountChanged); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(tracksCountChangedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(tracksCountChangedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1"), QStringLiteral("/")), QStringLiteral("album2")}, ElisaUtils::Album); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(tracksCountChangedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.clearPlayList(); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(tracksCountChangedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(myPlayList.rowCount(), 0); QCOMPARE(myPlayList.currentTrack().isValid(), false); } void MediaPlayListTest::undoClearPlayListCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy tracksCountChangedSpy(&myPlayList, &MediaPlayList::tracksCountChanged); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy displayUndoInlineSpy(&myPlayList, &MediaPlayList::displayUndoInline); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(tracksCountChangedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(tracksCountChangedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1"), QStringLiteral("/")), QStringLiteral("album2")}, ElisaUtils::Album); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(tracksCountChangedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.clearPlayList(); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(tracksCountChangedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(myPlayList.rowCount(), 0); QCOMPARE(myPlayList.currentTrack().isValid(), false); myPlayList.undoClearPlayList(); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(tracksCountChangedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 8); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 7); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(displayUndoInlineSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::undoReplacePlayListCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy tracksCountChangedSpy(&myPlayList, &MediaPlayList::tracksCountChanged); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy displayUndoInlineSpy(&myPlayList, &MediaPlayList::displayUndoInline); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(tracksCountChangedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(tracksCountChangedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1"), QStringLiteral("/")), QStringLiteral("album2")}, ElisaUtils::Album); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(tracksCountChangedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album1"), QStringLiteral("Various Artists"), QStringLiteral("/")), QStringLiteral("album1")}, ElisaUtils::Album, ElisaUtils::ReplacePlayList, ElisaUtils::TriggerPlay); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 2); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 2); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 3); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 4); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 4); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 4); myPlayList.undoClearPlayList(); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 2); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 5); QCOMPARE(rowsRemovedSpy.count(), 2); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 5); QCOMPARE(tracksCountChangedSpy.count(), 7); QCOMPARE(persistentStateChangedSpy.count(), 7); QCOMPARE(dataChangedSpy.count(), 9); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 8); QCOMPARE(currentTrackChangedSpy.count(), 5); QCOMPARE(displayUndoInlineSpy.count(), 2); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::enqueueArtistCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue({0, QStringLiteral("artist1")}, ElisaUtils::Artist); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 1); QCOMPARE(rowsAboutToBeInsertedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.rowCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumIdRole).toULongLong(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); } void MediaPlayListTest::removeFirstTrackOfAlbum() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1"), QStringLiteral("/")), QStringLiteral("album2")}, ElisaUtils::Album); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); myPlayList.removeRow(0); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); } void MediaPlayListTest::testHasHeader() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.removeRows(2, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::testHasHeaderWithRestore() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContentHeaderWithRestore")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myPlayList.enqueueRestoredEntry({QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 1); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.wait(50), false); myPlayList.enqueueRestoredEntry({QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 2); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.wait(50), false); myPlayList.enqueueRestoredEntry({QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 3); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.wait(50), false); myPlayList.enqueueRestoredEntry({QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 4); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 4); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); while (dataChangedSpy.count() < 8) { QCOMPARE(dataChangedSpy.wait(), true); } QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 8); QCOMPARE(newTrackByNameInListSpy.count(), 4); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); } void MediaPlayListTest::testHasHeaderWithRemove() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.removeRows(2, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.removeRows(0, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 2); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 2); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 6); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::testHasHeaderMoveFirst() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album2"), 4, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(myPlayList.moveRows({}, 0, 1, {}, 4), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 1); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 1); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::testHasHeaderMoveAnother() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album2"), 4, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(myPlayList.moveRows({}, 3, 1, {}, 0), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 1); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 1); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::testHasHeaderMoveFirstLikeQml() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album2"), 4, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.move(0, 3, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 1); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 1); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::testHasHeaderMoveAnotherLikeQml() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album2"), 4, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.move(3, 0, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 1); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 1); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::testHasHeaderYetAnotherMoveLikeQml() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album2"), 4, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.move(0, 2, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 1); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 1); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); myPlayList.move(2, 0, 1); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 2); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 2); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 6); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); } void MediaPlayListTest::enqueueReplaceAndPlay() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackID = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track6"), QStringLiteral("artist1 and artist2"), QStringLiteral("album2"), 6, 1); myPlayList.enqueue({firstTrackID, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); myPlayList.enqueue({myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album1"), QStringLiteral("Various Artists"), QStringLiteral("/")), QStringLiteral("album1")}, ElisaUtils::Album, ElisaUtils::ReplacePlayList, ElisaUtils::TriggerPlay); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 2); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 2); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 3); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 4); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 4); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 4); } void MediaPlayListTest::crashOnEnqueue() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); CrashEnqueuePlayList myCrash(&myPlayList); connect(&myPlayList, &MediaPlayList::rowsInserted, &myCrash, &CrashEnqueuePlayList::crashMediaPlayList); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto newTrackID = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track6"), QStringLiteral("artist1 and artist2"), QStringLiteral("album2"), 6, 1); myPlayList.enqueue({newTrackID, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); } void MediaPlayListTest::restoreMultipleIdenticalTracks() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContentHeaderWithRestore")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myPlayList.enqueueRestoredEntry({QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 1); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueueRestoredEntry({QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 2); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueueRestoredEntry({QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 3); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueueRestoredEntry({QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 4); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 4); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 8); QCOMPARE(newTrackByNameInListSpy.count(), 4); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 3); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 3); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 3); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 3); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 3); } void MediaPlayListTest::restoreTrackWithoutAlbum() { QTemporaryFile databaseFile; databaseFile.open(); qDebug() << "restoreTrackWithoutAlbum" << databaseFile.fileName(); MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("restoreTrackWithoutAlbum"), databaseFile.fileName()); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto newTrack = MusicAudioTrack{}; newTrack.setValid(true); newTrack.setId(QStringLiteral("$29")); newTrack.setParentId(QStringLiteral("0")); newTrack.setTitle(QStringLiteral("track19")); newTrack.setArtist(QStringLiteral("artist2")); newTrack.setDuration(QTime::fromMSecsSinceStartOfDay(29)); newTrack.setResourceURI(QUrl::fromLocalFile(QStringLiteral("/$29"))); newTrack.setFileModificationTime(QDateTime::fromMSecsSinceEpoch(29)); newTrack.setAlbumCover(QUrl::fromLocalFile(QStringLiteral("withoutAlbum"))); newTrack.setRating(9); newTrack.setIsSingleDiscAlbum(true); newTrack.setGenre(QStringLiteral("genre1")); newTrack.setComposer(QStringLiteral("composer1")); newTrack.setLyricist(QStringLiteral("lyricist1")); newTrack.setHasEmbeddedCover(false); myDatabaseContent.insertTracksList({newTrack}, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto newEntry = MediaPlayListEntry{}; newEntry.mTitle = QStringLiteral("track19"); newEntry.mArtist = QStringLiteral("artist2"); myPlayList.enqueueRestoredEntry(newEntry); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 1); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 1); QCOMPARE(newEntryInListSpy.count(), 0); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track19")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QString()); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 0); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 0); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 29); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 29); } void MediaPlayListTest::testHasHeaderAlbumWithSameTitle() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist2"), QStringLiteral("album3"), 1, 1); myPlayList.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayList.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist2"), QStringLiteral("album3"), 2, 1); myPlayList.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); auto fourthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist2"), QStringLiteral("album3"), 3, 1); myPlayList.enqueue({fourthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 4); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 4); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 4); auto fithTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track9"), QStringLiteral("artist2"), QStringLiteral("album3"), 9, 1); myPlayList.enqueue({fithTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 5); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 5); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 5); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 5); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 5); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 5); auto sixthTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist7"), QStringLiteral("album3"), 1, 1); myPlayList.enqueue({sixthTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 6); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 6); QCOMPARE(persistentStateChangedSpy.count(), 6); QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 6); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 6); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 6); QCOMPARE(persistentStateChangedSpy.count(), 6); QCOMPARE(dataChangedSpy.count(), 6); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 6); } void MediaPlayListTest::testSavePersistentState() { MediaPlayList myPlayListSave; QAbstractItemModelTester testModelSave(&myPlayListSave); DatabaseInterface myDatabaseContent; TracksListener myListenerSave(&myDatabaseContent); MediaPlayList myPlayListRead; QAbstractItemModelTester testModelRead(&myPlayListRead); TracksListener myListenerRead(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpySave(&myPlayListSave, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpySave(&myPlayListSave, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpySave(&myPlayListSave, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpySave(&myPlayListSave, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpySave(&myPlayListSave, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpySave(&myPlayListSave, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpySave(&myPlayListSave, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpySave(&myPlayListSave, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpySave(&myPlayListSave, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpySave(&myPlayListSave, &MediaPlayList::newEntryInList); QSignalSpy rowsAboutToBeMovedSpyRead(&myPlayListRead, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpyRead(&myPlayListRead, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpyRead(&myPlayListRead, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpyRead(&myPlayListRead, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpyRead(&myPlayListRead, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpyRead(&myPlayListRead, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpyRead(&myPlayListRead, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpyRead(&myPlayListRead, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpyRead(&myPlayListRead, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpyRead(&myPlayListRead, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 0); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 0); QCOMPARE(persistentStateChangedSpySave.count(), 0); QCOMPARE(dataChangedSpySave.count(), 0); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 0); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListenerSave, &TracksListener::trackHasChanged, &myPlayListSave, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListenerSave, &TracksListener::tracksListAdded, &myPlayListSave, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayListSave, &MediaPlayList::newTrackByNameInList, &myListenerSave, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayListSave, &MediaPlayList::newEntryInList, &myListenerSave, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListenerSave, &TracksListener::tracksAdded); connect(&myListenerRead, &TracksListener::trackHasChanged, &myPlayListRead, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListenerRead, &TracksListener::tracksListAdded, &myPlayListRead, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayListRead, &MediaPlayList::newTrackByNameInList, &myListenerRead, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayListRead, &MediaPlayList::newEntryInList, &myListenerRead, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListenerRead, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 0); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 0); QCOMPARE(persistentStateChangedSpySave.count(), 0); QCOMPARE(dataChangedSpySave.count(), 0); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 0); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist2"), QStringLiteral("album3"), 1, 1); myPlayListSave.enqueue({firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 1); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 1); QCOMPARE(persistentStateChangedSpySave.count(), 1); QCOMPARE(dataChangedSpySave.count(), 0); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 1); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); QCOMPARE(dataChangedSpySave.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 1); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 1); QCOMPARE(persistentStateChangedSpySave.count(), 1); QCOMPARE(dataChangedSpySave.count(), 1); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 1); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayListSave.enqueue({secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 2); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 2); QCOMPARE(persistentStateChangedSpySave.count(), 2); QCOMPARE(dataChangedSpySave.count(), 1); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 2); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); QCOMPARE(dataChangedSpySave.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 2); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 2); QCOMPARE(persistentStateChangedSpySave.count(), 2); QCOMPARE(dataChangedSpySave.count(), 2); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 2); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist2"), QStringLiteral("album3"), 2, 1); myPlayListSave.enqueue({thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 3); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 3); QCOMPARE(persistentStateChangedSpySave.count(), 3); QCOMPARE(dataChangedSpySave.count(), 2); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 3); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); QCOMPARE(dataChangedSpySave.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 3); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 3); QCOMPARE(persistentStateChangedSpySave.count(), 3); QCOMPARE(dataChangedSpySave.count(), 3); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 3); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 0); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 0); QCOMPARE(persistentStateChangedSpyRead.count(), 0); QCOMPARE(dataChangedSpyRead.count(), 0); QCOMPARE(newTrackByNameInListSpyRead.count(), 0); QCOMPARE(newEntryInListSpyRead.count(), 0); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); - QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(11)); + QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 11); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album3"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$11"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListSave.data(myPlayListSave.index(0, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), true); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); - QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(1)); + QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album1"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$1"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), false); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track2")); - QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(12)); + QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 12); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album3"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$12"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListSave.data(myPlayListSave.index(2, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), true); myPlayListRead.setPersistentState(myPlayListSave.persistentState()); QCOMPARE(dataChangedSpyRead.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeMovedSpySave.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpySave.count(), 3); QCOMPARE(rowsRemovedSpySave.count(), 0); QCOMPARE(rowsMovedSpySave.count(), 0); QCOMPARE(rowsInsertedSpySave.count(), 3); QCOMPARE(persistentStateChangedSpySave.count(), 3); QCOMPARE(dataChangedSpySave.count(), 3); QCOMPARE(newTrackByNameInListSpySave.count(), 0); QCOMPARE(newEntryInListSpySave.count(), 3); QCOMPARE(rowsAboutToBeRemovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeMovedSpyRead.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpyRead.count(), 3); QCOMPARE(rowsRemovedSpyRead.count(), 0); QCOMPARE(rowsMovedSpyRead.count(), 0); QCOMPARE(rowsInsertedSpyRead.count(), 3); QCOMPARE(persistentStateChangedSpyRead.count(), 4); QCOMPARE(dataChangedSpyRead.count(), 6); QCOMPARE(newTrackByNameInListSpyRead.count(), 3); QCOMPARE(newEntryInListSpyRead.count(), 0); QCOMPARE(myPlayListRead.tracksCount(), 3); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); - QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(11)); + QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 11); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album3"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$11"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListRead.data(myPlayListRead.index(0, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), true); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); - QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(1)); + QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album1"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$1"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), false); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track2")); - QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(12)); + QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 12); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album3"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$12"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListRead.data(myPlayListRead.index(2, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), true); } void MediaPlayListTest::testReplaceAndPlayArtist() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.replaceAndPlay({0, QStringLiteral("artist3")}, ElisaUtils::Artist); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.tracksCount(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track3")); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(3)); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album1"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$3"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), false); myPlayList.replaceAndPlay({0, QStringLiteral("artist4")}, ElisaUtils::Artist); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 4); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.tracksCount(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track4")); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(4)); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist4")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album1"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), false); } void MediaPlayListTest::testReplaceAndPlayTrackId() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3); QCOMPARE(firstTrackId != 0, true); myPlayList.replaceAndPlay(ElisaUtils::EntryData{firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.tracksCount(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track3")); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(3)); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist3")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album1"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$3"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), false); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist4"), QStringLiteral("album1"), 4, 4); QCOMPARE(secondTrackId != 0, true); myPlayList.replaceAndPlay(ElisaUtils::EntryData{secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 1); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.tracksCount(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track4")); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime(), QTime::fromMSecsSinceStartOfDay(4)); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DurationRole).toTime().msecsSinceStartOfDay(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist4")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageUrlRole).toUrl(), QUrl::fromLocalFile(QStringLiteral("album1"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsSingleDiscAlbumRole).toBool(), false); } void MediaPlayListTest::testSetData() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); auto firstTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist2"), QStringLiteral("album3"), 1, 1); myPlayList.enqueue(ElisaUtils::EntryData{firstTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); auto secondTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1); myPlayList.enqueue(ElisaUtils::EntryData{secondTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); auto thirdTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist2"), QStringLiteral("album3"), 2, 1); myPlayList.enqueue(ElisaUtils::EntryData{thirdTrackId, {}}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.setData(myPlayList.index(2, 0), true, MediaPlayList::ColumnsRoles::IsPlayingRole), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), true); QCOMPARE(myPlayList.setData(myPlayList.index(2, 0), true, MediaPlayList::ColumnsRoles::SecondaryTextRole), false); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(myPlayList.setData(myPlayList.index(4, 0), true, MediaPlayList::ColumnsRoles::TitleRole), false); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); QCOMPARE(myPlayList.setData({}, true, MediaPlayList::ColumnsRoles::TitleRole), false); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 4); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 3); } void MediaPlayListTest::testRemoveSelection() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.replaceAndPlay({0, QStringLiteral("artist1")}, ElisaUtils::Artist); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.tracksCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); myPlayList.removeSelection({2, 4, 5}); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 3); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 3); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 5); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.tracksCount(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); } void MediaPlayListTest::testTrackBeenRemoved() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.replaceAndPlay({0, QStringLiteral("artist1")}, ElisaUtils::Artist); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(dataChangedSpy.wait(), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.tracksCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); auto removedTrackId = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1); QCOMPARE(removedTrackId != 0, true); auto removedTrack = myDatabaseContent.trackDataFromDatabaseId(removedTrackId); QVERIFY(!removedTrack.isEmpty()); myPlayList.trackRemoved(removedTrack[DataTypes::DatabaseIdRole].toULongLong()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 2); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 2); QCOMPARE(persistentStateChangedSpy.count(), 2); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 1); QCOMPARE(myPlayList.tracksCount(), 6); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("Various Artists")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), -1); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 0); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::IsValidRole).toBool(), true); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::AlbumArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); } CrashEnqueuePlayList::CrashEnqueuePlayList(MediaPlayList *list, QObject *parent) : QObject(parent), mList(list) { } void CrashEnqueuePlayList::crashMediaPlayList() { mList->data(mList->index(0, 0), MediaPlayList::ResourceRole); } void MediaPlayListTest::testBringUpCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::testBringUpCaseFromNewAlbum() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); auto newTrackID = myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1); QVERIFY(newTrackID != 0); myPlayList.enqueue({newTrackID, QStringLiteral("track1")}, ElisaUtils::Track); QVERIFY(currentTrackChangedSpy.wait()); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::testBringUpAndDownCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.removeRow(0); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 1); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex()); } void MediaPlayListTest::testBringUpAndRemoveCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.removeRow(0); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 1); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex()); } void MediaPlayListTest::testBringUpAndRemoveMultipleCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album1"), 2, 2), QStringLiteral("track2")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.removeRow(0); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::testBringUpAndRemoveMultipleNotBeginCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album1"), 2, 2), QStringLiteral("track2")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album1"), 4, 1), QStringLiteral("track4")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.removeRow(1); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); } void MediaPlayListTest::testBringUpAndPlayCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist2"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); } void MediaPlayListTest::testBringUpAndSkipNextCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist2"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); } void MediaPlayListTest::testBringUpAndSkipPreviousCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist2"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::testBringUpAndSkipPreviousAndContinueCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.setRepeatPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1), QStringLiteral("track2")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album1"), 2, 2), QStringLiteral("track2")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 5); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(4, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 6); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(5, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 7); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(4, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 8); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 9); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 10); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 11); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipPreviousTrack(); QCOMPARE(currentTrackChangedSpy.count(), 12); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(5, 0))); } void MediaPlayListTest::finishPlayList() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist2"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 1); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::randomPlayList() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.setRandomPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.randomPlay(), true); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 5); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); } void MediaPlayListTest::randomAndContinuePlayList() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.setRandomPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.randomPlay(), true); myPlayList.setRepeatPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.repeatPlay(), true); myPlayList.switchTo(3); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 5); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); } void MediaPlayListTest::continuePlayList() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.setRepeatPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.repeatPlay(), true); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 5); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::testRestoreSettings() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QVariantMap settings; settings[QStringLiteral("currentTrack")] = 2; settings[QStringLiteral("randomPlay")] = true; settings[QStringLiteral("repeatPlay")] = true; myPlayList.setPersistentState(settings); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QVERIFY(currentTrackChangedSpy.wait()); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); } void MediaPlayListTest::testSaveAndRestoreSettings() { MediaPlayList myPlayListSave; QAbstractItemModelTester testModelSave(&myPlayListSave); DatabaseInterface myDatabaseContent; TracksListener myListenerSave(&myDatabaseContent); MediaPlayList myPlayListRestore; QAbstractItemModelTester testModelRestore(&myPlayListRestore); TracksListener myListenerRestore(&myDatabaseContent); QSignalSpy currentTrackChangedSaveSpy(&myPlayListSave, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSaveSpy(&myPlayListSave, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSaveSpy(&myPlayListSave, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSaveSpy(&myPlayListSave, &MediaPlayList::playListFinished); QSignalSpy currentTrackChangedRestoreSpy(&myPlayListRestore, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedRestoreSpy(&myPlayListRestore, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedRestoreSpy(&myPlayListRestore, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedRestoreSpy(&myPlayListRestore, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListenerSave, &TracksListener::trackHasChanged, &myPlayListSave, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListenerSave, &TracksListener::tracksListAdded, &myPlayListSave, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayListSave, &MediaPlayList::newTrackByNameInList, &myListenerSave, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayListSave, &MediaPlayList::newEntryInList, &myListenerSave, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListenerSave, &TracksListener::tracksAdded); connect(&myListenerRestore, &TracksListener::trackHasChanged, &myPlayListRestore, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListenerRestore, &TracksListener::tracksListAdded, &myPlayListRestore, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayListRestore, &MediaPlayList::newTrackByNameInList, &myListenerRestore, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayListRestore, &MediaPlayList::newEntryInList, &myListenerRestore, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListenerRestore, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); myPlayListSave.setRepeatPlay(true); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); myPlayListSave.setRandomPlay(true); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 1); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 1); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(currentTrackChangedSaveSpy.wait(), true); QCOMPARE(currentTrackChangedSaveSpy.count(), 1); QCOMPARE(randomPlayChangedSaveSpy.count(), 1); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(myPlayListSave.currentTrack(), QPersistentModelIndex(myPlayListSave.index(0, 0))); myPlayListSave.skipNextTrack(); QCOMPARE(currentTrackChangedSaveSpy.count(), 2); QCOMPARE(randomPlayChangedSaveSpy.count(), 1); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); myPlayListSave.skipNextTrack(); QCOMPARE(currentTrackChangedSaveSpy.count(), 3); QCOMPARE(randomPlayChangedSaveSpy.count(), 1); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); myPlayListRestore.setPersistentState(myPlayListSave.persistentState()); QCOMPARE(currentTrackChangedSaveSpy.count(), 3); QCOMPARE(randomPlayChangedSaveSpy.count(), 1); QCOMPARE(repeatPlayChangedSaveSpy.count(), 1); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 1); QCOMPARE(randomPlayChangedRestoreSpy.count(), 1); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 1); QCOMPARE(playListFinishedRestoreSpy.count(), 0); qDebug() << myPlayListRestore.currentTrack(); QCOMPARE(myPlayListRestore.repeatPlay(), true); QCOMPARE(myPlayListRestore.randomPlay(), true); const auto indexSavePlaylist = myPlayListRestore.currentTrack(); QCOMPARE(myPlayListRestore.currentTrack(), QPersistentModelIndex(myPlayListRestore.index(indexSavePlaylist.row(), 0))); } void MediaPlayListTest::removeBeforeCurrentTrack() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); myPlayList.removeRow(1); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); } void MediaPlayListTest::switchToTrackTest() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album1"), 4, 4), QStringLiteral("track4")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album1"), 2, 2), QStringLiteral("track2")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.switchTo(4); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(4, 0))); } void MediaPlayListTest::previousAndNextTracksTest() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy previousTrackChangedSpy(&myPlayList, &MediaPlayList::previousTrackChanged); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy nextTrackChangedSpy(&myPlayList, &MediaPlayList::nextTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(previousTrackChangedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(nextTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album1"), 4, 4), QStringLiteral("track4")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album1"), 2, 2), QStringLiteral("track2")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(previousTrackChangedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(nextTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(previousTrackChangedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(nextTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.previousTrack(), QPersistentModelIndex()); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); QCOMPARE(myPlayList.nextTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipNextTrack(); QCOMPARE(previousTrackChangedSpy.count(), 1); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(nextTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.previousTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); QCOMPARE(myPlayList.nextTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); myPlayList.switchTo(4); QCOMPARE(previousTrackChangedSpy.count(), 2); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(nextTrackChangedSpy.count(), 3); QCOMPARE(myPlayList.previousTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(4, 0))); QCOMPARE(myPlayList.nextTrack(), QPersistentModelIndex()); myPlayList.setRepeatPlay(true); QCOMPARE(previousTrackChangedSpy.count(), 2); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(nextTrackChangedSpy.count(), 4); QCOMPARE(myPlayList.previousTrack(), QPersistentModelIndex(myPlayList.index(3, 0))); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(4, 0))); QCOMPARE(myPlayList.nextTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(previousTrackChangedSpy.count(), 3); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(nextTrackChangedSpy.count(), 5); QCOMPARE(myPlayList.previousTrack(), QPersistentModelIndex(myPlayList.index(4, 0))); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); QCOMPARE(myPlayList.nextTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.setRandomPlay(true); QVERIFY(myPlayList.previousTrack() != QPersistentModelIndex()); QVERIFY(myPlayList.currentTrack() != QPersistentModelIndex()); QVERIFY(myPlayList.nextTrack() != QPersistentModelIndex()); } void MediaPlayListTest::singleTrack() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 1); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::remainingTracksTest() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy remainingTracksChangedSpy(&myPlayList, &MediaPlayList::remainingTracksChanged); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(remainingTracksChangedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track4"), QStringLiteral("artist1"), QStringLiteral("album1"), 4, 4), QStringLiteral("track4")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album1"), 2, 2), QStringLiteral("track2")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(remainingTracksChangedSpy.count(), 5); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(remainingTracksChangedSpy.count(), 6); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); QCOMPARE(myPlayList.remainingTracks(), 4); myPlayList.skipNextTrack(); QCOMPARE(remainingTracksChangedSpy.count(), 7); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); QCOMPARE(myPlayList.remainingTracks(), 3); myPlayList.setRandomPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 1); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(remainingTracksChangedSpy.count(), 8); QCOMPARE(myPlayList.remainingTracks(), -1); myPlayList.setRandomPlay(false); myPlayList.setRepeatPlay(true); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 2); QCOMPARE(repeatPlayChangedSpy.count(), 1); QCOMPARE(remainingTracksChangedSpy.count(), 10); QCOMPARE(myPlayList.remainingTracks(), -1); } void MediaPlayListTest::testBringUpAndRemoveLastCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy currentTrackChangedSpy(&myPlayList, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSpy(&myPlayList, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSpy(&myPlayList, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSpy(&myPlayList, &MediaPlayList::playListFinished); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track2"), QStringLiteral("artist1"), QStringLiteral("album2"), 2, 1), QStringLiteral("track2")}, ElisaUtils::Track); myPlayList.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist1"), QStringLiteral("album2"), 3, 1), QStringLiteral("track3")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSpy.count(), 0); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(currentTrackChangedSpy.wait(), true); QCOMPARE(currentTrackChangedSpy.count(), 1); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 2); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(1, 0))); myPlayList.skipNextTrack(); QCOMPARE(currentTrackChangedSpy.count(), 3); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 0); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(2, 0))); myPlayList.removeRow(2); QCOMPARE(currentTrackChangedSpy.count(), 4); QCOMPARE(randomPlayChangedSpy.count(), 0); QCOMPARE(repeatPlayChangedSpy.count(), 0); QCOMPARE(playListFinishedSpy.count(), 1); QCOMPARE(myPlayList.currentTrack(), QPersistentModelIndex(myPlayList.index(0, 0))); } void MediaPlayListTest::testSaveLoadPlayList() { MediaPlayList myPlayListSave; QAbstractItemModelTester testModelSave(&myPlayListSave); DatabaseInterface myDatabaseContent; TracksListener myListenerSave(&myDatabaseContent); MediaPlayList myPlayListRestore; QAbstractItemModelTester testModelRestore(&myPlayListRestore); TracksListener myListenerRestore(&myDatabaseContent); QSignalSpy currentTrackChangedSaveSpy(&myPlayListSave, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedSaveSpy(&myPlayListSave, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedSaveSpy(&myPlayListSave, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedSaveSpy(&myPlayListSave, &MediaPlayList::playListFinished); QSignalSpy playListLoadedSaveSpy(&myPlayListSave, &MediaPlayList::playListLoaded); QSignalSpy playListLoadFailedSaveSpy(&myPlayListSave, &MediaPlayList::playListLoadFailed); QSignalSpy currentTrackChangedRestoreSpy(&myPlayListRestore, &MediaPlayList::currentTrackChanged); QSignalSpy randomPlayChangedRestoreSpy(&myPlayListRestore, &MediaPlayList::randomPlayChanged); QSignalSpy repeatPlayChangedRestoreSpy(&myPlayListRestore, &MediaPlayList::repeatPlayChanged); QSignalSpy playListFinishedRestoreSpy(&myPlayListRestore, &MediaPlayList::playListFinished); QSignalSpy playListLoadedRestoreSpy(&myPlayListRestore, &MediaPlayList::playListLoaded); QSignalSpy playListLoadFailedRestoreSpy(&myPlayListRestore, &MediaPlayList::playListLoadFailed); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListenerSave, &TracksListener::trackHasChanged, &myPlayListSave, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListenerSave, &TracksListener::tracksListAdded, &myPlayListSave, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayListSave, &MediaPlayList::newTrackByNameInList, &myListenerSave, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayListSave, &MediaPlayList::newEntryInList, &myListenerSave, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListenerSave, &TracksListener::tracksAdded); connect(&myListenerRestore, &TracksListener::trackHasChanged, &myPlayListRestore, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListenerRestore, &TracksListener::tracksListAdded, &myPlayListRestore, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayListRestore, &MediaPlayList::newTrackByNameInList, &myListenerRestore, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayListRestore, &MediaPlayList::newEntryInList, &myListenerRestore, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListenerRestore, &TracksListener::tracksAdded); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 0); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 0); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 0); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album2"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), QStringLiteral("album1"), 3, 3), QStringLiteral("track3")}, ElisaUtils::Track); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track5"), QStringLiteral("artist1"), QStringLiteral("album2"), 5, 1), QStringLiteral("track5")}, ElisaUtils::Track); myPlayListSave.enqueue({myDatabaseContent.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track1"), QStringLiteral("artist1"), QStringLiteral("album1"), 1, 1), QStringLiteral("track1")}, ElisaUtils::Track); QCOMPARE(currentTrackChangedSaveSpy.count(), 0); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 0); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); QCOMPARE(currentTrackChangedSaveSpy.wait(), true); QCOMPARE(currentTrackChangedSaveSpy.count(), 1); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 0); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); QCOMPARE(myPlayListSave.currentTrack(), QPersistentModelIndex(myPlayListSave.index(0, 0))); QTemporaryFile playlistFile(QStringLiteral("./myPlaylistXXXXXX.m3u")); playlistFile.open(); QCOMPARE(myPlayListSave.savePlaylist(QUrl::fromLocalFile(playlistFile.fileName())), true); QCOMPARE(currentTrackChangedSaveSpy.count(), 1); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 0); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); myPlayListRestore.loadPlaylist(QUrl::fromLocalFile(playlistFile.fileName())); QCOMPARE(currentTrackChangedSaveSpy.count(), 1); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 0); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 1); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.wait(300), true); QCOMPARE(currentTrackChangedSaveSpy.count(), 1); QCOMPARE(randomPlayChangedSaveSpy.count(), 0); QCOMPARE(repeatPlayChangedSaveSpy.count(), 0); QCOMPARE(playListFinishedSaveSpy.count(), 0); QCOMPARE(playListLoadedSaveSpy.count(), 0); QCOMPARE(playListLoadFailedSaveSpy.count(), 0); QCOMPARE(currentTrackChangedRestoreSpy.count(), 1); QCOMPARE(randomPlayChangedRestoreSpy.count(), 0); QCOMPARE(repeatPlayChangedRestoreSpy.count(), 0); QCOMPARE(playListFinishedRestoreSpy.count(), 0); QCOMPARE(playListLoadedRestoreSpy.count(), 1); QCOMPARE(playListLoadFailedRestoreSpy.count(), 0); QCOMPARE(myPlayListRestore.currentTrack(), QPersistentModelIndex(myPlayListRestore.index(0, 0))); } void MediaPlayListTest::testEnqueueFiles() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue({{0, QStringLiteral("/$1")}, {0, QStringLiteral("/$2")}}, ElisaUtils::FileName); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.rowCount(), 2); QCOMPARE(dataChangedSpy.wait(300), true); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 2); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 2); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 2); } void MediaPlayListTest::testEnqueueSampleFiles() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue({{0, QStringLiteral(MEDIAPLAYLIST_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/test.ogg")}, {0, QStringLiteral(MEDIAPLAYLIST_TESTS_SAMPLE_FILES_PATH) + QStringLiteral("/test2.ogg")}}, ElisaUtils::FileName); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.rowCount(), 2); while (dataChangedSpy.count() < 3) { QCOMPARE(dataChangedSpy.wait(), true); } QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(persistentStateChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 3); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); #if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("Title")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("Test")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("Artist")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1000); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1000); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("Title2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("Test2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("Artist2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 1000); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 1000); #else QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("test.ogg")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), -1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), -1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 0); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 0); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("test2.ogg")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), -1); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), -1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 0); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 0); #endif } void MediaPlayListTest::testEmptyEnqueue() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue(ElisaUtils::EntryDataList{}, ElisaUtils::Track); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue(ElisaUtils::EntryDataList{}, ElisaUtils::FileName); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue(ElisaUtils::EntryDataList{}, ElisaUtils::Track, ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue(ElisaUtils::EntryDataList{}, ElisaUtils::Album, ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue(ElisaUtils::EntryDataList{}, ElisaUtils::Artist, ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(persistentStateChangedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); } void MediaPlayListTest::enqueueMultipleAlbumsCase() { MediaPlayList myPlayList; QAbstractItemModelTester testModel(&myPlayList); DatabaseInterface myDatabaseContent; TracksListener myListener(&myDatabaseContent); QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeMoved); QSignalSpy rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeInserted); QSignalSpy rowsMovedSpy(&myPlayList, &MediaPlayList::rowsMoved); QSignalSpy rowsRemovedSpy(&myPlayList, &MediaPlayList::rowsRemoved); QSignalSpy rowsInsertedSpy(&myPlayList, &MediaPlayList::rowsInserted); QSignalSpy persistentStateChangedSpy(&myPlayList, &MediaPlayList::persistentStateChanged); QSignalSpy dataChangedSpy(&myPlayList, &MediaPlayList::dataChanged); QSignalSpy newTrackByNameInListSpy(&myPlayList, &MediaPlayList::newTrackByNameInList); QSignalSpy newEntryInListSpy(&myPlayList, &MediaPlayList::newEntryInList); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myDatabaseContent.init(QStringLiteral("testDbDirectContent")); connect(&myListener, &TracksListener::trackHasChanged, &myPlayList, &MediaPlayList::trackChanged, Qt::QueuedConnection); connect(&myListener, &TracksListener::tracksListAdded, &myPlayList, &MediaPlayList::tracksListAdded, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newTrackByNameInList, &myListener, &TracksListener::trackByNameInList, Qt::QueuedConnection); connect(&myPlayList, &MediaPlayList::newEntryInList, &myListener, &TracksListener::newEntryInList, Qt::QueuedConnection); connect(&myDatabaseContent, &DatabaseInterface::tracksAdded, &myListener, &TracksListener::tracksAdded); myDatabaseContent.insertTracksList(mNewTracks, mNewCovers); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 0); myPlayList.enqueue({{myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1"), QStringLiteral("/")), QStringLiteral("album2")}, {myDatabaseContent.albumIdFromTitleAndArtist(QStringLiteral("album3"), QStringLiteral("artist2"), QStringLiteral("/")), QStringLiteral("album3")}}, ElisaUtils::Album); QVERIFY(dataChangedSpy.wait()); QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0); QCOMPARE(rowsAboutToBeMovedSpy.count(), 0); QCOMPARE(rowsAboutToBeInsertedSpy.count(), 3); QCOMPARE(rowsRemovedSpy.count(), 0); QCOMPARE(rowsMovedSpy.count(), 0); QCOMPARE(rowsInsertedSpy.count(), 3); QCOMPARE(persistentStateChangedSpy.count(), 3); QCOMPARE(dataChangedSpy.count(), 2); QCOMPARE(newTrackByNameInListSpy.count(), 0); QCOMPARE(newEntryInListSpy.count(), 2); QCOMPARE(myPlayList.rowCount(), 9); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 5); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 5); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 6); + QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 6); QCOMPARE(myPlayList.data(myPlayList.index(1, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 7); + QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 7); QCOMPARE(myPlayList.data(myPlayList.index(2, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track4")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 8); + QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 8); QCOMPARE(myPlayList.data(myPlayList.index(3, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track5")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1")); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::TrackNumberRole).toInt(), 5); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 9); + QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 9); QCOMPARE(myPlayList.data(myPlayList.index(4, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track6")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1 and artist2")); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::TrackNumberRole).toInt(), 6); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 10); + QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 10); QCOMPARE(myPlayList.data(myPlayList.index(5, 0), MediaPlayList::AlbumIdRole).toULongLong(), 2); QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track1")); QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 11); + QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 11); QCOMPARE(myPlayList.data(myPlayList.index(6, 0), MediaPlayList::AlbumIdRole).toULongLong(), 3); QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track2")); QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::TrackNumberRole).toInt(), 2); QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 12); + QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 12); QCOMPARE(myPlayList.data(myPlayList.index(7, 0), MediaPlayList::AlbumIdRole).toULongLong(), 3); QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::TitleRole).toString(), QStringLiteral("track3")); QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::AlbumRole).toString(), QStringLiteral("album3")); QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::ArtistRole).toString(), QStringLiteral("artist2")); QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::MilliSecondsDurationRole).toInt(), 13); + QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::DurationRole).toTime().msecsSinceStartOfDay(), 13); QCOMPARE(myPlayList.data(myPlayList.index(8, 0), MediaPlayList::AlbumIdRole).toULongLong(), 3); } QTEST_GUILESS_MAIN(MediaPlayListTest) #include "moc_mediaplaylisttest.cpp" diff --git a/src/abstractfile/abstractfilelisting.cpp b/src/abstractfile/abstractfilelisting.cpp index 0678b525..c049553a 100644 --- a/src/abstractfile/abstractfilelisting.cpp +++ b/src/abstractfile/abstractfilelisting.cpp @@ -1,481 +1,481 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "abstractfilelisting.h" #include "config-upnp-qt.h" #include "abstractfile/indexercommon.h" #include "musicaudiotrack.h" #include "filescanner.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class AbstractFileListingPrivate { public: QStringList mAllRootPaths; QFileSystemWatcher mFileSystemWatcher; QHash mAllAlbumCover; QHash>> mDiscoveredFiles; FileScanner mFileScanner; QMimeDatabase mMimeDb; QHash mAllFiles; QAtomicInt mStopRequest = 0; int mImportedTracksCount = 0; int mNewFilesEmitInterval = 1; bool mHandleNewFiles = true; bool mWaitEndTrackRemoval = false; bool mErrorWatchingFileSystemChanges = false; }; AbstractFileListing::AbstractFileListing(QObject *parent) : QObject(parent), d(std::make_unique()) { connect(&d->mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &AbstractFileListing::directoryChanged); connect(&d->mFileSystemWatcher, &QFileSystemWatcher::fileChanged, this, &AbstractFileListing::fileChanged); } AbstractFileListing::~AbstractFileListing() = default; void AbstractFileListing::init() { Q_EMIT askRestoredTracks(); } void AbstractFileListing::newTrackFile(const MusicAudioTrack &partialTrack) { auto scanFileInfo = QFileInfo(partialTrack.resourceURI().toLocalFile()); const auto &newTrack = scanOneFile(partialTrack.resourceURI(), scanFileInfo); if (newTrack.isValid() && newTrack != partialTrack) { Q_EMIT modifyTracksList({newTrack}, d->mAllAlbumCover); } } void AbstractFileListing::restoredTracks(QHash allFiles) { executeInit(std::move(allFiles)); refreshContent(); } void AbstractFileListing::setAllRootPaths(const QStringList &allRootPaths) { //resolve symlinks QStringList allPaths; for (const auto &path : allRootPaths) { QFileInfo newPath(path); if (newPath.isSymLink()) { allPaths << newPath.symLinkTarget(); } else { allPaths << path; } } d->mAllRootPaths = allPaths; } void AbstractFileListing::databaseFinishedInsertingTracksList() { } void AbstractFileListing::databaseFinishedRemovingTracksList() { if (waitEndTrackRemoval()) { Q_EMIT indexingFinished(); setWaitEndTrackRemoval(false); } } void AbstractFileListing::applicationAboutToQuit() { d->mStopRequest = 1; } const QStringList &AbstractFileListing::allRootPaths() const { return d->mAllRootPaths; } void AbstractFileListing::scanDirectory(QList &newFiles, const QUrl &path) { if (d->mStopRequest == 1) { return; } QDir rootDirectory(path.toLocalFile()); rootDirectory.refresh(); if (rootDirectory.exists()) { watchPath(path.toLocalFile()); } auto ¤tDirectoryListingFiles = d->mDiscoveredFiles[path]; auto currentFilesList = QSet(); rootDirectory.refresh(); const auto entryList = rootDirectory.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); for (const auto &oneEntry : entryList) { auto newFilePath = QUrl::fromLocalFile(oneEntry.canonicalFilePath()); if (oneEntry.isDir() || oneEntry.isFile()) { currentFilesList.insert(newFilePath); } } auto removedTracks = QVector>(); for (const auto &removedFilePath : currentDirectoryListingFiles) { auto itFilePath = std::find(currentFilesList.begin(), currentFilesList.end(), removedFilePath.first); if (itFilePath != currentFilesList.end()) { continue; } removedTracks.push_back(removedFilePath); } auto allRemovedTracks = QList(); for (const auto &oneRemovedTrack : removedTracks) { if (oneRemovedTrack.second) { allRemovedTracks.push_back(oneRemovedTrack.first); } else { removeFile(oneRemovedTrack.first, allRemovedTracks); } } for (const auto &oneRemovedTrack : removedTracks) { currentDirectoryListingFiles.remove(oneRemovedTrack); currentDirectoryListingFiles.remove(oneRemovedTrack); } if (!allRemovedTracks.isEmpty()) { Q_EMIT removedTracksList(allRemovedTracks); } if (!d->mHandleNewFiles) { return; } for (const auto &newFilePath : currentFilesList) { QFileInfo oneEntry(newFilePath.toLocalFile()); auto itFilePath = std::find(currentDirectoryListingFiles.begin(), currentDirectoryListingFiles.end(), QPair{newFilePath, oneEntry.isFile()}); if (itFilePath != currentDirectoryListingFiles.end()) { continue; } if (oneEntry.isDir()) { addFileInDirectory(newFilePath, path); scanDirectory(newFiles, newFilePath); if (d->mStopRequest == 1) { break; } continue; } if (!oneEntry.isFile()) { continue; } auto newTrack = scanOneFile(newFilePath, oneEntry); if (newTrack.isValid() && d->mStopRequest == 0) { addCover(newTrack); addFileInDirectory(newTrack.resourceURI(), path); newFiles.push_back(newTrack); ++d->mImportedTracksCount; if (newFiles.size() > d->mNewFilesEmitInterval && d->mStopRequest == 0) { d->mNewFilesEmitInterval = std::min(50, 1 + d->mNewFilesEmitInterval * d->mNewFilesEmitInterval); emitNewFiles(newFiles); newFiles.clear(); } } else { qCDebug(orgKdeElisaIndexer()) << "AbstractFileListing::scanDirectory" << newFilePath << "is not a valid track"; } if (d->mStopRequest == 1) { break; } } } void AbstractFileListing::directoryChanged(const QString &path) { const auto directoryEntry = d->mDiscoveredFiles.find(QUrl::fromLocalFile(path)); if (directoryEntry == d->mDiscoveredFiles.end()) { return; } Q_EMIT indexingStarted(); scanDirectoryTree(path); Q_EMIT indexingFinished(); } void AbstractFileListing::fileChanged(const QString &modifiedFileName) { QFileInfo modifiedFileInfo(modifiedFileName); auto modifiedFile = QUrl::fromLocalFile(modifiedFileName); auto modifiedTrack = scanOneFile(modifiedFile, modifiedFileInfo); if (modifiedTrack.isValid()) { Q_EMIT modifyTracksList({modifiedTrack}, d->mAllAlbumCover); } } void AbstractFileListing::executeInit(QHash allFiles) { d->mAllFiles = std::move(allFiles); } void AbstractFileListing::triggerRefreshOfContent() { d->mImportedTracksCount = 0; } void AbstractFileListing::refreshContent() { triggerRefreshOfContent(); } MusicAudioTrack AbstractFileListing::scanOneFile(const QUrl &scanFile, const QFileInfo &scanFileInfo) { MusicAudioTrack newTrack; qCDebug(orgKdeElisaIndexer) << "AbstractFileListing::scanOneFile" << scanFile; auto localFileName = scanFile.toLocalFile(); const auto &fileMimeType = d->mMimeDb.mimeTypeForFile(localFileName); if (!fileMimeType.name().startsWith(QLatin1String("audio/"))) { return newTrack; } if (scanFileInfo.exists()) { auto itExistingFile = d->mAllFiles.find(scanFile); if (itExistingFile != d->mAllFiles.end()) { if (*itExistingFile >= scanFileInfo.metadataChangeTime()) { d->mAllFiles.erase(itExistingFile); return newTrack; } } } - newTrack = d->mFileScanner.scanOneFile(scanFile, d->mMimeDb); + newTrack = MusicAudioTrack::trackFromData(d->mFileScanner.scanOneFile(scanFile, d->mMimeDb)); if (newTrack.isValid()) { newTrack.setHasEmbeddedCover(checkEmbeddedCoverImage(localFileName)); newTrack.setFileModificationTime(scanFileInfo.metadataChangeTime()); if (scanFileInfo.exists()) { watchPath(scanFile.toLocalFile()); } } return newTrack; } void AbstractFileListing::watchPath(const QString &pathName) { if (!d->mFileSystemWatcher.addPath(pathName)) { qCDebug(orgKdeElisaIndexer) << "AbstractFileListing::watchPath" << "fail for" << pathName; if (!d->mErrorWatchingFileSystemChanges) { d->mErrorWatchingFileSystemChanges = true; Q_EMIT errorWatchingFileSystemChanges(); } } } void AbstractFileListing::addFileInDirectory(const QUrl &newFile, const QUrl &directoryName) { const auto directoryEntry = d->mDiscoveredFiles.find(directoryName); if (directoryEntry == d->mDiscoveredFiles.end()) { watchPath(directoryName.toLocalFile()); QDir currentDirectory(directoryName.toLocalFile()); if (currentDirectory.cdUp()) { const auto parentDirectoryName = currentDirectory.absolutePath(); const auto parentDirectory = QUrl::fromLocalFile(parentDirectoryName); const auto parentDirectoryEntry = d->mDiscoveredFiles.find(parentDirectory); if (parentDirectoryEntry == d->mDiscoveredFiles.end()) { watchPath(parentDirectoryName); } auto &parentCurrentDirectoryListingFiles = d->mDiscoveredFiles[parentDirectory]; parentCurrentDirectoryListingFiles.insert({directoryName, false}); } } auto ¤tDirectoryListingFiles = d->mDiscoveredFiles[directoryName]; QFileInfo isAFile(newFile.toLocalFile()); currentDirectoryListingFiles.insert({newFile, isAFile.isFile()}); } void AbstractFileListing::scanDirectoryTree(const QString &path) { auto newFiles = QList(); qCDebug(orgKdeElisaIndexer()) << "AbstractFileListing::scanDirectoryTree" << path; scanDirectory(newFiles, QUrl::fromLocalFile(path)); if (!newFiles.isEmpty() && d->mStopRequest == 0) { emitNewFiles(newFiles); } } void AbstractFileListing::setHandleNewFiles(bool handleThem) { d->mHandleNewFiles = handleThem; } void AbstractFileListing::emitNewFiles(const QList &tracks) { Q_EMIT tracksList(tracks, d->mAllAlbumCover); } void AbstractFileListing::addCover(const MusicAudioTrack &newTrack) { auto itCover = d->mAllAlbumCover.find(newTrack.albumName()); if (itCover != d->mAllAlbumCover.end()) { return; } auto coverUrl = d->mFileScanner.searchForCoverFile(newTrack.resourceURI().toLocalFile()); if (!coverUrl.isEmpty()) { d->mAllAlbumCover[newTrack.resourceURI().toString()] = coverUrl; } } void AbstractFileListing::removeDirectory(const QUrl &removedDirectory, QList &allRemovedFiles) { const auto itRemovedDirectory = d->mDiscoveredFiles.find(removedDirectory); if (itRemovedDirectory == d->mDiscoveredFiles.end()) { return; } const auto ¤tRemovedDirectory = *itRemovedDirectory; for (const auto &itFile : currentRemovedDirectory) { if (itFile.first.isValid() && !itFile.first.isEmpty()) { removeFile(itFile.first, allRemovedFiles); if (itFile.second) { allRemovedFiles.push_back(itFile.first); } } } d->mDiscoveredFiles.erase(itRemovedDirectory); } void AbstractFileListing::removeFile(const QUrl &oneRemovedTrack, QList &allRemovedFiles) { auto itRemovedDirectory = d->mDiscoveredFiles.find(oneRemovedTrack); if (itRemovedDirectory != d->mDiscoveredFiles.end()) { removeDirectory(oneRemovedTrack, allRemovedFiles); } } QHash &AbstractFileListing::allFiles() { return d->mAllFiles; } void AbstractFileListing::checkFilesToRemove() { QList allRemovedFiles; for (auto itFile = d->mAllFiles.begin(); itFile != d->mAllFiles.end(); ++itFile) { allRemovedFiles.push_back(itFile.key()); } qCDebug(orgKdeElisaIndexer()) << "AbstractFileListing::checkFilesToRemove" << allRemovedFiles.size(); if (!allRemovedFiles.isEmpty()) { setWaitEndTrackRemoval(true); Q_EMIT removedTracksList(allRemovedFiles); } } FileScanner &AbstractFileListing::fileScanner() { return d->mFileScanner; } bool AbstractFileListing::checkEmbeddedCoverImage(const QString &localFileName) { return d->mFileScanner.checkEmbeddedCoverImage(localFileName); } bool AbstractFileListing::waitEndTrackRemoval() const { return d->mWaitEndTrackRemoval; } void AbstractFileListing::setWaitEndTrackRemoval(bool wait) { d->mWaitEndTrackRemoval = wait; } const QMimeDatabase &AbstractFileListing::mimeDatabase() const { return d->mMimeDb; } #include "moc_abstractfilelisting.cpp" diff --git a/src/baloo/localbaloofilelisting.cpp b/src/baloo/localbaloofilelisting.cpp index 896529b7..b8669248 100644 --- a/src/baloo/localbaloofilelisting.cpp +++ b/src/baloo/localbaloofilelisting.cpp @@ -1,426 +1,427 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "localbaloofilelisting.h" #include "baloo/baloocommon.h" #include "musicaudiotrack.h" #include "elisa_settings.h" #include "elisautils.h" #include "baloo/scheduler.h" #include "baloo/fileindexer.h" #include "baloo/main.h" #include "baloowatcherapplicationadaptor.h" #include "filescanner.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class LocalBalooFileListingPrivate { public: Baloo::Query mQuery; QHash> mAllAlbums; QDBusServiceWatcher mServiceWatcher; QScopedPointer mBalooMainInterface; QScopedPointer mBalooIndexer; QScopedPointer mBalooScheduler; BalooWatcherApplicationAdaptor *mDbusAdaptor = nullptr; QAtomicInt mStopRequest = 0; bool mIsRegisteredToBaloo = false; bool mIsRegisteringToBaloo = false; bool mIsRegisteredToBalooWatcher = false; bool mIsRegisteringToBalooWatcher = false; }; LocalBalooFileListing::LocalBalooFileListing(QObject *parent) : AbstractFileListing(parent), d(std::make_unique()) { d->mQuery.addType(QStringLiteral("Audio")); setHandleNewFiles(false); auto sessionBus = QDBusConnection::sessionBus(); d->mDbusAdaptor = new BalooWatcherApplicationAdaptor(this); sessionBus.registerObject(QStringLiteral("/org/kde/BalooWatcherApplication"), d->mDbusAdaptor, QDBusConnection::ExportAllContents); connect(&d->mServiceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &LocalBalooFileListing::serviceRegistered); connect(&d->mServiceWatcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &LocalBalooFileListing::serviceOwnerChanged); connect(&d->mServiceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &LocalBalooFileListing::serviceUnregistered); d->mServiceWatcher.setConnection(sessionBus); d->mServiceWatcher.addWatchedService(QStringLiteral("org.kde.baloo")); if (sessionBus.interface()->isServiceRegistered(QStringLiteral("org.kde.baloo"))) { registerToBaloo(); } } LocalBalooFileListing::~LocalBalooFileListing() { } void LocalBalooFileListing::applicationAboutToQuit() { AbstractFileListing::applicationAboutToQuit(); d->mStopRequest = 1; } void LocalBalooFileListing::newBalooFile(const QString &fileName) { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::newBalooFile" << fileName; auto scanFileInfo = QFileInfo(fileName); if (!scanFileInfo.exists()) { return; } const auto &fileMimeType = mimeDatabase().mimeTypeForFile(fileName); if (!fileMimeType.name().startsWith(QLatin1String("audio/"))) { return; } Q_EMIT indexingStarted(); auto newFile = QUrl::fromLocalFile(fileName); auto newTrack = scanOneFile(newFile, scanFileInfo); if (newTrack.isValid()) { QFileInfo newFileInfo(fileName); addFileInDirectory(newFile, QUrl::fromLocalFile(newFileInfo.absoluteDir().absolutePath())); emitNewFiles({newTrack}); } Q_EMIT indexingFinished(); } void LocalBalooFileListing::registeredToBaloo(QDBusPendingCallWatcher *watcher) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registeredToBaloo"; if (!watcher) { return; } QDBusPendingReply<> reply = *watcher; if (reply.isError()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registeredToBaloo" << reply.error().name() << reply.error().message(); d->mIsRegisteredToBaloo = false; } else { d->mIsRegisteredToBaloo = true; } d->mIsRegisteringToBaloo = false; watcher->deleteLater(); } void LocalBalooFileListing::registeredToBalooWatcher(QDBusPendingCallWatcher *watcher) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registeredToBalooWatcher"; if (!watcher) { return; } QDBusPendingReply<> reply = *watcher; if (reply.isError()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registeredToBalooWatcher" << reply.error().name() << reply.error().message(); d->mIsRegisteredToBalooWatcher = false; } else { d->mIsRegisteredToBalooWatcher = true; } d->mIsRegisteringToBalooWatcher = false; watcher->deleteLater(); } void LocalBalooFileListing::registerToBaloo() { if (d->mIsRegisteringToBaloo || d->mIsRegisteringToBalooWatcher) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo" << "already registering"; return; } qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo"; d->mIsRegisteringToBaloo = true; d->mIsRegisteringToBalooWatcher = true; auto sessionBus = QDBusConnection::sessionBus(); d->mBalooMainInterface.reset(new org::kde::baloo::main(QStringLiteral("org.kde.baloo"), QStringLiteral("/"), sessionBus, this)); if (!d->mBalooMainInterface->isValid()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo" << "invalid org.kde.baloo/main interface"; return; } d->mBalooIndexer.reset(new org::kde::baloo::fileindexer(QStringLiteral("org.kde.baloo"), QStringLiteral("/fileindexer"), sessionBus, this)); if (!d->mBalooIndexer->isValid()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo" << "invalid org.kde.baloo/fileindexer interface"; return; } connect(d->mBalooIndexer.data(), &org::kde::baloo::fileindexer::finishedIndexingFile, this, &LocalBalooFileListing::newBalooFile); d->mBalooScheduler.reset(new org::kde::baloo::scheduler(QStringLiteral("org.kde.baloo"), QStringLiteral("/scheduler"), sessionBus, this)); if (!d->mBalooScheduler->isValid()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo" << "invalid org.kde.baloo/scheduler interface"; return; } qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo" << "call registerMonitor"; auto answer = d->mBalooIndexer->registerMonitor(); if (answer.isError()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::executeInit" << answer.error().name() << answer.error().message(); } auto pendingCallWatcher = new QDBusPendingCallWatcher(answer); connect(pendingCallWatcher, &QDBusPendingCallWatcher::finished, this, &LocalBalooFileListing::registeredToBaloo); if (pendingCallWatcher->isFinished()) { registeredToBaloo(pendingCallWatcher); } auto pendingCall = d->mBalooMainInterface->registerBalooWatcher(QStringLiteral("org.mpris.MediaPlayer2.elisa/org/kde/BalooWatcherApplication")); qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::registerToBaloo" << "call registerBalooWatcher"; auto pendingCallWatcher2 = new QDBusPendingCallWatcher(pendingCall); connect(pendingCallWatcher2, &QDBusPendingCallWatcher::finished, this, &LocalBalooFileListing::registeredToBalooWatcher); if (pendingCallWatcher2->isFinished()) { registeredToBalooWatcher(pendingCallWatcher2); } } void LocalBalooFileListing::renamedFiles(const QString &from, const QString &to, const QStringList &listFiles) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::renamedFiles" << from << to << listFiles; } void LocalBalooFileListing::serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner) { Q_UNUSED(oldOwner); Q_UNUSED(newOwner); qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::serviceOwnerChanged" << serviceName << oldOwner << newOwner; if (serviceName == QLatin1String("org.kde.baloo") && !newOwner.isEmpty()) { d->mIsRegisteredToBaloo = false; d->mIsRegisteredToBalooWatcher = false; registerToBaloo(); } } void LocalBalooFileListing::serviceRegistered(const QString &serviceName) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::serviceRegistered" << serviceName; if (serviceName == QLatin1String("org.kde.baloo")) { registerToBaloo(); } } void LocalBalooFileListing::serviceUnregistered(const QString &serviceName) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::serviceUnregistered" << serviceName; if (serviceName == QLatin1String("org.kde.baloo")) { d->mIsRegisteredToBaloo = false; d->mIsRegisteredToBalooWatcher = false; } } void LocalBalooFileListing::executeInit(QHash allFiles) { AbstractFileListing::executeInit(std::move(allFiles)); } void LocalBalooFileListing::triggerRefreshOfContent() { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent"; Q_EMIT indexingStarted(); AbstractFileListing::triggerRefreshOfContent(); const auto &rootPaths = allRootPaths(); bool hasSingleRootPath = (rootPaths.size() == 1); auto singleRootPath = rootPaths.at(0); auto resultIterator = d->mQuery.exec(); auto newFiles = QList(); while(resultIterator.next() && d->mStopRequest == 0) { const auto &fileName = resultIterator.filePath(); if (hasSingleRootPath) { if (!fileName.startsWith(singleRootPath)) { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << fileName << "does not match root paths"; continue; } } else { bool isIncluded = false; for (const auto &oneRootPath : rootPaths) { if (fileName.startsWith(oneRootPath)) { isIncluded = true; break; } } if (!isIncluded) { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << fileName << "does not match root paths"; continue; } } const auto &newFileUrl = QUrl::fromLocalFile(resultIterator.filePath()); auto scanFileInfo = QFileInfo(fileName); if (!scanFileInfo.exists()) { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << fileName << "file does not exists"; continue; } auto itExistingFile = allFiles().find(newFileUrl); if (itExistingFile != allFiles().end()) { if (*itExistingFile >= scanFileInfo.fileTime(QFile::FileModificationTime)) { allFiles().erase(itExistingFile); qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << fileName << "file not modified since last scan"; continue; } } const auto currentDirectory = QUrl::fromLocalFile(scanFileInfo.absoluteDir().absolutePath()); addFileInDirectory(newFileUrl, currentDirectory); const auto &newTrack = scanOneFile(newFileUrl, scanFileInfo); if (newTrack.isValid()) { newFiles.push_back(newTrack); if (newFiles.size() > 500 && d->mStopRequest == 0) { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << "insert new tracks in database" << newFiles.count(); emitNewFiles(newFiles); newFiles.clear(); } } else { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << fileName << "invalid track" << newTrack; } } if (!newFiles.isEmpty() && d->mStopRequest == 0) { qCDebug(orgKdeElisaBaloo()) << "LocalBalooFileListing::triggerRefreshOfContent" << "insert new tracks in database" << newFiles.count(); emitNewFiles(newFiles); } setWaitEndTrackRemoval(false); checkFilesToRemove(); if (!waitEndTrackRemoval()) { Q_EMIT indexingFinished(); } } MusicAudioTrack LocalBalooFileListing::scanOneFile(const QUrl &scanFile, const QFileInfo &scanFileInfo) { - auto newTrack = MusicAudioTrack(); + DataTypes::TrackDataType trackData; auto localFileName = scanFile.toLocalFile(); Baloo::File match(localFileName); match.load(); + fileScanner().scanProperties(match, trackData); + + auto newTrack = MusicAudioTrack::trackFromData(trackData); newTrack.setFileModificationTime(scanFileInfo.metadataChangeTime()); newTrack.setResourceURI(scanFile); - fileScanner().scanProperties(match, newTrack); - if (!newTrack.isValid()) { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::scanOneFile" << scanFile << "falling back to plain file metadata analysis"; newTrack = AbstractFileListing::scanOneFile(scanFile, scanFileInfo); } if (newTrack.isValid()) { newTrack.setHasEmbeddedCover(checkEmbeddedCoverImage(localFileName)); addCover(newTrack); } else { qCDebug(orgKdeElisaBaloo) << "LocalBalooFileListing::scanOneFile" << scanFile << "invalid track"; } return newTrack; } #include "moc_localbaloofilelisting.cpp" diff --git a/src/databaseinterface.cpp b/src/databaseinterface.cpp index 6e90a641..bdfccba4 100644 --- a/src/databaseinterface.cpp +++ b/src/databaseinterface.cpp @@ -1,7757 +1,7756 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "databaseinterface.h" #include "databaseLogging.h" #include "musicaudiotrack.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include class DatabaseInterfacePrivate { public: DatabaseInterfacePrivate(const QSqlDatabase &tracksDatabase) : mTracksDatabase(tracksDatabase), mSelectAlbumQuery(mTracksDatabase), mSelectTrackQuery(mTracksDatabase), mSelectAlbumIdFromTitleQuery(mTracksDatabase), mInsertAlbumQuery(mTracksDatabase), mSelectTrackIdFromTitleAlbumIdArtistQuery(mTracksDatabase), mInsertTrackQuery(mTracksDatabase), mSelectTracksFromArtist(mTracksDatabase), mSelectTrackFromIdQuery(mTracksDatabase), mSelectRadioFromIdQuery(mTracksDatabase), mSelectCountAlbumsForArtistQuery(mTracksDatabase), mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery(mTracksDatabase), mSelectAllAlbumsFromArtistQuery(mTracksDatabase), mSelectAllArtistsQuery(mTracksDatabase), mInsertArtistsQuery(mTracksDatabase), mSelectArtistByNameQuery(mTracksDatabase), mSelectArtistQuery(mTracksDatabase), mUpdateTrackStatistics(mTracksDatabase), mRemoveTrackQuery(mTracksDatabase), mRemoveAlbumQuery(mTracksDatabase), mRemoveArtistQuery(mTracksDatabase), mSelectAllTracksQuery(mTracksDatabase), mSelectAllRadiosQuery(mTracksDatabase), mInsertTrackMapping(mTracksDatabase), mUpdateTrackFirstPlayStatistics(mTracksDatabase), mInsertMusicSource(mTracksDatabase), mSelectMusicSource(mTracksDatabase), mUpdateTrackPriority(mTracksDatabase), mUpdateTrackFileModifiedTime(mTracksDatabase), mSelectTracksMapping(mTracksDatabase), mSelectTracksMappingPriority(mTracksDatabase), mSelectRadioIdFromHttpAddress(mTracksDatabase), mUpdateAlbumArtUriFromAlbumIdQuery(mTracksDatabase), mSelectTracksMappingPriorityByTrackId(mTracksDatabase), mSelectAlbumIdsFromArtist(mTracksDatabase), mSelectAllTrackFilesQuery(mTracksDatabase), mRemoveTracksMappingFromSource(mTracksDatabase), mRemoveTracksMapping(mTracksDatabase), mSelectTracksWithoutMappingQuery(mTracksDatabase), mSelectAlbumIdFromTitleAndArtistQuery(mTracksDatabase), mSelectAlbumIdFromTitleWithoutArtistQuery(mTracksDatabase), mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery(mTracksDatabase), mSelectAlbumArtUriFromAlbumIdQuery(mTracksDatabase), mInsertComposerQuery(mTracksDatabase), mSelectComposerByNameQuery(mTracksDatabase), mSelectComposerQuery(mTracksDatabase), mInsertLyricistQuery(mTracksDatabase), mSelectLyricistByNameQuery(mTracksDatabase), mSelectLyricistQuery(mTracksDatabase), mInsertGenreQuery(mTracksDatabase), mSelectGenreByNameQuery(mTracksDatabase), mSelectGenreQuery(mTracksDatabase), mSelectAllTracksShortQuery(mTracksDatabase), mSelectAllAlbumsShortQuery(mTracksDatabase), mSelectAllComposersQuery(mTracksDatabase), mSelectAllLyricistsQuery(mTracksDatabase), mSelectCountAlbumsForComposerQuery(mTracksDatabase), mSelectCountAlbumsForLyricistQuery(mTracksDatabase), mSelectAllGenresQuery(mTracksDatabase), mSelectGenreForArtistQuery(mTracksDatabase), mSelectGenreForAlbumQuery(mTracksDatabase), mUpdateTrackQuery(mTracksDatabase), mUpdateAlbumArtistQuery(mTracksDatabase), mUpdateRadioQuery(mTracksDatabase), mUpdateAlbumArtistInTracksQuery(mTracksDatabase), mQueryMaximumTrackIdQuery(mTracksDatabase), mQueryMaximumAlbumIdQuery(mTracksDatabase), mQueryMaximumArtistIdQuery(mTracksDatabase), mQueryMaximumLyricistIdQuery(mTracksDatabase), mQueryMaximumComposerIdQuery(mTracksDatabase), mQueryMaximumGenreIdQuery(mTracksDatabase), mSelectAllArtistsWithGenreFilterQuery(mTracksDatabase), mSelectAllAlbumsShortWithGenreArtistFilterQuery(mTracksDatabase), mSelectAllAlbumsShortWithArtistFilterQuery(mTracksDatabase), mSelectAllRecentlyPlayedTracksQuery(mTracksDatabase), mSelectAllFrequentlyPlayedTracksQuery(mTracksDatabase), mClearTracksTable(mTracksDatabase), mClearAlbumsTable(mTracksDatabase), mClearArtistsTable(mTracksDatabase), mClearComposerTable(mTracksDatabase), mClearGenreTable(mTracksDatabase), mClearLyricistTable(mTracksDatabase), mArtistMatchGenreQuery(mTracksDatabase), mSelectTrackIdQuery(mTracksDatabase), mInsertRadioQuery(mTracksDatabase), mDeleteRadioQuery(mTracksDatabase) { } QSqlDatabase mTracksDatabase; QSqlQuery mSelectAlbumQuery; QSqlQuery mSelectTrackQuery; QSqlQuery mSelectAlbumIdFromTitleQuery; QSqlQuery mInsertAlbumQuery; QSqlQuery mSelectTrackIdFromTitleAlbumIdArtistQuery; QSqlQuery mInsertTrackQuery; QSqlQuery mSelectTracksFromArtist; QSqlQuery mSelectTrackFromIdQuery; QSqlQuery mSelectRadioFromIdQuery; QSqlQuery mSelectCountAlbumsForArtistQuery; QSqlQuery mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery; QSqlQuery mSelectAllAlbumsFromArtistQuery; QSqlQuery mSelectAllArtistsQuery; QSqlQuery mInsertArtistsQuery; QSqlQuery mSelectArtistByNameQuery; QSqlQuery mSelectArtistQuery; QSqlQuery mUpdateTrackStatistics; QSqlQuery mRemoveTrackQuery; QSqlQuery mRemoveAlbumQuery; QSqlQuery mRemoveArtistQuery; QSqlQuery mSelectAllTracksQuery; QSqlQuery mSelectAllRadiosQuery; QSqlQuery mInsertTrackMapping; QSqlQuery mUpdateTrackFirstPlayStatistics; QSqlQuery mInsertMusicSource; QSqlQuery mSelectMusicSource; QSqlQuery mUpdateTrackPriority; QSqlQuery mUpdateTrackFileModifiedTime; QSqlQuery mSelectTracksMapping; QSqlQuery mSelectTracksMappingPriority; QSqlQuery mSelectRadioIdFromHttpAddress; QSqlQuery mUpdateAlbumArtUriFromAlbumIdQuery; QSqlQuery mSelectTracksMappingPriorityByTrackId; QSqlQuery mSelectAlbumIdsFromArtist; QSqlQuery mSelectAllTrackFilesQuery; QSqlQuery mRemoveTracksMappingFromSource; QSqlQuery mRemoveTracksMapping; QSqlQuery mSelectTracksWithoutMappingQuery; QSqlQuery mSelectAlbumIdFromTitleAndArtistQuery; QSqlQuery mSelectAlbumIdFromTitleWithoutArtistQuery; QSqlQuery mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery; QSqlQuery mSelectAlbumArtUriFromAlbumIdQuery; QSqlQuery mInsertComposerQuery; QSqlQuery mSelectComposerByNameQuery; QSqlQuery mSelectComposerQuery; QSqlQuery mInsertLyricistQuery; QSqlQuery mSelectLyricistByNameQuery; QSqlQuery mSelectLyricistQuery; QSqlQuery mInsertGenreQuery; QSqlQuery mSelectGenreByNameQuery; QSqlQuery mSelectGenreQuery; QSqlQuery mSelectAllTracksShortQuery; QSqlQuery mSelectAllAlbumsShortQuery; QSqlQuery mSelectAllComposersQuery; QSqlQuery mSelectAllLyricistsQuery; QSqlQuery mSelectCountAlbumsForComposerQuery; QSqlQuery mSelectCountAlbumsForLyricistQuery; QSqlQuery mSelectAllGenresQuery; QSqlQuery mSelectGenreForArtistQuery; QSqlQuery mSelectGenreForAlbumQuery; QSqlQuery mUpdateTrackQuery; QSqlQuery mUpdateAlbumArtistQuery; QSqlQuery mUpdateRadioQuery; QSqlQuery mUpdateAlbumArtistInTracksQuery; QSqlQuery mQueryMaximumTrackIdQuery; QSqlQuery mQueryMaximumAlbumIdQuery; QSqlQuery mQueryMaximumArtistIdQuery; QSqlQuery mQueryMaximumLyricistIdQuery; QSqlQuery mQueryMaximumComposerIdQuery; QSqlQuery mQueryMaximumGenreIdQuery; QSqlQuery mSelectAllArtistsWithGenreFilterQuery; QSqlQuery mSelectAllAlbumsShortWithGenreArtistFilterQuery; QSqlQuery mSelectAllAlbumsShortWithArtistFilterQuery; QSqlQuery mSelectAllRecentlyPlayedTracksQuery; QSqlQuery mSelectAllFrequentlyPlayedTracksQuery; QSqlQuery mClearTracksTable; QSqlQuery mClearAlbumsTable; QSqlQuery mClearArtistsTable; QSqlQuery mClearComposerTable; QSqlQuery mClearGenreTable; QSqlQuery mClearLyricistTable; QSqlQuery mArtistMatchGenreQuery; QSqlQuery mSelectTrackIdQuery; QSqlQuery mInsertRadioQuery; QSqlQuery mDeleteRadioQuery; QSet mModifiedTrackIds; QSet mModifiedAlbumIds; QSet mModifiedArtistIds; QSet mInsertedTracks; QSet mInsertedAlbums; QSet mInsertedArtists; qulonglong mAlbumId = 1; qulonglong mArtistId = 1; qulonglong mComposerId = 1; qulonglong mLyricistId = 1; qulonglong mGenreId = 1; qulonglong mTrackId = 1; QAtomicInt mStopRequest = 0; bool mInitFinished = false; bool mIsInBadState = false; }; DatabaseInterface::DatabaseInterface(QObject *parent) : QObject(parent), d(nullptr) { } DatabaseInterface::~DatabaseInterface() { if (d) { d->mTracksDatabase.close(); } } void DatabaseInterface::init(const QString &dbName, const QString &databaseFileName) { QSqlDatabase tracksDatabase = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), dbName); if (!databaseFileName.isEmpty()) { tracksDatabase.setDatabaseName(QStringLiteral("file:") + databaseFileName); } else { tracksDatabase.setDatabaseName(QStringLiteral("file:memdb1?mode=memory")); } tracksDatabase.setConnectOptions(QStringLiteral("foreign_keys = ON;locking_mode = EXCLUSIVE;QSQLITE_OPEN_URI;QSQLITE_BUSY_TIMEOUT=500000")); auto result = tracksDatabase.open(); if (result) { qCDebug(orgKdeElisaDatabase) << "database open"; } else { qCDebug(orgKdeElisaDatabase) << "database not open"; } qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::init" << (tracksDatabase.driver()->hasFeature(QSqlDriver::Transactions) ? "yes" : "no"); tracksDatabase.exec(QStringLiteral("PRAGMA foreign_keys = ON;")); d = std::make_unique(tracksDatabase); initDatabase(); initRequest(); if (!databaseFileName.isEmpty()) { reloadExistingDatabase(); } } qulonglong DatabaseInterface::albumIdFromTitleAndArtist(const QString &title, const QString &artist, const QString &albumPath) { auto result = qulonglong{0}; auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalAlbumIdFromTitleAndArtist(title, artist, albumPath); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListTrackDataType DatabaseInterface::allTracksData() { auto result = DataTypes::ListTrackDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalAllTracksPartialData(); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListRadioDataType DatabaseInterface::allRadiosData() { auto result = DataTypes::ListRadioDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalAllRadiosPartialData(); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListTrackDataType DatabaseInterface::recentlyPlayedTracksData(int count) { auto result = DataTypes::ListTrackDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalRecentlyPlayedTracksData(count); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListTrackDataType DatabaseInterface::frequentlyPlayedTracksData(int count) { auto result = DataTypes::ListTrackDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalFrequentlyPlayedTracksData(count); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListAlbumDataType DatabaseInterface::allAlbumsData() { auto result = DataTypes::ListAlbumDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalAllAlbumsPartialData(d->mSelectAllAlbumsShortQuery); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListAlbumDataType DatabaseInterface::allAlbumsDataByGenreAndArtist(const QString &genre, const QString &artist) { auto result = DataTypes::ListAlbumDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.bindValue(QStringLiteral(":artistFilter"), artist); d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.bindValue(QStringLiteral(":genreFilter"), genre); result = internalAllAlbumsPartialData(d->mSelectAllAlbumsShortWithGenreArtistFilterQuery); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListAlbumDataType DatabaseInterface::allAlbumsDataByArtist(const QString &artist) { auto result = DataTypes::ListAlbumDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } d->mSelectAllAlbumsShortWithArtistFilterQuery.bindValue(QStringLiteral(":artistFilter"), artist); result = internalAllAlbumsPartialData(d->mSelectAllAlbumsShortWithArtistFilterQuery); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::AlbumDataType DatabaseInterface::albumDataFromDatabaseId(qulonglong id) { auto result = DataTypes::AlbumDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalOneAlbumPartialData(id); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListTrackDataType DatabaseInterface::albumData(qulonglong databaseId) { auto result = DataTypes::ListTrackDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } d->mSelectTrackQuery.bindValue(QStringLiteral(":albumId"), databaseId); auto queryResult = execQuery(d->mSelectTrackQuery); if (!queryResult || !d->mSelectTrackQuery.isSelect() || !d->mSelectTrackQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::albumData" << d->mSelectTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::albumData" << d->mSelectTrackQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::albumData" << d->mSelectTrackQuery.lastError(); } while (d->mSelectTrackQuery.next()) { const auto ¤tRecord = d->mSelectTrackQuery.record(); result.push_back(buildTrackDataFromDatabaseRecord(currentRecord)); } d->mSelectTrackQuery.finish(); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListArtistDataType DatabaseInterface::allArtistsData() { auto result = DataTypes::ListArtistDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalAllArtistsPartialData(d->mSelectAllArtistsQuery); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListArtistDataType DatabaseInterface::allArtistsDataByGenre(const QString &genre) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::allArtistsDataByGenre" << genre; auto result = DataTypes::ListArtistDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } d->mSelectAllArtistsWithGenreFilterQuery.bindValue(QStringLiteral(":genreFilter"), genre); result = internalAllArtistsPartialData(d->mSelectAllArtistsWithGenreFilterQuery); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::ListGenreDataType DatabaseInterface::allGenresData() { auto result = DataTypes::ListGenreDataType{}; if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalAllGenresPartialData(); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } bool DatabaseInterface::internalArtistMatchGenre(qulonglong databaseId, const QString &genre) { auto result = true; if (!d) { return result; } d->mArtistMatchGenreQuery.bindValue(QStringLiteral(":databaseId"), databaseId); d->mArtistMatchGenreQuery.bindValue(QStringLiteral(":genreFilter"), genre); auto queryResult = execQuery(d->mArtistMatchGenreQuery); if (!queryResult || !d->mArtistMatchGenreQuery.isSelect() || !d->mArtistMatchGenreQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::artistMatchGenre" << d->mArtistMatchGenreQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::artistMatchGenre" << d->mArtistMatchGenreQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::artistMatchGenre" << d->mArtistMatchGenreQuery.lastError(); d->mArtistMatchGenreQuery.finish(); auto transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } result = d->mArtistMatchGenreQuery.next(); d->mArtistMatchGenreQuery.finish(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalArtistMatchGenre" << databaseId << (result ? "match" : "does not match"); return result; } DataTypes::ListTrackDataType DatabaseInterface::tracksDataFromAuthor(const QString &ArtistName) { auto allTracks = DataTypes::ListTrackDataType{}; auto transactionResult = startTransaction(); if (!transactionResult) { return allTracks; } allTracks = internalTracksFromAuthor(ArtistName); transactionResult = finishTransaction(); if (!transactionResult) { return allTracks; } return allTracks; } DataTypes::TrackDataType DatabaseInterface::trackDataFromDatabaseId(qulonglong id) { auto result = DataTypes::TrackDataType(); if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalOneTrackPartialData(id); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } DataTypes::TrackDataType DatabaseInterface::radioDataFromDatabaseId(qulonglong id) { auto result = DataTypes::TrackDataType(); if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalOneRadioPartialData(id); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } qulonglong DatabaseInterface::trackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &artist, const std::optional &album, std::optional trackNumber, std::optional discNumber) { auto result = qulonglong(0); if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalTrackIdFromTitleAlbumTracDiscNumber(title, artist, album, trackNumber, discNumber); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } qulonglong DatabaseInterface::trackIdFromFileName(const QUrl &fileName) { auto result = qulonglong(0); if (!d) { return result; } auto transactionResult = startTransaction(); if (!transactionResult) { return result; } result = internalTrackIdFromFileName(fileName); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } void DatabaseInterface::applicationAboutToQuit() { d->mStopRequest = 1; } void DatabaseInterface::askRestoredTracks() { auto transactionResult = startTransaction(); if (!transactionResult) { return; } auto result = internalAllFileName(); Q_EMIT restoredTracks(result); transactionResult = finishTransaction(); if (!transactionResult) { return; } } void DatabaseInterface::trackHasStartedPlaying(const QUrl &fileName, const QDateTime &time) { auto transactionResult = startTransaction(); if (!transactionResult) { return; } updateTrackStatistics(fileName, time); auto trackId = internalTrackIdFromFileName(fileName); if (trackId != 0) { Q_EMIT trackModified(internalOneTrackPartialData(trackId)); } transactionResult = finishTransaction(); if (!transactionResult) { return; } } void DatabaseInterface::clearData() { auto transactionResult = startTransaction(); if (!transactionResult) { return; } auto queryResult = execQuery(d->mClearTracksTable); if (!queryResult || !d->mClearTracksTable.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksTable.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksTable.lastError(); } d->mClearTracksTable.finish(); queryResult = execQuery(d->mClearAlbumsTable); if (!queryResult || !d->mClearAlbumsTable.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearAlbumsTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearAlbumsTable.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearAlbumsTable.lastError(); } d->mClearAlbumsTable.finish(); queryResult = execQuery(d->mClearComposerTable); if (!queryResult || !d->mClearComposerTable.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearComposerTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearComposerTable.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearComposerTable.lastError(); } d->mClearComposerTable.finish(); queryResult = execQuery(d->mClearLyricistTable); if (!queryResult || !d->mClearLyricistTable.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearLyricistTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearLyricistTable.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearLyricistTable.lastError(); } d->mClearLyricistTable.finish(); queryResult = execQuery(d->mClearGenreTable); if (!queryResult || !d->mClearGenreTable.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearGenreTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearGenreTable.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearGenreTable.lastError(); } d->mClearGenreTable.finish(); queryResult = execQuery(d->mClearArtistsTable); if (!queryResult || !d->mClearArtistsTable.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearArtistsTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearArtistsTable.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearArtistsTable.lastError(); } d->mClearArtistsTable.finish(); transactionResult = finishTransaction(); if (!transactionResult) { return; } Q_EMIT cleanedDatabase(); } void DatabaseInterface::initChangesTrackers() { d->mModifiedTrackIds.clear(); d->mModifiedAlbumIds.clear(); d->mModifiedArtistIds.clear(); d->mInsertedTracks.clear(); d->mInsertedAlbums.clear(); d->mInsertedArtists.clear(); } void DatabaseInterface::recordModifiedTrack(qulonglong trackId) { d->mModifiedTrackIds.insert(trackId); } void DatabaseInterface::recordModifiedAlbum(qulonglong albumId) { d->mModifiedAlbumIds.insert(albumId); } void DatabaseInterface::insertTracksList(const QList &tracks, const QHash &covers) { qCDebug(orgKdeElisaDatabase()) << "DatabaseInterface::insertTracksList" << tracks.count(); if (d->mStopRequest == 1) { Q_EMIT finishInsertingTracksList(); return; } auto transactionResult = startTransaction(); if (!transactionResult) { Q_EMIT finishInsertingTracksList(); return; } initChangesTrackers(); for(const auto &oneTrack : tracks) { d->mSelectTracksMapping.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); auto result = execQuery(d->mSelectTracksMapping); if (!result || !d->mSelectTracksMapping.isSelect() || !d->mSelectTracksMapping.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << d->mSelectTracksMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << d->mSelectTracksMapping.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << d->mSelectTracksMapping.lastError(); d->mSelectTracksMapping.finish(); rollBackTransaction(); Q_EMIT finishInsertingTracksList(); return; } bool isNewTrack = !d->mSelectTracksMapping.next(); if (isNewTrack) { insertTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime(), QDateTime::currentDateTime()); } else if (!d->mSelectTracksMapping.record().value(0).isNull() && d->mSelectTracksMapping.record().value(0).toULongLong() != 0) { updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); } d->mSelectTracksMapping.finish(); bool isInserted = false; const auto insertedTrackId = internalInsertTrack(oneTrack, covers, isInserted); if (isInserted && insertedTrackId != 0) { d->mInsertedTracks.insert(insertedTrackId); } if (d->mStopRequest == 1) { transactionResult = finishTransaction(); if (!transactionResult) { Q_EMIT finishInsertingTracksList(); return; } Q_EMIT finishInsertingTracksList(); return; } } if (!d->mInsertedArtists.isEmpty()) { DataTypes::ListArtistDataType newArtists; for (auto artistId : qAsConst(d->mInsertedArtists)) { newArtists.push_back({{DataTypes::DatabaseIdRole, artistId}}); } qCInfo(orgKdeElisaDatabase) << "artistsAdded" << newArtists.size(); Q_EMIT artistsAdded(newArtists); } if (!d->mInsertedAlbums.isEmpty()) { DataTypes::ListAlbumDataType newAlbums; for (auto albumId : qAsConst(d->mInsertedAlbums)) { d->mModifiedAlbumIds.remove(albumId); newAlbums.push_back(internalOneAlbumPartialData(albumId)); } qCInfo(orgKdeElisaDatabase) << "albumsAdded" << newAlbums.size(); Q_EMIT albumsAdded(newAlbums); } for (auto albumId : qAsConst(d->mModifiedAlbumIds)) { Q_EMIT albumModified({{DataTypes::DatabaseIdRole, albumId}}, albumId); } if (!d->mInsertedTracks.isEmpty()) { DataTypes::ListTrackDataType newTracks; for (auto trackId : qAsConst(d->mInsertedTracks)) { newTracks.push_back(internalOneTrackPartialData(trackId)); d->mModifiedTrackIds.remove(trackId); } qCInfo(orgKdeElisaDatabase) << "tracksAdded" << newTracks.size(); Q_EMIT tracksAdded(newTracks); } for (auto trackId : qAsConst(d->mModifiedTrackIds)) { Q_EMIT trackModified(internalOneTrackPartialData(trackId)); } transactionResult = finishTransaction(); if (!transactionResult) { Q_EMIT finishInsertingTracksList(); return; } Q_EMIT finishInsertingTracksList(); } void DatabaseInterface::removeTracksList(const QList &removedTracks) { auto transactionResult = startTransaction(); if (!transactionResult) { Q_EMIT finishRemovingTracksList(); return; } initChangesTrackers(); internalRemoveTracksList(removedTracks); if (!d->mInsertedArtists.isEmpty()) { DataTypes::ListArtistDataType newArtists; for (auto artistId : qAsConst(d->mInsertedArtists)) { newArtists.push_back({{DataTypes::DatabaseIdRole, artistId}}); } Q_EMIT artistsAdded(newArtists); } transactionResult = finishTransaction(); if (!transactionResult) { Q_EMIT finishRemovingTracksList(); return; } Q_EMIT finishRemovingTracksList(); } bool DatabaseInterface::startTransaction() const { auto result = false; auto transactionResult = d->mTracksDatabase.transaction(); if (!transactionResult) { qCDebug(orgKdeElisaDatabase) << "transaction failed" << d->mTracksDatabase.lastError() << d->mTracksDatabase.lastError().driverText(); return result; } result = true; return result; } bool DatabaseInterface::finishTransaction() const { auto result = false; auto transactionResult = d->mTracksDatabase.commit(); if (!transactionResult) { qCDebug(orgKdeElisaDatabase) << "commit failed" << d->mTracksDatabase.lastError() << d->mTracksDatabase.lastError().nativeErrorCode(); return result; } result = true; return result; } bool DatabaseInterface::rollBackTransaction() const { auto result = false; auto transactionResult = d->mTracksDatabase.rollback(); if (!transactionResult) { qCDebug(orgKdeElisaDatabase) << "commit failed" << d->mTracksDatabase.lastError() << d->mTracksDatabase.lastError().nativeErrorCode(); return result; } result = true; return result; } void DatabaseInterface::initDatabase() { auto listTables = d->mTracksDatabase.tables(); if (listTables.contains(QLatin1String("DatabaseVersionV2")) || listTables.contains(QLatin1String("DatabaseVersionV3")) || listTables.contains(QLatin1String("DatabaseVersionV4")) || listTables.contains(QLatin1String("DatabaseVersionV6")) || listTables.contains(QLatin1String("DatabaseVersionV7")) || listTables.contains(QLatin1String("DatabaseVersionV8")) || listTables.contains(QLatin1String("DatabaseVersionV10"))) { qCDebug(orgKdeElisaDatabase()) << "Old database schema unsupported: delete and start from scratch"; qCDebug(orgKdeElisaDatabase()) << "list of old tables" << d->mTracksDatabase.tables(); auto oldTables = QStringList{ QStringLiteral("DatabaseVersionV2"), QStringLiteral("DatabaseVersionV3"), QStringLiteral("DatabaseVersionV4"), QStringLiteral("DatabaseVersionV5"), QStringLiteral("DatabaseVersionV6"), QStringLiteral("DatabaseVersionV7"), QStringLiteral("DatabaseVersionV8"), QStringLiteral("DatabaseVersionV10"), QStringLiteral("AlbumsArtists"), QStringLiteral("TracksArtists"), QStringLiteral("TracksMapping"), QStringLiteral("Tracks"), QStringLiteral("Composer"), QStringLiteral("Genre"), QStringLiteral("Lyricist"), QStringLiteral("Albums"), QStringLiteral("DiscoverSource"), QStringLiteral("Artists"),}; for (const auto &oneTable : oldTables) { if (listTables.indexOf(oneTable) == -1) { continue; } QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QLatin1String("DROP TABLE ") + oneTable); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabase" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } listTables = d->mTracksDatabase.tables(); } listTables = d->mTracksDatabase.tables(); if (listTables.contains(QLatin1String("DatabaseVersionV5")) && !listTables.contains(QLatin1String("DatabaseVersionV9"))) { upgradeDatabaseV9(); upgradeDatabaseV11(); upgradeDatabaseV12(); upgradeDatabaseV13(); upgradeDatabaseV14(); checkDatabaseSchema(); } else if (listTables.contains(QLatin1String("DatabaseVersionV9"))) { if (!listTables.contains(QLatin1String("DatabaseVersionV11"))) { upgradeDatabaseV11(); } if (!listTables.contains(QLatin1String("DatabaseVersionV12"))) { upgradeDatabaseV12(); } if (!listTables.contains(QLatin1String("DatabaseVersionV13"))) { upgradeDatabaseV13(); } if (!listTables.contains(QLatin1String("DatabaseVersionV14"))) { upgradeDatabaseV14(); } checkDatabaseSchema(); } else { createDatabaseV9(); upgradeDatabaseV11(); upgradeDatabaseV12(); upgradeDatabaseV13(); upgradeDatabaseV14(); } } void DatabaseInterface::createDatabaseV9() { qCInfo(orgKdeElisaDatabase) << "begin creation of v9 database schema"; { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV9` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DiscoverSource` (`ID` INTEGER PRIMARY KEY NOT NULL, " "`Name` VARCHAR(55) NOT NULL, " "UNIQUE (`Name`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Artists` (`ID` INTEGER PRIMARY KEY NOT NULL, " "`Name` VARCHAR(55) NOT NULL, " "UNIQUE (`Name`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Composer` (`ID` INTEGER PRIMARY KEY NOT NULL, " "`Name` VARCHAR(55) NOT NULL, " "UNIQUE (`Name`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Genre` (`ID` INTEGER PRIMARY KEY NOT NULL, " "`Name` VARCHAR(85) NOT NULL, " "UNIQUE (`Name`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Lyricist` (`ID` INTEGER PRIMARY KEY NOT NULL, " "`Name` VARCHAR(55) NOT NULL, " "UNIQUE (`Name`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Albums` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(55) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255) NOT NULL, " "`CoverFileName` VARCHAR(255) NOT NULL, " "UNIQUE (`Title`, `ArtistName`, `AlbumPath`), " "CONSTRAINT fk_artists FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`) " "ON DELETE CASCADE)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Tracks` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumTitle` VARCHAR(55), " "`AlbumArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255), " "`TrackNumber` INTEGER DEFAULT -1, " "`DiscNumber` INTEGER DEFAULT -1, " "`Duration` INTEGER NOT NULL, " "`Rating` INTEGER NOT NULL DEFAULT 0, " "`Genre` VARCHAR(55), " "`Composer` VARCHAR(55), " "`Lyricist` VARCHAR(55), " "`Comment` VARCHAR(255) DEFAULT '', " "`Year` INTEGER DEFAULT 0, " "`Channels` INTEGER DEFAULT -1, " "`BitRate` INTEGER DEFAULT -1, " "`SampleRate` INTEGER DEFAULT -1, " "`HasEmbeddedCover` BOOLEAN NOT NULL, " "`ImportDate` INTEGER NOT NULL, " "`FirstPlayDate` INTEGER, " "`LastPlayDate` INTEGER, " "`PlayCounter` INTEGER NOT NULL, " "UNIQUE (" "`Title`, `AlbumTitle`, `AlbumArtistName`, " "`AlbumPath`, `TrackNumber`, `DiscNumber`" "), " "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " "CONSTRAINT fk_tracks_album FOREIGN KEY (" "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `TracksMapping` (" "`TrackID` INTEGER NULL, " "`DiscoverID` INTEGER NOT NULL, " "`FileName` VARCHAR(255) NOT NULL, " "`Priority` INTEGER NOT NULL, " "`FileModifiedTime` DATETIME NOT NULL, " "PRIMARY KEY (`FileName`), " "CONSTRAINT TracksUnique UNIQUE (`TrackID`, `Priority`), " "CONSTRAINT fk_tracksmapping_trackID FOREIGN KEY (`TrackID`) REFERENCES `Tracks`(`ID`) ON DELETE CASCADE, " "CONSTRAINT fk_tracksmapping_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TitleAlbumsIndex` ON `Albums` " "(`Title`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`ArtistNameAlbumsIndex` ON `Albums` " "(`ArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksAlbumIndex` ON `Tracks` " "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`ArtistNameIndex` ON `Tracks` " "(`ArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`AlbumArtistNameIndex` ON `Tracks` " "(`AlbumArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksFileNameIndex` ON `TracksMapping` " "(`FileName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } qCInfo(orgKdeElisaDatabase) << "end creation of v9 database schema"; } void DatabaseInterface::upgradeDatabaseV9() { qCInfo(orgKdeElisaDatabase) << "begin update to v9 of database schema"; { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV9` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery disableForeignKeys(d->mTracksDatabase); auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << disableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << disableForeignKeys.lastError(); Q_EMIT databaseError(); } } d->mTracksDatabase.transaction(); { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewAlbums` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(55) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255) NOT NULL, " "`CoverFileName` VARCHAR(255) NOT NULL, " "UNIQUE (`Title`, `ArtistName`, `AlbumPath`), " "CONSTRAINT fk_artists FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`) " "ON DELETE CASCADE)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewAlbums` " "SELECT " "album.`ID`, " "album.`Title`, " "artist.`Name`, " "album.`AlbumPath`, " "album.`CoverFileName` " "FROM " "`Albums` album, " "`AlbumsArtists` albumArtistMapping, " "`Artists` artist " "WHERE " "album.`ID` = albumArtistMapping.`AlbumID` AND " "albumArtistMapping.`ArtistID` = artist.`ID`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Albums`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `AlbumsArtists`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewAlbums` RENAME TO `Albums`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumTitle` VARCHAR(55), " "`AlbumArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255), " "`TrackNumber` INTEGER DEFAULT -1, " "`DiscNumber` INTEGER DEFAULT -1, " "`Duration` INTEGER NOT NULL, " "`Rating` INTEGER NOT NULL DEFAULT 0, " "`Genre` VARCHAR(55), " "`Composer` VARCHAR(55), " "`Lyricist` VARCHAR(55), " "`Comment` VARCHAR(255) DEFAULT '', " "`Year` INTEGER DEFAULT 0, " "`Channels` INTEGER DEFAULT -1, " "`BitRate` INTEGER DEFAULT -1, " "`SampleRate` INTEGER DEFAULT -1, " "`HasEmbeddedCover` BOOLEAN NOT NULL, " "`ImportDate` INTEGER NOT NULL, " "`FirstPlayDate` INTEGER, " "`LastPlayDate` INTEGER, " "`PlayCounter` INTEGER NOT NULL, " "UNIQUE (" "`Title`, `AlbumTitle`, `AlbumArtistName`, " "`AlbumPath`, `TrackNumber`, `DiscNumber`" "), " "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " "CONSTRAINT fk_tracks_album FOREIGN KEY (" "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracks` " "(`ID`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " "`TrackNumber`, `DiscNumber`, `Duration`, " "`Rating`, `Genre`, `Composer`, " "`Lyricist`, `Comment`, `Year`, " "`Channels`, `BitRate`, `SampleRate`, " "`HasEmbeddedCover`, `ImportDate`, `PlayCounter`) " "SELECT " "track.`ID`, " "track.`Title`, " "artist.`Name`, " "album.`Title`, " "album.`ArtistName`, " "album.`AlbumPath`, " "track.`TrackNumber`, " "track.`DiscNumber`, " "track.`Duration`, " "track.`Rating`, " "genre.`Name`, " "composer.`Name`, " "lyricist.`Name`, " "track.`Comment`, " "track.`Year`, " "track.`Channels`, " "track.`BitRate`, " "track.`SampleRate`, " "FALSE, " "strftime('%s', 'now'), " "0 " "FROM " "`Tracks` track, " "`TracksArtists` trackArtistMapping, " "`Artists` artist, " "`Albums` album " "left join " "`Genre` genre " "on track.`GenreID` = genre.`ID` " "left join " "`Composer` composer " "on track.`ComposerID` = composer.`ID` " "left join " "`Lyricist` lyricist " "on track.`LyricistID` = lyricist.`ID` " "WHERE " "track.`ID` = trackArtistMapping.`TrackID` AND " "trackArtistMapping.`ArtistID` = artist.`ID` AND " "track.`AlbumID` = album.`ID`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `TracksArtists`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << 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::upgradeDatabaseV9" << enableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << enableForeignKeys.lastError(); Q_EMIT databaseError(); } } qCInfo(orgKdeElisaDatabase) << "finished update to v9 of database schema"; } void DatabaseInterface::upgradeDatabaseV11() { qCInfo(orgKdeElisaDatabase) << "begin update to v11 of database schema"; { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV11` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery disableForeignKeys(d->mTracksDatabase); auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << disableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << disableForeignKeys.lastError(); Q_EMIT databaseError(); } } d->mTracksDatabase.transaction(); { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `TracksData` (" "`DiscoverID` INTEGER NOT NULL, " "`FileName` VARCHAR(255) NOT NULL, " "`FileModifiedTime` DATETIME NOT NULL, " "`ImportDate` INTEGER NOT NULL, " "`FirstPlayDate` INTEGER, " "`LastPlayDate` INTEGER, " "`PlayCounter` INTEGER NOT NULL, " "PRIMARY KEY (`FileName`, `DiscoverID`), " "CONSTRAINT fk_tracksmapping_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `TracksData` " "SELECT " "m.`DiscoverID`, " "m.`FileName`, " "m.`FileModifiedTime`, " "t.`ImportDate`, " "t.`FirstPlayDate`, " "t.`LastPlayDate`, " "t.`PlayCounter` " "FROM " "`Tracks` t, " "`TracksMapping` m " "WHERE " "t.`ID` = m.`TrackID`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " "`DiscoverID` INTEGER NOT NULL, " "`FileName` VARCHAR(255) NOT NULL, " "`Priority` INTEGER NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumTitle` VARCHAR(55), " "`AlbumArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255), " "`TrackNumber` INTEGER, " "`DiscNumber` INTEGER, " "`Duration` INTEGER NOT NULL, " "`Rating` INTEGER NOT NULL DEFAULT 0, " "`Genre` VARCHAR(55), " "`Composer` VARCHAR(55), " "`Lyricist` VARCHAR(55), " "`Comment` VARCHAR(255), " "`Year` INTEGER, " "`Channels` INTEGER, " "`BitRate` INTEGER, " "`SampleRate` INTEGER, " "`HasEmbeddedCover` BOOLEAN NOT NULL, " "UNIQUE (" "`FileName`" "), " "UNIQUE (" "`Priority`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`" "), " "CONSTRAINT fk_fileName FOREIGN KEY (`FileName`, `DiscoverID`) " "REFERENCES `TracksData`(`FileName`, `DiscoverID`) ON DELETE CASCADE, " "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " "CONSTRAINT fk_tracks_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`)" "CONSTRAINT fk_tracks_album FOREIGN KEY (" "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT OR IGNORE INTO `NewTracks` " "(" "`DiscoverID`, " "`FileName`, " "`Priority`, " "`Title`, " "`ArtistName`, " "`AlbumTitle`, " "`AlbumArtistName`, " "`AlbumPath`, " "`TrackNumber`, " "`DiscNumber`, " "`Duration`, " "`Rating`, " "`Genre`, " "`Composer`, " "`Lyricist`, " "`Comment`, " "`Year`, " "`Channels`, " "`BitRate`, " "`SampleRate`, " "`HasEmbeddedCover`" ") " "SELECT " "m.`DiscoverID`, " "m.`FileName`, " "m.`Priority`, " "t.`Title`, " "t.`ArtistName`, " "t.`AlbumTitle`, " "t.`AlbumArtistName`, " "t.`AlbumPath`, " "t.`TrackNumber`, " "t.`DiscNumber`, " "t.`Duration`, " "t.`Rating`, " "t.`Genre`, " "t.`Composer`, " "t.`Lyricist`, " "t.`Comment`, " "t.`Year`, " "t.`Channels`, " "t.`BitRate`, " "t.`SampleRate`, " "t.`HasEmbeddedCover` " "FROM " "`Tracks` t, " "`TracksMapping` m " "WHERE " "t.`ID` = m.`TrackID`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery updateDataQuery(d->mTracksDatabase); auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " "SET " "`TrackNumber` = NULL " "WHERE " "`TrackNumber` = -1")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery updateDataQuery(d->mTracksDatabase); auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " "SET " "`Channels` = NULL " "WHERE " "`Channels` = -1")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery updateDataQuery(d->mTracksDatabase); auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " "SET " "`BitRate` = NULL " "WHERE " "`BitRate` = -1")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery updateDataQuery(d->mTracksDatabase); auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " "SET " "`SampleRate` = NULL " "WHERE " "`SampleRate` = -1")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `TracksMapping`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << 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::upgradeDatabaseV11" << enableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << enableForeignKeys.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksAlbumIndex` ON `Tracks` " "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`ArtistNameIndex` ON `Tracks` " "(`ArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`AlbumArtistNameIndex` ON `Tracks` " "(`AlbumArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksUniqueData` ON `Tracks` " "(`Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksUniqueDataPriority` ON `Tracks` " "(`Priority`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksFileNameIndex` ON `Tracks` " "(`FileName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } qCInfo(orgKdeElisaDatabase) << "finished update to v11 of database schema"; } void DatabaseInterface::upgradeDatabaseV12() { qCInfo(orgKdeElisaDatabase) << "begin update to v12 of database schema"; { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV12` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery disableForeignKeys(d->mTracksDatabase); auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << disableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << disableForeignKeys.lastError(); Q_EMIT databaseError(); } } d->mTracksDatabase.transaction(); { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " "`FileName` VARCHAR(255) NOT NULL, " "`Priority` INTEGER NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumTitle` VARCHAR(55), " "`AlbumArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255), " "`TrackNumber` INTEGER, " "`DiscNumber` INTEGER, " "`Duration` INTEGER NOT NULL, " "`Rating` INTEGER NOT NULL DEFAULT 0, " "`Genre` VARCHAR(55), " "`Composer` VARCHAR(55), " "`Lyricist` VARCHAR(55), " "`Comment` VARCHAR(255), " "`Year` INTEGER, " "`Channels` INTEGER, " "`BitRate` INTEGER, " "`SampleRate` INTEGER, " "`HasEmbeddedCover` BOOLEAN NOT NULL, " "UNIQUE (" "`FileName`" "), " "UNIQUE (" "`Priority`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`" "), " "CONSTRAINT fk_fileName FOREIGN KEY (`FileName`) " "REFERENCES `TracksData`(`FileName`) ON DELETE CASCADE, " "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " "CONSTRAINT fk_tracks_album FOREIGN KEY (" "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracksData` (" "`FileName` VARCHAR(255) NOT NULL, " "`FileModifiedTime` DATETIME NOT NULL, " "`ImportDate` INTEGER NOT NULL, " "`FirstPlayDate` INTEGER, " "`LastPlayDate` INTEGER, " "`PlayCounter` INTEGER NOT NULL, " "PRIMARY KEY (`FileName`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracksData` " "SELECT " "td.`FileName`, " "td.`FileModifiedTime`, " "td.`ImportDate`, " "td.`FirstPlayDate`, " "td.`LastPlayDate`, " "td.`PlayCounter` " "FROM " "`TracksData` td")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracks` " "SELECT " "t.`ID`, " "t.`FileName`, " "t.`Priority`, " "t.`Title`, " "t.`ArtistName`, " "t.`AlbumTitle`, " "t.`AlbumArtistName`, " "t.`AlbumPath`, " "t.`TrackNumber`, " "t.`DiscNumber`, " "t.`Duration`, " "t.`Rating`, " "t.`Genre`, " "t.`Composer`, " "t.`Lyricist`, " "t.`Comment`, " "t.`Year`, " "t.`Channels`, " "t.`BitRate`, " "t.`SampleRate`, " "t.`HasEmbeddedCover` " "FROM " "`Tracks` t")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `TracksData`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracksData` RENAME TO `TracksData`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << 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::upgradeDatabaseV12" << enableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << enableForeignKeys.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksAlbumIndex` ON `Tracks` " "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`ArtistNameIndex` ON `Tracks` " "(`ArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`AlbumArtistNameIndex` ON `Tracks` " "(`AlbumArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksUniqueData` ON `Tracks` " "(`Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksUniqueDataPriority` ON `Tracks` " "(`Priority`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksFileNameIndex` ON `Tracks` " "(`FileName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } qCInfo(orgKdeElisaDatabase) << "finished update to v12 of database schema"; } void DatabaseInterface::upgradeDatabaseV13() { qCInfo(orgKdeElisaDatabase) << "begin update to v13 of database schema"; { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV13` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery disableForeignKeys(d->mTracksDatabase); auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << disableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << disableForeignKeys.lastError(); Q_EMIT databaseError(); } } d->mTracksDatabase.transaction(); { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " "`FileName` VARCHAR(255) NOT NULL, " "`Priority` INTEGER NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " "`ArtistName` VARCHAR(55), " "`AlbumTitle` VARCHAR(55), " "`AlbumArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255), " "`TrackNumber` INTEGER, " "`DiscNumber` INTEGER, " "`Duration` INTEGER NOT NULL, " "`Rating` INTEGER NOT NULL DEFAULT 0, " "`Genre` VARCHAR(55), " "`Composer` VARCHAR(55), " "`Lyricist` VARCHAR(55), " "`Comment` VARCHAR(255), " "`Year` INTEGER, " "`Channels` INTEGER, " "`BitRate` INTEGER, " "`SampleRate` INTEGER, " "`HasEmbeddedCover` BOOLEAN NOT NULL, " "UNIQUE (" "`FileName`" "), " "UNIQUE (" "`Priority`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " "`TrackNumber`, `DiscNumber`" "), " "CONSTRAINT fk_fileName FOREIGN KEY (`FileName`) " "REFERENCES `TracksData`(`FileName`) ON DELETE CASCADE, " "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " "CONSTRAINT fk_tracks_album FOREIGN KEY (" "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); } } { QSqlQuery copyDataQuery(d->mTracksDatabase); auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracks` " "SELECT " "t.`ID`, " "t.`FileName`, " "t.`Priority`, " "t.`Title`, " "t.`ArtistName`, " "t.`AlbumTitle`, " "t.`AlbumArtistName`, " "t.`AlbumPath`, " "t.`TrackNumber`, " "t.`DiscNumber`, " "t.`Duration`, " "t.`Rating`, " "t.`Genre`, " "t.`Composer`, " "t.`Lyricist`, " "t.`Comment`, " "t.`Year`, " "t.`Channels`, " "t.`BitRate`, " "t.`SampleRate`, " "t.`HasEmbeddedCover` " "FROM " "`Tracks` t")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << copyDataQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << copyDataQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << 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::upgradeDatabaseV13" << enableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << enableForeignKeys.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksAlbumIndex` ON `Tracks` " "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`ArtistNameIndex` ON `Tracks` " "(`ArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`AlbumArtistNameIndex` ON `Tracks` " "(`AlbumArtistName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksUniqueData` ON `Tracks` " "(`Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " "`TrackNumber`, `DiscNumber`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksUniqueDataPriority` ON `Tracks` " "(`Priority`, `Title`, `ArtistName`, " "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " "`TrackNumber`, `DiscNumber`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createTrackIndex(d->mTracksDatabase); const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " "`TracksFileNameIndex` ON `Tracks` " "(`FileName`)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); Q_EMIT databaseError(); } } qCInfo(orgKdeElisaDatabase) << "finished update to v13 of database schema"; } void DatabaseInterface::upgradeDatabaseV14() { qCInfo(orgKdeElisaDatabase) << "begin update to v14 of database schema"; { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV14` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery disableForeignKeys(d->mTracksDatabase); auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << disableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << disableForeignKeys.lastError(); Q_EMIT databaseError(); } } d->mTracksDatabase.transaction(); { QSqlQuery createSchemaQuery(d->mTracksDatabase); const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Radios` (" "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " "`HttpAddress` VARCHAR(255) NOT NULL, " "`Priority` INTEGER 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`" ") " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`))" )); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastError(); Q_EMIT databaseError(); } } { QSqlQuery createSchemaQuery(d->mTracksDatabase); //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'" )); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << createSchemaQuery.lastQuery(); qCDebug(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::upgradeDatabaseV14" << enableForeignKeys.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << enableForeignKeys.lastError(); Q_EMIT databaseError(); } } qCInfo(orgKdeElisaDatabase) << "finished update to v14 of database schema"; } void DatabaseInterface::checkDatabaseSchema() { checkAlbumsTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } checkArtistsTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } checkComposerTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } checkGenreTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } checkLyricistTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } checkTracksTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } checkTracksDataTableSchema(); if (d->mIsInBadState) { resetDatabase(); return; } } void DatabaseInterface::checkAlbumsTableSchema() { auto fieldsList = QStringList{QStringLiteral("ID"), QStringLiteral("Title"), QStringLiteral("ArtistName"), QStringLiteral("AlbumPath"), QStringLiteral("CoverFileName")}; genericCheckTable(QStringLiteral("Albums"), fieldsList); } void DatabaseInterface::checkArtistsTableSchema() { auto fieldsList = QStringList{QStringLiteral("ID"), QStringLiteral("Name")}; genericCheckTable(QStringLiteral("Artists"), fieldsList); } void DatabaseInterface::checkComposerTableSchema() { auto fieldsList = QStringList{QStringLiteral("ID"), QStringLiteral("Name")}; genericCheckTable(QStringLiteral("Composer"), fieldsList); } void DatabaseInterface::checkGenreTableSchema() { auto fieldsList = QStringList{QStringLiteral("ID"), QStringLiteral("Name")}; genericCheckTable(QStringLiteral("Genre"), fieldsList); } void DatabaseInterface::checkLyricistTableSchema() { auto fieldsList = QStringList{QStringLiteral("ID"), QStringLiteral("Name")}; genericCheckTable(QStringLiteral("Lyricist"), fieldsList); } void DatabaseInterface::checkTracksTableSchema() { auto fieldsList = QStringList{QStringLiteral("ID"), QStringLiteral("FileName"), QStringLiteral("Priority"), QStringLiteral("Title"), QStringLiteral("ArtistName"), QStringLiteral("AlbumTitle"), QStringLiteral("AlbumArtistName"), QStringLiteral("AlbumPath"), QStringLiteral("TrackNumber"), QStringLiteral("DiscNumber"), QStringLiteral("Duration"), QStringLiteral("Rating"), QStringLiteral("Genre"), QStringLiteral("Composer"), QStringLiteral("Lyricist"), QStringLiteral("Comment"), QStringLiteral("Year"), QStringLiteral("Channels"), QStringLiteral("BitRate"), QStringLiteral("SampleRate"), QStringLiteral("HasEmbeddedCover")}; genericCheckTable(QStringLiteral("Tracks"), fieldsList); } void DatabaseInterface::checkTracksDataTableSchema() { auto fieldsList = QStringList{QStringLiteral("FileName"), QStringLiteral("FileModifiedTime"), QStringLiteral("ImportDate"), QStringLiteral("FirstPlayDate"), QStringLiteral("LastPlayDate"), QStringLiteral("PlayCounter")}; genericCheckTable(QStringLiteral("TracksData"), fieldsList); } void DatabaseInterface::genericCheckTable(const QString &tableName, const QStringList &expectedColumns) { auto columnsList = d->mTracksDatabase.record(tableName); if (columnsList.count() != expectedColumns.count()) { qCInfo(orgKdeElisaDatabase()) << tableName << "table has wrong number of columns" << columnsList.count() << "expected" << expectedColumns.count(); d->mIsInBadState = true; return; } for (const auto &oneField : expectedColumns) { if (!columnsList.contains(oneField)) { qCInfo(orgKdeElisaDatabase()) << tableName << "table has missing column" << oneField; d->mIsInBadState = true; return; } } } void DatabaseInterface::resetDatabase() { qCInfo(orgKdeElisaDatabase()) << "Full reset of database due to corrupted database"; auto listTables = d->mTracksDatabase.tables(); while(!listTables.isEmpty()) { for (const auto &oneTable : listTables) { QSqlQuery createSchemaQuery(d->mTracksDatabase); qCDebug(orgKdeElisaDatabase()) << "dropping table" << oneTable; createSchemaQuery.exec(QStringLiteral("DROP TABLE ") + oneTable); } listTables = d->mTracksDatabase.tables(); if (listTables == QStringList{QStringLiteral("sqlite_sequence")}) { break; } } d->mIsInBadState = false; } void DatabaseInterface::initRequest() { auto transactionResult = startTransaction(); if (!transactionResult) { return; } { auto selectAlbumQueryText = QStringLiteral("SELECT " "album.`ID`, " "album.`Title`, " "album.`ArtistName`, " "album.`AlbumPath`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(*) " "FROM " "`Tracks` tracks3 " "WHERE " "tracks3.`AlbumTitle` = album.`Title` AND " "(tracks3.`AlbumArtistName` = album.`ArtistName` OR " "(tracks3.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks3.`AlbumPath` = album.`AlbumPath` " ") as `TracksCount`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " "MAX(tracks.`Rating`) as HighestRating, " "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Albums` album LEFT JOIN " "`Tracks` tracks ON " "tracks.`AlbumTitle` = album.`Title` AND " "(" "tracks.`AlbumArtistName` = album.`ArtistName` OR " "(" "tracks.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks.`AlbumPath` = album.`AlbumPath`" "LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "WHERE " "album.`ID` = :albumId " "GROUP BY album.`ID`"); auto result = prepareQuery(d->mSelectAlbumQuery, selectAlbumQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllGenresText = QStringLiteral("SELECT " "genre.`ID`, " "genre.`Name` " "FROM `Genre` genre " "ORDER BY genre.`Name` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllGenresQuery, selectAllGenresText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllGenresQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllGenresQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllAlbumsText = QStringLiteral("SELECT " "album.`ID`, " "album.`Title`, " "album.`ArtistName` as SecondaryText, " "album.`CoverFileName`, " "album.`ArtistName`, " "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " "MAX(tracks.`Rating`) as HighestRating, " "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Albums` album, " "`Tracks` tracks LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "WHERE " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR " "(tracks.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ") " ") AND " "tracks.`AlbumPath` = album.`AlbumPath` " "GROUP BY album.`ID`, album.`Title`, album.`AlbumPath` " "ORDER BY album.`Title` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllAlbumsShortQuery, selectAllAlbumsText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllAlbumsShortQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllAlbumsShortQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllAlbumsText = QStringLiteral("SELECT " "album.`ID`, " "album.`Title`, " "album.`ArtistName` as SecondaryText, " "album.`CoverFileName`, " "album.`ArtistName`, " "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " "MAX(tracks.`Rating`) as HighestRating, " "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Albums` album, " "`Tracks` tracks LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "WHERE " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR " "(tracks.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks.`AlbumPath` = album.`AlbumPath` AND " "EXISTS (" " SELECT tracks2.`Genre` " " FROM " " `Tracks` tracks2, " " `Genre` genre2 " " WHERE " " tracks2.`AlbumTitle` = album.`Title` AND " " (tracks2.`AlbumArtistName` = album.`ArtistName` OR " " (tracks2.`AlbumArtistName` IS NULL AND " " album.`ArtistName` IS NULL" " )" " ) AND " " tracks2.`Genre` = genre2.`Name` AND " " genre2.`Name` = :genreFilter AND " " (tracks2.`ArtistName` = :artistFilter OR tracks2.`AlbumArtistName` = :artistFilter) " ") " "GROUP BY album.`ID`, album.`Title`, album.`AlbumPath` " "ORDER BY album.`Title` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllAlbumsShortWithGenreArtistFilterQuery, selectAllAlbumsText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllAlbumsText = QStringLiteral("SELECT " "album.`ID`, " "album.`Title`, " "album.`ArtistName` as SecondaryText, " "album.`CoverFileName`, " "album.`ArtistName`, " "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " "MAX(tracks.`Rating`) as HighestRating, " "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Albums` album, " "`Tracks` tracks LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "WHERE " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR " "(tracks.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks.`AlbumPath` = album.`AlbumPath` AND " "EXISTS (" " SELECT tracks2.`Genre` " " FROM " " `Tracks` tracks2 " " WHERE " " tracks2.`AlbumTitle` = album.`Title` AND " " ( " " tracks2.`AlbumArtistName` = album.`ArtistName` OR " " ( " " tracks2.`AlbumArtistName` IS NULL AND " " album.`ArtistName` IS NULL " " )" " ) AND " " (tracks2.`ArtistName` = :artistFilter OR tracks2.`AlbumArtistName` = :artistFilter) " ") " "GROUP BY album.`ID`, album.`Title`, album.`AlbumPath` " "ORDER BY album.`Title` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllAlbumsShortWithArtistFilterQuery, selectAllAlbumsText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllAlbumsShortWithArtistFilterQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllAlbumsShortWithArtistFilterQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllArtistsWithFilterText = QStringLiteral("SELECT artists.`ID`, " "artists.`Name`, " "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres " "FROM `Artists` artists LEFT JOIN " "`Tracks` tracks ON artists.`Name` = tracks.`ArtistName` LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "GROUP BY artists.`ID` " "ORDER BY artists.`Name` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllArtistsQuery, selectAllArtistsWithFilterText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllArtistsQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllArtistsQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllArtistsWithGenreFilterText = QStringLiteral("SELECT artists.`ID`, " "artists.`Name`, " "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres " "FROM `Artists` artists LEFT JOIN " "`Tracks` tracks ON (tracks.`ArtistName` = artists.`Name` OR tracks.`AlbumArtistName` = artists.`Name`) LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "WHERE " "EXISTS (" " SELECT tracks2.`Genre` " " FROM " " `Tracks` tracks2, " " `Genre` genre2 " " WHERE " " (tracks2.`ArtistName` = artists.`Name` OR tracks2.`AlbumArtistName` = artists.`Name`) AND " " tracks2.`Genre` = genre2.`Name` AND " " genre2.`Name` = :genreFilter " ") " "GROUP BY artists.`ID` " "ORDER BY artists.`Name` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllArtistsWithGenreFilterQuery, selectAllArtistsWithGenreFilterText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllArtistsWithGenreFilterQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllArtistsWithGenreFilterQuery.lastError(); Q_EMIT databaseError(); } } { auto artistMatchGenreText = QStringLiteral("SELECT artists.`ID` " "FROM `Artists` artists LEFT JOIN " "`Tracks` tracks ON (tracks.`ArtistName` = artists.`Name` OR tracks.`AlbumArtistName` = artists.`Name`) LEFT JOIN " "`Genre` genres ON tracks.`Genre` = genres.`Name` " "WHERE " "EXISTS (" " SELECT tracks2.`Genre` " " FROM " " `Tracks` tracks2, " " `Genre` genre2 " " WHERE " " (tracks2.`ArtistName` = artists.`Name` OR tracks2.`AlbumArtistName` = artists.`Name`) AND " " tracks2.`Genre` = genre2.`Name` AND " " genre2.`Name` = :genreFilter " ") AND " "artists.`ID` = :databaseId"); auto result = prepareQuery(d->mArtistMatchGenreQuery, artistMatchGenreText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mArtistMatchGenreQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mArtistMatchGenreQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllComposersWithFilterText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Artists` " "ORDER BY `Name` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllComposersQuery, selectAllComposersWithFilterText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllComposersQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllComposersQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllLyricistsWithFilterText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Lyricist` " "ORDER BY `Name` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllLyricistsQuery, selectAllLyricistsWithFilterText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllLyricistsQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllLyricistsQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllTracksText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "tracksMapping.`PlayCounter` / (strftime('%s', 'now') - tracksMapping.`FirstPlayDate`) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "WHERE " "tracksMapping.`FileName` = tracks.`FileName` AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" ""); auto result = prepareQuery(d->mSelectAllTracksQuery, selectAllTracksText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllTracksQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllTracksQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllRadiosText = QStringLiteral("SELECT " "radios.`ID`, " "radios.`Title`, " "radios.`HttpAddress`, " "radios.`Rating`, " "trackGenre.`Name`, " "radios.`Comment` " "FROM " "`Radios` radios " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = radios.`Genre` " ""); auto result = prepareQuery(d->mSelectAllRadiosQuery, selectAllRadiosText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllRadiosQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllRadiosQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllTracksText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "tracksMapping.`PlayCounter` / (strftime('%s', 'now') - tracksMapping.`FirstPlayDate`) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "WHERE " "tracksMapping.`FileName` = tracks.`FileName` AND " "tracksMapping.`PlayCounter` > 0 AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" "ORDER BY tracksMapping.`LastPlayDate` DESC " "LIMIT :maximumResults"); auto result = prepareQuery(d->mSelectAllRecentlyPlayedTracksQuery, selectAllTracksText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllRecentlyPlayedTracksQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllRecentlyPlayedTracksQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAllTracksText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "CAST(tracksMapping.`PlayCounter` AS REAL) / ((CAST(strftime('%s','now') as INTEGER) - CAST(tracksMapping.`FirstPlayDate` / 1000 as INTEGER)) / CAST(1000 AS REAL)) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "WHERE " "tracksMapping.`FileName` = tracks.`FileName` AND " "tracksMapping.`PlayCounter` > 0 AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" "ORDER BY CAST(tracksMapping.`PlayCounter` AS REAL) / ((CAST(strftime('%s','now') as INTEGER) - CAST(tracksMapping.`FirstPlayDate` / 1000 as INTEGER)) / CAST(1000 AS REAL)) DESC " "LIMIT :maximumResults"); auto result = prepareQuery(d->mSelectAllFrequentlyPlayedTracksQuery, selectAllTracksText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllFrequentlyPlayedTracksQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllFrequentlyPlayedTracksQuery.lastError(); Q_EMIT databaseError(); } } { auto clearAlbumsTableText = QStringLiteral("DELETE FROM `Albums`"); auto result = prepareQuery(d->mClearAlbumsTable, clearAlbumsTableText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearAlbumsTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearAlbumsTable.lastError(); Q_EMIT databaseError(); } } { auto clearArtistsTableText = QStringLiteral("DELETE FROM `Artists`"); auto result = prepareQuery(d->mClearArtistsTable, clearArtistsTableText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearArtistsTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearArtistsTable.lastError(); Q_EMIT databaseError(); } } { auto clearComposerTableText = QStringLiteral("DELETE FROM `Composer`"); auto result = prepareQuery(d->mClearComposerTable, clearComposerTableText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearComposerTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearComposerTable.lastError(); Q_EMIT databaseError(); } } { auto clearGenreTableText = QStringLiteral("DELETE FROM `Genre`"); auto result = prepareQuery(d->mClearGenreTable, clearGenreTableText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearGenreTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearGenreTable.lastError(); Q_EMIT databaseError(); } } { auto clearLyricistTableText = QStringLiteral("DELETE FROM `Lyricist`"); auto result = prepareQuery(d->mClearLyricistTable, clearLyricistTableText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearLyricistTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearLyricistTable.lastError(); Q_EMIT databaseError(); } } { auto clearTracksTableText = QStringLiteral("DELETE FROM `Tracks`"); auto result = prepareQuery(d->mClearTracksTable, clearTracksTableText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearTracksTable.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mClearTracksTable.lastError(); Q_EMIT databaseError(); } } { auto selectAllTracksShortText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " "tracks.`ArtistName`, " "tracks.`AlbumTitle`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracks.`Duration`, " "album.`CoverFileName`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Rating` " "FROM " "`Tracks` tracks " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " ""); auto result = prepareQuery(d->mSelectAllTracksShortQuery, selectAllTracksShortText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllTracksShortQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllTracksShortQuery.lastError(); Q_EMIT databaseError(); } } { auto selectArtistByNameText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Artists` " "WHERE " "`Name` = :name"); auto result = prepareQuery(d->mSelectArtistByNameQuery, selectArtistByNameText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectArtistByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectArtistByNameQuery.lastError(); Q_EMIT databaseError(); } } { auto selectComposerByNameText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Composer` " "WHERE " "`Name` = :name"); auto result = prepareQuery(d->mSelectComposerByNameQuery, selectComposerByNameText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectComposerByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectComposerByNameQuery.lastError(); } } { auto selectLyricistByNameText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Lyricist` " "WHERE " "`Name` = :name"); auto result = prepareQuery(d->mSelectLyricistByNameQuery, selectLyricistByNameText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectLyricistByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectLyricistByNameQuery.lastError(); } } { auto selectGenreByNameText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Genre` " "WHERE " "`Name` = :name"); auto result = prepareQuery(d->mSelectGenreByNameQuery, selectGenreByNameText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreByNameQuery.lastError(); Q_EMIT databaseError(); } } { auto insertArtistsText = QStringLiteral("INSERT INTO `Artists` (`ID`, `Name`) " "VALUES (:artistId, :name)"); auto result = prepareQuery(d->mInsertArtistsQuery, insertArtistsText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertArtistsQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertArtistsQuery.lastError(); Q_EMIT databaseError(); } } { auto insertGenreText = QStringLiteral("INSERT INTO `Genre` (`ID`, `Name`) " "VALUES (:genreId, :name)"); auto result = prepareQuery(d->mInsertGenreQuery, insertGenreText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertGenreQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertGenreQuery.lastError(); Q_EMIT databaseError(); } } { auto insertComposerText = QStringLiteral("INSERT INTO `Composer` (`ID`, `Name`) " "VALUES (:composerId, :name)"); auto result = prepareQuery(d->mInsertComposerQuery, insertComposerText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertComposerQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertComposerQuery.lastError(); } } { auto insertLyricistText = QStringLiteral("INSERT INTO `Lyricist` (`ID`, `Name`) " "VALUES (:lyricistId, :name)"); auto result = prepareQuery(d->mInsertLyricistQuery, insertLyricistText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertLyricistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertLyricistQuery.lastError(); } } { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "tracksMapping.`PlayCounter` / (strftime('%s', 'now') - tracksMapping.`FirstPlayDate`) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "album.`ID` = :albumId AND " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "WHERE " "tracksMapping.`FileName` = tracks.`FileName` AND " "album.`ID` = :albumId AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" "ORDER BY tracks.`DiscNumber` ASC, " "tracks.`TrackNumber` ASC"); auto result = prepareQuery(d->mSelectTrackQuery, selectTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackQuery.lastError(); Q_EMIT databaseError(); } } { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.`ID` " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "album.`ID` = :albumId AND " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "WHERE " "tracksMapping.`FileName` = tracks.`FileName` AND " "album.`ID` = :albumId AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" "ORDER BY tracks.`DiscNumber` ASC, " "tracks.`TrackNumber` ASC"); auto result = prepareQuery(d->mSelectTrackIdQuery, selectTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdQuery.lastError(); Q_EMIT databaseError(); } } { auto selectTrackFromIdQueryText = QStringLiteral("SELECT " "tracks.`Id`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "tracksMapping.`PlayCounter` / (strftime('%s', 'now') - tracksMapping.`FirstPlayDate`) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "WHERE " "tracks.`ID` = :trackId AND " "tracksMapping.`FileName` = tracks.`FileName` AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" ""); auto result = prepareQuery(d->mSelectTrackFromIdQuery, selectTrackFromIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackFromIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackFromIdQuery.lastError(); Q_EMIT databaseError(); } } { auto selectRadioFromIdQueryText = QStringLiteral("SELECT " "radios.`ID`, " "radios.`Title`, " "radios.`HttpAddress`, " "radios.`Rating`, " "trackGenre.`Name`, " "radios.`Comment` " "FROM " "`Radios` radios " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = radios.`Genre` " "WHERE " "radios.`ID` = :radioId " ""); auto result = prepareQuery(d->mSelectRadioFromIdQuery, selectRadioFromIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectRadioFromIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectRadioFromIdQuery.lastError(); Q_EMIT databaseError(); } } { auto selectCountAlbumsQueryText = QStringLiteral("SELECT count(*) " "FROM `Albums` album " "WHERE album.`ArtistName` = :artistName "); const auto result = prepareQuery(d->mSelectCountAlbumsForArtistQuery, selectCountAlbumsQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectCountAlbumsForArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectCountAlbumsForArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto selectGenreForArtistQueryText = QStringLiteral("SELECT DISTINCT trackGenre.`Name` " "FROM " "`Tracks` tracks " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "WHERE " "album.`ArtistName` = :artistName"); const auto result = prepareQuery(d->mSelectGenreForArtistQuery, selectGenreForArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreForArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreForArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto selectGenreForAlbumQueryText = QStringLiteral("SELECT DISTINCT trackGenre.`Name` " "FROM " "`Tracks` tracks " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "WHERE " "album.`ID` = :albumId"); const auto result = prepareQuery(d->mSelectGenreForAlbumQuery, selectGenreForAlbumQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreForAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreForAlbumQuery.lastError(); Q_EMIT databaseError(); } } { auto selectCountAlbumsQueryText = QStringLiteral("SELECT distinct count(album.`ID`) " "FROM " "`Tracks` tracks, " "`Albums` album " "LEFT JOIN `Composer` albumComposer ON albumComposer.`Name` = tracks.`Composer` " "WHERE " "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " "albumComposer.`Name` = :artistName"); const auto result = prepareQuery(d->mSelectCountAlbumsForComposerQuery, selectCountAlbumsQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectCountAlbumsForComposerQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectCountAlbumsForComposerQuery.lastError(); Q_EMIT databaseError(); } } { auto selectCountAlbumsQueryText = QStringLiteral("SELECT distinct count(album.`ID`) " "FROM " "`Tracks` tracks, " "`Albums` album " "LEFT JOIN `Lyricist` albumLyricist ON albumLyricist.`Name` = tracks.`Lyricist` " "WHERE " "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " "albumLyricist.`Name` = :artistName"); const auto result = prepareQuery(d->mSelectCountAlbumsForLyricistQuery, selectCountAlbumsQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectCountAlbumsForLyricistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectCountAlbumsForLyricistQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAlbumIdFromTitleQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " "`Albums` album " "WHERE " "album.`ArtistName` = :artistName AND " "album.`Title` = :title"); auto result = prepareQuery(d->mSelectAlbumIdFromTitleQuery, selectAlbumIdFromTitleQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdFromTitleQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdFromTitleQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAlbumIdFromTitleAndArtistQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " "`Albums` album " "WHERE " "(album.`ArtistName` = :artistName OR :artistName IS NULL OR album.`ArtistName` IS NULL) AND " "album.`Title` = :title AND " "album.`AlbumPath` = :albumPath"); auto result = prepareQuery(d->mSelectAlbumIdFromTitleAndArtistQuery, selectAlbumIdFromTitleAndArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAlbumIdFromTitleWithoutArtistQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " "`Albums` album " "WHERE " "album.`AlbumPath` = :albumPath AND " "album.`Title` = :title AND " "album.`ArtistName` IS NULL"); auto result = prepareQuery(d->mSelectAlbumIdFromTitleWithoutArtistQuery, selectAlbumIdFromTitleWithoutArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto insertAlbumQueryText = QStringLiteral("INSERT INTO `Albums` " "(`ID`, " "`Title`, " "`ArtistName`, " "`AlbumPath`, " "`CoverFileName`) " "VALUES " "(:albumId, " ":title, " ":albumArtist, " ":albumPath, " ":coverFileName)"); auto result = prepareQuery(d->mInsertAlbumQuery, insertAlbumQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertAlbumQuery.lastError(); Q_EMIT databaseError(); } } { auto insertTrackMappingQueryText = QStringLiteral("INSERT INTO " "`TracksData` " "(`FileName`, " "`FileModifiedTime`, " "`ImportDate`, " "`PlayCounter`) " "VALUES (:fileName, :mtime, :importDate, 0)"); auto result = prepareQuery(d->mInsertTrackMapping, insertTrackMappingQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertTrackMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertTrackMapping.lastError(); Q_EMIT databaseError(); } } { auto initialUpdateTracksValidityQueryText = QStringLiteral("UPDATE `TracksData` " "SET " "`FileModifiedTime` = :mtime " "WHERE `FileName` = :fileName"); auto result = prepareQuery(d->mUpdateTrackFileModifiedTime, initialUpdateTracksValidityQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackFileModifiedTime.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackFileModifiedTime.lastError(); Q_EMIT databaseError(); } } { auto initialUpdateTracksValidityQueryText = QStringLiteral("UPDATE `Tracks` " "SET " "`Priority` = :priority " "WHERE `FileName` = :fileName"); auto result = prepareQuery(d->mUpdateTrackPriority, initialUpdateTracksValidityQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackPriority.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackPriority.lastError(); Q_EMIT databaseError(); } } { auto removeTracksMappingFromSourceQueryText = QStringLiteral("DELETE FROM `TracksData` " "WHERE `FileName` = :fileName"); auto result = prepareQuery(d->mRemoveTracksMappingFromSource, removeTracksMappingFromSourceQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveTracksMappingFromSource.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveTracksMappingFromSource.lastError(); Q_EMIT databaseError(); } } { auto removeTracksMappingQueryText = QStringLiteral("DELETE FROM `TracksData` " "WHERE `FileName` = :fileName"); auto result = prepareQuery(d->mRemoveTracksMapping, removeTracksMappingQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveTracksMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveTracksMapping.lastError(); Q_EMIT databaseError(); } } { auto selectTracksWithoutMappingQueryText = QStringLiteral("SELECT " "tracks.`Id`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "\"\" as FileName, " "NULL as FileModifiedTime, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "tracksMapping.`PlayCounter` / (strftime('%s', 'now') - tracksMapping.`FirstPlayDate`) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "WHERE " "tracks.`FileName` = tracksMapping.`FileName` AND " "tracks.`FileName` NOT IN (SELECT tracksMapping2.`FileName` FROM `TracksData` tracksMapping2)"); auto result = prepareQuery(d->mSelectTracksWithoutMappingQuery, selectTracksWithoutMappingQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksWithoutMappingQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksWithoutMappingQuery.lastError(); Q_EMIT databaseError(); } } { auto selectTracksMappingQueryText = QStringLiteral("SELECT " "track.`ID`, " "trackData.`FileName`, " "track.`Priority`, " "trackData.`FileModifiedTime` " "FROM " "`TracksData` trackData " "LEFT JOIN " "`Tracks` track " "ON " "track.`FileName` = trackData.`FileName` " "WHERE " "trackData.`FileName` = :fileName"); auto result = prepareQuery(d->mSelectTracksMapping, selectTracksMappingQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksMapping.lastError(); Q_EMIT databaseError(); } } { auto selectRadioIdFromHttpAddress = QStringLiteral("SELECT " "`ID` " "FROM " "`Radios` " "WHERE " "`HttpAddress` = :httpAddress"); auto result = prepareQuery(d->mSelectRadioIdFromHttpAddress, selectRadioIdFromHttpAddress); if (!result) { qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectRadioIdFromHttpAddress.lastQuery(); qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectRadioIdFromHttpAddress.lastError(); Q_EMIT databaseError(); } } { auto selectTracksMappingPriorityQueryText = QStringLiteral("SELECT " "max(tracks.`Priority`) AS Priority " "FROM " "`Tracks` tracks, " "`Albums` albums " "WHERE " "tracks.`Title` = :title AND " "(tracks.`ArtistName` = :trackArtist OR tracks.`ArtistName` IS NULL) AND " "(tracks.`AlbumTitle` = :album OR tracks.`AlbumTitle` IS NULL) AND " "(tracks.`AlbumArtistName` = :albumArtist OR tracks.`AlbumArtistName` IS NULL) AND " "(tracks.`AlbumPath` = :albumPath OR tracks.`AlbumPath` IS NULL)"); auto result = prepareQuery(d->mSelectTracksMappingPriority, selectTracksMappingPriorityQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksMappingPriority.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksMappingPriority.lastError(); Q_EMIT databaseError(); } } { auto selectTracksMappingPriorityQueryByTrackIdText = QStringLiteral("SELECT " "MAX(track.`Priority`) " "FROM " "`TracksData` trackData, " "`Tracks` track " "WHERE " "track.`ID` = :trackId AND " "trackData.`FileName` = track.`FileName`"); auto result = prepareQuery(d->mSelectTracksMappingPriorityByTrackId, selectTracksMappingPriorityQueryByTrackIdText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksMappingPriorityByTrackId.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksMappingPriorityByTrackId.lastError(); Q_EMIT databaseError(); } } { auto selectAllTrackFilesFromSourceQueryText = QStringLiteral("SELECT " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime` " "FROM " "`TracksData` tracksMapping, " "`Tracks` tracks " "WHERE " "tracks.`FileName` = tracksMapping.`FileName`"); auto result = prepareQuery(d->mSelectAllTrackFilesQuery, selectAllTrackFilesFromSourceQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllTrackFilesQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAllTrackFilesQuery.lastError(); Q_EMIT databaseError(); } } { auto insertMusicSourceQueryText = QStringLiteral("INSERT OR IGNORE INTO `DiscoverSource` (`ID`, `Name`) " "VALUES (:discoverId, :name)"); auto result = prepareQuery(d->mInsertMusicSource, insertMusicSourceQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertMusicSource.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertMusicSource.lastError(); Q_EMIT databaseError(); } } { auto selectMusicSourceQueryText = QStringLiteral("SELECT `ID` FROM `DiscoverSource` WHERE `Name` = :name"); auto result = prepareQuery(d->mSelectMusicSource, selectMusicSourceQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectMusicSource.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectMusicSource.lastError(); Q_EMIT databaseError(); } } { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.`ID`, tracksMapping.`FileName` " "FROM " "`Tracks` tracks, " "`Albums` album, " "`TracksData` tracksMapping " "WHERE " "tracks.`Title` = :title AND " "album.`ID` = :album AND " "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " "tracks.`ArtistName` = :artist AND " "tracksMapping.`FileName` = tracks.`FileName` AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" ""); auto result = prepareQuery(d->mSelectTrackIdFromTitleAlbumIdArtistQuery, selectTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdFromTitleAlbumIdArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdFromTitleAlbumIdArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto insertTrackQueryText = QStringLiteral("INSERT INTO `Tracks` " "(" "`ID`, " "`FileName`, " "`Priority`, " "`Title`, " "`ArtistName`, " "`AlbumTitle`, " "`AlbumArtistName`, " "`AlbumPath`, " "`Genre`, " "`Composer`, " "`Lyricist`, " "`Comment`, " "`TrackNumber`, " "`DiscNumber`, " "`Channels`, " "`BitRate`, " "`SampleRate`, " "`Year`, " "`Duration`, " "`Rating`, " "`HasEmbeddedCover`) " "VALUES " "(" ":trackId, " ":fileName, " ":priority, " ":title, " ":artistName, " ":albumTitle, " ":albumArtistName, " ":albumPath, " ":genre, " ":composer, " ":lyricist, " ":comment, " ":trackNumber, " ":discNumber, " ":channels, " ":bitRate, " ":sampleRate, " ":year, " ":trackDuration, " ":trackRating, " ":hasEmbeddedCover)"); auto result = prepareQuery(d->mInsertTrackQuery, insertTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertTrackQuery.lastError(); Q_EMIT databaseError(); } } { auto updateTrackQueryText = QStringLiteral("UPDATE `Tracks` " "SET " "`FileName` = :fileName, " "`Title` = :title, " "`ArtistName` = :artistName, " "`AlbumTitle` = :albumTitle, " "`AlbumArtistName` = :albumArtistName, " "`AlbumPath` = :albumPath, " "`Genre` = :genre, " "`Composer` = :composer, " "`Lyricist` = :lyricist, " "`Comment` = :comment, " "`TrackNumber` = :trackNumber, " "`DiscNumber` = :discNumber, " "`Channels` = :channels, " "`BitRate` = :bitRate, " "`SampleRate` = :sampleRate, " "`Year` = :year, " " `Duration` = :trackDuration, " "`Rating` = :trackRating " "WHERE " "`ID` = :trackId"); auto result = prepareQuery(d->mUpdateTrackQuery, updateTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackQuery.lastError(); Q_EMIT databaseError(); } } { auto insertRadioQueryText = QStringLiteral("INSERT INTO `Radios` " "(" "`Title`, " "`httpAddress`, " "`Comment`, " "`Rating`, " "`Priority`) " "VALUES " "(" ":title, " ":httpAddress, " ":comment, " ":trackRating," "1)"); auto result = prepareQuery(d->mInsertRadioQuery, insertRadioQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertRadioQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mInsertRadioQuery.lastError(); Q_EMIT databaseError(); } } { auto deleteRadioQueryText = QStringLiteral("DELETE FROM `Radios` " "WHERE `ID` = :radioId"); auto result = prepareQuery(d->mDeleteRadioQuery, deleteRadioQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mDeleteRadioQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mDeleteRadioQuery.lastError(); Q_EMIT databaseError(); } } { auto updateRadioQueryText = QStringLiteral("UPDATE `Radios` " "SET " "`HttpAddress` = :httpAddress, " "`Title` = :title, " "`Comment` = :comment, " "`Rating` = :trackRating " "WHERE " "`ID` = :radioId"); auto result = prepareQuery(d->mUpdateRadioQuery, updateRadioQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateRadioQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateRadioQuery.lastError(); Q_EMIT databaseError(); } } { auto updateAlbumArtistQueryText = QStringLiteral("UPDATE `Albums` " "SET " "`ArtistName` = :artistName " "WHERE " "`ID` = :albumId"); auto result = prepareQuery(d->mUpdateAlbumArtistQuery, updateAlbumArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto updateAlbumArtistInTracksQueryText = QStringLiteral("UPDATE `Tracks` " "SET " "`AlbumArtistName` = :artistName " "WHERE " "`AlbumTitle` = :albumTitle AND " "`AlbumPath` = :albumPath AND " "`AlbumArtistName` IS NULL"); auto result = prepareQuery(d->mUpdateAlbumArtistInTracksQuery, updateAlbumArtistInTracksQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistInTracksQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistInTracksQuery.lastError(); Q_EMIT databaseError(); } } { auto queryMaximumTrackIdQueryText = QStringLiteral("SELECT MAX(tracks.`ID`)" "FROM " "`Tracks` tracks"); auto result = prepareQuery(d->mQueryMaximumTrackIdQuery, queryMaximumTrackIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumTrackIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumTrackIdQuery.lastError(); Q_EMIT databaseError(); } } { auto queryMaximumAlbumIdQueryText = QStringLiteral("SELECT MAX(albums.`ID`)" "FROM " "`Albums` albums"); auto result = prepareQuery(d->mQueryMaximumAlbumIdQuery, queryMaximumAlbumIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumAlbumIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumAlbumIdQuery.lastError(); Q_EMIT databaseError(); } } { auto queryMaximumArtistIdQueryText = QStringLiteral("SELECT MAX(artists.`ID`)" "FROM " "`Artists` artists"); auto result = prepareQuery(d->mQueryMaximumArtistIdQuery, queryMaximumArtistIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumArtistIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumArtistIdQuery.lastError(); Q_EMIT databaseError(); } } { auto queryMaximumLyricistIdQueryText = QStringLiteral("SELECT MAX(lyricists.`ID`)" "FROM " "`Lyricist` lyricists"); auto result = prepareQuery(d->mQueryMaximumLyricistIdQuery, queryMaximumLyricistIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumLyricistIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumLyricistIdQuery.lastError(); Q_EMIT databaseError(); } } { auto queryMaximumComposerIdQueryText = QStringLiteral("SELECT MAX(composers.`ID`)" "FROM " "`Composer` composers"); auto result = prepareQuery(d->mQueryMaximumComposerIdQuery, queryMaximumComposerIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumComposerIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumComposerIdQuery.lastError(); Q_EMIT databaseError(); } } { auto queryMaximumGenreIdQueryText = QStringLiteral("SELECT MAX(genres.`ID`)" "FROM " "`Genre` genres"); auto result = prepareQuery(d->mQueryMaximumGenreIdQuery, queryMaximumGenreIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumGenreIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mQueryMaximumGenreIdQuery.lastError(); Q_EMIT databaseError(); } } { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.ID " "FROM " "`Tracks` tracks " "WHERE " "tracks.`Title` = :title AND " "(tracks.`AlbumTitle` = :album OR (:album IS NULL AND tracks.`AlbumTitle` IS NULL)) AND " "(tracks.`TrackNumber` = :trackNumber OR (:trackNumber IS NULL AND tracks.`TrackNumber` IS NULL)) AND " "(tracks.`DiscNumber` = :discNumber OR (:discNumber IS NULL AND tracks.`DiscNumber` IS NULL)) AND " "tracks.`ArtistName` = :artist"); auto result = prepareQuery(d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery, selectTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastError(); Q_EMIT databaseError(); } } { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.ID " "FROM " "`Tracks` tracks, " "`Albums` albums " "WHERE " "tracks.`Title` = :title AND " "tracks.`Priority` = :priority AND " "(tracks.`ArtistName` = :trackArtist OR tracks.`ArtistName` IS NULL) AND " "(tracks.`AlbumTitle` = :album OR tracks.`AlbumTitle` IS NULL) AND " "(tracks.`AlbumArtistName` = :albumArtist OR tracks.`AlbumArtistName` IS NULL) AND " "(tracks.`AlbumPath` = :albumPath OR tracks.`AlbumPath` IS NULL) AND " "(tracks.`TrackNumber` = :trackNumber OR tracks.`TrackNumber` IS NULL) AND " "(tracks.`DiscNumber` = :discNumber OR tracks.`DiscNumber` IS NULL) " ""); auto result = prepareQuery(d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery, selectTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastError(); Q_EMIT databaseError(); } } { auto selectAlbumArtUriFromAlbumIdQueryText = QStringLiteral("SELECT `CoverFileName`" "FROM " "`Albums` " "WHERE " "`ID` = :albumId"); auto result = prepareQuery(d->mSelectAlbumArtUriFromAlbumIdQuery, selectAlbumArtUriFromAlbumIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastError(); Q_EMIT databaseError(); } } { auto updateAlbumArtUriFromAlbumIdQueryText = QStringLiteral("UPDATE `Albums` " "SET `CoverFileName` = :coverFileName " "WHERE " "`ID` = :albumId"); auto result = prepareQuery(d->mUpdateAlbumArtUriFromAlbumIdQuery, updateAlbumArtUriFromAlbumIdQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastError(); Q_EMIT databaseError(); } } { auto selectTracksFromArtistQueryText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " "album.`ID`, " "tracks.`ArtistName`, " "( " "SELECT " "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum1 " "WHERE " "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " ") AS ArtistsCount, " "( " "SELECT " "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " "FROM " "`Tracks` tracksFromAlbum2 " "WHERE " "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " ") AS AllArtists, " "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " "(" "SELECT " "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " "FROM " "`Tracks` tracks2 " "WHERE " "tracks2.`AlbumTitle` = album.`Title` AND " "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " "(tracks2.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL" ")" ") AND " "tracks2.`AlbumPath` = album.`AlbumPath` " ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate`, " "tracks.`HasEmbeddedCover`, " "tracksMapping.`ImportDate`, " "tracksMapping.`FirstPlayDate`, " "tracksMapping.`LastPlayDate`, " "tracksMapping.`PlayCounter`, " "tracksMapping.`PlayCounter` / (strftime('%s', 'now') - tracksMapping.`FirstPlayDate`) as PlayFrequency, " "( " "SELECT tracksCover.`FileName` " "FROM " "`Tracks` tracksCover " "WHERE " "tracksCover.`HasEmbeddedCover` = 1 AND " "tracksCover.`AlbumTitle` = album.`Title` AND " "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " "(tracksCover.`AlbumArtistName` IS NULL AND " "album.`ArtistName` IS NULL " ") " ") AND " "tracksCover.`AlbumPath` = album.`AlbumPath` " ") as EmbeddedCover " "FROM " "`Tracks` tracks, " "`TracksData` tracksMapping " "LEFT JOIN " "`Albums` album " "ON " "tracks.`AlbumTitle` = album.`Title` AND " "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " "WHERE " "tracks.`ArtistName` = :artistName AND " "tracksMapping.`FileName` = tracks.`FileName` AND " "tracks.`Priority` = (" " SELECT " " MIN(`Priority`) " " FROM " " `Tracks` tracks2 " " WHERE " " tracks.`Title` = tracks2.`Title` AND " " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" ")" "ORDER BY " "album.`Title` ASC, " "tracks.`DiscNumber` ASC, " "tracks.`TrackNumber` ASC, " "tracks.`Title` ASC" ""); auto result = prepareQuery(d->mSelectTracksFromArtist, selectTracksFromArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksFromArtist.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectTracksFromArtist.lastError(); Q_EMIT databaseError(); } } { auto selectAlbumIdsFromArtistQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " "`Albums` album " "WHERE " "album.`ArtistName` = :artistName"); auto result = prepareQuery(d->mSelectAlbumIdsFromArtist, selectAlbumIdsFromArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdsFromArtist.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectAlbumIdsFromArtist.lastError(); Q_EMIT databaseError(); } } { auto selectArtistQueryText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Artists` " "WHERE " "`ID` = :artistId"); auto result = prepareQuery(d->mSelectArtistQuery, selectArtistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectArtistQuery.lastError(); Q_EMIT databaseError(); } } { auto updateTrackStatisticsQueryText = QStringLiteral("UPDATE `TracksData` " "SET " "`LastPlayDate` = :playDate, " "`PlayCounter` = `PlayCounter` + 1 " "WHERE " "`FileName` = :fileName"); auto result = prepareQuery(d->mUpdateTrackStatistics, updateTrackStatisticsQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackStatistics.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackStatistics.lastError(); Q_EMIT databaseError(); } } { auto updateTrackFirstPlayStatisticsQueryText = QStringLiteral("UPDATE `TracksData` " "SET " "`FirstPlayDate` = :playDate " "WHERE " "`FileName` = :fileName AND " "`FirstPlayDate` IS NULL"); auto result = prepareQuery(d->mUpdateTrackFirstPlayStatistics, updateTrackFirstPlayStatisticsQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackFirstPlayStatistics.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mUpdateTrackFirstPlayStatistics.lastError(); Q_EMIT databaseError(); } } { auto selectGenreQueryText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Genre` " "WHERE " "`ID` = :genreId"); auto result = prepareQuery(d->mSelectGenreQuery, selectGenreQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectGenreQuery.lastError(); Q_EMIT databaseError(); } } { auto selectComposerQueryText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Composer` " "WHERE " "`ID` = :composerId"); auto result = prepareQuery(d->mSelectComposerQuery, selectComposerQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectComposerQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectComposerQuery.lastError(); } } { auto selectLyricistQueryText = QStringLiteral("SELECT `ID`, " "`Name` " "FROM `Lyricist` " "WHERE " "`ID` = :lyricistId"); auto result = prepareQuery(d->mSelectLyricistQuery, selectLyricistQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectLyricistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mSelectLyricistQuery.lastError(); } } { auto removeTrackQueryText = QStringLiteral("DELETE FROM `Tracks` " "WHERE " "`ID` = :trackId"); auto result = prepareQuery(d->mRemoveTrackQuery, removeTrackQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveTrackQuery.lastError(); Q_EMIT databaseError(); } } { auto removeAlbumQueryText = QStringLiteral("DELETE FROM `Albums` " "WHERE " "`ID` = :albumId"); auto result = prepareQuery(d->mRemoveAlbumQuery, removeAlbumQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveAlbumQuery.lastError(); Q_EMIT databaseError(); } } { auto removeAlbumQueryText = QStringLiteral("DELETE FROM `Artists` " "WHERE " "`ID` = :artistId"); auto result = prepareQuery(d->mRemoveArtistQuery, removeAlbumQueryText); if (!result) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initRequest" << d->mRemoveArtistQuery.lastError(); Q_EMIT databaseError(); } } finishTransaction(); d->mInitFinished = true; Q_EMIT requestsInitDone(); } qulonglong DatabaseInterface::insertAlbum(const QString &title, const QString &albumArtist, const QString &trackPath, const QUrl &albumArtURI) { auto result = qulonglong(0); if (title.isEmpty()) { return result; } d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":title"), title); d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistName"), albumArtist); auto queryResult = execQuery(d->mSelectAlbumIdFromTitleAndArtistQuery); if (!queryResult || !d->mSelectAlbumIdFromTitleAndArtistQuery.isSelect() || !d->mSelectAlbumIdFromTitleAndArtistQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mSelectAlbumIdFromTitleAndArtistQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastError(); d->mSelectAlbumIdFromTitleAndArtistQuery.finish(); return result; } if (d->mSelectAlbumIdFromTitleAndArtistQuery.next()) { result = d->mSelectAlbumIdFromTitleAndArtistQuery.record().value(0).toULongLong(); d->mSelectAlbumIdFromTitleAndArtistQuery.finish(); if (!albumArtist.isEmpty()) { const auto similarAlbum = internalOneAlbumPartialData(result); updateAlbumArtist(result, title, trackPath, albumArtist); } return result; } d->mSelectAlbumIdFromTitleAndArtistQuery.finish(); d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumId"), d->mAlbumId); d->mInsertAlbumQuery.bindValue(QStringLiteral(":title"), title); if (!albumArtist.isEmpty()) { insertArtist(albumArtist); d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumArtist"), albumArtist); } else { d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumArtist"), {}); } d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mInsertAlbumQuery.bindValue(QStringLiteral(":coverFileName"), albumArtURI); queryResult = execQuery(d->mInsertAlbumQuery); if (!queryResult || !d->mInsertAlbumQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mInsertAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mInsertAlbumQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mInsertAlbumQuery.lastError(); d->mInsertAlbumQuery.finish(); return result; } result = d->mAlbumId; d->mInsertAlbumQuery.finish(); ++d->mAlbumId; d->mInsertedAlbums.insert(result); return result; } bool DatabaseInterface::updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, const MusicAudioTrack ¤tTrack, const QString &albumPath) { auto modifiedAlbum = false; modifiedAlbum = true; if (!albumArtUri.isValid()) { return modifiedAlbum; } auto storedAlbumArtUri = internalAlbumArtUriFromAlbumId(albumId); if (!storedAlbumArtUri.isValid() || storedAlbumArtUri != albumArtUri) { d->mUpdateAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":albumId"), albumId); d->mUpdateAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":coverFileName"), albumArtUri); auto result = execQuery(d->mUpdateAlbumArtUriFromAlbumIdQuery); if (!result || !d->mUpdateAlbumArtUriFromAlbumIdQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastError(); d->mUpdateAlbumArtUriFromAlbumIdQuery.finish(); return modifiedAlbum; } d->mUpdateAlbumArtUriFromAlbumIdQuery.finish(); modifiedAlbum = true; } if (!isValidArtist(albumId) && currentTrack.isValidAlbumArtist()) { updateAlbumArtist(albumId, currentTrack.albumName(), albumPath, currentTrack.albumArtist()); modifiedAlbum = true; } return modifiedAlbum; } qulonglong DatabaseInterface::insertArtist(const QString &name) { auto result = qulonglong(0); if (name.isEmpty()) { return result; } d->mSelectArtistByNameQuery.bindValue(QStringLiteral(":name"), name); auto queryResult = execQuery(d->mSelectArtistByNameQuery); if (!queryResult || !d->mSelectArtistByNameQuery.isSelect() || !d->mSelectArtistByNameQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastError(); d->mSelectArtistByNameQuery.finish(); return result; } if (d->mSelectArtistByNameQuery.next()) { result = d->mSelectArtistByNameQuery.record().value(0).toULongLong(); d->mSelectArtistByNameQuery.finish(); return result; } d->mSelectArtistByNameQuery.finish(); d->mInsertArtistsQuery.bindValue(QStringLiteral(":artistId"), d->mArtistId); d->mInsertArtistsQuery.bindValue(QStringLiteral(":name"), name); queryResult = execQuery(d->mInsertArtistsQuery); if (!queryResult || !d->mInsertArtistsQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertArtistsQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertArtistsQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertArtistsQuery.lastError(); d->mInsertArtistsQuery.finish(); return result; } result = d->mArtistId; ++d->mArtistId; d->mInsertedArtists.insert(result); d->mInsertArtistsQuery.finish(); return result; } qulonglong DatabaseInterface::insertComposer(const QString &name) { auto result = qulonglong(0); if (name.isEmpty()) { return result; } d->mSelectComposerByNameQuery.bindValue(QStringLiteral(":name"), name); auto queryResult = execQuery(d->mSelectComposerByNameQuery); if (!queryResult || !d->mSelectComposerByNameQuery.isSelect() || !d->mSelectComposerByNameQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mSelectComposerByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mSelectComposerByNameQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mSelectComposerByNameQuery.lastError(); d->mSelectComposerByNameQuery.finish(); return result; } if (d->mSelectComposerByNameQuery.next()) { result = d->mSelectComposerByNameQuery.record().value(0).toULongLong(); d->mSelectComposerByNameQuery.finish(); return result; } d->mSelectComposerByNameQuery.finish(); d->mInsertComposerQuery.bindValue(QStringLiteral(":composerId"), d->mComposerId); d->mInsertComposerQuery.bindValue(QStringLiteral(":name"), name); queryResult = execQuery(d->mInsertComposerQuery); if (!queryResult || !d->mInsertComposerQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mInsertComposerQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mInsertComposerQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mInsertComposerQuery.lastError(); d->mInsertComposerQuery.finish(); return result; } result = d->mComposerId; ++d->mComposerId; d->mInsertComposerQuery.finish(); Q_EMIT composersAdded(internalAllComposersPartialData()); return result; } qulonglong DatabaseInterface::insertGenre(const QString &name) { auto result = qulonglong(0); if (name.isEmpty()) { return result; } d->mSelectGenreByNameQuery.bindValue(QStringLiteral(":name"), name); auto queryResult = execQuery(d->mSelectGenreByNameQuery); if (!queryResult || !d->mSelectGenreByNameQuery.isSelect() || !d->mSelectGenreByNameQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mSelectGenreByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mSelectGenreByNameQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mSelectGenreByNameQuery.lastError(); d->mSelectGenreByNameQuery.finish(); return result; } if (d->mSelectGenreByNameQuery.next()) { result = d->mSelectGenreByNameQuery.record().value(0).toULongLong(); d->mSelectGenreByNameQuery.finish(); return result; } d->mSelectGenreByNameQuery.finish(); d->mInsertGenreQuery.bindValue(QStringLiteral(":genreId"), d->mGenreId); d->mInsertGenreQuery.bindValue(QStringLiteral(":name"), name); queryResult = execQuery(d->mInsertGenreQuery); if (!queryResult || !d->mInsertGenreQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mInsertGenreQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mInsertGenreQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mInsertGenreQuery.lastError(); d->mInsertGenreQuery.finish(); return result; } result = d->mGenreId; ++d->mGenreId; d->mInsertGenreQuery.finish(); Q_EMIT genresAdded({{{DataTypes::DatabaseIdRole, result}}}); return result; } void DatabaseInterface::insertTrackOrigin(const QUrl &fileNameURI, const QDateTime &fileModifiedTime, const QDateTime &importDate) { d->mInsertTrackMapping.bindValue(QStringLiteral(":fileName"), fileNameURI); d->mInsertTrackMapping.bindValue(QStringLiteral(":priority"), 1); d->mInsertTrackMapping.bindValue(QStringLiteral(":mtime"), fileModifiedTime); d->mInsertTrackMapping.bindValue(QStringLiteral(":importDate"), importDate.toMSecsSinceEpoch()); auto queryResult = execQuery(d->mInsertTrackMapping); if (!queryResult || !d->mInsertTrackMapping.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertTrackMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertTrackMapping.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertTrackMapping.lastError(); d->mInsertTrackMapping.finish(); return; } d->mInsertTrackMapping.finish(); } void DatabaseInterface::updateTrackOrigin(const QUrl &fileName, const QDateTime &fileModifiedTime) { d->mUpdateTrackFileModifiedTime.bindValue(QStringLiteral(":fileName"), fileName); d->mUpdateTrackFileModifiedTime.bindValue(QStringLiteral(":mtime"), fileModifiedTime); auto queryResult = execQuery(d->mUpdateTrackFileModifiedTime); if (!queryResult || !d->mUpdateTrackFileModifiedTime.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackOrigin" << d->mUpdateTrackFileModifiedTime.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackOrigin" << d->mUpdateTrackFileModifiedTime.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackOrigin" << d->mUpdateTrackFileModifiedTime.lastError(); d->mUpdateTrackFileModifiedTime.finish(); return; } d->mUpdateTrackFileModifiedTime.finish(); } qulonglong DatabaseInterface::internalInsertTrack(const MusicAudioTrack &oneTrack, const QHash &covers, bool &isInserted) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack trying to insert" << oneTrack; qulonglong resultId = 0; if (oneTrack.title().isEmpty()) { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << oneTrack << "is not inserted"; return resultId; } QUrl::FormattingOptions currentOptions = QUrl::PreferLocalFile | QUrl::RemoveAuthority | QUrl::RemoveFilename | QUrl::RemoveFragment | QUrl::RemovePassword | QUrl::RemovePort | QUrl::RemoveQuery | QUrl::RemoveScheme | QUrl::RemoveUserInfo; const auto &trackPath = oneTrack.resourceURI().toString(currentOptions); auto albumCover = covers[oneTrack.resourceURI().toString()]; if (albumCover.isEmpty() && !covers.contains(oneTrack.resourceURI().toString())) { albumCover = oneTrack.albumCover(); } auto albumId = insertAlbum(oneTrack.albumName(), (oneTrack.isValidAlbumArtist() ? oneTrack.albumArtist() : QString()), trackPath, albumCover); auto oldAlbumId = albumId; auto existingTrackId = internalTrackIdFromFileName(oneTrack.resourceURI()); bool isModifiedTrack = (existingTrackId != 0); if (isModifiedTrack) { resultId = existingTrackId; auto oldTrack = internalTrackFromDatabaseId(existingTrackId); oldAlbumId = oldTrack.albumId(); auto isSameTrack = true; isSameTrack = isSameTrack && (oldTrack.title() == oneTrack.title()); isSameTrack = isSameTrack && (oldTrack.albumName() == oneTrack.albumName()); isSameTrack = isSameTrack && (oldTrack.artist() == oneTrack.artist()); isSameTrack = isSameTrack && (oldTrack.albumArtist() == oneTrack.albumArtist()); isSameTrack = isSameTrack && (oldTrack.trackNumberIsValid() == oneTrack.trackNumberIsValid()); if (isSameTrack && oldTrack.trackNumberIsValid()) { isSameTrack = isSameTrack && (oldTrack.trackNumber() == oneTrack.trackNumber()); } isSameTrack = isSameTrack && (oldTrack.discNumberIsValid() == oneTrack.discNumberIsValid()); if (isSameTrack && oldTrack.discNumberIsValid()) { isSameTrack = isSameTrack && (oldTrack.discNumber() == oneTrack.discNumber()); } isSameTrack = isSameTrack && (oldTrack.duration() == oneTrack.duration()); isSameTrack = isSameTrack && (oldTrack.rating() == oneTrack.rating()); isSameTrack = isSameTrack && (oldTrack.resourceURI() == oneTrack.resourceURI()); isSameTrack = isSameTrack && (oldTrack.genre() == oneTrack.genre()); isSameTrack = isSameTrack && (oldTrack.composer() == oneTrack.composer()); isSameTrack = isSameTrack && (oldTrack.lyricist() == oneTrack.lyricist()); isSameTrack = isSameTrack && (oldTrack.comment() == oneTrack.comment()); isSameTrack = isSameTrack && (oldTrack.year() == oneTrack.year()); isSameTrack = isSameTrack && (oldTrack.channelsIsValid() == oneTrack.channelsIsValid()); if (isSameTrack && oldTrack.channelsIsValid()) { isSameTrack = isSameTrack && (oldTrack.channels() == oneTrack.channels()); } isSameTrack = isSameTrack && (oldTrack.bitRateIsValid() == oneTrack.bitRateIsValid()); if (isSameTrack && oldTrack.bitRateIsValid()) { isSameTrack = isSameTrack && (oldTrack.bitRate() == oneTrack.bitRate()); } isSameTrack = isSameTrack && (oldTrack.sampleRateIsValid() == oneTrack.sampleRateIsValid()); if (isSameTrack && oldTrack.sampleRateIsValid()) { isSameTrack = isSameTrack && (oldTrack.sampleRate() == oneTrack.sampleRate()); } if (isSameTrack) { return resultId; } auto newTrack = oneTrack; newTrack.setDatabaseId(resultId); updateTrackInDatabase(newTrack, trackPath); updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); updateAlbumFromId(albumId, oneTrack.albumCover(), oneTrack, trackPath); recordModifiedTrack(existingTrackId); if (albumId != 0) { recordModifiedAlbum(albumId); } if (oldAlbumId != 0) { auto tracksCount = fetchTrackIds(oldAlbumId).count(); if (tracksCount) { recordModifiedAlbum(oldAlbumId); } else { removeAlbumInDatabase(oldAlbumId); Q_EMIT albumRemoved(oldAlbumId); } } isInserted = false; return resultId; } else { oldAlbumId = 0; existingTrackId = d->mTrackId; isInserted = true; } int priority = 1; while(true) { auto otherTrackId = getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(oneTrack.title(), oneTrack.artist(), oneTrack.albumName(), oneTrack.albumArtist(), trackPath, oneTrack.trackNumber(), oneTrack.discNumber(), priority); if (otherTrackId) { ++priority; } else { break; } } resultId = existingTrackId; d->mInsertTrackQuery.bindValue(QStringLiteral(":trackId"), existingTrackId); d->mInsertTrackQuery.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); d->mInsertTrackQuery.bindValue(QStringLiteral(":priority"), priority); d->mInsertTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); insertArtist(oneTrack.artist()); d->mInsertTrackQuery.bindValue(QStringLiteral(":artistName"), oneTrack.artist()); d->mInsertTrackQuery.bindValue(QStringLiteral(":albumTitle"), oneTrack.albumName()); if (oneTrack.isValidAlbumArtist()) { d->mInsertTrackQuery.bindValue(QStringLiteral(":albumArtistName"), oneTrack.albumArtist()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":albumArtistName"), {}); } d->mInsertTrackQuery.bindValue(QStringLiteral(":albumPath"), trackPath); if (oneTrack.trackNumberIsValid()) { d->mInsertTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.trackNumber()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":trackNumber"), {}); } if (oneTrack.discNumberIsValid()) { d->mInsertTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.discNumber()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":discNumber"), {}); } d->mInsertTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue(oneTrack.duration().msecsSinceStartOfDay())); d->mInsertTrackQuery.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); if (insertGenre(oneTrack.genre()) != 0) { d->mInsertTrackQuery.bindValue(QStringLiteral(":genre"), oneTrack.genre()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":genre"), {}); } if (insertComposer(oneTrack.composer()) != 0) { d->mInsertTrackQuery.bindValue(QStringLiteral(":composer"), oneTrack.composer()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":composer"), {}); } if (insertLyricist(oneTrack.lyricist()) != 0) { d->mInsertTrackQuery.bindValue(QStringLiteral(":lyricist"), oneTrack.lyricist()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":lyricist"), {}); } d->mInsertTrackQuery.bindValue(QStringLiteral(":comment"), oneTrack.comment()); d->mInsertTrackQuery.bindValue(QStringLiteral(":year"), oneTrack.year()); if (oneTrack.channelsIsValid()) { d->mInsertTrackQuery.bindValue(QStringLiteral(":channels"), oneTrack.channels()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":channels"), {}); } if (oneTrack.bitRateIsValid()) { d->mInsertTrackQuery.bindValue(QStringLiteral(":bitRate"), oneTrack.bitRate()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":bitRate"), {}); } if (oneTrack.sampleRateIsValid()) { d->mInsertTrackQuery.bindValue(QStringLiteral(":sampleRate"), oneTrack.sampleRate()); } else { d->mInsertTrackQuery.bindValue(QStringLiteral(":sampleRate"), {}); } d->mInsertTrackQuery.bindValue(QStringLiteral(":hasEmbeddedCover"), oneTrack.hasEmbeddedCover()); auto result = execQuery(d->mInsertTrackQuery); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << oneTrack << "is inserted"; if (result && d->mInsertTrackQuery.isActive()) { d->mInsertTrackQuery.finish(); if (!isModifiedTrack) { ++d->mTrackId; } updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); if (isModifiedTrack) { recordModifiedTrack(existingTrackId); if (albumId != 0) { recordModifiedAlbum(albumId); } if (oldAlbumId != 0) { recordModifiedAlbum(oldAlbumId); } } if (albumId != 0) { if (updateAlbumFromId(albumId, covers[oneTrack.resourceURI().toString()], oneTrack, trackPath)) { auto modifiedTracks = fetchTrackIds(albumId); for (auto oneModifiedTrack : modifiedTracks) { if (oneModifiedTrack != resultId) { recordModifiedTrack(oneModifiedTrack); } } } recordModifiedAlbum(albumId); } } else { d->mInsertTrackQuery.finish(); Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << oneTrack << oneTrack.resourceURI(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackQuery.lastError(); } return resultId; } MusicAudioTrack DatabaseInterface::buildTrackFromDatabaseRecord(const QSqlRecord &trackRecord) const { auto id = trackRecord.value(0).toULongLong(); auto result = MusicAudioTrack{}; if (result.isValid()) { return result; } result.setDatabaseId(id); result.setTitle(trackRecord.value(1).toString()); result.setParentId(trackRecord.value(2).toString()); result.setArtist(trackRecord.value(3).toString()); if (trackRecord.value(6).isValid()) { result.setAlbumArtist(trackRecord.value(6).toString()); } else { if (trackRecord.value(5).toInt() == 1) { result.setAlbumArtist(trackRecord.value(6).toString()); } else if (trackRecord.value(5).toInt() > 1) { result.setAlbumArtist(QStringLiteral("Various Artists")); } } result.setResourceURI(trackRecord.value(7).toUrl()); result.setFileModificationTime(trackRecord.value(8).toDateTime()); if (trackRecord.value(9).isValid()) { result.setTrackNumber(trackRecord.value(9).toInt()); } if (trackRecord.value(10).isValid()) { result.setDiscNumber(trackRecord.value(10).toInt()); } result.setDuration(QTime::fromMSecsSinceStartOfDay(trackRecord.value(11).toInt())); result.setAlbumName(trackRecord.value(12).toString()); result.setRating(trackRecord.value(13).toInt()); result.setAlbumCover(trackRecord.value(14).toUrl()); result.setIsSingleDiscAlbum(trackRecord.value(15).toBool()); result.setGenre(trackRecord.value(16).toString()); result.setComposer(trackRecord.value(17).toString()); result.setLyricist(trackRecord.value(18).toString()); result.setComment(trackRecord.value(19).toString()); result.setYear(trackRecord.value(20).toInt()); if (trackRecord.value(21).isValid()) { bool isValid; auto value = trackRecord.value(21).toInt(&isValid); if (isValid) { result.setChannels(value); } } if (trackRecord.value(22).isValid()) { bool isValid; auto value = trackRecord.value(22).toInt(&isValid); if (isValid) { result.setBitRate(value); } } if (trackRecord.value(23).isValid()) { bool isValid; auto value = trackRecord.value(23).toInt(&isValid); if (isValid) { result.setSampleRate(value); } } result.setAlbumId(trackRecord.value(2).toULongLong()); result.setHasEmbeddedCover(trackRecord.value(24).toBool()); result.setValid(true); return result; } DataTypes::TrackDataType DatabaseInterface::buildTrackDataFromDatabaseRecord(const QSqlRecord &trackRecord) const { DataTypes::TrackDataType result; result[DataTypes::TrackDataType::key_type::DatabaseIdRole] = trackRecord.value(0); result[DataTypes::TrackDataType::key_type::TitleRole] = trackRecord.value(1); if (!trackRecord.value(12).isNull()) { result[DataTypes::TrackDataType::key_type::AlbumRole] = trackRecord.value(12); result[DataTypes::TrackDataType::key_type::AlbumIdRole] = trackRecord.value(2); } if (!trackRecord.value(3).isNull()) { result[DataTypes::TrackDataType::key_type::ArtistRole] = trackRecord.value(3); } if (!trackRecord.value(6).isNull()) { result[DataTypes::TrackDataType::key_type::IsValidAlbumArtistRole] = true; result[DataTypes::TrackDataType::key_type::AlbumArtistRole] = trackRecord.value(6); } else { result[DataTypes::TrackDataType::key_type::IsValidAlbumArtistRole] = false; if (trackRecord.value(4).toInt() == 1) { result[DataTypes::TrackDataType::key_type::AlbumArtistRole] = trackRecord.value(3); } else if (trackRecord.value(4).toInt() > 1) { result[DataTypes::TrackDataType::key_type::AlbumArtistRole] = i18n("Various Artists"); } } result[DataTypes::TrackDataType::key_type::ResourceRole] = trackRecord.value(7); if (!trackRecord.value(9).isNull()) { result[DataTypes::TrackDataType::key_type::TrackNumberRole] = trackRecord.value(9); } if (!trackRecord.value(10).isNull()) { result[DataTypes::TrackDataType::key_type::DiscNumberRole] = trackRecord.value(10); } result[DataTypes::TrackDataType::key_type::DurationRole] = QTime::fromMSecsSinceStartOfDay(trackRecord.value(11).toInt()); - result[DataTypes::TrackDataType::key_type::MilliSecondsDurationRole] = trackRecord.value(11).toInt(); result[DataTypes::TrackDataType::key_type::RatingRole] = trackRecord.value(13); if (!trackRecord.value(14).toString().isEmpty()) { result[DataTypes::TrackDataType::key_type::ImageUrlRole] = QUrl(trackRecord.value(14).toString()); } else if (!trackRecord.value(30).toString().isEmpty()) { result[DataTypes::TrackDataType::key_type::ImageUrlRole] = QVariant{QLatin1String("image://cover/") + trackRecord.value(30).toUrl().toLocalFile()}; } result[DataTypes::TrackDataType::key_type::IsSingleDiscAlbumRole] = trackRecord.value(15); if (!trackRecord.value(16).isNull()) { result[DataTypes::TrackDataType::key_type::GenreRole] = trackRecord.value(16); } if (!trackRecord.value(17).isNull()) { result[DataTypes::TrackDataType::key_type::ComposerRole] = trackRecord.value(17); } if (!trackRecord.value(18).isNull()) { result[DataTypes::TrackDataType::key_type::LyricistRole] = trackRecord.value(18); } if (!trackRecord.value(19).isNull()) { result[DataTypes::TrackDataType::key_type::CommentRole] = trackRecord.value(19); } if (!trackRecord.value(20).isNull()) { result[DataTypes::TrackDataType::key_type::YearRole] = trackRecord.value(20); } if (!trackRecord.value(21).isNull()) { result[DataTypes::TrackDataType::key_type::ChannelsRole] = trackRecord.value(21); } if (!trackRecord.value(22).isNull()) { result[DataTypes::TrackDataType::key_type::BitRateRole] = trackRecord.value(22); } if (!trackRecord.value(23).isNull()) { result[DataTypes::TrackDataType::key_type::SampleRateRole] = trackRecord.value(23); } result[DataTypes::TrackDataType::key_type::HasEmbeddedCover] = trackRecord.value(24); result[DataTypes::TrackDataType::key_type::FileModificationTime] = trackRecord.value(8); if (!trackRecord.value(26).isNull()) { result[DataTypes::TrackDataType::key_type::FirstPlayDate] = trackRecord.value(26); } if (!trackRecord.value(27).isNull()) { result[DataTypes::TrackDataType::key_type::LastPlayDate] = trackRecord.value(27); } result[DataTypes::TrackDataType::key_type::PlayCounter] = trackRecord.value(28); result[DataTypes::TrackDataType::key_type::PlayFrequency] = trackRecord.value(29); result[DataTypes::TrackDataType::key_type::ElementTypeRole] = ElisaUtils::Track; return result; } DataTypes::TrackDataType DatabaseInterface::buildRadioDataFromDatabaseRecord(const QSqlRecord &trackRecord) const { DataTypes::TrackDataType result; 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::CommentRole] = trackRecord.value(5); result[DataTypes::TrackDataType::key_type::ElementTypeRole] = ElisaUtils::Radio; return result; } void DatabaseInterface::internalRemoveTracksList(const QList &removedTracks) { QSet modifiedAlbums; QUrl::FormattingOptions currentOptions = QUrl::PreferLocalFile | QUrl::RemoveAuthority | QUrl::RemoveFilename | QUrl::RemoveFragment | QUrl::RemovePassword | QUrl::RemovePort | QUrl::RemoveQuery | QUrl::RemoveScheme | QUrl::RemoveUserInfo; for (const auto &removedTrackFileName : removedTracks) { auto removedTrackId = internalTrackIdFromFileName(removedTrackFileName); Q_EMIT trackRemoved(removedTrackId); auto oneRemovedTrack = internalTrackFromDatabaseId(removedTrackId); removeTrackInDatabase(removedTrackId); const auto &trackPath = oneRemovedTrack.resourceURI().toString(currentOptions); const auto &modifiedAlbumId = internalAlbumIdFromTitleAndArtist(oneRemovedTrack.albumName(), oneRemovedTrack.albumArtist(), trackPath); const auto &allTracksFromArtist = internalTracksFromAuthor(oneRemovedTrack.artist()); const auto &allAlbumsFromArtist = internalAlbumIdsFromAuthor(oneRemovedTrack.artist()); const auto &removedArtistId = internalArtistIdFromName(oneRemovedTrack.artist()); if (modifiedAlbumId) { recordModifiedAlbum(modifiedAlbumId); modifiedAlbums.insert(modifiedAlbumId); updateAlbumFromId(modifiedAlbumId, oneRemovedTrack.albumCover(), oneRemovedTrack, trackPath); } if (removedArtistId != 0 && allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { removeArtistInDatabase(removedArtistId); Q_EMIT artistRemoved(removedArtistId); } d->mRemoveTracksMapping.bindValue(QStringLiteral(":fileName"), removedTrackFileName.toString()); auto result = execQuery(d->mRemoveTracksMapping); if (!result || !d->mRemoveTracksMapping.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalRemoveTracksList" << d->mRemoveTracksMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalRemoveTracksList" << d->mRemoveTracksMapping.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalRemoveTracksList" << d->mRemoveTracksMapping.lastError(); continue; } d->mRemoveTracksMapping.finish(); } for (auto modifiedAlbumId : modifiedAlbums) { const auto &modifiedAlbumData = internalOneAlbumPartialData(modifiedAlbumId); auto tracksCount = fetchTrackIds(modifiedAlbumId).count(); if (!modifiedAlbumData.isEmpty() && tracksCount) { Q_EMIT albumModified({{DataTypes::DatabaseIdRole, modifiedAlbumId}}, modifiedAlbumId); } else { removeAlbumInDatabase(modifiedAlbumId); Q_EMIT albumRemoved(modifiedAlbumId); const auto &allTracksFromArtist = internalTracksFromAuthor(modifiedAlbumData[DataTypes::AlbumDataType::key_type::ArtistRole].toString()); const auto &allAlbumsFromArtist = internalAlbumIdsFromAuthor(modifiedAlbumData[DataTypes::AlbumDataType::key_type::ArtistRole].toString()); const auto &removedArtistId = internalArtistIdFromName(modifiedAlbumData[DataTypes::AlbumDataType::key_type::ArtistRole].toString()); if (removedArtistId != 0 && allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { removeArtistInDatabase(removedArtistId); Q_EMIT artistRemoved(removedArtistId); } } } } QUrl DatabaseInterface::internalAlbumArtUriFromAlbumId(qulonglong albumId) { auto result = QUrl(); d->mSelectAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":albumId"), albumId); auto queryResult = execQuery(d->mSelectAlbumArtUriFromAlbumIdQuery); if (!queryResult || !d->mSelectAlbumArtUriFromAlbumIdQuery.isSelect() || !d->mSelectAlbumArtUriFromAlbumIdQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectAlbumArtUriFromAlbumIdQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastError(); d->mSelectAlbumArtUriFromAlbumIdQuery.finish(); return result; } if (!d->mSelectAlbumArtUriFromAlbumIdQuery.next()) { d->mSelectAlbumArtUriFromAlbumIdQuery.finish(); return result; } result = d->mSelectAlbumArtUriFromAlbumIdQuery.record().value(0).toUrl(); d->mSelectAlbumArtUriFromAlbumIdQuery.finish(); return result; } bool DatabaseInterface::isValidArtist(qulonglong albumId) { auto result = false; d->mSelectAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); auto queryResult = execQuery(d->mSelectAlbumQuery); if (!queryResult || !d->mSelectAlbumQuery.isSelect() || !d->mSelectAlbumQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumFromId" << d->mSelectAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumFromId" << d->mSelectAlbumQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumFromId" << d->mSelectAlbumQuery.lastError(); d->mSelectAlbumQuery.finish(); return result; } if (!d->mSelectAlbumQuery.next()) { d->mSelectAlbumQuery.finish(); return result; } const auto ¤tRecord = d->mSelectAlbumQuery.record(); result = !currentRecord.value(2).toString().isEmpty(); return result; } bool DatabaseInterface::internalGenericPartialData(QSqlQuery &query) { auto result = false; auto queryResult = execQuery(query); if (!queryResult || !query.isSelect() || !query.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAllGenericPartialData" << query.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAllGenericPartialData" << query.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAllGenericPartialData" << query.lastError(); query.finish(); auto transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } result = true; return result; } qulonglong DatabaseInterface::insertLyricist(const QString &name) { auto result = qulonglong(0); if (name.isEmpty()) { return result; } d->mSelectLyricistByNameQuery.bindValue(QStringLiteral(":name"), name); auto queryResult = execQuery(d->mSelectLyricistByNameQuery); if (!queryResult || !d->mSelectLyricistByNameQuery.isSelect() || !d->mSelectLyricistByNameQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mSelectLyricistByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mSelectLyricistByNameQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mSelectLyricistByNameQuery.lastError(); d->mSelectLyricistByNameQuery.finish(); return result; } if (d->mSelectLyricistByNameQuery.next()) { result = d->mSelectLyricistByNameQuery.record().value(0).toULongLong(); d->mSelectLyricistByNameQuery.finish(); return result; } d->mSelectLyricistByNameQuery.finish(); d->mInsertLyricistQuery.bindValue(QStringLiteral(":lyricistId"), d->mLyricistId); d->mInsertLyricistQuery.bindValue(QStringLiteral(":name"), name); queryResult = execQuery(d->mInsertLyricistQuery); if (!queryResult || !d->mInsertLyricistQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mInsertLyricistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mInsertLyricistQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mInsertLyricistQuery.lastError(); d->mInsertLyricistQuery.finish(); return result; } result = d->mLyricistId; ++d->mLyricistId; d->mInsertLyricistQuery.finish(); Q_EMIT lyricistsAdded(internalAllLyricistsPartialData()); return result; } QHash DatabaseInterface::internalAllFileName() { auto allFileNames = QHash{}; auto queryResult = execQuery(d->mSelectAllTrackFilesQuery); if (!queryResult || !d->mSelectAllTrackFilesQuery.isSelect() || !d->mSelectAllTrackFilesQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << d->mSelectAllTrackFilesQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << d->mSelectAllTrackFilesQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << d->mSelectAllTrackFilesQuery.lastError(); d->mSelectAllTrackFilesQuery.finish(); return allFileNames; } while(d->mSelectAllTrackFilesQuery.next()) { auto fileName = d->mSelectAllTrackFilesQuery.record().value(0).toUrl(); auto fileModificationTime = d->mSelectAllTrackFilesQuery.record().value(1).toDateTime(); allFileNames[fileName] = fileModificationTime; } d->mSelectAllTrackFilesQuery.finish(); return allFileNames; } qulonglong DatabaseInterface::internalArtistIdFromName(const QString &name) { auto result = qulonglong(0); if (name.isEmpty()) { return result; } d->mSelectArtistByNameQuery.bindValue(QStringLiteral(":name"), name); auto queryResult = execQuery(d->mSelectArtistByNameQuery); if (!queryResult || !d->mSelectArtistByNameQuery.isSelect() || !d->mSelectArtistByNameQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastError(); d->mSelectArtistByNameQuery.finish(); return result; } if (!d->mSelectArtistByNameQuery.next()) { d->mSelectArtistByNameQuery.finish(); return result; } result = d->mSelectArtistByNameQuery.record().value(0).toULongLong(); d->mSelectArtistByNameQuery.finish(); return result; } void DatabaseInterface::removeTrackInDatabase(qulonglong trackId) { d->mRemoveTrackQuery.bindValue(QStringLiteral(":trackId"), trackId); auto result = execQuery(d->mRemoveTrackQuery); if (!result || !d->mRemoveTrackQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackQuery.lastError(); } d->mRemoveTrackQuery.finish(); } void DatabaseInterface::updateTrackInDatabase(const MusicAudioTrack &oneTrack, const QString &albumPath) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackId"), oneTrack.databaseId()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); insertArtist(oneTrack.artist()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":artistName"), oneTrack.artist()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumTitle"), oneTrack.albumName()); if (oneTrack.isValidAlbumArtist()) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumArtistName"), oneTrack.albumArtist()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumArtistName"), {}); } d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumPath"), albumPath); if (oneTrack.trackNumberIsValid()) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.trackNumber()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackNumber"), {}); } if (oneTrack.discNumberIsValid()) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.discNumber()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":discNumber"), {}); } d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue(oneTrack.duration().msecsSinceStartOfDay())); d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); if (insertGenre(oneTrack.genre()) != 0) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":genre"), oneTrack.genre()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":genre"), {}); } if (insertComposer(oneTrack.composer()) != 0) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":composer"), oneTrack.composer()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":composer"), {}); } if (insertLyricist(oneTrack.lyricist()) != 0) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":lyricist"), oneTrack.lyricist()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":lyricist"), {}); } d->mUpdateTrackQuery.bindValue(QStringLiteral(":comment"), oneTrack.comment()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":year"), oneTrack.year()); if (oneTrack.channelsIsValid()) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":channels"), oneTrack.channels()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":channels"), {}); } if (oneTrack.bitRateIsValid()) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":bitRate"), oneTrack.bitRate()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":bitRate"), {}); } if (oneTrack.sampleRateIsValid()) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":sampleRate"), oneTrack.sampleRate()); } else { d->mUpdateTrackQuery.bindValue(QStringLiteral(":sampleRate"), {}); } auto result = execQuery(d->mUpdateTrackQuery); if (!result || !d->mUpdateTrackQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.lastError(); } d->mUpdateTrackQuery.finish(); } void DatabaseInterface::insertRadio(const DataTypes::TrackDataType &oneTrack) { QSqlQuery query = d->mUpdateRadioQuery; if (oneTrack.databaseId() == -1ull) { query = d->mInsertRadioQuery; } query.bindValue(QStringLiteral(":httpAddress"), oneTrack.resourceURI()); query.bindValue(QStringLiteral(":radioId"), oneTrack.databaseId()); query.bindValue(QStringLiteral(":title"), oneTrack.title()); query.bindValue(QStringLiteral(":comment"), oneTrack.comment()); query.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); auto result = execQuery(query); if (!result || !query.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.lastError(); } else { if (oneTrack[DataTypes::TrackDataType::key_type::DatabaseIdRole] == -1) { auto radio = internalOneRadioPartialData(internalRadioIdFromHttpAddress(oneTrack.resourceURI().toString())); Q_EMIT radioAdded(radio); } else { auto radio = internalOneRadioPartialData(oneTrack.databaseId()); Q_EMIT radioModified(radio); } } query.finish(); } void DatabaseInterface::removeRadio(qulonglong radioId) { QSqlQuery query = d->mDeleteRadioQuery; query.bindValue(QStringLiteral(":radioId"), radioId); auto result = execQuery(query); if (!result || !query.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.lastError(); }else{ Q_EMIT radioRemoved(radioId); } query.finish(); } void DatabaseInterface::removeAlbumInDatabase(qulonglong albumId) { d->mRemoveAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); auto result = execQuery(d->mRemoveAlbumQuery); if (!result || !d->mRemoveAlbumQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumQuery.lastError(); } d->mRemoveAlbumQuery.finish(); } void DatabaseInterface::removeArtistInDatabase(qulonglong artistId) { d->mRemoveArtistQuery.bindValue(QStringLiteral(":artistId"), artistId); auto result = execQuery(d->mRemoveArtistQuery); if (!result || !d->mRemoveArtistQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeArtistInDatabase" << d->mRemoveArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeArtistInDatabase" << d->mRemoveArtistQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeArtistInDatabase" << d->mRemoveArtistQuery.lastError(); } d->mRemoveArtistQuery.finish(); } void DatabaseInterface::reloadExistingDatabase() { qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::reloadExistingDatabase"; d->mArtistId = genericInitialId(d->mQueryMaximumArtistIdQuery); d->mComposerId = genericInitialId(d->mQueryMaximumComposerIdQuery); d->mLyricistId = genericInitialId(d->mQueryMaximumLyricistIdQuery); d->mAlbumId = genericInitialId(d->mQueryMaximumAlbumIdQuery); d->mTrackId = genericInitialId(d->mQueryMaximumTrackIdQuery); d->mGenreId = genericInitialId(d->mQueryMaximumGenreIdQuery); } qulonglong DatabaseInterface::genericInitialId(QSqlQuery &request) { auto result = qulonglong(0); auto transactionResult = startTransaction(); if (!transactionResult) { return result; } auto queryResult = execQuery(request); if (!queryResult || !request.isSelect() || !request.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << request.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << request.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << request.lastError(); request.finish(); transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } if (request.next()) { result = request.record().value(0).toULongLong() + 1; request.finish(); } transactionResult = finishTransaction(); if (!transactionResult) { return result; } return result; } QList DatabaseInterface::fetchTrackIds(qulonglong albumId) { auto allTracks = QList(); d->mSelectTrackIdQuery.bindValue(QStringLiteral(":albumId"), albumId); auto result = execQuery(d->mSelectTrackIdQuery); if (!result || !d->mSelectTrackIdQuery.isSelect() || !d->mSelectTrackIdQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::fetchTrackIds" << d->mSelectTrackIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::fetchTrackIds" << d->mSelectTrackIdQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::fetchTrackIds" << d->mSelectTrackIdQuery.lastError(); } while (d->mSelectTrackIdQuery.next()) { const auto ¤tRecord = d->mSelectTrackIdQuery.record(); allTracks.push_back(currentRecord.value(0).toULongLong()); } d->mSelectTrackIdQuery.finish(); return allTracks; } qulonglong DatabaseInterface::internalAlbumIdFromTitleAndArtist(const QString &title, const QString &artist, const QString &albumPath) { auto result = qulonglong(0); d->mSelectAlbumIdFromTitleQuery.bindValue(QStringLiteral(":title"), title); d->mSelectAlbumIdFromTitleQuery.bindValue(QStringLiteral(":artistName"), artist); auto queryResult = execQuery(d->mSelectAlbumIdFromTitleQuery); if (!queryResult || !d->mSelectAlbumIdFromTitleQuery.isSelect() || !d->mSelectAlbumIdFromTitleQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleQuery.lastError(); d->mSelectAlbumIdFromTitleQuery.finish(); return result; } if (d->mSelectAlbumIdFromTitleQuery.next()) { result = d->mSelectAlbumIdFromTitleQuery.record().value(0).toULongLong(); } d->mSelectAlbumIdFromTitleQuery.finish(); if (result == 0) { d->mSelectAlbumIdFromTitleWithoutArtistQuery.bindValue(QStringLiteral(":title"), title); d->mSelectAlbumIdFromTitleWithoutArtistQuery.bindValue(QStringLiteral(":albumPath"), albumPath); auto queryResult = execQuery(d->mSelectAlbumIdFromTitleWithoutArtistQuery); if (!queryResult || !d->mSelectAlbumIdFromTitleWithoutArtistQuery.isSelect() || !d->mSelectAlbumIdFromTitleWithoutArtistQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastError(); d->mSelectAlbumIdFromTitleWithoutArtistQuery.finish(); return result; } if (d->mSelectAlbumIdFromTitleWithoutArtistQuery.next()) { result = d->mSelectAlbumIdFromTitleWithoutArtistQuery.record().value(0).toULongLong(); } d->mSelectAlbumIdFromTitleWithoutArtistQuery.finish(); } return result; } MusicAudioTrack DatabaseInterface::internalTrackFromDatabaseId(qulonglong id) { auto result = MusicAudioTrack(); if (result.isValid()) { return result; } if (!d || !d->mTracksDatabase.isValid() || !d->mInitFinished) { return result; } d->mSelectTrackFromIdQuery.bindValue(QStringLiteral(":trackId"), id); auto queryResult = execQuery(d->mSelectTrackFromIdQuery); if (!queryResult || !d->mSelectTrackFromIdQuery.isSelect() || !d->mSelectTrackFromIdQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackFromDatabaseId" << d->mSelectTrackFromIdQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackFromDatabaseId" << d->mSelectTrackFromIdQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackFromDatabaseId" << d->mSelectTrackFromIdQuery.lastError(); d->mSelectTrackFromIdQuery.finish(); return result; } if (!d->mSelectTrackFromIdQuery.next()) { d->mSelectTrackFromIdQuery.finish(); return result; } const auto ¤tRecord = d->mSelectTrackFromIdQuery.record(); result = buildTrackFromDatabaseRecord(currentRecord); d->mSelectTrackFromIdQuery.finish(); return result; } qulonglong DatabaseInterface::internalTrackIdFromTitleAlbumTracDiscNumber(const QString &title, const QString &artist, const std::optional &album, std::optional trackNumber, std::optional discNumber) { auto result = qulonglong(0); if (!d) { return result; } d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":title"), title); d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":artist"), artist); if (album.has_value()) { d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), album.value()); } else { d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), {}); } if (trackNumber.has_value()) { d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), trackNumber.value()); } else { d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), {}); } if (discNumber.has_value()) { d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), discNumber.value()); } else { d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), {}); } auto queryResult = execQuery(d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery); if (!queryResult || !d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.isSelect() || !d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastError(); d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.finish(); return result; } if (d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.next()) { result = d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.record().value(0).toULongLong(); } d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.finish(); return result; } qulonglong DatabaseInterface::getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &trackArtist, const QString &album, const QString &albumArtist, const QString &trackPath, int trackNumber, int discNumber, int priority) { auto result = qulonglong(0); if (!d) { return result; } d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":title"), title); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackArtist"), trackArtist); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), album); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":albumArtist"), albumArtist); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), trackNumber); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), discNumber); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":priority"), priority); auto queryResult = execQuery(d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery); if (!queryResult || !d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.isSelect() || !d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastError(); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.finish(); return result; } if (d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.next()) { result = d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.record().value(0).toULongLong(); } d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.finish(); return result; } qulonglong DatabaseInterface::internalTrackIdFromFileName(const QUrl &fileName) { auto result = qulonglong(0); if (!d) { return result; } d->mSelectTracksMapping.bindValue(QStringLiteral(":fileName"), fileName.toString()); auto queryResult = execQuery(d->mSelectTracksMapping); if (!queryResult || !d->mSelectTracksMapping.isSelect() || !d->mSelectTracksMapping.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectTracksMapping.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectTracksMapping.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectTracksMapping.lastError(); d->mSelectTracksMapping.finish(); return result; } if (d->mSelectTracksMapping.next()) { const auto ¤tRecordValue = d->mSelectTracksMapping.record().value(0); if (currentRecordValue.isValid()) { result = currentRecordValue.toULongLong(); } } d->mSelectTracksMapping.finish(); return result; } qulonglong DatabaseInterface::internalRadioIdFromHttpAddress(const QString &httpAddress) { auto result = qulonglong(0); if (!d) { return result; } d->mSelectRadioIdFromHttpAddress.bindValue(QStringLiteral(":httpAddress"), httpAddress); auto queryResult = execQuery(d->mSelectRadioIdFromHttpAddress); if (!queryResult || !d->mSelectRadioIdFromHttpAddress.isSelect() || !d->mSelectRadioIdFromHttpAddress.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectRadioIdFromHttpAddress.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectRadioIdFromHttpAddress.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectRadioIdFromHttpAddress.lastError(); d->mSelectRadioIdFromHttpAddress.finish(); return result; } if (d->mSelectRadioIdFromHttpAddress.next()) { const auto ¤tRecordValue = d->mSelectRadioIdFromHttpAddress.record().value(0); if (currentRecordValue.isValid()) { result = currentRecordValue.toULongLong(); } } d->mSelectRadioIdFromHttpAddress.finish(); return result; } DataTypes::ListTrackDataType DatabaseInterface::internalTracksFromAuthor(const QString &ArtistName) { auto allTracks = DataTypes::ListTrackDataType{}; d->mSelectTracksFromArtist.bindValue(QStringLiteral(":artistName"), ArtistName); auto result = execQuery(d->mSelectTracksFromArtist); if (!result || !d->mSelectTracksFromArtist.isSelect() || !d->mSelectTracksFromArtist.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectTracksFromArtist.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectTracksFromArtist.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectTracksFromArtist.lastError(); return allTracks; } while (d->mSelectTracksFromArtist.next()) { const auto ¤tRecord = d->mSelectTracksFromArtist.record(); allTracks.push_back(buildTrackDataFromDatabaseRecord(currentRecord)); } d->mSelectTracksFromArtist.finish(); return allTracks; } QList DatabaseInterface::internalAlbumIdsFromAuthor(const QString &ArtistName) { auto allAlbumIds = QList(); d->mSelectAlbumIdsFromArtist.bindValue(QStringLiteral(":artistName"), ArtistName); auto result = execQuery(d->mSelectAlbumIdsFromArtist); if (!result || !d->mSelectAlbumIdsFromArtist.isSelect() || !d->mSelectAlbumIdsFromArtist.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectAlbumIdsFromArtist.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectAlbumIdsFromArtist.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectAlbumIdsFromArtist.lastError(); return allAlbumIds; } while (d->mSelectAlbumIdsFromArtist.next()) { const auto ¤tRecord = d->mSelectAlbumIdsFromArtist.record(); allAlbumIds.push_back(currentRecord.value(0).toULongLong()); } d->mSelectAlbumIdsFromArtist.finish(); return allAlbumIds; } DataTypes::ListArtistDataType DatabaseInterface::internalAllArtistsPartialData(QSqlQuery &artistsQuery) { auto result = DataTypes::ListArtistDataType{}; if (!internalGenericPartialData(artistsQuery)) { return result; } while(artistsQuery.next()) { auto newData = DataTypes::ArtistDataType{}; const auto ¤tRecord = artistsQuery.record(); newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); newData[DataTypes::TitleRole] = currentRecord.value(1); newData[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(2).toString().split(QStringLiteral(", "))); newData[DataTypes::ElementTypeRole] = ElisaUtils::Artist; result.push_back(newData); } artistsQuery.finish(); return result; } DataTypes::ListAlbumDataType DatabaseInterface::internalAllAlbumsPartialData(QSqlQuery &query) { auto result = DataTypes::ListAlbumDataType{}; if (!internalGenericPartialData(query)) { return result; } while(query.next()) { auto newData = DataTypes::AlbumDataType{}; const auto ¤tRecord = query.record(); newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); newData[DataTypes::TitleRole] = currentRecord.value(1); if (!currentRecord.value(3).toString().isEmpty()) { newData[DataTypes::ImageUrlRole] = currentRecord.value(3); } else if (!currentRecord.value(10).toString().isEmpty()) { newData[DataTypes::ImageUrlRole] = QVariant{QLatin1String("image://cover/") + currentRecord.value(10).toUrl().toLocalFile()}; } auto allArtists = currentRecord.value(6).toString().split(QStringLiteral(", ")); allArtists.removeDuplicates(); newData[DataTypes::AllArtistsRole] = QVariant::fromValue(allArtists); if (!currentRecord.value(4).isNull()) { newData[DataTypes::IsValidAlbumArtistRole] = true; newData[DataTypes::SecondaryTextRole] = currentRecord.value(4); } else { newData[DataTypes::IsValidAlbumArtistRole] = false; if (currentRecord.value(5).toInt() == 1) { newData[DataTypes::SecondaryTextRole] = allArtists.first(); } else if (currentRecord.value(5).toInt() > 1) { newData[DataTypes::SecondaryTextRole] = i18n("Various Artists"); } } newData[DataTypes::ArtistRole] = newData[DataTypes::SecondaryTextRole]; newData[DataTypes::HighestTrackRating] = currentRecord.value(7); newData[DataTypes::IsSingleDiscAlbumRole] = currentRecord.value(9); newData[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(8).toString().split(QStringLiteral(", "))); newData[DataTypes::ElementTypeRole] = ElisaUtils::Album; result.push_back(newData); } query.finish(); return result; } DataTypes::AlbumDataType DatabaseInterface::internalOneAlbumPartialData(qulonglong databaseId) { auto result = DataTypes::AlbumDataType{}; d->mSelectAlbumQuery.bindValue(QStringLiteral(":albumId"), databaseId); if (!internalGenericPartialData(d->mSelectAlbumQuery)) { return result; } if (d->mSelectAlbumQuery.next()) { const auto ¤tRecord = d->mSelectAlbumQuery.record(); result[DataTypes::DatabaseIdRole] = currentRecord.value(0); result[DataTypes::TitleRole] = currentRecord.value(1); if (!currentRecord.value(4).toString().isEmpty()) { result[DataTypes::ImageUrlRole] = currentRecord.value(4); } else if (!currentRecord.value(11).toString().isEmpty()) { result[DataTypes::ImageUrlRole] = QVariant{QLatin1String("image://cover/") + currentRecord.value(11).toUrl().toLocalFile()}; } auto allArtists = currentRecord.value(8).toString().split(QStringLiteral(", ")); allArtists.removeDuplicates(); result[DataTypes::AllArtistsRole] = QVariant::fromValue(allArtists); if (!currentRecord.value(2).isNull()) { result[DataTypes::IsValidAlbumArtistRole] = true; result[DataTypes::SecondaryTextRole] = currentRecord.value(2); } else { result[DataTypes::IsValidAlbumArtistRole] = false; if (currentRecord.value(7).toInt() == 1) { result[DataTypes::SecondaryTextRole] = allArtists.first(); } else if (currentRecord.value(7).toInt() > 1) { result[DataTypes::SecondaryTextRole] = i18n("Various Artists"); } } result[DataTypes::ArtistRole] = result[DataTypes::SecondaryTextRole]; result[DataTypes::HighestTrackRating] = currentRecord.value(9); result[DataTypes::IsSingleDiscAlbumRole] = currentRecord.value(6); result[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(10).toString().split(QStringLiteral(", "))); result[DataTypes::ElementTypeRole] = ElisaUtils::Album; } d->mSelectAlbumQuery.finish(); return result; } DataTypes::ListTrackDataType DatabaseInterface::internalAllTracksPartialData() { auto result = DataTypes::ListTrackDataType{}; if (!internalGenericPartialData(d->mSelectAllTracksQuery)) { return result; } while(d->mSelectAllTracksQuery.next()) { const auto ¤tRecord = d->mSelectAllTracksQuery.record(); auto newData = buildTrackDataFromDatabaseRecord(currentRecord); result.push_back(newData); } d->mSelectAllTracksQuery.finish(); return result; } DataTypes::ListRadioDataType DatabaseInterface::internalAllRadiosPartialData() { auto result = DataTypes::ListRadioDataType{}; if (!internalGenericPartialData(d->mSelectAllRadiosQuery)) { return result; } while(d->mSelectAllRadiosQuery.next()) { const auto ¤tRecord = d->mSelectAllRadiosQuery.record(); auto newData = buildRadioDataFromDatabaseRecord(currentRecord); result.push_back(newData); } d->mSelectAllRadiosQuery.finish(); return result; } DataTypes::ListTrackDataType DatabaseInterface::internalRecentlyPlayedTracksData(int count) { auto result = DataTypes::ListTrackDataType{}; d->mSelectAllRecentlyPlayedTracksQuery.bindValue(QStringLiteral(":maximumResults"), count); if (!internalGenericPartialData(d->mSelectAllRecentlyPlayedTracksQuery)) { return result; } while(d->mSelectAllRecentlyPlayedTracksQuery.next()) { const auto ¤tRecord = d->mSelectAllRecentlyPlayedTracksQuery.record(); auto newData = buildTrackDataFromDatabaseRecord(currentRecord); result.push_back(newData); } d->mSelectAllRecentlyPlayedTracksQuery.finish(); return result; } DataTypes::ListTrackDataType DatabaseInterface::internalFrequentlyPlayedTracksData(int count) { auto result = DataTypes::ListTrackDataType{}; d->mSelectAllFrequentlyPlayedTracksQuery.bindValue(QStringLiteral(":maximumResults"), count); if (!internalGenericPartialData(d->mSelectAllFrequentlyPlayedTracksQuery)) { return result; } while(d->mSelectAllFrequentlyPlayedTracksQuery.next()) { const auto ¤tRecord = d->mSelectAllFrequentlyPlayedTracksQuery.record(); auto newData = buildTrackDataFromDatabaseRecord(currentRecord); result.push_back(newData); } d->mSelectAllFrequentlyPlayedTracksQuery.finish(); return result; } DataTypes::TrackDataType DatabaseInterface::internalOneTrackPartialData(qulonglong databaseId) { auto result = DataTypes::TrackDataType{}; d->mSelectTrackFromIdQuery.bindValue(QStringLiteral(":trackId"), databaseId); if (!internalGenericPartialData(d->mSelectTrackFromIdQuery)) { return result; } if (d->mSelectTrackFromIdQuery.next()) { const auto ¤tRecord = d->mSelectTrackFromIdQuery.record(); result = buildTrackDataFromDatabaseRecord(currentRecord); } d->mSelectTrackFromIdQuery.finish(); return result; } DataTypes::TrackDataType DatabaseInterface::internalOneRadioPartialData(qulonglong databaseId) { auto result = DataTypes::TrackDataType{}; d->mSelectRadioFromIdQuery.bindValue(QStringLiteral(":radioId"), databaseId); if (!internalGenericPartialData(d->mSelectRadioFromIdQuery)) { return result; } if (d->mSelectRadioFromIdQuery.next()) { const auto ¤tRecord = d->mSelectRadioFromIdQuery.record(); result = buildRadioDataFromDatabaseRecord(currentRecord); } d->mSelectRadioFromIdQuery.finish(); return result; } DataTypes::ListGenreDataType DatabaseInterface::internalAllGenresPartialData() { DataTypes::ListGenreDataType result; if (!internalGenericPartialData(d->mSelectAllGenresQuery)) { return result; } while(d->mSelectAllGenresQuery.next()) { auto newData = DataTypes::GenreDataType{}; const auto ¤tRecord = d->mSelectAllGenresQuery.record(); newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); newData[DataTypes::TitleRole] = currentRecord.value(1); newData[DataTypes::ElementTypeRole] = ElisaUtils::Genre; result.push_back(newData); } d->mSelectAllGenresQuery.finish(); return result; } DataTypes::ListArtistDataType DatabaseInterface::internalAllComposersPartialData() { DataTypes::ListArtistDataType result; if (!internalGenericPartialData(d->mSelectAllComposersQuery)) { return result; } while(d->mSelectAllComposersQuery.next()) { auto newData = DataTypes::ArtistDataType{}; const auto ¤tRecord = d->mSelectAllComposersQuery.record(); newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); newData[DataTypes::TitleRole] = currentRecord.value(1); newData[DataTypes::ElementTypeRole] = ElisaUtils::Composer; result.push_back(newData); } d->mSelectAllComposersQuery.finish(); return result; } DataTypes::ListArtistDataType DatabaseInterface::internalAllLyricistsPartialData() { DataTypes::ListArtistDataType result; if (!internalGenericPartialData(d->mSelectAllLyricistsQuery)) { return result; } while(d->mSelectAllLyricistsQuery.next()) { auto newData = DataTypes::ArtistDataType{}; const auto ¤tRecord = d->mSelectAllLyricistsQuery.record(); newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); newData[DataTypes::TitleRole] = currentRecord.value(1); newData[DataTypes::ElementTypeRole] = ElisaUtils::Lyricist; result.push_back(newData); } d->mSelectAllLyricistsQuery.finish(); return result; } bool DatabaseInterface::prepareQuery(QSqlQuery &query, const QString &queryText) const { query.setForwardOnly(true); return query.prepare(queryText); } bool DatabaseInterface::execQuery(QSqlQuery &query) { #if !defined NDEBUG auto timer = QElapsedTimer{}; timer.start(); #endif auto result = query.exec(); #if !defined NDEBUG if (timer.nsecsElapsed() > 10000000) { qCDebug(orgKdeElisaDatabase) << "[[" << timer.nsecsElapsed() << "]]" << query.lastQuery(); } #endif return result; } void DatabaseInterface::updateAlbumArtist(qulonglong albumId, const QString &title, const QString &albumPath, const QString &artistName) { d->mUpdateAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); insertArtist(artistName); d->mUpdateAlbumArtistQuery.bindValue(QStringLiteral(":artistName"), artistName); auto queryResult = execQuery(d->mUpdateAlbumArtistQuery); if (!queryResult || !d->mUpdateAlbumArtistQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.lastError(); d->mUpdateAlbumArtistQuery.finish(); return; } d->mUpdateAlbumArtistQuery.finish(); d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":albumTitle"), title); d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":albumPath"), albumPath); d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":artistName"), artistName); queryResult = execQuery(d->mUpdateAlbumArtistInTracksQuery); if (!queryResult || !d->mUpdateAlbumArtistInTracksQuery.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.lastError(); d->mUpdateAlbumArtistInTracksQuery.finish(); return; } d->mUpdateAlbumArtistInTracksQuery.finish(); } void DatabaseInterface::updateTrackStatistics(const QUrl &fileName, const QDateTime &time) { d->mUpdateTrackStatistics.bindValue(QStringLiteral(":fileName"), fileName); d->mUpdateTrackStatistics.bindValue(QStringLiteral(":playDate"), time.toMSecsSinceEpoch()); auto queryResult = execQuery(d->mUpdateTrackStatistics); if (!queryResult || !d->mUpdateTrackStatistics.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStatistics" << d->mUpdateTrackStatistics.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStatistics" << d->mUpdateTrackStatistics.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStatistics" << d->mUpdateTrackStatistics.lastError(); d->mUpdateTrackStatistics.finish(); return; } d->mUpdateTrackStatistics.finish(); d->mUpdateTrackFirstPlayStatistics.bindValue(QStringLiteral(":fileName"), fileName); d->mUpdateTrackFirstPlayStatistics.bindValue(QStringLiteral(":playDate"), time.toMSecsSinceEpoch()); queryResult = execQuery(d->mUpdateTrackFirstPlayStatistics); if (!queryResult || !d->mUpdateTrackFirstPlayStatistics.isActive()) { Q_EMIT databaseError(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStatistics" << d->mUpdateTrackFirstPlayStatistics.lastQuery(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStatistics" << d->mUpdateTrackFirstPlayStatistics.boundValues(); qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStatistics" << d->mUpdateTrackFirstPlayStatistics.lastError(); d->mUpdateTrackFirstPlayStatistics.finish(); return; } d->mUpdateTrackFirstPlayStatistics.finish(); } #include "moc_databaseinterface.cpp" diff --git a/src/datatypes.h b/src/datatypes.h index cf490a9c..d7567b56 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -1,338 +1,337 @@ /* * Copyright 2016-2017 Matthieu Gallien * Copyright 2019 Alexander Stippich * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef DATATYPES_H #define DATATYPES_H #include "elisaLib_export.h" #include #include #include #include #include #include #include class ELISALIB_EXPORT DataTypes : public QObject { Q_OBJECT public: enum ColumnsRoles { TitleRole = Qt::UserRole + 1, SecondaryTextRole, ImageUrlRole, ShadowForImageRole, ChildModelRole, DurationRole, StringDurationRole, - MilliSecondsDurationRole, ArtistRole, AllArtistsRole, HighestTrackRating, AlbumRole, AlbumArtistRole, IsValidAlbumArtistRole, TrackNumberRole, DiscNumberRole, RatingRole, GenreRole, LyricistRole, ComposerRole, CommentRole, YearRole, ChannelsRole, BitRateRole, SampleRateRole, ResourceRole, IdRole, DatabaseIdRole, IsSingleDiscAlbumRole, ContainerDataRole, IsPartialDataRole, AlbumIdRole, HasEmbeddedCover, FileModificationTime, FirstPlayDate, LastPlayDate, PlayCounter, PlayFrequency, ElementTypeRole, LyricsRole, }; Q_ENUM(ColumnsRoles) private: using DataType = QMap; public: class TrackDataType : public DataType { public: using DataType::DataType; bool isValid() const { - return !isEmpty(); + return !isEmpty() && duration().isValid(); } qulonglong databaseId() const { return operator[](key_type::DatabaseIdRole).toULongLong(); } QString title() const { return operator[](key_type::TitleRole).toString(); } QString artist() const { return operator[](key_type::ArtistRole).toString(); } qulonglong albumId() const { return operator[](key_type::AlbumIdRole).toULongLong(); } bool hasAlbum() const { return find(key_type::AlbumRole) != end(); } QString album() const { return operator[](key_type::AlbumRole).toString(); } QString albumArtist() const { return operator[](key_type::AlbumArtistRole).toString(); } bool hasTrackNumber() const { return find(key_type::TrackNumberRole) != end(); } int trackNumber() const { return operator[](key_type::TrackNumberRole).toInt(); } bool hasDiscNumber() const { return find(key_type::DiscNumberRole) != end(); } int discNumber() const { return operator[](key_type::DiscNumberRole).toInt(); } QTime duration() const { return operator[](key_type::DurationRole).toTime(); } QUrl resourceURI() const { return operator[](key_type::ResourceRole).toUrl(); } QUrl albumCover() const { return operator[](key_type::ImageUrlRole).toUrl(); } bool isSingleDiscAlbum() const { return operator[](key_type::IsSingleDiscAlbumRole).toBool(); } int rating() const { return operator[](key_type::RatingRole).toInt(); } QString genre() const { return operator[](key_type::GenreRole).toString(); } QString composer() const { return operator[](key_type::ComposerRole).toString(); } QString lyricist() const { return operator[](key_type::LyricistRole).toString(); } QString lyrics() const { return operator[](key_type::LyricsRole).toString(); } QString comment() const { return operator[](key_type::CommentRole).toString(); } int year() const { return operator[](key_type::YearRole).toInt(); } int channels() const { return operator[](key_type::ChannelsRole).toInt(); } int bitRate() const { return operator[](key_type::BitRateRole).toInt(); } int sampleRate() const { return operator[](key_type::SampleRateRole).toInt(); } bool hasEmbeddedCover() const { return operator[](key_type::HasEmbeddedCover).toBool(); } QDateTime fileModificationTime() const { return operator[](key_type::FileModificationTime).toDateTime(); } }; using ListTrackDataType = QList; using ListRadioDataType = QList; class AlbumDataType : public DataType { public: using DataType::DataType; qulonglong databaseId() const { return operator[](key_type::DatabaseIdRole).toULongLong(); } QString title() const { return operator[](key_type::TitleRole).toString(); } QString artist() const { return operator[](key_type::ArtistRole).toString(); } bool isValidArtist() const { const auto &artistData = operator[](key_type::ArtistRole); return artistData.isValid() && !artistData.toString().isEmpty(); } QStringList genres() const { return operator[](key_type::GenreRole).toStringList(); } QUrl albumArtURI() const { return operator[](key_type::ImageUrlRole).toUrl(); } bool isSingleDiscAlbum() const { return operator[](key_type::IsSingleDiscAlbumRole).toBool(); } bool isValid() const { return !isEmpty(); } }; using ListAlbumDataType = QList; class ArtistDataType : public DataType { public: using DataType::DataType; qulonglong databaseId() const { return operator[](key_type::DatabaseIdRole).toULongLong(); } }; using ListArtistDataType = QList; class GenreDataType : public DataType { public: using DataType::DataType; qulonglong databaseId() const { return operator[](key_type::DatabaseIdRole).toULongLong(); } QString title() const { return operator[](key_type::TitleRole).toString(); } }; using ListGenreDataType = QList; }; Q_DECLARE_METATYPE(DataTypes::TrackDataType) Q_DECLARE_METATYPE(DataTypes::AlbumDataType) Q_DECLARE_METATYPE(DataTypes::ArtistDataType) Q_DECLARE_METATYPE(DataTypes::GenreDataType) Q_DECLARE_METATYPE(DataTypes::ListTrackDataType) Q_DECLARE_METATYPE(DataTypes::ListAlbumDataType) Q_DECLARE_METATYPE(DataTypes::ListArtistDataType) Q_DECLARE_METATYPE(DataTypes::ListGenreDataType) #endif // DATABASEINTERFACE_H diff --git a/src/filescanner.cpp b/src/filescanner.cpp index 7e80f835..01fe096c 100644 --- a/src/filescanner.cpp +++ b/src/filescanner.cpp @@ -1,290 +1,257 @@ /* * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "filescanner.h" #include "config-upnp-qt.h" #include "abstractfile/indexercommon.h" #if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND #include #include #include #include #include #include #if defined KF5Baloo_FOUND && KF5Baloo_FOUND #include #endif #endif #include #include #include #include +#include +#if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND + +static const QHash propertyTranslation = { + {KFileMetaData::Property::Artist, DataTypes::ColumnsRoles::ArtistRole}, + {KFileMetaData::Property::AlbumArtist, DataTypes::ColumnsRoles::AlbumArtistRole}, + {KFileMetaData::Property::Genre, DataTypes::ColumnsRoles::GenreRole}, + {KFileMetaData::Property::Composer, DataTypes::ColumnsRoles::ComposerRole}, + {KFileMetaData::Property::Lyricist, DataTypes::ColumnsRoles::LyricistRole}, + {KFileMetaData::Property::Title, DataTypes::ColumnsRoles::TitleRole}, + {KFileMetaData::Property::Album, DataTypes::ColumnsRoles::AlbumRole}, + {KFileMetaData::Property::TrackNumber, DataTypes::ColumnsRoles::TrackNumberRole}, + {KFileMetaData::Property::DiscNumber, DataTypes::ColumnsRoles::DiscNumberRole}, + {KFileMetaData::Property::ReleaseYear, DataTypes::ColumnsRoles::YearRole}, + {KFileMetaData::Property::Lyrics, DataTypes::ColumnsRoles::LyricsRole}, + {KFileMetaData::Property::Comment, DataTypes::ColumnsRoles::CommentRole}, + {KFileMetaData::Property::Rating, DataTypes::ColumnsRoles::RatingRole}, + {KFileMetaData::Property::Channels, DataTypes::ColumnsRoles::ChannelsRole}, + {KFileMetaData::Property::SampleRate, DataTypes::ColumnsRoles::SampleRateRole}, + {KFileMetaData::Property::BitRate, DataTypes::ColumnsRoles::BitRateRole}, + {KFileMetaData::Property::Duration, DataTypes::ColumnsRoles::DurationRole}, +}; + +#endif class FileScannerPrivate { public: - static const QStringList constSearchStrings; #if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND KFileMetaData::ExtractorCollection mAllExtractors; KFileMetaData::PropertyMap mAllProperties; KFileMetaData::EmbeddedImageData mImageScanner; #endif }; -const QStringList FileScannerPrivate::constSearchStrings = { +const QStringList constSearchStrings = { QStringLiteral("*[Cc]over*.jpg"), QStringLiteral("*[Cc]over*.png"), QStringLiteral("*[Ff]older*.jpg"), QStringLiteral("*[Ff]older*.png"), QStringLiteral("*[Ff]ront*.jpg"), QStringLiteral("*[Ff]ront*.png") }; FileScanner::FileScanner() : d(std::make_unique()) { } FileScanner::~FileScanner() = default; -MusicAudioTrack FileScanner::scanOneFile(const QUrl &scanFile, const QMimeDatabase &mimeDatabase) +DataTypes::TrackDataType FileScanner::scanOneFile(const QUrl &scanFile, const QMimeDatabase &mimeDatabase) { - MusicAudioTrack newTrack; + + DataTypes::TrackDataType newTrack; auto localFileName = scanFile.toLocalFile(); QFileInfo scanFileInfo(localFileName); - newTrack.setFileModificationTime(scanFileInfo.metadataChangeTime()); - newTrack.setResourceURI(scanFile); - newTrack.setRating(0); + newTrack[DataTypes::FileModificationTime] = scanFileInfo.metadataChangeTime(); + newTrack[DataTypes::ResourceRole] = scanFile; + newTrack[DataTypes::RatingRole] = 0; #if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND const auto &fileMimeType = mimeDatabase.mimeTypeForFile(localFileName); if (!fileMimeType.name().startsWith(QLatin1String("audio/"))) { return newTrack; } QString mimetype = fileMimeType.name(); QList exList = d->mAllExtractors.fetchExtractors(mimetype); if (exList.isEmpty()) { return newTrack; } KFileMetaData::Extractor* ex = exList.first(); KFileMetaData::SimpleExtractionResult result(localFileName, mimetype, KFileMetaData::ExtractionResult::ExtractMetaData); ex->extract(&result); d->mAllProperties = result.properties(); scanProperties(localFileName, newTrack); qCDebug(orgKdeElisaIndexer()) << "scanOneFile" << scanFile << "using KFileMetaData" << newTrack; #else + Q_UNUSED(scanFile) Q_UNUSED(mimeDatabase) - newTrack.setTitle(scanFileInfo.fileName()); - newTrack.setValid(true); - qCDebug(orgKdeElisaIndexer()) << "scanOneFile" << scanFile << "no metadata provider" << newTrack; #endif return newTrack; } -void FileScanner::scanProperties(const Baloo::File &match, MusicAudioTrack &trackData) +void FileScanner::scanProperties(const Baloo::File &match, DataTypes::TrackDataType &trackData) { #if defined KF5Baloo_FOUND && KF5Baloo_FOUND d->mAllProperties = match.properties(); scanProperties(match.path(), trackData); qCDebug(orgKdeElisaIndexer()) << "scanProperties" << match.path() << "using Baloo" << trackData; #else Q_UNUSED(match) Q_UNUSED(trackData) qCDebug(orgKdeElisaIndexer()) << "scanProperties" << "no metadata provider" << trackData; #endif } -void FileScanner::scanProperties(const QString &localFileName, MusicAudioTrack &trackData) +void FileScanner::scanProperties(const QString &localFileName, DataTypes::TrackDataType &trackData) { #if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND if (d->mAllProperties.isEmpty()) { return; } using entry = std::pair; auto rangeBegin = d->mAllProperties.constKeyValueBegin(); QVariant value; while (rangeBegin != d->mAllProperties.constKeyValueEnd()) { auto key = (*rangeBegin).first; auto rangeEnd = std::find_if(rangeBegin, d->mAllProperties.constKeyValueEnd(), [key](const entry& e) { return e.first != key; }); auto distance = std::distance(rangeBegin, rangeEnd); if (distance > 1) { QStringList list; list.reserve(static_cast(distance)); std::for_each(rangeBegin, rangeEnd, [&list](const entry& s) { list.append(s.second.toString()); }); value = QLocale().createSeparatedList(list); } else { value = (*rangeBegin).second; if (value.canConvert()) { value = QLocale().createSeparatedList(value.toStringList()); } } - switch (key) - { - case KFileMetaData::Property::Artist: - trackData.setArtist(value.toString()); - break; - case KFileMetaData::Property::AlbumArtist: - trackData.setAlbumArtist(value.toString()); - break; - case KFileMetaData::Property::Genre: - trackData.setGenre(value.toString()); - break; - case KFileMetaData::Property::Composer: - trackData.setComposer(value.toString()); - break; - case KFileMetaData::Property::Lyricist: - trackData.setLyricist(value.toString()); - break; - case KFileMetaData::Property::Title: - trackData.setTitle(value.toString()); - break; - case KFileMetaData::Property::Duration: - trackData.setDuration(QTime::fromMSecsSinceStartOfDay(int(1000 * value.toDouble()))); - break; - case KFileMetaData::Property::Album: - trackData.setAlbumName(value.toString()); - break; - case KFileMetaData::Property::TrackNumber: - trackData.setTrackNumber(value.toInt()); - break; - case KFileMetaData::Property::DiscNumber: - trackData.setDiscNumber(value.toInt()); - break; - case KFileMetaData::Property::ReleaseYear: - trackData.setYear(value.toInt()); - break; - case KFileMetaData::Property::Lyrics: - trackData.setLyrics(value.toString()); - break; - case KFileMetaData::Property::Channels: - trackData.setChannels(value.toInt()); - break; - case KFileMetaData::Property::BitRate: - trackData.setBitRate(value.toInt()); - break; - case KFileMetaData::Property::SampleRate: - trackData.setSampleRate(value.toInt()); - break; - case KFileMetaData::Property::Comment: - trackData.setComment(value.toString()); - break; - case KFileMetaData::Property::Rating: - trackData.setRating(value.toInt()); - break; - default: - break; + auto translatedKey = propertyTranslation.find(key); + if (translatedKey.value() == DataTypes::DurationRole) { + trackData.insert(translatedKey.value(), QTime::fromMSecsSinceStartOfDay(int(1000 * (*rangeBegin).second.toDouble()))); + } else if (translatedKey != propertyTranslation.end()) { + trackData.insert(translatedKey.value(), (*rangeBegin).second); } rangeBegin = rangeEnd; } #if !defined Q_OS_ANDROID && !defined Q_OS_WIN auto fileData = KFileMetaData::UserMetaData(localFileName); QString comment = fileData.userComment(); if (!comment.isEmpty()) { - trackData.setComment(comment); + trackData[DataTypes::CommentRole] = comment; } int rating = fileData.rating(); if (rating >= 0) { - trackData.setRating(rating); + trackData[DataTypes::RatingRole] = rating; } #endif - if (!trackData.duration().isValid()) { - return; - } - - trackData.setValid(true); #else Q_UNUSED(localFileName) Q_UNUSED(trackData) #endif } QUrl FileScanner::searchForCoverFile(const QString &localFileName) { QFileInfo trackFilePath(localFileName); QDir trackFileDir = trackFilePath.absoluteDir(); trackFileDir.setFilter(QDir::Files); - trackFileDir.setNameFilters(d->constSearchStrings); + trackFileDir.setNameFilters(constSearchStrings); QFileInfoList coverFiles = trackFileDir.entryInfoList(); if (coverFiles.isEmpty()) { QString dirNamePattern = QLatin1String("*") + trackFileDir.dirName() + QLatin1String("*"); QString dirNameNoSpaces = dirNamePattern.remove(QLatin1Char(' ')); QStringList filters = { dirNamePattern + QStringLiteral(".jpg"), dirNamePattern + QStringLiteral(".png"), dirNameNoSpaces + QStringLiteral(".jpg"), dirNameNoSpaces + QStringLiteral(".png") }; trackFileDir.setNameFilters(filters); coverFiles = trackFileDir.entryInfoList(); } if (coverFiles.isEmpty()) { return QUrl(); } return QUrl::fromLocalFile(coverFiles.first().absoluteFilePath()); } bool FileScanner::checkEmbeddedCoverImage(const QString &localFileName) { #if defined KF5FileMetaData_FOUND && KF5FileMetaData_FOUND auto imageData = d->mImageScanner.imageData(localFileName); if (imageData.contains(KFileMetaData::EmbeddedImageData::FrontCover)) { if (!imageData[KFileMetaData::EmbeddedImageData::FrontCover].isEmpty()) { return true; } } #else Q_UNUSED(localFileName) #endif return false; } diff --git a/src/filescanner.h b/src/filescanner.h index 766ba520..9e5170db 100644 --- a/src/filescanner.h +++ b/src/filescanner.h @@ -1,63 +1,62 @@ /* * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef FILESCANNER_H #define FILESCANNER_H #include "elisaLib_export.h" -#include "musicaudiotrack.h" +#include "datatypes.h" #include #include -#include #include namespace Baloo { class File; } class FileScannerPrivate; class ELISALIB_EXPORT FileScanner { public: FileScanner(); virtual ~FileScanner(); - MusicAudioTrack scanOneFile(const QUrl &scanFile, const QMimeDatabase &mimeDatabase); + DataTypes::TrackDataType scanOneFile(const QUrl &scanFile, const QMimeDatabase &mimeDatabase); - void scanProperties(const Baloo::File &match, MusicAudioTrack &trackData); + void scanProperties(const Baloo::File &match, DataTypes::TrackDataType &trackData); - void scanProperties(const QString &localFileName, MusicAudioTrack &trackData); + void scanProperties(const QString &localFileName, DataTypes::TrackDataType &trackData); QUrl searchForCoverFile(const QString &localFileName); bool checkEmbeddedCoverImage(const QString &localFileName); private: std::unique_ptr d; }; #endif // FILESCANNER_H diff --git a/src/mediaplaylist.h b/src/mediaplaylist.h index 61c34f6f..11b7b04e 100644 --- a/src/mediaplaylist.h +++ b/src/mediaplaylist.h @@ -1,411 +1,410 @@ /* * Copyright 2015-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef MEDIAPLAYLIST_H #define MEDIAPLAYLIST_H #include "elisaLib_export.h" #include "musicaudiotrack.h" #include "elisautils.h" #include "datatypes.h" #include #include #include #include #include class MediaPlayListPrivate; class MusicListenersManager; class MediaPlayListEntry; class QDebug; class ELISALIB_EXPORT MediaPlayList : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QVariantMap persistentState READ persistentState WRITE setPersistentState NOTIFY persistentStateChanged) Q_PROPERTY(MusicListenersManager* musicListenersManager READ musicListenersManager WRITE setMusicListenersManager NOTIFY musicListenersManagerChanged) Q_PROPERTY(int tracksCount READ tracksCount NOTIFY tracksCountChanged) Q_PROPERTY(QPersistentModelIndex previousTrack READ previousTrack NOTIFY previousTrackChanged) Q_PROPERTY(QPersistentModelIndex currentTrack READ currentTrack NOTIFY currentTrackChanged) Q_PROPERTY(QPersistentModelIndex nextTrack READ nextTrack NOTIFY nextTrackChanged) Q_PROPERTY(int currentTrackRow READ currentTrackRow NOTIFY currentTrackRowChanged) Q_PROPERTY(bool randomPlay READ randomPlay WRITE setRandomPlay NOTIFY randomPlayChanged) Q_PROPERTY(bool repeatPlay READ repeatPlay WRITE setRepeatPlay NOTIFY repeatPlayChanged) Q_PROPERTY(int remainingTracks READ remainingTracks NOTIFY remainingTracksChanged) public: enum ColumnsRoles { TitleRole = DataTypes::TitleRole, SecondaryTextRole, ImageUrlRole, ShadowForImageRole, ChildModelRole, DurationRole, StringDurationRole, - MilliSecondsDurationRole, ArtistRole, AllArtistsRole, HighestTrackRating, AlbumRole, AlbumArtistRole, IsValidAlbumArtistRole, TrackNumberRole, DiscNumberRole, RatingRole, GenreRole, LyricistRole, ComposerRole, CommentRole, YearRole, ChannelsRole, BitRateRole, SampleRateRole, ResourceRole, IdRole, DatabaseIdRole, IsSingleDiscAlbumRole, ContainerDataRole, IsPartialDataRole, AlbumIdRole, HasEmbeddedCover, FileModificationTime, FirstPlayDate, LastPlayDate, PlayCounter, PlayFrequency, ElementTypeRole, LyricsRole, IsValidRole, TrackDataRole, CountRole, IsPlayingRole, AlbumSectionRole, }; Q_ENUM(ColumnsRoles) enum PlayState { NotPlaying, IsPlaying, IsPaused, }; Q_ENUM(PlayState) using ListTrackDataType = DataTypes::ListTrackDataType; using TrackDataType = DataTypes::TrackDataType; explicit MediaPlayList(QObject *parent = nullptr); ~MediaPlayList() override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; QHash roleNames() const override; Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; Q_INVOKABLE bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override; Q_INVOKABLE void move(int from, int to, int n); Q_INVOKABLE void clearPlayList(); Q_INVOKABLE bool savePlaylist(const QUrl &fileName); QVariantMap persistentState() const; MusicListenersManager* musicListenersManager() const; int tracksCount() const; QPersistentModelIndex previousTrack() const; QPersistentModelIndex currentTrack() const; QPersistentModelIndex nextTrack() const; int currentTrackRow() const; bool randomPlay() const; bool repeatPlay() const; int remainingTracks() const; Q_SIGNALS: void displayUndoInline(); void hideUndoInline(); void newTrackByNameInList(const QVariant &title, const QVariant &artist, const QVariant &album, const QVariant &trackNumber, const QVariant &discNumber); void newEntryInList(qulonglong newDatabaseId, const QString &entryTitle, ElisaUtils::PlayListEntryType databaseIdType); void persistentStateChanged(); void musicListenersManagerChanged(); void tracksCountChanged(); void previousTrackChanged(const QPersistentModelIndex &previousTrack); void currentTrackChanged(const QPersistentModelIndex ¤tTrack); void nextTrackChanged(const QPersistentModelIndex &nextTrack); void clearPlayListPlayer(); void undoClearPlayListPlayer(); void currentTrackRowChanged(); void randomPlayChanged(); void repeatPlayChanged(); void playListFinished(); void playListLoaded(); void playListLoadFailed(); void ensurePlay(); void remainingTracksChanged(); public Q_SLOTS: void setPersistentState(const QVariantMap &persistentState); void removeSelection(QList selection); void tracksListAdded(qulonglong newDatabaseId, const QString &entryTitle, ElisaUtils::PlayListEntryType databaseIdType, const MediaPlayList::ListTrackDataType &tracks); void trackChanged(const MediaPlayList::TrackDataType &track); void trackRemoved(qulonglong trackId); void setMusicListenersManager(MusicListenersManager* musicListenersManager); void setRandomPlay(bool value); void setRepeatPlay(bool value); void skipNextTrack(); void skipPreviousTrack(); void switchTo(int row); void loadPlaylist(const QString &localFileName); void loadPlaylist(const QUrl &fileName); void enqueue(const ElisaUtils::EntryData &newEntry, ElisaUtils::PlayListEntryType databaseIdType); void enqueue(const ElisaUtils::EntryDataList &newEntries, ElisaUtils::PlayListEntryType databaseIdType); void enqueue(qulonglong newEntryDatabaseId, const QString &newEntryTitle, ElisaUtils::PlayListEntryType databaseIdType, ElisaUtils::PlayListEnqueueMode enqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); void enqueue(const ElisaUtils::EntryData &newEntry, ElisaUtils::PlayListEntryType databaseIdType, ElisaUtils::PlayListEnqueueMode enqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); void enqueue(const ElisaUtils::EntryDataList &newEntries, ElisaUtils::PlayListEntryType databaseIdType, ElisaUtils::PlayListEnqueueMode enqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); void replaceAndPlay(const ElisaUtils::EntryData &newEntry, ElisaUtils::PlayListEntryType databaseIdType); void enqueueRestoredEntry(const MediaPlayListEntry &newEntry); void trackInError(const QUrl &sourceInError, QMediaPlayer::Error playerError); void undoClearPlayList(); void updateRadioData(const QVariant &value, int role); private Q_SLOTS: void loadPlayListLoaded(); void loadPlayListLoadFailed(); private: void displayOrHideUndoInline(bool value); void clearPlayList(bool prepareUndo); void resetCurrentTrack(); void notifyCurrentTrackChanged(); void restorePlayListPosition(); void restoreRandomPlay(); void createRandomList(); void restoreRepeatPlay(); void notifyPreviousAndNextTracks(); void enqueueArtist(const QString &artistName); void enqueueFilesList(const ElisaUtils::EntryDataList &newEntries); void enqueueTracksListById(const ElisaUtils::EntryDataList &newEntries, ElisaUtils::PlayListEntryType type); void enqueueOneEntry(const ElisaUtils::EntryData &entryData, ElisaUtils::PlayListEntryType type); void enqueueMultipleEntries(const ElisaUtils::EntryDataList &entriesData, ElisaUtils::PlayListEntryType type); void enqueueCommon(); void copyD(); std::unique_ptr d; std::unique_ptr dOld; }; class MediaPlayListEntry { public: MediaPlayListEntry() = default; explicit MediaPlayListEntry(qulonglong id) : mId(id), mIsValid(true) { } MediaPlayListEntry(QString title, QString artist, QString album, int trackNumber, int discNumber, ElisaUtils::PlayListEntryType entryType = ElisaUtils::Unknown) : mTitle(std::move(title)), mAlbum(std::move(album)), mArtist(std::move(artist)), mTrackNumber(trackNumber), mDiscNumber(discNumber), mEntryType(entryType) { } MediaPlayListEntry(qulonglong id, QVariant title, QVariant artist, QVariant album, QVariant trackNumber, QVariant discNumber, ElisaUtils::PlayListEntryType entryType = ElisaUtils::Unknown) : mTitle(std::move(title)), mAlbum(std::move(album)), mArtist(std::move(artist)), mTrackNumber(trackNumber), mDiscNumber(discNumber), mId(id), mEntryType(entryType) { } explicit MediaPlayListEntry(const MusicAudioTrack &track) : mTitle(track.title()), mAlbum(track.albumName()), mTrackNumber(track.trackNumber()), mDiscNumber(track.discNumber()), mId(track.databaseId()), mIsValid(true) { } explicit MediaPlayListEntry(const MediaPlayList::TrackDataType &track) : mTitle(track[DataTypes::TitleRole]), mAlbum(track[DataTypes::AlbumRole]), mTrackNumber(track[DataTypes::TrackNumberRole]), mDiscNumber(track[DataTypes::DiscNumberRole]), mId(track[DataTypes::DatabaseIdRole].toULongLong()), mIsValid(true) { } explicit MediaPlayListEntry(QString artist) : mArtist(std::move(artist)), mEntryType(ElisaUtils::Artist) { } explicit MediaPlayListEntry(QUrl fileName) : mTrackUrl(std::move(fileName)) { } explicit MediaPlayListEntry(qulonglong id, const QString &entryTitle, ElisaUtils::PlayListEntryType type) : mTitle(entryTitle), mId(id), mIsValid(type == ElisaUtils::Track), mEntryType(type) { } QVariant mTitle; QVariant mAlbum; QVariant mArtist; QVariant mTrackUrl; QVariant mTrackNumber; QVariant mDiscNumber; qulonglong mId = 0; bool mIsValid = false; ElisaUtils::PlayListEntryType mEntryType = ElisaUtils::PlayListEntryType::Unknown; MediaPlayList::PlayState mIsPlaying = MediaPlayList::NotPlaying; }; QDebug operator<<(const QDebug &stream, const MediaPlayListEntry &data); #endif // MEDIAPLAYLIST_H diff --git a/src/modeldataloader.cpp b/src/modeldataloader.cpp index 93020cec..097f11bd 100644 --- a/src/modeldataloader.cpp +++ b/src/modeldataloader.cpp @@ -1,435 +1,399 @@ /* * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "modeldataloader.h" -#include "filescanner.h" - -#include - class ModelDataLoaderPrivate { public: DatabaseInterface *mDatabase = nullptr; - QMimeDatabase mMimeDatabase; - - FileScanner mFileScanner; - ElisaUtils::PlayListEntryType mModelType = ElisaUtils::Unknown; ModelDataLoader::FilterType mFilterType = ModelDataLoader::FilterType::UnknownFilter; QString mArtist; QString mAlbumTitle; QString mAlbumArtist; QString mGenre; qulonglong mDatabaseId = 0; }; ModelDataLoader::ModelDataLoader(QObject *parent) : QObject(parent), d(std::make_unique()) { } ModelDataLoader::~ModelDataLoader() = default; void ModelDataLoader::setDatabase(DatabaseInterface *database) { d->mDatabase = database; connect(database, &DatabaseInterface::genresAdded, this, &ModelDataLoader::genresAdded); connect(database, &DatabaseInterface::albumsAdded, this, &ModelDataLoader::databaseAlbumsAdded); connect(database, &DatabaseInterface::albumModified, this, &ModelDataLoader::albumModified); connect(database, &DatabaseInterface::albumRemoved, this, &ModelDataLoader::albumRemoved); connect(database, &DatabaseInterface::tracksAdded, this, &ModelDataLoader::databaseTracksAdded); connect(database, &DatabaseInterface::trackModified, this, &ModelDataLoader::trackModified); connect(database, &DatabaseInterface::trackRemoved, this, &ModelDataLoader::trackRemoved); connect(database, &DatabaseInterface::artistsAdded, this, &ModelDataLoader::databaseArtistsAdded); connect(database, &DatabaseInterface::artistRemoved, this, &ModelDataLoader::artistRemoved); connect(this, &ModelDataLoader::saveRadioModified, database, &DatabaseInterface::insertRadio); connect(this, &ModelDataLoader::removeRadio, database, &DatabaseInterface::removeRadio); connect(database, &DatabaseInterface::radioAdded, this, &ModelDataLoader::radioAdded); connect(database, &DatabaseInterface::radioModified, this, &ModelDataLoader::radioModified); connect(database, &DatabaseInterface::radioRemoved, this, &ModelDataLoader::radioRemoved); } void ModelDataLoader::loadData(ElisaUtils::PlayListEntryType dataType) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::NoFilter; switch (dataType) { case ElisaUtils::Album: Q_EMIT allAlbumsData(d->mDatabase->allAlbumsData()); break; case ElisaUtils::Artist: Q_EMIT allArtistsData(d->mDatabase->allArtistsData()); break; case ElisaUtils::Composer: break; case ElisaUtils::Genre: Q_EMIT allGenresData(d->mDatabase->allGenresData()); break; case ElisaUtils::Lyricist: break; case ElisaUtils::Track: Q_EMIT allTracksData(d->mDatabase->allTracksData()); break; case ElisaUtils::FileName: case ElisaUtils::Unknown: break; case ElisaUtils::Radio: Q_EMIT allRadiosData(d->mDatabase->allRadiosData()); break; } } void ModelDataLoader::loadDataByAlbumId(ElisaUtils::PlayListEntryType dataType, qulonglong databaseId) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterById; d->mDatabaseId = databaseId; switch (dataType) { case ElisaUtils::Album: break; case ElisaUtils::Artist: break; case ElisaUtils::Composer: break; case ElisaUtils::Genre: break; case ElisaUtils::Lyricist: break; case ElisaUtils::Track: Q_EMIT allTracksData(d->mDatabase->albumData(databaseId)); break; case ElisaUtils::FileName: case ElisaUtils::Unknown: case ElisaUtils::Radio: break; } } void ModelDataLoader::loadDataByGenre(ElisaUtils::PlayListEntryType dataType, const QString &genre) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterByGenre; d->mGenre = genre; switch (dataType) { case ElisaUtils::Artist: Q_EMIT allArtistsData(d->mDatabase->allArtistsDataByGenre(genre)); break; case ElisaUtils::Album: case ElisaUtils::Composer: case ElisaUtils::Track: case ElisaUtils::Genre: case ElisaUtils::Lyricist: case ElisaUtils::FileName: case ElisaUtils::Unknown: case ElisaUtils::Radio: break; } } void ModelDataLoader::loadDataByArtist(ElisaUtils::PlayListEntryType dataType, const QString &artist) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterByArtist; d->mArtist = artist; switch (dataType) { case ElisaUtils::Album: Q_EMIT allAlbumsData(d->mDatabase->allAlbumsDataByArtist(artist)); break; case ElisaUtils::Artist: case ElisaUtils::Composer: case ElisaUtils::Track: case ElisaUtils::Genre: case ElisaUtils::Lyricist: case ElisaUtils::FileName: case ElisaUtils::Unknown: case ElisaUtils::Radio: break; } } void ModelDataLoader::loadDataByGenreAndArtist(ElisaUtils::PlayListEntryType dataType, const QString &genre, const QString &artist) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterByGenreAndArtist; d->mArtist = artist; d->mGenre = genre; switch (dataType) { case ElisaUtils::Album: Q_EMIT allAlbumsData(d->mDatabase->allAlbumsDataByGenreAndArtist(genre, artist)); break; case ElisaUtils::Artist: case ElisaUtils::Composer: case ElisaUtils::Genre: case ElisaUtils::Lyricist: case ElisaUtils::Track: case ElisaUtils::FileName: case ElisaUtils::Unknown: case ElisaUtils::Radio: break; } } void ModelDataLoader::loadDataByDatabaseId(ElisaUtils::PlayListEntryType dataType, qulonglong databaseId) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterById; d->mDatabaseId = databaseId; switch (dataType) { case ElisaUtils::Track: Q_EMIT allTrackData(d->mDatabase->trackDataFromDatabaseId(databaseId)); break; case ElisaUtils::Radio: Q_EMIT allRadioData(d->mDatabase->radioDataFromDatabaseId(databaseId)); break; case ElisaUtils::Album: case ElisaUtils::Artist: case ElisaUtils::Composer: case ElisaUtils::Genre: case ElisaUtils::Lyricist: case ElisaUtils::FileName: case ElisaUtils::Unknown: break; } } -void ModelDataLoader::loadDataByFileName(ElisaUtils::PlayListEntryType dataType, const QUrl &fileName) -{ - if (!d->mDatabase) { - return; - } - - d->mFilterType = ModelDataLoader::FilterType::UnknownFilter; - - switch (dataType) - { - case ElisaUtils::FileName: - { - auto result = d->mFileScanner.scanOneFile(fileName, d->mMimeDatabase); - Q_EMIT allTrackData(result.toTrackData()); - break; - } - case ElisaUtils::Track: - case ElisaUtils::Album: - case ElisaUtils::Artist: - case ElisaUtils::Composer: - case ElisaUtils::Genre: - case ElisaUtils::Lyricist: - case ElisaUtils::Unknown: - case ElisaUtils::Radio: - break; - } -} - void ModelDataLoader::loadRecentlyPlayedData(ElisaUtils::PlayListEntryType dataType) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterByRecentlyPlayed; switch (dataType) { case ElisaUtils::Track: Q_EMIT allTracksData(d->mDatabase->recentlyPlayedTracksData(50)); break; case ElisaUtils::Album: case ElisaUtils::Artist: case ElisaUtils::Composer: case ElisaUtils::Genre: case ElisaUtils::Lyricist: case ElisaUtils::FileName: case ElisaUtils::Unknown: case ElisaUtils::Radio: break; } } void ModelDataLoader::loadFrequentlyPlayedData(ElisaUtils::PlayListEntryType dataType) { if (!d->mDatabase) { return; } d->mFilterType = ModelDataLoader::FilterType::FilterByFrequentlyPlayed; switch (dataType) { case ElisaUtils::Track: Q_EMIT allTracksData(d->mDatabase->frequentlyPlayedTracksData(50)); break; case ElisaUtils::Album: case ElisaUtils::Artist: case ElisaUtils::Composer: case ElisaUtils::Genre: case ElisaUtils::Lyricist: case ElisaUtils::FileName: case ElisaUtils::Unknown: case ElisaUtils::Radio: break; } } void ModelDataLoader::databaseTracksAdded(const ListTrackDataType &newData) { switch(d->mFilterType) { case ModelDataLoader::FilterType::NoFilter: Q_EMIT tracksAdded(newData); break; case ModelDataLoader::FilterType::FilterById: { auto filteredData = newData; auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), [&](const auto &oneTrack) { return oneTrack.albumId() != d->mDatabaseId; }); filteredData.erase(new_end, filteredData.end()); Q_EMIT tracksAdded(filteredData); break; } case ModelDataLoader::FilterType::FilterByGenre: case ModelDataLoader::FilterType::FilterByGenreAndArtist: case ModelDataLoader::FilterType::FilterByArtist: case ModelDataLoader::FilterType::FilterByRecentlyPlayed: case ModelDataLoader::FilterType::FilterByFrequentlyPlayed: case ModelDataLoader::FilterType::UnknownFilter: break; } } void ModelDataLoader::databaseArtistsAdded(const ListArtistDataType &newData) { switch(d->mFilterType) { case ModelDataLoader::FilterType::FilterByGenre: { auto filteredData = newData; auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), [&](const auto &oneArtist){return !d->mDatabase->internalArtistMatchGenre(oneArtist.databaseId(), d->mGenre);}); filteredData.erase(new_end, filteredData.end()); Q_EMIT artistsAdded(filteredData); break; } case ModelDataLoader::FilterType::NoFilter: Q_EMIT artistsAdded(newData); break; case ModelDataLoader::FilterType::FilterByGenreAndArtist: case ModelDataLoader::FilterType::FilterByArtist: case ModelDataLoader::FilterType::FilterById: case ModelDataLoader::FilterType::FilterByRecentlyPlayed: case ModelDataLoader::FilterType::FilterByFrequentlyPlayed: case ModelDataLoader::FilterType::UnknownFilter: break; } } void ModelDataLoader::databaseAlbumsAdded(const ListAlbumDataType &newData) { switch(d->mFilterType) { case ModelDataLoader::FilterType::FilterByArtist: { auto filteredData = newData; auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), [&](const auto &oneAlbum){return oneAlbum.artist() != d->mArtist;}); filteredData.erase(new_end, filteredData.end()); Q_EMIT albumsAdded(filteredData); break; } case ModelDataLoader::FilterType::NoFilter: Q_EMIT albumsAdded(newData); break; case ModelDataLoader::FilterType::FilterByGenreAndArtist: { auto filteredData = newData; auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), [&](const auto &oneAlbum){ const auto &allGenres = oneAlbum.genres(); return oneAlbum.artist() != d->mArtist || !allGenres.contains(d->mGenre); }); filteredData.erase(new_end, filteredData.end()); Q_EMIT albumsAdded(filteredData); break; } case ModelDataLoader::FilterType::FilterByGenre: case ModelDataLoader::FilterType::FilterById: case ModelDataLoader::FilterType::FilterByRecentlyPlayed: case ModelDataLoader::FilterType::FilterByFrequentlyPlayed: case ModelDataLoader::FilterType::UnknownFilter: break; } } #include "moc_modeldataloader.cpp" diff --git a/src/modeldataloader.h b/src/modeldataloader.h index 2483a115..3e22fcc4 100644 --- a/src/modeldataloader.h +++ b/src/modeldataloader.h @@ -1,140 +1,137 @@ /* * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef MODELDATALOADER_H #define MODELDATALOADER_H #include "elisaLib_export.h" #include "elisautils.h" #include "databaseinterface.h" #include "datatypes.h" #include "models/datamodel.h" #include #include class ModelDataLoaderPrivate; class ELISALIB_EXPORT ModelDataLoader : public QObject { Q_OBJECT public: using ListAlbumDataType = DataTypes::ListAlbumDataType; using ListArtistDataType = DataTypes::ListArtistDataType; using ListGenreDataType = DataTypes::ListGenreDataType; using ListTrackDataType = DataTypes::ListTrackDataType; using ListRadioDataType = DataTypes::ListRadioDataType; using TrackDataType = DataTypes::TrackDataType; using AlbumDataType = DataTypes::AlbumDataType; using FilterType = ElisaUtils::FilterType; explicit ModelDataLoader(QObject *parent = nullptr); ~ModelDataLoader() override; void setDatabase(DatabaseInterface *database); Q_SIGNALS: void allAlbumsData(const ModelDataLoader::ListAlbumDataType &allData); void allArtistsData(const ModelDataLoader::ListArtistDataType &allData); void allGenresData(const ModelDataLoader::ListGenreDataType &allData); void allTracksData(const ModelDataLoader::ListTrackDataType &allData); void allRadiosData(const ModelDataLoader::ListRadioDataType &radiosData); void radioAdded(const ModelDataLoader::TrackDataType &radiosData); void radioModified(const ModelDataLoader::TrackDataType &radiosData); void allTrackData(const ModelDataLoader::TrackDataType &allData); void allRadioData(const ModelDataLoader::TrackDataType &allData); void tracksAdded(const ModelDataLoader::ListTrackDataType &newData); void trackModified(const ModelDataLoader::TrackDataType &modifiedTrack); void trackRemoved(qulonglong removedTrackId); void genresAdded(const ModelDataLoader::ListGenreDataType &newData); void artistsAdded(const ModelDataLoader::ListArtistDataType &newData); void artistRemoved(qulonglong removedDatabaseId); void albumsAdded(const ModelDataLoader::ListAlbumDataType &newData); void albumRemoved(qulonglong removedDatabaseId); void albumModified(const ModelDataLoader::AlbumDataType &modifiedAlbum); void saveRadioModified(const ModelDataLoader::TrackDataType &trackDataType); void removeRadio(qulonglong radioId); void radioRemoved(qulonglong radioId); public Q_SLOTS: void loadData(ElisaUtils::PlayListEntryType dataType); void loadDataByAlbumId(ElisaUtils::PlayListEntryType dataType, qulonglong databaseId); void loadDataByGenre(ElisaUtils::PlayListEntryType dataType, const QString &genre); void loadDataByArtist(ElisaUtils::PlayListEntryType dataType, const QString &artist); void loadDataByGenreAndArtist(ElisaUtils::PlayListEntryType dataType, const QString &genre, const QString &artist); void loadDataByDatabaseId(ElisaUtils::PlayListEntryType dataType, qulonglong databaseId); - void loadDataByFileName(ElisaUtils::PlayListEntryType dataType, - const QUrl &fileName); - void loadRecentlyPlayedData(ElisaUtils::PlayListEntryType dataType); void loadFrequentlyPlayedData(ElisaUtils::PlayListEntryType dataType); private Q_SLOTS: void databaseTracksAdded(const ListTrackDataType &newData); void databaseArtistsAdded(const ListArtistDataType &newData); void databaseAlbumsAdded(const ListAlbumDataType &newData); private: std::unique_ptr d; }; #endif // MODELDATALOADER_H diff --git a/src/models/trackmetadatamodel.cpp b/src/models/trackmetadatamodel.cpp index 07b3b90b..803c752a 100644 --- a/src/models/trackmetadatamodel.cpp +++ b/src/models/trackmetadatamodel.cpp @@ -1,561 +1,557 @@ /* * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "trackmetadatamodel.h" #include "musiclistenersmanager.h" #include #include TrackMetadataModel::TrackMetadataModel(QObject *parent) : QAbstractListModel(parent) { connect(&mLyricsValueWatcher, &QFutureWatcher::finished, this, &TrackMetadataModel::lyricsValueIsReady); } TrackMetadataModel::~TrackMetadataModel() { if (mLyricsValueWatcher.isRunning() && !mLyricsValueWatcher.isFinished()) { mLyricsValueWatcher.waitForFinished(); } } int TrackMetadataModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return mTrackData.count(); } QVariant TrackMetadataModel::data(const QModelIndex &index, int role) const { auto result = QVariant{}; const auto currentKey = mTrackKeys[index.row()]; switch (role) { case Qt::DisplayRole: switch (currentKey) { case DataTypes::TrackNumberRole: { auto trackNumber = mTrackData.trackNumber(); if (trackNumber > 0) { result = trackNumber; } break; } case DataTypes::DiscNumberRole: { auto discNumber = mTrackData.discNumber(); if (discNumber > 0) { result = discNumber; } break; } case DataTypes::ChannelsRole: { auto channels = mTrackData.channels(); if (channels > 0) { result = channels; } break; } case DataTypes::BitRateRole: { auto bitRate = mTrackData.bitRate(); if (bitRate > 0) { result = bitRate; } break; } case DataTypes::SampleRateRole: { auto sampleRate = mTrackData.sampleRate(); if (sampleRate > 0) { result = sampleRate; } break; } default: result = mTrackData[currentKey]; break; } 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::SecondaryTextRole: case DataTypes::ImageUrlRole: case DataTypes::ShadowForImageRole: case DataTypes::ChildModelRole: case DataTypes::StringDurationRole: - case DataTypes::MilliSecondsDurationRole: case DataTypes::IsValidAlbumArtistRole: case DataTypes::AllArtistsRole: case DataTypes::HighestTrackRating: case DataTypes::IdRole: 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: break; } break; case ItemTypeRole: switch (currentKey) { case DataTypes::TitleRole: result = TextEntry; break; case DataTypes::ResourceRole: result = TextEntry; break; case DataTypes::ArtistRole: result = TextEntry; break; case DataTypes::AlbumRole: result = TextEntry; break; case DataTypes::AlbumArtistRole: result = TextEntry; break; case DataTypes::TrackNumberRole: result = IntegerEntry; break; case DataTypes::DiscNumberRole: result = IntegerEntry; break; case DataTypes::RatingRole: result = RatingEntry; break; case DataTypes::GenreRole: result = TextEntry; break; case DataTypes::LyricistRole: result = TextEntry; break; case DataTypes::ComposerRole: result = TextEntry; break; case DataTypes::CommentRole: result = TextEntry; break; case DataTypes::YearRole: result = IntegerEntry; break; case DataTypes::LastPlayDate: result = DateEntry; break; case DataTypes::PlayCounter: result = IntegerEntry; break; case DataTypes::LyricsRole: result = LongTextEntry; break; case DataTypes::DurationRole: case DataTypes::SampleRateRole: case DataTypes::BitRateRole: case DataTypes::ChannelsRole: case DataTypes::SecondaryTextRole: case DataTypes::ImageUrlRole: case DataTypes::ShadowForImageRole: case DataTypes::ChildModelRole: case DataTypes::StringDurationRole: - case DataTypes::MilliSecondsDurationRole: case DataTypes::IsValidAlbumArtistRole: case DataTypes::AllArtistsRole: case DataTypes::HighestTrackRating: case DataTypes::IdRole: 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: break; } break; } return result; } bool TrackMetadataModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (data(index, role) != value) { mTrackData[mTrackKeys[index.row()]] = value; emit dataChanged(index, index, QVector() << role); return true; } return false; } QHash TrackMetadataModel::roleNames() const { auto names = QAbstractListModel::roleNames(); names[ItemNameRole] = "name"; names[ItemTypeRole] = "type"; return names; } QString TrackMetadataModel::fileUrl() const { return mFileUrl; } QUrl TrackMetadataModel::coverUrl() const { if (mCoverImage.isEmpty()) { return QUrl(QStringLiteral("image://icon/media-optical-audio")); } else { return mCoverImage; } } MusicListenersManager *TrackMetadataModel::manager() const { return mManager; } QString TrackMetadataModel::lyrics() const { return mFullData[TrackDataType::key_type::LyricsRole].toString(); } qulonglong TrackMetadataModel::databaseId() const { return mDatabaseId; } void TrackMetadataModel::trackData(const TrackMetadataModel::TrackDataType &trackData) { if (!mFullData.isEmpty() && trackData.databaseId() != mFullData.databaseId()) { return; } const QList fieldsForTrack({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::LastPlayDate, DataTypes::PlayCounter}); fillDataFromTrackData(trackData, fieldsForTrack); } void TrackMetadataModel::fillDataFromTrackData(const TrackMetadataModel::TrackDataType &trackData, const QList &fieldsForTrack) { beginResetModel(); mFullData = trackData; mTrackData.clear(); mTrackKeys.clear(); for (DataTypes::ColumnsRoles role : fieldsForTrack) { if (trackData.constFind(role) != trackData.constEnd()) { if (role == DataTypes::RatingRole) { if (trackData[role].toInt() == 0) { continue; } } mTrackKeys.push_back(role); mTrackData[role] = trackData[role]; } } filterDataFromTrackData(); endResetModel(); fetchLyrics(); mDatabaseId = trackData[DataTypes::DatabaseIdRole].toULongLong(); Q_EMIT databaseIdChanged(); mCoverImage = trackData[DataTypes::ImageUrlRole].toUrl(); Q_EMIT coverUrlChanged(); auto rawFileUrl = trackData[DataTypes::ResourceRole].toUrl(); if (rawFileUrl.isLocalFile()) { mFileUrl = rawFileUrl.toLocalFile(); } else { mFileUrl = rawFileUrl.toString(); } Q_EMIT fileUrlChanged(); } void TrackMetadataModel::filterDataFromTrackData() { } void TrackMetadataModel::removeMetaData(DataTypes::ColumnsRoles metaData) { auto itMetaData = std::find(mTrackKeys.begin(), mTrackKeys.end(), metaData); if (itMetaData == mTrackKeys.end()) { return; } mTrackKeys.erase(itMetaData); mTrackData.remove(metaData); } TrackMetadataModel::TrackDataType::mapped_type TrackMetadataModel::dataFromType(TrackDataType::key_type metaData) const { return mFullData[metaData]; } void TrackMetadataModel::fillLyricsDataFromTrack() { beginInsertRows({}, mTrackData.size(), mTrackData.size()); mTrackKeys.push_back(DataTypes::LyricsRole); mTrackData[DataTypes::LyricsRole] = mLyricsValueWatcher.result(); endInsertRows(); } void TrackMetadataModel::lyricsValueIsReady() { if (!mLyricsValueWatcher.result().isEmpty()) { fillLyricsDataFromTrack(); mFullData[DataTypes::LyricsRole] = mLyricsValueWatcher.result(); Q_EMIT lyricsChanged(); } } void TrackMetadataModel::initializeById(ElisaUtils::PlayListEntryType type, qulonglong databaseId) { mFullData.clear(); mTrackData.clear(); mCoverImage.clear(); mFileUrl.clear(); Q_EMIT lyricsChanged(); Q_EMIT needDataByDatabaseId(type, databaseId); } void TrackMetadataModel::initialize(MusicListenersManager *newManager, DatabaseInterface *trackDatabase) { mManager = newManager; Q_EMIT managerChanged(); if (mManager) { mDataLoader.setDatabase(mManager->viewDatabase()); } else if (trackDatabase) { mDataLoader.setDatabase(trackDatabase); } if (mManager) { mManager->connectModel(&mDataLoader); } connect(this, &TrackMetadataModel::needDataByDatabaseId, &mDataLoader, &ModelDataLoader::loadDataByDatabaseId); - connect(this, &TrackMetadataModel::needDataByFileName, - &mDataLoader, &ModelDataLoader::loadDataByFileName); connect(this, &TrackMetadataModel::saveRadioData, &mDataLoader, &ModelDataLoader::saveRadioModified); connect(this, &TrackMetadataModel::deleteRadioData, &mDataLoader, &ModelDataLoader::removeRadio); connect(&mDataLoader, &ModelDataLoader::trackModified, this, &TrackMetadataModel::trackData); connect(&mDataLoader, &ModelDataLoader::allTrackData, this, &TrackMetadataModel::trackData); connect(&mDataLoader, &ModelDataLoader::allRadioData, this, &TrackMetadataModel::radioData); connect(&mDataLoader, &ModelDataLoader::radioAdded, this, &TrackMetadataModel::radioData); connect(&mDataLoader, &ModelDataLoader::radioModified, this, &TrackMetadataModel::radioData); } void TrackMetadataModel::fetchLyrics() { auto lyricicsValue = QtConcurrent::run(QThreadPool::globalInstance(), [=]() { auto trackData = mFileScanner.scanOneFile(mFullData[DataTypes::ResourceRole].toUrl(), mMimeDatabase); if (!trackData.lyrics().isEmpty()) { return trackData.lyrics(); } return QString{}; }); mLyricsValueWatcher.setFuture(lyricicsValue); } void TrackMetadataModel::initializeForNewRadio() { mFullData.clear(); mTrackData.clear(); fillDataForNewRadio(); } void TrackMetadataModel::fillDataForNewRadio() { beginResetModel(); mTrackData.clear(); mTrackKeys.clear(); for (auto role : { DataTypes::TitleRole, DataTypes::ResourceRole, DataTypes::CommentRole, DataTypes::DatabaseIdRole }) { mTrackKeys.push_back(role); if (role == DataTypes::DatabaseIdRole) { mTrackData[role] = -1; } else { mTrackData[role] = QString(); } } filterDataFromTrackData(); endResetModel(); } void TrackMetadataModel::initializeByTrackFileName(const QString &fileName) { mFullData.clear(); mTrackData.clear(); mCoverImage.clear(); mFileUrl.clear(); Q_EMIT lyricsChanged(); - Q_EMIT needDataByFileName(ElisaUtils::FileName, QUrl::fromLocalFile(fileName)); + Q_EMIT needDataByFileName(QUrl::fromLocalFile(fileName)); } void TrackMetadataModel::setManager(MusicListenersManager *newManager) { initialize(newManager, nullptr); } void TrackMetadataModel::setDatabase(DatabaseInterface *trackDatabase) { initialize(nullptr, trackDatabase); } void TrackMetadataModel::saveData() { Q_EMIT saveRadioData(mTrackData); } void TrackMetadataModel::deleteRadio() { if (mTrackData[DataTypes::DatabaseIdRole]>=0) { Q_EMIT deleteRadioData(mTrackData[DataTypes::DatabaseIdRole].toULongLong()); } } void TrackMetadataModel::radioData(const TrackDataType &radiosData) { if (!mFullData.isEmpty() && mFullData[DataTypes::DatabaseIdRole].toInt() != -1 && mFullData.databaseId() != radiosData.databaseId()) { return; } const QList fieldsForTrack({DataTypes::TitleRole, DataTypes::ResourceRole, DataTypes::CommentRole, DataTypes::DatabaseIdRole}); fillDataFromTrackData(radiosData, fieldsForTrack); } #include "moc_trackmetadatamodel.cpp" diff --git a/src/models/trackmetadatamodel.h b/src/models/trackmetadatamodel.h index e620c893..98bed774 100644 --- a/src/models/trackmetadatamodel.h +++ b/src/models/trackmetadatamodel.h @@ -1,193 +1,193 @@ /* * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef TRACKMETADATAMODEL_H #define TRACKMETADATAMODEL_H #include "elisaLib_export.h" #include "elisautils.h" #include "datatypes.h" #include "modeldataloader.h" #include "filescanner.h" #include #include #include #include class MusicListenersManager; class ELISALIB_EXPORT TrackMetadataModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QUrl coverUrl READ coverUrl NOTIFY coverUrlChanged) Q_PROPERTY(QString fileUrl READ fileUrl NOTIFY fileUrlChanged) Q_PROPERTY(qulonglong databaseId READ databaseId NOTIFY databaseIdChanged) Q_PROPERTY(MusicListenersManager* manager READ manager WRITE setManager NOTIFY managerChanged) Q_PROPERTY(QString lyrics READ lyrics NOTIFY lyricsChanged) public: enum ColumnRoles { ItemNameRole = Qt::UserRole + 1, ItemTypeRole, }; enum ItemType { TextEntry, IntegerEntry, RatingEntry, DateEntry, LongTextEntry, }; Q_ENUM(ItemType) using TrackDataType = DataTypes::TrackDataType; explicit TrackMetadataModel(QObject *parent = nullptr); ~TrackMetadataModel() override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; QHash roleNames() const override; QUrl coverUrl() const; QString fileUrl() const; MusicListenersManager* manager() const; QString lyrics() const; qulonglong databaseId() const; Q_SIGNALS: void needDataByDatabaseId(ElisaUtils::PlayListEntryType dataType, qulonglong databaseId); - void needDataByFileName(ElisaUtils::PlayListEntryType dataType, const QUrl &fileName); + void needDataByFileName(const QUrl &fileName); void coverUrlChanged(); void fileUrlChanged(); void managerChanged(); void lyricsChanged(); void saveRadioData(const DataTypes::TrackDataType &trackDataType); void deleteRadioData(qulonglong radioId); void databaseIdChanged(); public Q_SLOTS: void trackData(const TrackMetadataModel::TrackDataType &trackData); void initializeById(ElisaUtils::PlayListEntryType type, qulonglong databaseId); void initializeByTrackFileName(const QString &fileName); void initializeForNewRadio(); void setManager(MusicListenersManager *newManager); void setDatabase(DatabaseInterface *trackDatabase); void saveData(); void deleteRadio(); void radioData(const TrackMetadataModel::TrackDataType &radiosData); protected: void fillDataFromTrackData(const TrackMetadataModel::TrackDataType &trackData, const QList &fieldsForTrack); void fillDataForNewRadio(); virtual void filterDataFromTrackData(); void removeMetaData(DataTypes::ColumnsRoles metaData); TrackDataType::mapped_type dataFromType(TrackDataType::key_type metaData) const; virtual void fillLyricsDataFromTrack(); private Q_SLOTS: void lyricsValueIsReady(); private: void initialize(MusicListenersManager *newManager, DatabaseInterface *trackDatabase); void fetchLyrics(); TrackDataType mFullData; TrackDataType mTrackData; QUrl mCoverImage; QString mFileUrl; qulonglong mDatabaseId = 0; QList mTrackKeys; ModelDataLoader mDataLoader; MusicListenersManager *mManager = nullptr; FileScanner mFileScanner; QMimeDatabase mMimeDatabase; QFutureWatcher mLyricsValueWatcher; }; #endif // TRACKMETADATAMODEL_H diff --git a/src/musicaudiotrack.cpp b/src/musicaudiotrack.cpp index fa7ed0a5..9e7f8a51 100644 --- a/src/musicaudiotrack.cpp +++ b/src/musicaudiotrack.cpp @@ -1,605 +1,606 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "musicaudiotrack.h" #include #include #include #include class MusicAudioTrackPrivate : public QSharedData { public: MusicAudioTrackPrivate() = default; MusicAudioTrackPrivate(bool aValid, QString aId, QString aParentId, QString aTitle, QString aArtist, QString aAlbumName, QString aAlbumArtist, int aTrackNumber, int aDiscNumber, QTime aDuration, QUrl aResourceURI, QDateTime fileModificationTime, QUrl aAlbumCover, int rating, bool aIsSingleDiscAlbum, QString aGenre, QString aComposer, QString aLyricist, bool aHasEmbeddedCover) : QSharedData(), mId(std::move(aId)), mParentId(std::move(aParentId)), mTitle(std::move(aTitle)), mArtist(std::move(aArtist)), mAlbumName(std::move(aAlbumName)), mAlbumArtist(std::move(aAlbumArtist)), mGenre(std::move(aGenre)), mComposer(std::move(aComposer)), mLyricist(std::move(aLyricist)), mLyrics(), mResourceURI(std::move(aResourceURI)), mAlbumCover(std::move(aAlbumCover)), mFileModificationTime(std::move(fileModificationTime)), mDuration(aDuration), mTrackNumber(aTrackNumber), mDiscNumber(aDiscNumber), mRating(rating), mIsValid(aValid), mIsSingleDiscAlbum(aIsSingleDiscAlbum), mHasBooleanCover(aHasEmbeddedCover), mTrackNumberIsValid(true), mDiscNumberIsValid(true) { } QString mId; QString mParentId; QString mTitle; QString mArtist; QString mAlbumName; QString mAlbumArtist; QString mGenre; QString mComposer; QString mLyricist; QString mLyrics; QString mComment; QUrl mResourceURI; QUrl mAlbumCover; qulonglong mDatabaseId = 0; qulonglong mAlbumId = 0; QDateTime mFileModificationTime; QTime mDuration; int mTrackNumber = -1; int mDiscNumber = -1; int mChannels = -1; int mBitRate = -1; int mSampleRate = -1; int mYear = 0; int mRating = 0; bool mIsValid = false; bool mIsSingleDiscAlbum = true; bool mHasBooleanCover = false; bool mTrackNumberIsValid = false; bool mDiscNumberIsValid = false; bool mChannelsIsValid = false; bool mBitRateIsValid = false; bool mSampleRateIsValid = false; }; MusicAudioTrack::MusicAudioTrack() : d(new MusicAudioTrackPrivate()) { } MusicAudioTrack::MusicAudioTrack(bool aValid, QString aId, QString aParentId, QString aTitle, QString aArtist, QString aAlbumName, QString aAlbumArtist, int aTrackNumber, int aDiscNumber, QTime aDuration, QUrl aResourceURI, const QDateTime &fileModificationTime, QUrl aAlbumCover, int rating, bool aIsSingleDiscAlbum, QString aGenre, QString aComposer, QString aLyricist, bool aHasEmbeddedCover) : d(new MusicAudioTrackPrivate(aValid, std::move(aId), std::move(aParentId), std::move(aTitle), std::move(aArtist), std::move(aAlbumName), std::move(aAlbumArtist), aTrackNumber, aDiscNumber, aDuration, std::move(aResourceURI), fileModificationTime, std::move(aAlbumCover), rating, aIsSingleDiscAlbum, std::move(aGenre), std::move(aComposer), std::move(aLyricist), aHasEmbeddedCover)) { } MusicAudioTrack::MusicAudioTrack(MusicAudioTrack &&other) noexcept = default; MusicAudioTrack::MusicAudioTrack(const MusicAudioTrack &other) = default; MusicAudioTrack::~MusicAudioTrack() = default; MusicAudioTrack& MusicAudioTrack::operator=(MusicAudioTrack &&other) noexcept = default; MusicAudioTrack& MusicAudioTrack::operator=(const MusicAudioTrack &other) = default; bool MusicAudioTrack::operator <(const MusicAudioTrack &other) const { return d->mDiscNumber < other.d->mDiscNumber || (d->mDiscNumber == other.d->mDiscNumber && d->mTrackNumber < other.d->mTrackNumber); } bool MusicAudioTrack::operator ==(const MusicAudioTrack &other) const { return d->mTitle == other.d->mTitle && d->mArtist == other.d->mArtist && d->mAlbumName == other.d->mAlbumName && d->mAlbumArtist == other.d->mAlbumArtist && d->mTrackNumber == other.d->mTrackNumber && d->mDiscNumber == other.d->mDiscNumber && d->mDuration == other.d->mDuration && d->mResourceURI == other.d->mResourceURI && d->mFileModificationTime == other.d->mFileModificationTime && d->mAlbumCover == other.d->mAlbumCover && d->mRating == other.d->mRating && d->mGenre == other.d->mGenre && d->mComposer == other.d->mComposer && d->mLyricist == other.d->mLyricist && d->mLyrics == other.d->mLyrics && d->mComment == other.d->mComment && d->mYear == other.d->mYear && d->mChannels == other.d->mChannels && d->mBitRate == other.d->mBitRate && d->mSampleRate == other.d->mSampleRate; } bool MusicAudioTrack::operator !=(const MusicAudioTrack &other) const { return d->mTitle != other.d->mTitle || d->mArtist != other.d->mArtist || d->mAlbumName != other.d->mAlbumName || d->mAlbumArtist != other.d->mAlbumArtist || d->mTrackNumber != other.d->mTrackNumber || d->mDiscNumber != other.d->mDiscNumber || d->mDuration != other.d->mDuration || d->mResourceURI != other.d->mResourceURI || d->mFileModificationTime != other.d->mFileModificationTime || d->mAlbumCover != other.d->mAlbumCover || d->mRating != other.d->mRating || d->mGenre != other.d->mGenre || d->mComposer != other.d->mComposer || d->mLyricist != other.d->mLyricist || d->mLyrics != other.d->mLyrics || d->mComment != other.d->mComment || d->mYear != other.d->mYear || d->mChannels != other.d->mChannels || d->mBitRate != other.d->mBitRate || d->mSampleRate != other.d->mSampleRate; } MusicAudioTrack MusicAudioTrack::trackFromData(const DataTypes::TrackDataType &data) { auto result = MusicAudioTrack{}; result.setDatabaseId(data.databaseId()); result.setTitle(data.title()); result.setArtist(data.artist()); result.setAlbumName(data.album()); result.setAlbumArtist(data.albumArtist()); result.setGenre(data.genre()); result.setComposer(data.composer()); result.setLyricist(data.lyricist()); result.setLyrics(data.lyrics()); result.setComment(data.comment()); result.setAlbumCover(data.albumCover()); result.setTrackNumber(data.trackNumber()); result.setDiscNumber(data.discNumber()); result.setYear(data.year()); result.setChannels(data.channels()); result.setBitRate(data.bitRate()); result.setSampleRate(data.sampleRate()); result.setResourceURI(data.resourceURI()); result.setRating(data.rating()); - result.setDuration(data[MusicAudioTrack::TrackDataType::key_type::DurationRole].toTime()); + result.setDuration(data.duration()); result.setFileModificationTime(data.fileModificationTime()); + result.setValid(data.isValid()); return result; } void MusicAudioTrack::setValid(bool value) { d->mIsValid = value; } bool MusicAudioTrack::isValid() const { return d->mIsValid; } void MusicAudioTrack::setDatabaseId(qulonglong value) { d->mDatabaseId = value; } qulonglong MusicAudioTrack::databaseId() const { return d->mDatabaseId; } void MusicAudioTrack::setAlbumId(qulonglong value) { d->mAlbumId = value; } qulonglong MusicAudioTrack::albumId() const { return d->mAlbumId; } void MusicAudioTrack::setId(const QString &value) { d->mId = value; } QString MusicAudioTrack::id() const { return d->mId; } void MusicAudioTrack::setParentId(const QString &value) { d->mParentId = value; } QString MusicAudioTrack::parentId() const { return d->mParentId; } void MusicAudioTrack::setTitle(const QString &value) { d->mTitle = value; } QString MusicAudioTrack::title() const { return d->mTitle; } void MusicAudioTrack::setArtist(const QString &value) { d->mArtist = value; } QString MusicAudioTrack::artist() const { return d->mArtist; } void MusicAudioTrack::setAlbumName(const QString &value) { d->mAlbumName = value; } QString MusicAudioTrack::albumName() const { return d->mAlbumName; } void MusicAudioTrack::setAlbumArtist(const QString &value) { d->mAlbumArtist = value; } QString MusicAudioTrack::albumArtist() const { return (d->mAlbumArtist.isEmpty() ? d->mArtist : d->mAlbumArtist); } bool MusicAudioTrack::isValidAlbumArtist() const { return !d->mAlbumArtist.isEmpty(); } void MusicAudioTrack::setAlbumCover(const QUrl &value) { d->mAlbumCover = value; } QUrl MusicAudioTrack::albumCover() const { if (d->mAlbumCover.isValid() || !hasEmbeddedCover()) { return d->mAlbumCover; } else { return QUrl(QStringLiteral("image://cover/") + d->mResourceURI.toLocalFile()); } } void MusicAudioTrack::setGenre(const QString &value) { d->mGenre = value; } QString MusicAudioTrack::genre() const { return d->mGenre; } void MusicAudioTrack::setComposer(const QString &value) { d->mComposer = value; } QString MusicAudioTrack::composer() const { return d->mComposer; } void MusicAudioTrack::setLyricist(const QString &value) { d->mLyricist = value; } QString MusicAudioTrack::lyricist() const { return d->mLyricist; } void MusicAudioTrack::setLyrics(const QString &value) { d->mLyrics = value; } QString MusicAudioTrack::lyrics() const { return d->mLyrics; } void MusicAudioTrack::setComment(const QString &value) { d->mComment = value; } QString MusicAudioTrack::comment() const { return d->mComment; } void MusicAudioTrack::setTrackNumber(int value) { d->mTrackNumber = value; d->mTrackNumberIsValid = true; } int MusicAudioTrack::trackNumber() const { return d->mTrackNumber; } bool MusicAudioTrack::trackNumberIsValid() const { return d->mTrackNumberIsValid; } void MusicAudioTrack::setDiscNumber(int value) { d->mDiscNumber = value; d->mDiscNumberIsValid = true; } int MusicAudioTrack::discNumber() const { return d->mDiscNumber; } bool MusicAudioTrack::discNumberIsValid() const { return d->mDiscNumberIsValid; } void MusicAudioTrack::setYear(int value) { d->mYear = value; } int MusicAudioTrack::year() const { return d->mYear; } void MusicAudioTrack::setChannels(int value) { d->mChannels = value; d->mChannelsIsValid = true; } int MusicAudioTrack::channels() const { return d->mChannels; } bool MusicAudioTrack::channelsIsValid() const { return d->mChannelsIsValid; } void MusicAudioTrack::setBitRate(int value) { d->mBitRate = value; d->mBitRateIsValid = true; } int MusicAudioTrack::bitRate() const { return d->mBitRate; } bool MusicAudioTrack::bitRateIsValid() const { return d->mBitRateIsValid; } void MusicAudioTrack::setSampleRate(int value) { d->mSampleRate = value; d->mSampleRateIsValid = true; } int MusicAudioTrack::sampleRate() const { return d->mSampleRate; } bool MusicAudioTrack::sampleRateIsValid() const { return d->mSampleRateIsValid; } void MusicAudioTrack::setDuration(QTime value) { d->mDuration = value; } QTime MusicAudioTrack::duration() const { return d->mDuration; } void MusicAudioTrack::setFileModificationTime(const QDateTime &value) { d->mFileModificationTime = value; } const QDateTime &MusicAudioTrack::fileModificationTime() const { return d->mFileModificationTime; } void MusicAudioTrack::setResourceURI(const QUrl &value) { d->mResourceURI = value; } const QUrl &MusicAudioTrack::resourceURI() const { return d->mResourceURI; } void MusicAudioTrack::setRating(int value) { d->mRating = value; } int MusicAudioTrack::rating() const { return d->mRating; } void MusicAudioTrack::setIsSingleDiscAlbum(bool value) { d->mIsSingleDiscAlbum = value; } bool MusicAudioTrack::isSingleDiscAlbum() const { return d->mIsSingleDiscAlbum; } void MusicAudioTrack::setHasEmbeddedCover(bool value) { d->mHasBooleanCover = value; } bool MusicAudioTrack::hasEmbeddedCover() const { return d->mHasBooleanCover; } MusicAudioTrack::TrackDataType MusicAudioTrack::toTrackData() const { auto result = MusicAudioTrack::TrackDataType{}; result[MusicAudioTrack::TrackDataType::key_type::DatabaseIdRole] = databaseId(); if (!title().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::TitleRole] = title(); } if (!artist().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::ArtistRole] = artist(); } if (!albumName().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::AlbumRole] = albumName(); } if (!albumArtist().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::AlbumArtistRole] = albumArtist(); } if (!genre().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::GenreRole] = genre(); } if (!composer().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::ComposerRole] = composer(); } if (!lyricist().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::LyricistRole] = lyricist(); } if (!comment().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::CommentRole] = comment(); } if (!albumCover().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::ImageUrlRole] = albumCover(); } if (trackNumber() != -1) { result[MusicAudioTrack::TrackDataType::key_type::TrackNumberRole] = trackNumber(); } if (discNumber()) { result[MusicAudioTrack::TrackDataType::key_type::DiscNumberRole] = discNumber(); } if (year()) { result[MusicAudioTrack::TrackDataType::key_type::YearRole] = year(); } if (channels()) { result[MusicAudioTrack::TrackDataType::key_type::ChannelsRole] = channels(); } if (bitRate()) { result[MusicAudioTrack::TrackDataType::key_type::BitRateRole] = bitRate(); } if (sampleRate()) { result[MusicAudioTrack::TrackDataType::key_type::SampleRateRole] = sampleRate(); } if (!resourceURI().isEmpty()) { result[MusicAudioTrack::TrackDataType::key_type::ResourceRole] = resourceURI(); } if (rating()) { result[MusicAudioTrack::TrackDataType::key_type::RatingRole] = rating(); } if (duration().isValid()) { result[MusicAudioTrack::TrackDataType::key_type::DurationRole] = duration(); } return result; } ELISALIB_EXPORT QDebug operator<<(QDebug stream, const MusicAudioTrack &data) { stream << data.title() << data.artist() << data.albumName() << data.albumArtist() << data.duration() << data.resourceURI(); return stream; } diff --git a/src/trackslistener.cpp b/src/trackslistener.cpp index 2a06588e..99afb551 100644 --- a/src/trackslistener.cpp +++ b/src/trackslistener.cpp @@ -1,276 +1,250 @@ /* * Copyright 2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "trackslistener.h" #include "playListLogging.h" #include "databaseinterface.h" #include "datatypes.h" #include "filescanner.h" #include #include #include #include #include #include class TracksListenerPrivate { public: QSet mTracksByIdSet; QSet mRadiosByIdSet; QList> mTracksByNameSet; QList mTracksByFileNameSet; DatabaseInterface *mDatabase = nullptr; FileScanner mFileScanner; QMimeDatabase mMimeDb; }; TracksListener::TracksListener(DatabaseInterface *database, QObject *parent) : QObject(parent), d(std::make_unique()) { d->mDatabase = database; } TracksListener::~TracksListener() = default; void TracksListener::tracksAdded(const ListTrackDataType &allTracks) { for (const auto &oneTrack : allTracks) { if (d->mTracksByIdSet.contains(oneTrack.databaseId())) { Q_EMIT trackHasChanged(oneTrack); } if (d->mTracksByNameSet.isEmpty()) { return; } for (auto itTrack = d->mTracksByNameSet.begin(); itTrack != d->mTracksByNameSet.end(); ) { if (!std::get<0>(*itTrack).isEmpty() && std::get<0>(*itTrack) != oneTrack.title()) { ++itTrack; continue; } if (!std::get<1>(*itTrack).isEmpty() && std::get<1>(*itTrack) != oneTrack.artist()) { ++itTrack; continue; } if (!std::get<2>(*itTrack).isEmpty() && std::get<2>(*itTrack) != oneTrack.album()) { ++itTrack; continue; } if (std::get<3>(*itTrack) != oneTrack.trackNumber()) { ++itTrack; continue; } if (std::get<4>(*itTrack) != oneTrack.discNumber()) { ++itTrack; continue; } Q_EMIT trackHasChanged(TrackDataType(oneTrack)); d->mTracksByIdSet.insert(oneTrack.databaseId()); itTrack = d->mTracksByNameSet.erase(itTrack); } } } void TracksListener::trackRemoved(qulonglong id) { if (d->mTracksByIdSet.contains(id)) { Q_EMIT trackHasBeenRemoved(id); } } void TracksListener::trackModified(const TrackDataType &modifiedTrack) { if (d->mTracksByIdSet.contains(modifiedTrack.databaseId())) { Q_EMIT trackHasChanged(modifiedTrack); } } void TracksListener::trackByNameInList(const QVariant &title, const QVariant &artist, const QVariant &album, const QVariant &trackNumber, const QVariant &discNumber) { const auto realTitle = title.toString(); const auto realArtist = artist.toString(); const auto albumIsValid = !album.isNull() && album.isValid() && !album.toString().isEmpty(); auto realAlbum = std::optional{}; if (albumIsValid) { realAlbum = album.toString(); } auto trackNumberIsValid = bool{}; const auto trackNumberValue = trackNumber.toInt(&trackNumberIsValid); auto realTrackNumber = std::optional{}; if (trackNumberIsValid) { realTrackNumber = trackNumberValue; } auto discNumberIsValid = bool{}; const auto discNumberValue = discNumber.toInt(&discNumberIsValid); auto realDiscNumber = std::optional{}; if (discNumberIsValid) { realDiscNumber = discNumberValue; } auto newTrackId = d->mDatabase->trackIdFromTitleAlbumTrackDiscNumber(realTitle, realArtist, realAlbum, realTrackNumber, realDiscNumber); if (newTrackId == 0) { auto newTrack = std::tuple(realTitle, realArtist, album.toString(), trackNumber.toInt(), discNumber.toInt()); d->mTracksByNameSet.push_back(newTrack); return; } d->mTracksByIdSet.insert(newTrackId); auto newTrack = d->mDatabase->trackDataFromDatabaseId(newTrackId); if (!newTrack.isEmpty()) { Q_EMIT trackHasChanged(newTrack); } } void TracksListener::trackByFileNameInList(const QUrl &fileName) { auto newTrackId = d->mDatabase->trackIdFromFileName(fileName); if (newTrackId == 0) { - auto newTrack = scanOneFile(fileName); + auto newTrack = d->mFileScanner.scanOneFile(fileName, d->mMimeDb); if (newTrack.isValid()) { - auto oneData = DataTypes::TrackDataType{}; - - if (!newTrack.title().isEmpty()) { - oneData[DataTypes::TrackDataType::key_type::TitleRole] = newTrack.title(); - } else { - const auto &fileUrl = newTrack.resourceURI(); - oneData[DataTypes::TrackDataType::key_type::TitleRole] = fileUrl.fileName(); - } - - oneData[DataTypes::TrackDataType::key_type::ArtistRole] = newTrack.artist(); - oneData[DataTypes::TrackDataType::key_type::AlbumRole] = newTrack.albumName(); - oneData[DataTypes::TrackDataType::key_type::AlbumIdRole] = newTrack.albumId(); - oneData[DataTypes::TrackDataType::key_type::TrackNumberRole] = newTrack.trackNumber(); - oneData[DataTypes::TrackDataType::key_type::DiscNumberRole] = newTrack.discNumber(); - oneData[DataTypes::TrackDataType::key_type::DurationRole] = newTrack.duration(); - oneData[DataTypes::TrackDataType::key_type::MilliSecondsDurationRole] = newTrack.duration().msecsSinceStartOfDay(); - oneData[DataTypes::TrackDataType::key_type::ResourceRole] = newTrack.resourceURI(); - oneData[DataTypes::TrackDataType::key_type::ImageUrlRole] = newTrack.albumCover(); - - Q_EMIT trackHasChanged(oneData); + Q_EMIT trackHasChanged(newTrack); return; } d->mTracksByFileNameSet.push_back(fileName); - return; } d->mTracksByIdSet.insert(newTrackId); auto newTrack = d->mDatabase->trackDataFromDatabaseId(newTrackId); if (!newTrack.isEmpty()) { Q_EMIT trackHasChanged({newTrack}); } } void TracksListener::newAlbumInList(qulonglong newDatabaseId, const QString &entryTitle) { qCDebug(orgKdeElisaPlayList()) << "TracksListener::newAlbumInList" << newDatabaseId << entryTitle << d->mDatabase->albumData(newDatabaseId); Q_EMIT tracksListAdded(newDatabaseId, entryTitle, ElisaUtils::Album, d->mDatabase->albumData(newDatabaseId)); } void TracksListener::newEntryInList(qulonglong newDatabaseId, const QString &entryTitle, ElisaUtils::PlayListEntryType databaseIdType) { qCDebug(orgKdeElisaPlayList()) << "TracksListener::newEntryInList" << newDatabaseId << entryTitle << databaseIdType; switch (databaseIdType) { case ElisaUtils::Track: { d->mTracksByIdSet.insert(newDatabaseId); auto newTrack = d->mDatabase->trackDataFromDatabaseId(newDatabaseId); if (!newTrack.isEmpty()) { Q_EMIT trackHasChanged(newTrack); } break; } case ElisaUtils::Radio: { d->mRadiosByIdSet.insert(newDatabaseId); auto newRadio = d->mDatabase->radioDataFromDatabaseId(newDatabaseId); if (!newRadio.isEmpty()) { Q_EMIT trackHasChanged(newRadio); } break; } case ElisaUtils::Artist: newArtistInList(newDatabaseId, entryTitle); break; case ElisaUtils::FileName: trackByFileNameInList(QUrl::fromLocalFile(entryTitle)); break; case ElisaUtils::Album: newAlbumInList(newDatabaseId, entryTitle); break; case ElisaUtils::Lyricist: case ElisaUtils::Composer: case ElisaUtils::Genre: case ElisaUtils::Unknown: break; } } void TracksListener::newArtistInList(qulonglong newDatabaseId, const QString &artist) { auto newTracks = d->mDatabase->tracksDataFromAuthor(artist); if (newTracks.isEmpty()) { return; } for (const auto &oneTrack : newTracks) { d->mTracksByIdSet.insert(oneTrack.databaseId()); } Q_EMIT tracksListAdded(newDatabaseId, artist, ElisaUtils::Artist, newTracks); } -MusicAudioTrack TracksListener::scanOneFile(const QUrl &scanFile) -{ - return d->mFileScanner.scanOneFile(scanFile, d->mMimeDb); -} - - #include "moc_trackslistener.cpp" diff --git a/src/trackslistener.h b/src/trackslistener.h index 44f62821..fcb7f0bb 100644 --- a/src/trackslistener.h +++ b/src/trackslistener.h @@ -1,88 +1,86 @@ /* * Copyright 2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef TRACKSLISTENER_H #define TRACKSLISTENER_H #include "elisaLib_export.h" #include "databaseinterface.h" #include "datatypes.h" #include "musicaudiotrack.h" #include "elisautils.h" #include #include class TracksListenerPrivate; class ELISALIB_EXPORT TracksListener : public QObject { Q_OBJECT public: using ListTrackDataType = DataTypes::ListTrackDataType; using TrackDataType = DataTypes::TrackDataType; explicit TracksListener(DatabaseInterface *database, QObject *parent = nullptr); ~TracksListener() override; Q_SIGNALS: void trackHasChanged(const TracksListener::TrackDataType &audioTrack); void trackHasBeenRemoved(qulonglong id); void tracksListAdded(qulonglong newDatabaseId, const QString &entryTitle, ElisaUtils::PlayListEntryType databaseIdType, const TracksListener::ListTrackDataType &tracks); public Q_SLOTS: void tracksAdded(const TracksListener::ListTrackDataType &allTracks); void trackRemoved(qulonglong id); void trackModified(const TracksListener::TrackDataType &modifiedTrack); void trackByNameInList(const QVariant &title, const QVariant &artist, const QVariant &album, const QVariant &trackNumber, const QVariant &discNumber); void newEntryInList(qulonglong newDatabaseId, const QString &entryTitle, ElisaUtils::PlayListEntryType databaseIdType); private: - MusicAudioTrack scanOneFile(const QUrl &scanFile); - void newArtistInList(qulonglong newDatabaseId, const QString &artist); void trackByFileNameInList(const QUrl &fileName); void newAlbumInList(qulonglong newDatabaseId, const QString &entryTitle); std::unique_ptr d; }; #endif // TRACKSLISTENER_H