strawberry-audio-player-win.../src/collection/collection.cpp

185 lines
5.9 KiB
C++
Raw Normal View History

2018-02-27 18:06:05 +01:00
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
2019-09-23 19:17:41 +02:00
* Copyright 2018-2019, Jonas Kvinge <jonas@jkvinge.net>
2018-02-27 18:06:05 +01:00
*
* Strawberry 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.
*
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
2018-08-09 18:39:44 +02:00
*
2018-02-27 18:06:05 +01:00
*/
#include "config.h"
2020-02-08 03:40:30 +01:00
#include <QtGlobal>
#include <QObject>
#include <QThread>
#include <QList>
2020-02-08 03:40:30 +01:00
#include <QtDebug>
2018-02-27 18:06:05 +01:00
#include "core/application.h"
#include "core/database.h"
#include "core/player.h"
#include "core/tagreaderclient.h"
#include "core/thread.h"
#include "core/utilities.h"
2019-04-08 23:00:07 +02:00
#include "core/song.h"
2020-02-08 03:40:30 +01:00
#include "core/logging.h"
#include "collection.h"
#include "collectionwatcher.h"
#include "collectionbackend.h"
#include "collectionmodel.h"
#include "playlist/playlistmanager.h"
2020-08-30 18:09:13 +02:00
#include "scrobbler/lastfmimport.h"
2018-02-27 18:06:05 +01:00
2018-07-01 22:26:46 +02:00
const char *SCollection::kSongsTable = "songs";
const char *SCollection::kDirsTable = "directories";
const char *SCollection::kSubdirsTable = "subdirectories";
const char *SCollection::kFtsTable = "songs_fts";
2018-02-27 18:06:05 +01:00
2018-07-01 22:26:46 +02:00
SCollection::SCollection(Application *app, QObject *parent)
2018-02-27 18:06:05 +01:00
: QObject(parent),
app_(app),
backend_(nullptr),
model_(nullptr),
watcher_(nullptr),
watcher_thread_(nullptr),
original_thread_(nullptr) {
original_thread_ = thread();
2018-02-27 18:06:05 +01:00
2019-04-08 23:00:07 +02:00
backend_ = new CollectionBackend();
2018-02-27 18:06:05 +01:00
backend()->moveToThread(app->database()->thread());
qLog(Debug) << backend_ << "moved to thread" << app->database()->thread();
2018-02-27 18:06:05 +01:00
backend_->Init(app->database(), Song::Source_Collection, kSongsTable, kDirsTable, kSubdirsTable, kFtsTable);
2018-02-27 18:06:05 +01:00
model_ = new CollectionModel(backend_, app_, this);
ReloadSettings();
}
2018-07-01 22:26:46 +02:00
SCollection::~SCollection() {
if (watcher_) {
watcher_->Stop();
watcher_->deleteLater();
}
if (watcher_thread_) {
watcher_thread_->exit();
watcher_thread_->wait(5000 /* five seconds */);
}
2019-07-22 20:53:05 +02:00
backend_->deleteLater();
2018-02-27 18:06:05 +01:00
}
2018-07-01 22:26:46 +02:00
void SCollection::Init() {
2018-10-02 00:38:52 +02:00
2019-04-08 23:00:07 +02:00
watcher_ = new CollectionWatcher(Song::Source_Collection);
2018-02-27 18:06:05 +01:00
watcher_thread_ = new Thread(this);
watcher_thread_->SetIoPriority(Utilities::IOPRIO_CLASS_IDLE);
watcher_->moveToThread(watcher_thread_);
watcher_thread_->start(QThread::IdlePriority);
qLog(Debug) << watcher_ << "moved to thread" << watcher_thread_;
2018-02-27 18:06:05 +01:00
watcher_->set_backend(backend_);
watcher_->set_task_manager(app_->task_manager());
connect(backend_, SIGNAL(DirectoryDiscovered(Directory, SubdirectoryList)), watcher_, SLOT(AddDirectory(Directory, SubdirectoryList)));
connect(backend_, SIGNAL(DirectoryDeleted(Directory)), watcher_, SLOT(RemoveDirectory(Directory)));
connect(watcher_, SIGNAL(NewOrUpdatedSongs(SongList)), backend_, SLOT(AddOrUpdateSongs(SongList)));
connect(watcher_, SIGNAL(SongsMTimeUpdated(SongList)), backend_, SLOT(UpdateMTimesOnly(SongList)));
connect(watcher_, SIGNAL(SongsDeleted(SongList)), backend_, SLOT(DeleteSongs(SongList)));
connect(watcher_, SIGNAL(SongsUnavailable(SongList)), backend_, SLOT(MarkSongsUnavailable(SongList)));
2018-02-27 18:06:05 +01:00
connect(watcher_, SIGNAL(SongsReadded(SongList, bool)), backend_, SLOT(MarkSongsUnavailable(SongList, bool)));
connect(watcher_, SIGNAL(SubdirsDiscovered(SubdirectoryList)), backend_, SLOT(AddOrUpdateSubdirs(SubdirectoryList)));
connect(watcher_, SIGNAL(SubdirsMTimeUpdated(SubdirectoryList)), backend_, SLOT(AddOrUpdateSubdirs(SubdirectoryList)));
connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_, SLOT(UpdateCompilations()));
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), SLOT(CurrentSongChanged(Song)));
connect(app_->player(), SIGNAL(Stopped()), SLOT(Stopped()));
connect(app_->lastfm_import(), SIGNAL(UpdateLastPlayed(QString, QString, QString, qint64)), backend_, SLOT(UpdateLastPlayed(QString, QString, QString, qint64)));
2020-08-30 18:09:13 +02:00
connect(app_->lastfm_import(), SIGNAL(UpdatePlayCount(QString, QString, int)), backend_, SLOT(UpdatePlayCount(QString, QString, int)));
2018-02-27 18:06:05 +01:00
// This will start the watcher checking for updates
backend_->LoadDirectoriesAsync();
}
void SCollection::Exit() {
wait_for_exit_ << backend_ << watcher_;
2020-06-14 17:02:47 +02:00
disconnect(backend_, nullptr, watcher_, nullptr);
disconnect(watcher_, nullptr, backend_, nullptr);
connect(backend_, SIGNAL(ExitFinished()), this, SLOT(ExitReceived()));
connect(watcher_, SIGNAL(ExitFinished()), this, SLOT(ExitReceived()));
backend_->ExitAsync();
watcher_->ExitAsync();
}
void SCollection::ExitReceived() {
QObject *obj = qobject_cast<QObject*>(sender());
2020-06-14 17:02:47 +02:00
disconnect(obj, nullptr, this, nullptr);
2019-07-24 23:29:09 +02:00
qLog(Debug) << obj << "successfully exited.";
wait_for_exit_.removeAll(obj);
if (wait_for_exit_.isEmpty()) emit ExitFinished();
2018-02-27 18:06:05 +01:00
}
2018-07-01 22:26:46 +02:00
void SCollection::IncrementalScan() { watcher_->IncrementalScanAsync(); }
2018-02-27 18:06:05 +01:00
2018-07-01 22:26:46 +02:00
void SCollection::FullScan() { watcher_->FullScanAsync(); }
2018-02-27 18:06:05 +01:00
2019-06-30 21:06:07 +02:00
void SCollection::AbortScan() { watcher_->Stop(); }
void SCollection::Rescan(const SongList &songs) {
qLog(Debug) << "Rescan" << songs.size() << "songs";
if (!songs.isEmpty()) watcher_->RescanTracksAsync(songs);
}
2018-07-01 22:26:46 +02:00
void SCollection::PauseWatcher() { watcher_->SetRescanPausedAsync(true); }
2018-02-27 18:06:05 +01:00
2018-07-01 22:26:46 +02:00
void SCollection::ResumeWatcher() { watcher_->SetRescanPausedAsync(false); }
void SCollection::ReloadSettings() {
2018-02-27 18:06:05 +01:00
watcher_->ReloadSettingsAsync();
model_->ReloadSettings();
2018-02-27 18:06:05 +01:00
}
2018-07-01 22:26:46 +02:00
void SCollection::Stopped() {
2018-02-27 18:06:05 +01:00
CurrentSongChanged(Song());
}
2019-04-08 18:46:11 +02:00
void SCollection::CurrentSongChanged(const Song &song) { // FIXME
2018-10-02 00:38:52 +02:00
2019-09-15 20:27:32 +02:00
Q_UNUSED(song);
2018-02-27 18:06:05 +01:00
TagReaderReply *reply = nullptr;
if (reply) {
connect(reply, SIGNAL(Finished(bool)), reply, SLOT(deleteLater()));
}
}