Lazy initialise everything in Application.
This commit is contained in:
parent
6844dcc140
commit
f2daa772c1
@ -41,6 +41,13 @@ class Lazy {
|
|||||||
|
|
||||||
T* operator->() const { return get(); }
|
T* operator->() const { return get(); }
|
||||||
|
|
||||||
|
// Returns true if the object is not yet initialised.
|
||||||
|
explicit operator bool() const { return ptr_; }
|
||||||
|
|
||||||
|
// Deletes the underlying object and will re-run the initialisation function
|
||||||
|
// if the object is requested again.
|
||||||
|
void reset() { ptr_.reset(nullptr); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CheckInitialised() const {
|
void CheckInitialised() const {
|
||||||
if (!ptr_) {
|
if (!ptr_) {
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
@ -202,7 +204,8 @@ QDebug CreateLogger(Level level, const QString& class_name, int line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QDebug ret(type);
|
QDebug ret(type);
|
||||||
ret.nospace() << kMessageHandlerMagic << QDateTime::currentDateTime()
|
ret.nospace() << kMessageHandlerMagic
|
||||||
|
<< QDateTime::currentDateTime()
|
||||||
.toString("hh:mm:ss.zzz")
|
.toString("hh:mm:ss.zzz")
|
||||||
.toAscii()
|
.toAscii()
|
||||||
.constData() << level_name
|
.constData() << level_name
|
||||||
@ -257,7 +260,8 @@ void DumpStackTrace() {
|
|||||||
backtrace_symbols(reinterpret_cast<void**>(&callstack), callstack_size);
|
backtrace_symbols(reinterpret_cast<void**>(&callstack), callstack_size);
|
||||||
// Start from 1 to skip ourself.
|
// Start from 1 to skip ourself.
|
||||||
for (int i = 1; i < callstack_size; ++i) {
|
for (int i = 1; i < callstack_size; ++i) {
|
||||||
qLog(Debug) << DemangleSymbol(QString::fromAscii(symbols[i]));
|
std::cerr << DemangleSymbol(QString::fromAscii(symbols[i])).toStdString()
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
free(symbols);
|
free(symbols);
|
||||||
#else
|
#else
|
||||||
@ -269,7 +273,7 @@ void DumpStackTrace() {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
QString print_duration(T duration, const std::string& unit) {
|
QString print_duration(T duration, const std::string& unit) {
|
||||||
return QString("%1%2").arg(duration.count()).arg(unit.c_str());
|
return QString("%1%2").arg(duration.count()).arg(unit.c_str());
|
||||||
}
|
}
|
||||||
|
@ -21,29 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "appearance.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "database.h"
|
|
||||||
#include "player.h"
|
|
||||||
#include "tagreaderclient.h"
|
|
||||||
#include "taskmanager.h"
|
|
||||||
#include "covers/albumcoverloader.h"
|
|
||||||
#include "covers/coverproviders.h"
|
|
||||||
#include "covers/currentartloader.h"
|
|
||||||
#include "devices/devicemanager.h"
|
|
||||||
#include "internet/core/internetmodel.h"
|
|
||||||
#include "globalsearch/globalsearch.h"
|
|
||||||
#include "library/library.h"
|
|
||||||
#include "library/librarybackend.h"
|
|
||||||
#include "networkremote/networkremote.h"
|
|
||||||
#include "networkremote/networkremotehelper.h"
|
|
||||||
#include "playlist/playlistbackend.h"
|
|
||||||
#include "playlist/playlistmanager.h"
|
|
||||||
#include "internet/podcasts/gpoddersync.h"
|
|
||||||
#include "internet/podcasts/podcastbackend.h"
|
|
||||||
#include "internet/podcasts/podcastdeleter.h"
|
|
||||||
#include "internet/podcasts/podcastdownloader.h"
|
|
||||||
#include "internet/podcasts/podcastupdater.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
#include "internet/lastfm/lastfmservice.h"
|
#include "internet/lastfm/lastfmservice.h"
|
||||||
@ -58,95 +35,96 @@ bool Application::kIsPortable = false;
|
|||||||
|
|
||||||
Application::Application(QObject* parent)
|
Application::Application(QObject* parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
tag_reader_client_(nullptr),
|
tag_reader_client_([&](){
|
||||||
database_(nullptr),
|
TagReaderClient* client = new TagReaderClient(this);
|
||||||
album_cover_loader_(nullptr),
|
MoveToNewThread(client);
|
||||||
playlist_backend_(nullptr),
|
client->Start();
|
||||||
podcast_backend_(nullptr),
|
return client;
|
||||||
appearance_(nullptr),
|
}),
|
||||||
cover_providers_(nullptr),
|
database_([&]() {
|
||||||
task_manager_(nullptr),
|
Database* db = new Database(this, this);
|
||||||
player_(nullptr),
|
MoveToNewThread(db);
|
||||||
playlist_manager_(nullptr),
|
DoInAMinuteOrSo(db, SLOT(DoBackup()));
|
||||||
current_art_loader_(nullptr),
|
return db;
|
||||||
global_search_(nullptr),
|
}),
|
||||||
internet_model_(nullptr),
|
album_cover_loader_([&]() {
|
||||||
library_(nullptr),
|
AlbumCoverLoader* loader = new AlbumCoverLoader(this);
|
||||||
device_manager_(nullptr),
|
MoveToNewThread(loader);
|
||||||
podcast_updater_(nullptr),
|
return loader;
|
||||||
podcast_deleter_(nullptr),
|
}),
|
||||||
podcast_downloader_(nullptr),
|
playlist_backend_([&]() {
|
||||||
gpodder_sync_(nullptr),
|
PlaylistBackend* backend = new PlaylistBackend(this, this);
|
||||||
moodbar_loader_(nullptr),
|
MoveToThread(backend, database_->thread());
|
||||||
moodbar_controller_(nullptr),
|
return backend;
|
||||||
network_remote_(nullptr),
|
}),
|
||||||
network_remote_helper_(nullptr),
|
podcast_backend_([&]() {
|
||||||
scrobbler_(nullptr) {
|
PodcastBackend* backend = new PodcastBackend(this, this);
|
||||||
tag_reader_client_ = new TagReaderClient(this);
|
MoveToThread(backend, database_->thread());
|
||||||
MoveToNewThread(tag_reader_client_);
|
return backend;
|
||||||
tag_reader_client_->Start();
|
}),
|
||||||
|
appearance_([=]() { return new Appearance(this); }),
|
||||||
database_ = new Database(this, this);
|
cover_providers_([=]() { return new CoverProviders(this); }),
|
||||||
MoveToNewThread(database_);
|
task_manager_([=]() { return new TaskManager(this); }),
|
||||||
|
player_([=]() { return new Player(this, this); }),
|
||||||
album_cover_loader_ = new AlbumCoverLoader(this);
|
playlist_manager_([=]() { return new PlaylistManager(this); }),
|
||||||
MoveToNewThread(album_cover_loader_);
|
current_art_loader_([=]() { return new CurrentArtLoader(this, this); }),
|
||||||
|
global_search_([=]() { return new GlobalSearch(this, this); }),
|
||||||
playlist_backend_ = new PlaylistBackend(this, this);
|
internet_model_([=]() { return new InternetModel(this, this); }),
|
||||||
MoveToThread(playlist_backend_, database_->thread());
|
library_([=]() { return new Library(this, this); }),
|
||||||
|
device_manager_([=]() { return new DeviceManager(this, this); }),
|
||||||
podcast_backend_ = new PodcastBackend(this, this);
|
podcast_updater_([=]() { return new PodcastUpdater(this, this); }),
|
||||||
MoveToThread(podcast_backend_, database_->thread());
|
podcast_deleter_([=]() {
|
||||||
|
PodcastDeleter* deleter = new PodcastDeleter(this, this);
|
||||||
appearance_ = new Appearance(this);
|
MoveToNewThread(deleter);
|
||||||
cover_providers_ = new CoverProviders(this);
|
return deleter;
|
||||||
task_manager_ = new TaskManager(this);
|
}),
|
||||||
player_ = new Player(this, this);
|
podcast_downloader_([=]() {
|
||||||
playlist_manager_ = new PlaylistManager(this, this);
|
return new PodcastDownloader(this, this);
|
||||||
current_art_loader_ = new CurrentArtLoader(this, this);
|
}),
|
||||||
global_search_ = new GlobalSearch(this, this);
|
gpodder_sync_([=]() { return new GPodderSync(this, this); }),
|
||||||
internet_model_ = new InternetModel(this, this);
|
moodbar_loader_([=]() {
|
||||||
library_ = new Library(this, this);
|
|
||||||
device_manager_ = new DeviceManager(this, this);
|
|
||||||
podcast_updater_ = new PodcastUpdater(this, this);
|
|
||||||
|
|
||||||
podcast_deleter_ = new PodcastDeleter(this, this);
|
|
||||||
MoveToNewThread(podcast_deleter_);
|
|
||||||
|
|
||||||
podcast_downloader_ = new PodcastDownloader(this, this);
|
|
||||||
gpodder_sync_ = new GPodderSync(this, this);
|
|
||||||
|
|
||||||
#ifdef HAVE_MOODBAR
|
#ifdef HAVE_MOODBAR
|
||||||
moodbar_loader_ = new MoodbarLoader(this, this);
|
return new MoodbarLoader(this, this);
|
||||||
moodbar_controller_ = new MoodbarController(this, this);
|
#else
|
||||||
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
}),
|
||||||
// Network Remote
|
moodbar_controller_([=]() {
|
||||||
network_remote_ = new NetworkRemote(this);
|
#ifdef HAVE_MOODBAR
|
||||||
MoveToNewThread(network_remote_);
|
return new MoodbarController(this, this);
|
||||||
|
#else
|
||||||
// This must be before libraray_->Init();
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}),
|
||||||
|
network_remote_([=]() {
|
||||||
|
NetworkRemote* remote = new NetworkRemote(this);
|
||||||
|
MoveToNewThread(remote);
|
||||||
|
return remote;
|
||||||
|
}),
|
||||||
|
network_remote_helper_([=]() {
|
||||||
|
return new NetworkRemoteHelper(this);
|
||||||
|
}),
|
||||||
|
scrobbler_([=]() {
|
||||||
|
#ifdef HAVE_LIBLASTFM
|
||||||
|
return new LastFMService(this, this);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}) {
|
||||||
|
// This must be before library_->Init();
|
||||||
// In the constructor the helper waits for the signal
|
// In the constructor the helper waits for the signal
|
||||||
// PlaylistManagerInitialized
|
// PlaylistManagerInitialized
|
||||||
// to start the remote. Without the playlist manager clementine can
|
// to start the remote. Without the playlist manager clementine can
|
||||||
// crash when a client connects before the manager is initialized!
|
// crash when a client connects before the manager is initialized!
|
||||||
network_remote_helper_ = new NetworkRemoteHelper(this);
|
network_remote_helper_.get();
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
|
||||||
scrobbler_ = new LastFMService(this, this);
|
|
||||||
#endif // HAVE_LIBLASTFM
|
|
||||||
|
|
||||||
library_->Init();
|
library_->Init();
|
||||||
|
|
||||||
DoInAMinuteOrSo(database_, SLOT(DoBackup()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {
|
Application::~Application() {
|
||||||
// It's important that the device manager is deleted before the database.
|
// It's important that the device manager is deleted before the database.
|
||||||
// Deleting the database deletes all objects that have been created in its
|
// Deleting the database deletes all objects that have been created in its
|
||||||
// thread, including some device library backends.
|
// thread, including some device library backends.
|
||||||
delete device_manager_;
|
device_manager_.reset();
|
||||||
device_manager_ = nullptr;
|
|
||||||
|
|
||||||
for (QObject* object : objects_in_threads_) {
|
for (QObject* object : objects_in_threads_) {
|
||||||
object->deleteLater();
|
object->deleteLater();
|
||||||
|
@ -22,37 +22,37 @@
|
|||||||
#ifndef CORE_APPLICATION_H_
|
#ifndef CORE_APPLICATION_H_
|
||||||
#define CORE_APPLICATION_H_
|
#define CORE_APPLICATION_H_
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "core/appearance.h"
|
||||||
|
#include "core/database.h"
|
||||||
|
#include "core/lazy.h"
|
||||||
|
#include "core/player.h"
|
||||||
|
#include "covers/albumcoverloader.h"
|
||||||
|
#include "covers/coverproviders.h"
|
||||||
|
#include "covers/currentartloader.h"
|
||||||
|
#include "devices/devicemanager.h"
|
||||||
|
#include "globalsearch/globalsearch.h"
|
||||||
|
#include "internet/core/internetmodel.h"
|
||||||
|
#include "internet/core/scrobbler.h"
|
||||||
|
#include "internet/podcasts/gpoddersync.h"
|
||||||
|
#include "internet/podcasts/podcastbackend.h"
|
||||||
|
#include "internet/podcasts/podcastdeleter.h"
|
||||||
|
#include "internet/podcasts/podcastdownloader.h"
|
||||||
|
#include "internet/podcasts/podcastupdater.h"
|
||||||
|
#include "library/librarybackend.h"
|
||||||
|
#include "library/library.h"
|
||||||
|
#include "moodbar/moodbarcontroller.h"
|
||||||
|
#include "moodbar/moodbarloader.h"
|
||||||
|
#include "networkremote/networkremote.h"
|
||||||
|
#include "networkremote/networkremotehelper.h"
|
||||||
|
#include "playlist/playlistbackend.h"
|
||||||
|
#include "playlist/playlistmanager.h"
|
||||||
|
#include "tagreaderclient.h"
|
||||||
|
#include "taskmanager.h"
|
||||||
#include "ui/settingsdialog.h"
|
#include "ui/settingsdialog.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class AlbumCoverLoader;
|
|
||||||
class Appearance;
|
|
||||||
class CoverProviders;
|
|
||||||
class CurrentArtLoader;
|
|
||||||
class Database;
|
|
||||||
class DeviceManager;
|
|
||||||
class GlobalSearch;
|
|
||||||
class GPodderSync;
|
|
||||||
class InternetModel;
|
|
||||||
class Library;
|
|
||||||
class LibraryBackend;
|
|
||||||
class LibraryModel;
|
|
||||||
class MoodbarController;
|
|
||||||
class MoodbarLoader;
|
|
||||||
class NetworkRemote;
|
|
||||||
class NetworkRemoteHelper;
|
|
||||||
class Player;
|
|
||||||
class PlaylistBackend;
|
|
||||||
class PodcastDeleter;
|
|
||||||
class PodcastDownloader;
|
|
||||||
class PlaylistManager;
|
|
||||||
class PodcastBackend;
|
|
||||||
class PodcastUpdater;
|
|
||||||
class Scrobbler;
|
|
||||||
class TagReaderClient;
|
|
||||||
class TaskManager;
|
|
||||||
|
|
||||||
class Application : public QObject {
|
class Application : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -68,32 +68,42 @@ class Application : public QObject {
|
|||||||
QString language_without_region() const;
|
QString language_without_region() const;
|
||||||
void set_language_name(const QString& name) { language_name_ = name; }
|
void set_language_name(const QString& name) { language_name_ = name; }
|
||||||
|
|
||||||
TagReaderClient* tag_reader_client() const { return tag_reader_client_; }
|
TagReaderClient* tag_reader_client() const {
|
||||||
Database* database() const { return database_; }
|
return tag_reader_client_.get();
|
||||||
AlbumCoverLoader* album_cover_loader() const { return album_cover_loader_; }
|
|
||||||
PlaylistBackend* playlist_backend() const { return playlist_backend_; }
|
|
||||||
PodcastBackend* podcast_backend() const { return podcast_backend_; }
|
|
||||||
Appearance* appearance() const { return appearance_; }
|
|
||||||
CoverProviders* cover_providers() const { return cover_providers_; }
|
|
||||||
TaskManager* task_manager() const { return task_manager_; }
|
|
||||||
Player* player() const { return player_; }
|
|
||||||
PlaylistManager* playlist_manager() const { return playlist_manager_; }
|
|
||||||
CurrentArtLoader* current_art_loader() const { return current_art_loader_; }
|
|
||||||
GlobalSearch* global_search() const { return global_search_; }
|
|
||||||
InternetModel* internet_model() const { return internet_model_; }
|
|
||||||
Library* library() const { return library_; }
|
|
||||||
DeviceManager* device_manager() const { return device_manager_; }
|
|
||||||
PodcastUpdater* podcast_updater() const { return podcast_updater_; }
|
|
||||||
PodcastDeleter* podcast_deleter() const { return podcast_deleter_; }
|
|
||||||
PodcastDownloader* podcast_downloader() const { return podcast_downloader_; }
|
|
||||||
GPodderSync* gpodder_sync() const { return gpodder_sync_; }
|
|
||||||
MoodbarLoader* moodbar_loader() const { return moodbar_loader_; }
|
|
||||||
MoodbarController* moodbar_controller() const { return moodbar_controller_; }
|
|
||||||
NetworkRemote* network_remote() const { return network_remote_; }
|
|
||||||
NetworkRemoteHelper* network_remote_helper() const {
|
|
||||||
return network_remote_helper_;
|
|
||||||
}
|
}
|
||||||
Scrobbler* scrobbler() const { return scrobbler_; }
|
Database* database() const { return database_.get(); }
|
||||||
|
AlbumCoverLoader* album_cover_loader() const {
|
||||||
|
return album_cover_loader_.get();
|
||||||
|
}
|
||||||
|
PlaylistBackend* playlist_backend() const { return playlist_backend_.get(); }
|
||||||
|
PodcastBackend* podcast_backend() const { return podcast_backend_.get(); }
|
||||||
|
Appearance* appearance() const { return appearance_.get(); }
|
||||||
|
CoverProviders* cover_providers() const { return cover_providers_.get(); }
|
||||||
|
TaskManager* task_manager() const { return task_manager_.get(); }
|
||||||
|
Player* player() const { return player_.get(); }
|
||||||
|
PlaylistManager* playlist_manager() const { return playlist_manager_.get(); }
|
||||||
|
CurrentArtLoader* current_art_loader() const {
|
||||||
|
return current_art_loader_.get();
|
||||||
|
}
|
||||||
|
GlobalSearch* global_search() const { return global_search_.get(); }
|
||||||
|
InternetModel* internet_model() const { return internet_model_.get(); }
|
||||||
|
Library* library() const { return library_.get(); }
|
||||||
|
DeviceManager* device_manager() const { return device_manager_.get(); }
|
||||||
|
PodcastUpdater* podcast_updater() const { return podcast_updater_.get(); }
|
||||||
|
PodcastDeleter* podcast_deleter() const { return podcast_deleter_.get(); }
|
||||||
|
PodcastDownloader* podcast_downloader() const {
|
||||||
|
return podcast_downloader_.get();
|
||||||
|
}
|
||||||
|
GPodderSync* gpodder_sync() const { return gpodder_sync_.get(); }
|
||||||
|
MoodbarLoader* moodbar_loader() const { return moodbar_loader_.get(); }
|
||||||
|
MoodbarController* moodbar_controller() const {
|
||||||
|
return moodbar_controller_.get();
|
||||||
|
}
|
||||||
|
NetworkRemote* network_remote() const { return network_remote_.get(); }
|
||||||
|
NetworkRemoteHelper* network_remote_helper() const {
|
||||||
|
return network_remote_helper_.get();
|
||||||
|
}
|
||||||
|
Scrobbler* scrobbler() const { return scrobbler_.get(); }
|
||||||
|
|
||||||
LibraryBackend* library_backend() const;
|
LibraryBackend* library_backend() const;
|
||||||
LibraryModel* library_model() const;
|
LibraryModel* library_model() const;
|
||||||
@ -106,7 +116,7 @@ class Application : public QObject {
|
|||||||
void ReloadSettings();
|
void ReloadSettings();
|
||||||
void OpenSettingsDialogAtPage(SettingsDialog::Page page);
|
void OpenSettingsDialogAtPage(SettingsDialog::Page page);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ErrorAdded(const QString& message);
|
void ErrorAdded(const QString& message);
|
||||||
void SettingsChanged();
|
void SettingsChanged();
|
||||||
void SettingsDialogRequested(SettingsDialog::Page page);
|
void SettingsDialogRequested(SettingsDialog::Page page);
|
||||||
@ -114,30 +124,30 @@ class Application : public QObject {
|
|||||||
private:
|
private:
|
||||||
QString language_name_;
|
QString language_name_;
|
||||||
|
|
||||||
TagReaderClient* tag_reader_client_;
|
Lazy<TagReaderClient> tag_reader_client_;
|
||||||
Database* database_;
|
Lazy<Database> database_;
|
||||||
AlbumCoverLoader* album_cover_loader_;
|
Lazy<AlbumCoverLoader> album_cover_loader_;
|
||||||
PlaylistBackend* playlist_backend_;
|
Lazy<PlaylistBackend> playlist_backend_;
|
||||||
PodcastBackend* podcast_backend_;
|
Lazy<PodcastBackend> podcast_backend_;
|
||||||
Appearance* appearance_;
|
Lazy<Appearance> appearance_;
|
||||||
CoverProviders* cover_providers_;
|
Lazy<CoverProviders> cover_providers_;
|
||||||
TaskManager* task_manager_;
|
Lazy<TaskManager> task_manager_;
|
||||||
Player* player_;
|
Lazy<Player> player_;
|
||||||
PlaylistManager* playlist_manager_;
|
Lazy<PlaylistManager> playlist_manager_;
|
||||||
CurrentArtLoader* current_art_loader_;
|
Lazy<CurrentArtLoader> current_art_loader_;
|
||||||
GlobalSearch* global_search_;
|
Lazy<GlobalSearch> global_search_;
|
||||||
InternetModel* internet_model_;
|
Lazy<InternetModel> internet_model_;
|
||||||
Library* library_;
|
Lazy<Library> library_;
|
||||||
DeviceManager* device_manager_;
|
Lazy<DeviceManager> device_manager_;
|
||||||
PodcastUpdater* podcast_updater_;
|
Lazy<PodcastUpdater> podcast_updater_;
|
||||||
PodcastDeleter* podcast_deleter_;
|
Lazy<PodcastDeleter> podcast_deleter_;
|
||||||
PodcastDownloader* podcast_downloader_;
|
Lazy<PodcastDownloader> podcast_downloader_;
|
||||||
GPodderSync* gpodder_sync_;
|
Lazy<GPodderSync> gpodder_sync_;
|
||||||
MoodbarLoader* moodbar_loader_;
|
Lazy<MoodbarLoader> moodbar_loader_;
|
||||||
MoodbarController* moodbar_controller_;
|
Lazy<MoodbarController> moodbar_controller_;
|
||||||
NetworkRemote* network_remote_;
|
Lazy<NetworkRemote> network_remote_;
|
||||||
NetworkRemoteHelper* network_remote_helper_;
|
Lazy<NetworkRemoteHelper> network_remote_helper_;
|
||||||
Scrobbler* scrobbler_;
|
Lazy<Scrobbler> scrobbler_;
|
||||||
|
|
||||||
QList<QObject*> objects_in_threads_;
|
QList<QObject*> objects_in_threads_;
|
||||||
QList<QThread*> threads_;
|
QList<QThread*> threads_;
|
||||||
|
@ -17,15 +17,18 @@
|
|||||||
|
|
||||||
#include "networkremote.h"
|
#include "networkremote.h"
|
||||||
|
|
||||||
#include "core/logging.h"
|
|
||||||
#include "covers/currentartloader.h"
|
|
||||||
#include "networkremote/zeroconf.h"
|
|
||||||
#include "playlist/playlistmanager.h"
|
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
#include <QTcpServer>
|
||||||
|
|
||||||
|
#include "core/logging.h"
|
||||||
|
#include "covers/currentartloader.h"
|
||||||
|
#include "networkremote/incomingdataparser.h"
|
||||||
|
#include "networkremote/outgoingdatacreator.h"
|
||||||
|
#include "networkremote/zeroconf.h"
|
||||||
|
#include "playlist/playlistmanager.h"
|
||||||
|
|
||||||
const char* NetworkRemote::kSettingsGroup = "NetworkRemote";
|
const char* NetworkRemote::kSettingsGroup = "NetworkRemote";
|
||||||
const quint16 NetworkRemote::kDefaultServerPort = 5500;
|
const quint16 NetworkRemote::kDefaultServerPort = 5500;
|
||||||
|
@ -3,14 +3,17 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <QTcpServer>
|
#include <QList>
|
||||||
#include <QTcpSocket>
|
#include <QObject>
|
||||||
|
|
||||||
#include "core/player.h"
|
class Application;
|
||||||
#include "core/application.h"
|
class IncomingDataParser;
|
||||||
#include "incomingdataparser.h"
|
class OutgoingDataCreator;
|
||||||
#include "outgoingdatacreator.h"
|
class QHostAddress;
|
||||||
#include "remoteclient.h"
|
class QImage;
|
||||||
|
class QTcpServer;
|
||||||
|
class QTcpSocket;
|
||||||
|
class RemoteClient;
|
||||||
|
|
||||||
class NetworkRemote : public QObject {
|
class NetworkRemote : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -15,10 +15,11 @@
|
|||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "core/logging.h"
|
#include "networkremote/networkremotehelper.h"
|
||||||
|
|
||||||
#include "networkremote.h"
|
#include "core/application.h"
|
||||||
#include "networkremotehelper.h"
|
#include "core/logging.h"
|
||||||
|
#include "networkremote/networkremote.h"
|
||||||
|
|
||||||
NetworkRemoteHelper* NetworkRemoteHelper::sInstance = nullptr;
|
NetworkRemoteHelper* NetworkRemoteHelper::sInstance = nullptr;
|
||||||
|
|
||||||
|
@ -17,14 +17,15 @@
|
|||||||
|
|
||||||
#include "songsender.h"
|
#include "songsender.h"
|
||||||
|
|
||||||
#include "networkremote.h"
|
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/utilities.h"
|
#include "core/utilities.h"
|
||||||
#include "library/librarybackend.h"
|
#include "library/librarybackend.h"
|
||||||
|
#include "networkremote/networkremote.h"
|
||||||
|
#include "networkremote/outgoingdatacreator.h"
|
||||||
|
#include "networkremote/remoteclient.h"
|
||||||
#include "playlist/playlistitem.h"
|
#include "playlist/playlistitem.h"
|
||||||
|
|
||||||
const quint32 SongSender::kFileChunkSize = 100000; // in Bytes
|
const quint32 SongSender::kFileChunkSize = 100000; // in Bytes
|
||||||
@ -32,16 +33,18 @@ const quint32 SongSender::kFileChunkSize = 100000; // in Bytes
|
|||||||
SongSender::SongSender(Application* app, RemoteClient* client)
|
SongSender::SongSender(Application* app, RemoteClient* client)
|
||||||
: app_(app),
|
: app_(app),
|
||||||
client_(client),
|
client_(client),
|
||||||
transcoder_(new Transcoder(this, NetworkRemote::kTranscoderSettingPostfix)) {
|
transcoder_(
|
||||||
|
new Transcoder(this, NetworkRemote::kTranscoderSettingPostfix)) {
|
||||||
QSettings s;
|
QSettings s;
|
||||||
s.beginGroup(NetworkRemote::kSettingsGroup);
|
s.beginGroup(NetworkRemote::kSettingsGroup);
|
||||||
|
|
||||||
transcode_lossless_files_ = s.value("convert_lossless", false).toBool();
|
transcode_lossless_files_ = s.value("convert_lossless", false).toBool();
|
||||||
|
|
||||||
// Load preset
|
// Load preset
|
||||||
QString last_output_format = s.value("last_output_format", "audio/x-vorbis").toString();
|
QString last_output_format =
|
||||||
|
s.value("last_output_format", "audio/x-vorbis").toString();
|
||||||
QList<TranscoderPreset> presets = transcoder_->GetAllPresets();
|
QList<TranscoderPreset> presets = transcoder_->GetAllPresets();
|
||||||
for (int i = 0; i<presets.count(); ++i) {
|
for (int i = 0; i < presets.count(); ++i) {
|
||||||
if (last_output_format == presets.at(i).codec_mimetype_) {
|
if (last_output_format == presets.at(i).codec_mimetype_) {
|
||||||
transcoder_preset_ = presets.at(i);
|
transcoder_preset_ = presets.at(i);
|
||||||
break;
|
break;
|
||||||
@ -59,7 +62,8 @@ SongSender::SongSender(Application* app, RemoteClient* client)
|
|||||||
SongSender::~SongSender() {
|
SongSender::~SongSender() {
|
||||||
disconnect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)), this,
|
disconnect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)), this,
|
||||||
SLOT(TranscodeJobComplete(QString, QString, bool)));
|
SLOT(TranscodeJobComplete(QString, QString, bool)));
|
||||||
disconnect(transcoder_, SIGNAL(AllJobsComplete()), this, SLOT(StartTransfer()));
|
disconnect(transcoder_, SIGNAL(AllJobsComplete()), this,
|
||||||
|
SLOT(StartTransfer()));
|
||||||
transcoder_->Cancel();
|
transcoder_->Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +106,7 @@ void SongSender::SendSongs(const pb::remote::RequestDownloadSongs& request) {
|
|||||||
void SongSender::TranscodeLosslessFiles() {
|
void SongSender::TranscodeLosslessFiles() {
|
||||||
for (DownloadItem item : download_queue_) {
|
for (DownloadItem item : download_queue_) {
|
||||||
// Check only lossless files
|
// Check only lossless files
|
||||||
if (!item.song_.IsFileLossless())
|
if (!item.song_.IsFileLossless()) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
// Add the file to the transcoder
|
// Add the file to the transcoder
|
||||||
QString local_file = item.song_.url().toLocalFile();
|
QString local_file = item.song_.url().toLocalFile();
|
||||||
@ -122,7 +125,8 @@ void SongSender::TranscodeLosslessFiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongSender::TranscodeJobComplete(const QString& input, const QString& output, bool success) {
|
void SongSender::TranscodeJobComplete(const QString& input,
|
||||||
|
const QString& output, bool success) {
|
||||||
qLog(Debug) << input << "transcoded to" << output << success;
|
qLog(Debug) << input << "transcoded to" << output << success;
|
||||||
|
|
||||||
// If it wasn't successful send original file
|
// If it wasn't successful send original file
|
||||||
@ -204,7 +208,8 @@ void SongSender::OfferNextSong() {
|
|||||||
chunk->set_file_number(item.song_no_);
|
chunk->set_file_number(item.song_no_);
|
||||||
chunk->set_size(file.size());
|
chunk->set_size(file.size());
|
||||||
|
|
||||||
OutgoingDataCreator::CreateSong(item.song_, QImage(), -1, chunk->mutable_song_metadata());
|
OutgoingDataCreator::CreateSong(item.song_, QImage(), -1,
|
||||||
|
chunk->mutable_song_metadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
client_->SendData(&msg);
|
client_->SendData(&msg);
|
||||||
@ -215,8 +220,7 @@ void SongSender::ResponseSongOffer(bool accepted) {
|
|||||||
|
|
||||||
// Get the item and send the single song
|
// Get the item and send the single song
|
||||||
DownloadItem item = download_queue_.dequeue();
|
DownloadItem item = download_queue_.dequeue();
|
||||||
if (accepted)
|
if (accepted) SendSingleSong(item);
|
||||||
SendSingleSong(item);
|
|
||||||
|
|
||||||
// And offer the next song
|
// And offer the next song
|
||||||
OfferNextSong();
|
OfferNextSong();
|
||||||
@ -273,7 +277,8 @@ void SongSender::SendSingleSong(DownloadItem download_item) {
|
|||||||
int i = app_->playlist_manager()->active()->current_row();
|
int i = app_->playlist_manager()->active()->current_row();
|
||||||
pb::remote::SongMetadata* song_metadata =
|
pb::remote::SongMetadata* song_metadata =
|
||||||
msg.mutable_response_song_file_chunk()->mutable_song_metadata();
|
msg.mutable_response_song_file_chunk()->mutable_song_metadata();
|
||||||
OutgoingDataCreator::CreateSong(download_item.song_, null_image, i,song_metadata);
|
OutgoingDataCreator::CreateSong(download_item.song_, null_image, i,
|
||||||
|
song_metadata);
|
||||||
|
|
||||||
// if the file was transcoded, we have to change the filename and filesize
|
// if the file was transcoded, we have to change the filename and filesize
|
||||||
if (is_transcoded) {
|
if (is_transcoded) {
|
||||||
@ -341,7 +346,7 @@ void SongSender::SendPlaylist(int playlist_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongSender::SendUrls(const pb::remote::RequestDownloadSongs &request) {
|
void SongSender::SendUrls(const pb::remote::RequestDownloadSongs& request) {
|
||||||
SongList song_list;
|
SongList song_list;
|
||||||
|
|
||||||
// First gather all valid songs
|
// First gather all valid songs
|
||||||
|
@ -15,18 +15,23 @@
|
|||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "iconloader.h"
|
|
||||||
#include "networkremotesettingspage.h"
|
#include "networkremotesettingspage.h"
|
||||||
#include "ui_networkremotesettingspage.h"
|
#include "ui_networkremotesettingspage.h"
|
||||||
|
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QHostInfo>
|
||||||
|
#include <QNetworkInterface>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include "core/application.h"
|
||||||
#include "networkremote/networkremote.h"
|
#include "networkremote/networkremote.h"
|
||||||
#include "networkremote/networkremotehelper.h"
|
#include "networkremote/networkremotehelper.h"
|
||||||
#include "transcoder/transcoder.h"
|
#include "transcoder/transcoder.h"
|
||||||
#include "transcoder/transcoderoptionsdialog.h"
|
#include "transcoder/transcoderoptionsdialog.h"
|
||||||
|
#include "ui/iconloader.h"
|
||||||
#include <QDesktopServices>
|
#include "ui/settingsdialog.h"
|
||||||
#include <QSettings>
|
|
||||||
#include <QHostInfo>
|
|
||||||
#include <QNetworkInterface>
|
|
||||||
|
|
||||||
const char* NetworkRemoteSettingsPage::kPlayStoreUrl =
|
const char* NetworkRemoteSettingsPage::kPlayStoreUrl =
|
||||||
"https://play.google.com/store/apps/details?id=de.qspool.clementineremote";
|
"https://play.google.com/store/apps/details?id=de.qspool.clementineremote";
|
||||||
@ -83,10 +88,12 @@ void NetworkRemoteSettingsPage::Load() {
|
|||||||
ui_->auth_code->setValue(s.value("auth_code", qrand() % 100000).toInt());
|
ui_->auth_code->setValue(s.value("auth_code", qrand() % 100000).toInt());
|
||||||
|
|
||||||
ui_->allow_downloads->setChecked(s.value("allow_downloads", false).toBool());
|
ui_->allow_downloads->setChecked(s.value("allow_downloads", false).toBool());
|
||||||
ui_->convert_lossless->setChecked(s.value("convert_lossless", false).toBool());
|
ui_->convert_lossless->setChecked(
|
||||||
|
s.value("convert_lossless", false).toBool());
|
||||||
|
|
||||||
// Load settings
|
// Load settings
|
||||||
QString last_output_format = s.value("last_output_format", "audio/x-vorbis").toString();
|
QString last_output_format =
|
||||||
|
s.value("last_output_format", "audio/x-vorbis").toString();
|
||||||
for (int i = 0; i < ui_->format->count(); ++i) {
|
for (int i = 0; i < ui_->format->count(); ++i) {
|
||||||
if (last_output_format ==
|
if (last_output_format ==
|
||||||
ui_->format->itemData(i).value<TranscoderPreset>().codec_mimetype_) {
|
ui_->format->itemData(i).value<TranscoderPreset>().codec_mimetype_) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user