diff --git a/src/baloo/baloolistener.cpp b/src/baloo/baloolistener.cpp index 5e0fb410..829d266b 100644 --- a/src/baloo/baloolistener.cpp +++ b/src/baloo/baloolistener.cpp @@ -1,80 +1,86 @@ /* * Copyright 2016 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "baloolistener.h" #include "localbaloofilelisting.h" #include "databaseinterface.h" #include class BalooListenerPrivate { public: QThread mBalooQueryThread; LocalBalooFileListing mFileListing; DatabaseInterface* mDatabaseInterface = nullptr; }; BalooListener::BalooListener(QObject *parent) : QObject(parent), d(new BalooListenerPrivate) { d->mBalooQueryThread.start(); d->mFileListing.moveToThread(&d->mBalooQueryThread); } BalooListener::~BalooListener() { delete d; } DatabaseInterface *BalooListener::databaseInterface() const { return d->mDatabaseInterface; } void BalooListener::setDatabaseInterface(DatabaseInterface *model) { if (d->mDatabaseInterface == model) { return; } if (d->mDatabaseInterface) { disconnect(d->mDatabaseInterface); } d->mDatabaseInterface = model; if (d->mDatabaseInterface) { connect(this, &BalooListener::refreshContent, &d->mFileListing, &LocalBalooFileListing::refreshContent, Qt::QueuedConnection); connect(&d->mFileListing, &LocalBalooFileListing::tracksList, d->mDatabaseInterface, &DatabaseInterface::insertTracksList); QMetaObject::invokeMethod(&d->mFileListing, "init", Qt::QueuedConnection); Q_EMIT refreshContent(); } emit databaseInterfaceChanged(); } +void BalooListener::applicationAboutToQuit() +{ + d->mBalooQueryThread.exit(); + d->mBalooQueryThread.wait(); +} + #include "moc_baloolistener.cpp" diff --git a/src/baloo/baloolistener.h b/src/baloo/baloolistener.h index 8c0add96..6164660c 100644 --- a/src/baloo/baloolistener.h +++ b/src/baloo/baloolistener.h @@ -1,60 +1,62 @@ /* * Copyright 2016 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef BALOOLISTENER_H #define BALOOLISTENER_H #include class BalooListenerPrivate; class DatabaseInterface; class BalooListener : public QObject { Q_OBJECT Q_PROPERTY(DatabaseInterface* databaseInterface READ databaseInterface WRITE setDatabaseInterface NOTIFY databaseInterfaceChanged) public: explicit BalooListener(QObject *parent = 0); virtual ~BalooListener(); DatabaseInterface* databaseInterface() const; Q_SIGNALS: void refreshContent(); void databaseInterfaceChanged(); public Q_SLOTS: void setDatabaseInterface(DatabaseInterface* databaseInterface); + void applicationAboutToQuit(); + private: BalooListenerPrivate *d = nullptr; }; #endif // BALOOLISTENER_H diff --git a/src/file/filelistener.cpp b/src/file/filelistener.cpp index 555b9a7d..f257354d 100644 --- a/src/file/filelistener.cpp +++ b/src/file/filelistener.cpp @@ -1,81 +1,87 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "filelistener.h" #include "localfilelisting.h" #include "databaseinterface.h" #include class FileListenerPrivate { public: QThread mFileQueryThread; LocalFileListing mFileListing; DatabaseInterface* mDatabaseInterface = nullptr; }; FileListener::FileListener(QObject *parent) : QObject(parent), d(new FileListenerPrivate) { d->mFileQueryThread.start(); d->mFileListing.moveToThread(&d->mFileQueryThread); } FileListener::~FileListener() { delete d; } DatabaseInterface *FileListener::databaseInterface() const { return d->mDatabaseInterface; } void FileListener::setDatabaseInterface(DatabaseInterface *model) { if (d->mDatabaseInterface == model) { return; } if (d->mDatabaseInterface) { disconnect(d->mDatabaseInterface); } d->mDatabaseInterface = model; if (d->mDatabaseInterface) { connect(this, &FileListener::refreshContent, &d->mFileListing, &LocalFileListing::refreshContent, Qt::QueuedConnection); connect(&d->mFileListing, &LocalFileListing::tracksList, d->mDatabaseInterface, &DatabaseInterface::insertTracksList); connect(&d->mFileListing, &LocalFileListing::removedTracksList, d->mDatabaseInterface, &DatabaseInterface::removeTracksList); QMetaObject::invokeMethod(&d->mFileListing, "init", Qt::QueuedConnection); Q_EMIT refreshContent(); } emit databaseInterfaceChanged(); } +void FileListener::applicationAboutToQuit() +{ + d->mFileQueryThread.exit(); + d->mFileQueryThread.wait(); +} + #include "moc_filelistener.cpp" diff --git a/src/file/filelistener.h b/src/file/filelistener.h index 6b9d7027..ecab8b11 100644 --- a/src/file/filelistener.h +++ b/src/file/filelistener.h @@ -1,60 +1,62 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef FILELISTENER_H #define FILELISTENER_H #include class FileListenerPrivate; class DatabaseInterface; class FileListener : public QObject { Q_OBJECT Q_PROPERTY(DatabaseInterface* databaseInterface READ databaseInterface WRITE setDatabaseInterface NOTIFY databaseInterfaceChanged) public: explicit FileListener(QObject *parent = 0); virtual ~FileListener(); DatabaseInterface* databaseInterface() const; Q_SIGNALS: void refreshContent(); void databaseInterfaceChanged(); public Q_SLOTS: void setDatabaseInterface(DatabaseInterface* databaseInterface); + void applicationAboutToQuit(); + private: FileListenerPrivate *d = nullptr; }; #endif // FILELISTENER_H diff --git a/src/musiclistenersmanager.cpp b/src/musiclistenersmanager.cpp index c2e05fc1..5c59ebaa 100644 --- a/src/musiclistenersmanager.cpp +++ b/src/musiclistenersmanager.cpp @@ -1,147 +1,163 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "musiclistenersmanager.h" #include "config-upnp-qt.h" -#include "databaseinterface.h" -#include "mediaplaylist.h" - #if defined UPNPQT_FOUND && UPNPQT_FOUND #include "upnp/upnplistener.h" #endif #if defined KF5Baloo_FOUND && KF5Baloo_FOUND #include "baloo/baloolistener.h" #endif +#include "databaseinterface.h" +#include "mediaplaylist.h" #include "file/filelistener.h" +#include "trackslistener.h" #include #include #include #include - -#include "trackslistener.h" +#include class MusicListenersManagerPrivate { public: QThread mDatabaseThread; #if defined UPNPQT_FOUND && UPNPQT_FOUND UpnpListener mUpnpListener; #endif #if defined KF5Baloo_FOUND && KF5Baloo_FOUND BalooListener mBalooListener; #endif FileListener mFileListener; DatabaseInterface mDatabaseInterface; }; MusicListenersManager::MusicListenersManager(QObject *parent) : QObject(parent), d(new MusicListenersManagerPrivate) { d->mDatabaseThread.start(); d->mDatabaseInterface.moveToThread(&d->mDatabaseThread); connect(&d->mDatabaseInterface, &DatabaseInterface::requestsInitDone, this, &MusicListenersManager::databaseReady); const auto &localDataPaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); auto databaseFileName = QString(); if (!localDataPaths.isEmpty()) { QDir myDataDirectory; myDataDirectory.mkpath(localDataPaths.first()); databaseFileName = localDataPaths.first() + QStringLiteral("/elisaDatabase.db"); } QMetaObject::invokeMethod(&d->mDatabaseInterface, "init", Qt::QueuedConnection, Q_ARG(QString, QStringLiteral("listeners")), Q_ARG(QString, databaseFileName)); connect(&d->mDatabaseInterface, &DatabaseInterface::artistAdded, this, &MusicListenersManager::artistAdded); connect(&d->mDatabaseInterface, &DatabaseInterface::albumAdded, this, &MusicListenersManager::albumAdded); connect(&d->mDatabaseInterface, &DatabaseInterface::trackAdded, this, &MusicListenersManager::trackAdded); connect(&d->mDatabaseInterface, &DatabaseInterface::artistRemoved, this, &MusicListenersManager::artistRemoved); connect(&d->mDatabaseInterface, &DatabaseInterface::albumRemoved, this, &MusicListenersManager::albumRemoved); connect(&d->mDatabaseInterface, &DatabaseInterface::trackRemoved, this, &MusicListenersManager::trackRemoved); connect(&d->mDatabaseInterface, &DatabaseInterface::artistModified, this, &MusicListenersManager::artistModified); connect(&d->mDatabaseInterface, &DatabaseInterface::albumModified, this, &MusicListenersManager::albumModified); connect(&d->mDatabaseInterface, &DatabaseInterface::trackModified, this, &MusicListenersManager::trackModified); + + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, + this, &MusicListenersManager::applicationAboutToQuit); } MusicListenersManager::~MusicListenersManager() { delete d; } DatabaseInterface *MusicListenersManager::viewDatabase() const { return &d->mDatabaseInterface; } void MusicListenersManager::subscribeForTracks(MediaPlayList *client) { auto helper = new TracksListener(&d->mDatabaseInterface); helper->moveToThread(&d->mDatabaseThread); connect(this, &MusicListenersManager::trackRemoved, client, &MediaPlayList::trackRemoved); connect(this, &MusicListenersManager::trackAdded, client, &MediaPlayList::trackChanged); connect(helper, &TracksListener::trackChanged, client, &MediaPlayList::trackChanged); connect(helper, &TracksListener::albumAdded, client, &MediaPlayList::albumAdded); connect(client, &MediaPlayList::newTrackByIdInList, helper, &TracksListener::trackByIdInList); connect(client, &MediaPlayList::newTrackByNameInList, helper, &TracksListener::trackByNameInList); connect(client, &MediaPlayList::newArtistInList, helper, &TracksListener::newArtistInList); connect(&d->mDatabaseInterface, &DatabaseInterface::trackAdded, helper, &TracksListener::trackAdded); } void MusicListenersManager::databaseReady() { #if defined KF5Baloo_FOUND && KF5Baloo_FOUND d->mBalooListener.setDatabaseInterface(&d->mDatabaseInterface); d->mBalooListener.moveToThread(&d->mDatabaseThread); + connect(this, &MusicListenersManager::applicationIsTerminating, + &d->mBalooListener, &BalooListener::applicationAboutToQuit, Qt::BlockingQueuedConnection); #endif #if defined UPNPQT_FOUND && UPNPQT_FOUND d->mUpnpListener.setDatabaseInterface(&d->mDatabaseInterface); d->mUpnpListener.moveToThread(&d->mDatabaseThread); + connect(this, &MusicListenersManager::applicationIsTerminating, + &d->mUpnpListener, &UpnpListener::applicationAboutToQuit, Qt::BlockingQueuedConnection); #endif d->mFileListener.setDatabaseInterface(&d->mDatabaseInterface); d->mFileListener.moveToThread(&d->mDatabaseThread); + connect(this, &MusicListenersManager::applicationIsTerminating, + &d->mFileListener, &FileListener::applicationAboutToQuit, Qt::BlockingQueuedConnection); +} + +void MusicListenersManager::applicationAboutToQuit() +{ + Q_EMIT applicationIsTerminating(); + + d->mDatabaseThread.exit(); + d->mDatabaseThread.wait(); } #include "moc_musiclistenersmanager.cpp" diff --git a/src/musiclistenersmanager.h b/src/musiclistenersmanager.h index da7358d3..5d054118 100644 --- a/src/musiclistenersmanager.h +++ b/src/musiclistenersmanager.h @@ -1,84 +1,88 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef MUSICLISTENERSMANAGER_H #define MUSICLISTENERSMANAGER_H #include #include "musicalbum.h" #include "musicartist.h" #include "musicaudiotrack.h" class MusicListenersManagerPrivate; class DatabaseInterface; class MediaPlayList; class MusicListenersManager : public QObject { Q_OBJECT Q_PROPERTY(DatabaseInterface* viewDatabase READ viewDatabase NOTIFY viewDatabaseChanged) public: explicit MusicListenersManager(QObject *parent = 0); virtual ~MusicListenersManager(); DatabaseInterface* viewDatabase() const; void subscribeForTracks(MediaPlayList *client); Q_SIGNALS: void viewDatabaseChanged(); void artistAdded(MusicArtist newArtist); void albumAdded(MusicAlbum newAlbum); void trackAdded(MusicAudioTrack newTrack); void artistRemoved(MusicArtist removedArtist); void albumRemoved(MusicAlbum removedAlbum); void trackRemoved(MusicAudioTrack removedTrack); void artistModified(MusicArtist modifiedArtist); void albumModified(MusicAlbum modifiedAlbum); void trackModified(MusicAudioTrack modifiedTrack); + void applicationIsTerminating(); + public Q_SLOTS: void databaseReady(); + void applicationAboutToQuit(); + private: MusicListenersManagerPrivate *d; }; #endif // MUSICLISTENERSMANAGER_H diff --git a/src/upnp/upnplistener.cpp b/src/upnp/upnplistener.cpp index 6d160b7c..9f4e355c 100644 --- a/src/upnp/upnplistener.cpp +++ b/src/upnp/upnplistener.cpp @@ -1,78 +1,82 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "upnplistener.h" #include "databaseinterface.h" #include "upnpdiscoverallmusic.h" #include "upnpssdpengine.h" class UpnpListenerPrivate { public: DatabaseInterface* mDatabaseInterface = nullptr; UpnpDiscoverAllMusic mUpnpManager; UpnpSsdpEngine mSsdpEngine; }; UpnpListener::UpnpListener(QObject *parent) : QObject(parent), d(new UpnpListenerPrivate) { d->mSsdpEngine.initialize(); d->mSsdpEngine.searchAllUpnpDevice(); d->mUpnpManager.setDeviceId(QStringLiteral("urn:schemas-upnp-org:service:ContentDirectory:1")); connect(&d->mSsdpEngine, &UpnpSsdpEngine::newService, &d->mUpnpManager, &UpnpDiscoverAllMusic::newDevice); connect(&d->mSsdpEngine, &UpnpSsdpEngine::removedService, &d->mUpnpManager, &UpnpDiscoverAllMusic::removedDevice); } UpnpListener::~UpnpListener() { delete d; } DatabaseInterface *UpnpListener::databaseInterface() const { return d->mDatabaseInterface; } void UpnpListener::setDatabaseInterface(DatabaseInterface *model) { if (d->mDatabaseInterface == model) { return; } if (d->mDatabaseInterface) { disconnect(d->mDatabaseInterface); } d->mDatabaseInterface = model; d->mUpnpManager.setAlbumDatabase(d->mDatabaseInterface); emit databaseInterfaceChanged(); } +void UpnpListener::applicationAboutToQuit() +{ +} + #include "moc_upnplistener.cpp" diff --git a/src/upnp/upnplistener.h b/src/upnp/upnplistener.h index e29213c0..1f866b8b 100644 --- a/src/upnp/upnplistener.h +++ b/src/upnp/upnplistener.h @@ -1,62 +1,64 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef UPNPLISTENER_H #define UPNPLISTENER_H #include class UpnpListenerPrivate; class DatabaseInterface; class UpnpDiscoverAllMusic; class UpnpSsdpEngine; class UpnpListener : public QObject { Q_OBJECT Q_PROPERTY(DatabaseInterface* databaseInterface READ databaseInterface WRITE setDatabaseInterface NOTIFY databaseInterfaceChanged) public: explicit UpnpListener(QObject *parent = 0); virtual ~UpnpListener(); DatabaseInterface* databaseInterface() const; Q_SIGNALS: void databaseInterfaceChanged(); public Q_SLOTS: void setDatabaseInterface(DatabaseInterface* databaseInterface); + void applicationAboutToQuit(); + private: UpnpListenerPrivate *d = nullptr; }; #endif // UPNPLISTENER_H