/* LocalLibrary.cpp */ /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras) * * This file is part of sayonara player * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "LocalLibrary.h" #include "Importer/LibraryImporter.h" #include "Threads/ReloadThread.h" #include "Components/LibraryManagement/LibraryManager.h" #include "Database/Connector.h" #include "Database/Library.h" #include "Database/LibraryDatabase.h" #include "Interfaces/LibraryPlaylistInteractor.h" #include "Utils/MetaData/Album.h" #include "Utils/MetaData/Artist.h" #include "Utils/MetaData/MetaDataList.h" #include "Utils/Settings/Settings.h" #include "Utils/Library/LibraryInfo.h" #include "Utils/Logger/Logger.h" #include struct LocalLibrary::Private { LibraryId libraryId; DB::LibraryDatabase* libraryDatabase; Library::Manager* libraryManager; Library::ReloadThread* reloadThread = nullptr; Library::Importer* libraryImporter = nullptr; Private(Library::Manager* libraryManager, LibraryId libraryId) : libraryId(libraryId), libraryDatabase(DB::Connector::instance()->libraryDatabase(libraryId, 0)), libraryManager(libraryManager) {} }; LocalLibrary::LocalLibrary(Library::Manager* libraryManager, LibraryId libraryId, LibraryPlaylistInteractor* playlistInteractor, QObject* parent) : AbstractLibrary(playlistInteractor, parent) { m = Pimpl::make(libraryManager, libraryId); applyDatabaseFixes(); connect(libraryManager, &Library::Manager::sigRenamed, this, [&](const auto id) { if(id == m->libraryId) { emit sigRenamed(info().name()); } }); connect(libraryManager, &Library::Manager::sigPathChanged, this, [&](const auto id) { if(id == m->libraryId) { emit sigPathChanged(info().path()); } }); ListenSettingNoCall(Set::Lib_SearchMode, LocalLibrary::searchModeChanged); ListenSettingNoCall(Set::Lib_ShowAlbumArtists, LocalLibrary::showAlbumArtistsChanged); } LocalLibrary::~LocalLibrary() = default; void LocalLibrary::applyDatabaseFixes() {} void LocalLibrary::reloadLibrary(bool clearFirst, Library::ReloadQuality quality) { if(isReloading()) { return; } if(!m->reloadThread) { initReloadThread(); } if(clearFirst) { deleteAllTracks(); } const auto info = this->info(); m->reloadThread->setLibrary(info.id(), info.path()); m->reloadThread->setQuality(quality); m->reloadThread->start(); } void LocalLibrary::reloadThreadFinished() { load(); emit sigReloadingLibrary(QString(), -1); emit sigReloadingLibraryFinished(); } void LocalLibrary::searchModeChanged() { spLog(Log::Debug, this) << "Updating cissearch... " << GetSetting(Set::Lib_SearchMode); m->libraryDatabase->updateSearchMode(); spLog(Log::Debug, this) << "Updating cissearch finished" << GetSetting(Set::Lib_SearchMode); } void LocalLibrary::showAlbumArtistsChanged() { const auto showAlbumArtists = GetSetting(Set::Lib_ShowAlbumArtists); const auto libraryDatabases = DB::Connector::instance()->libraryDatabases(); for(auto* libraryDatabase : libraryDatabases) { if(libraryDatabase->databaseId() == 0) { const auto field = (showAlbumArtists) ? DB::LibraryDatabase::ArtistIDField::AlbumArtistID : DB::LibraryDatabase::ArtistIDField::ArtistID; libraryDatabase->changeArtistIdField(field); } } refreshCurrentView(); } void LocalLibrary::importStatusChanged(Library::Importer::ImportStatus status) { if(status == Library::Importer::ImportStatus::Imported) { refreshCurrentView(); } } void LocalLibrary::reloadThreadNewBlock() { m->reloadThread->pause(); refreshCurrentView(); m->reloadThread->goon(); } void LocalLibrary::getAllArtists(ArtistList& artists) const { m->libraryDatabase->getAllArtists(artists, false); } void LocalLibrary::getAllArtistsBySearchstring(Library::Filter filter, ArtistList& artists) const { m->libraryDatabase->getAllArtistsBySearchString(filter, artists); } void LocalLibrary::getAllAlbums(AlbumList& albums) const { m->libraryDatabase->getAllAlbums(albums, false); } void LocalLibrary::getAllAlbumsByArtist(IdList artistIds, AlbumList& albums, Library::Filter filter) const { m->libraryDatabase->getAllAlbumsByArtist(artistIds, albums, filter); } void LocalLibrary::getAllAlbumsBySearchstring(Library::Filter filter, AlbumList& albums) const { m->libraryDatabase->getAllAlbumsBySearchString(filter, albums); } int LocalLibrary::getTrackCount() const { return m->libraryDatabase->getNumTracks(); } void LocalLibrary::getAllTracks(MetaDataList& tracks) const { m->libraryDatabase->getAllTracks(tracks); } void LocalLibrary::getAllTracks(const QStringList& paths, MetaDataList& tracks) const { m->libraryDatabase->getMultipleTracksByPath(paths, tracks); } void LocalLibrary::getAllTracksByArtist(IdList artistIds, MetaDataList& tracks, Library::Filter filter) const { m->libraryDatabase->getAllTracksByArtist(artistIds, tracks, filter); } void LocalLibrary::getAllTracksByAlbum(IdList albumIds, MetaDataList& tracks, Library::Filter filter) const { m->libraryDatabase->getAllTracksByAlbum(albumIds, tracks, filter, -1); } void LocalLibrary::getAllTracksBySearchstring(Library::Filter filter, MetaDataList& tracks) const { m->libraryDatabase->getAllTracksBySearchString(filter, tracks); } void LocalLibrary::getAllTracksByPath(const QStringList& paths, MetaDataList& tracks) const { m->libraryDatabase->getAllTracksByPaths(paths, tracks); } void LocalLibrary::getTrackById(TrackID trackId, MetaData& track) const { const auto tmpTrack = m->libraryDatabase->getTrackById(trackId); track = (tmpTrack.libraryId() == m->libraryId) ? tmpTrack : MetaData(); } void LocalLibrary::getAlbumById(AlbumId albumId, Album& album) const { m->libraryDatabase->getAlbumByID(albumId, album); } void LocalLibrary::getArtistById(ArtistId artistId, Artist& artist) const { m->libraryDatabase->getArtistByID(artistId, artist); } void LocalLibrary::initReloadThread() { if(!m->reloadThread) { m->reloadThread = new Library::ReloadThread(this); connect(m->reloadThread, &Library::ReloadThread::sigReloadingLibrary, this, &LocalLibrary::sigReloadingLibrary); connect(m->reloadThread, &Library::ReloadThread::sigNewBlockSaved, this, &LocalLibrary::reloadThreadNewBlock); connect(m->reloadThread, &Library::ReloadThread::finished, this, &LocalLibrary::reloadThreadFinished); } } void LocalLibrary::deleteTracks(const MetaDataList& tracks, Library::TrackDeletionMode mode) { m->libraryDatabase->deleteTracks(tracks); AbstractLibrary::deleteTracks(tracks, mode); } void LocalLibrary::refreshArtists() {} void LocalLibrary::refreshAlbums() {} void LocalLibrary::refreshTracks() {} void LocalLibrary::importFiles(const QStringList& files) { importFilesTo(files, QString()); } void LocalLibrary::importFilesTo(const QStringList& files, const QString& targetDirectory) { if(!files.isEmpty()) { if(!m->libraryImporter) { m->libraryImporter = new Library::Importer(this); connect(m->libraryImporter, &Library::Importer::sigStatusChanged, this, &LocalLibrary::importStatusChanged); } m->libraryImporter->importFiles(files, targetDirectory); emit sigImportDialogRequested(targetDirectory); } } bool LocalLibrary::setLibraryPath(const QString& library_path) { return m->libraryManager->changeLibraryPath(m->libraryId, library_path); } bool LocalLibrary::setLibraryName(const QString& library_name) { return m->libraryManager->renameLibrary(m->libraryId, library_name); } Library::Info LocalLibrary::info() const { return m->libraryManager->libraryInfo(m->libraryId); } Library::Importer* LocalLibrary::importer() { if(!m->libraryImporter) { m->libraryImporter = new Library::Importer(this); connect(m->libraryImporter, &Library::Importer::sigStatusChanged, this, &LocalLibrary::importStatusChanged); } return m->libraryImporter; } bool LocalLibrary::isReloading() const { return (m->reloadThread != nullptr && m->reloadThread->isRunning()); }