Refactoring
This commit is contained in:
parent
28222b1832
commit
b97b772b2e
|
@ -176,9 +176,11 @@ if(UNIX AND NOT APPLE)
|
|||
endif()
|
||||
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
|
||||
pkg_check_modules(GOBJECT REQUIRED IMPORTED_TARGET gobject-2.0)
|
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||
if(GIO_FOUND AND UNIX)
|
||||
if(UNIX AND NOT APPLE)
|
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||
if(GIO_FOUND AND UNIX)
|
||||
pkg_check_modules(GIO_UNIX IMPORTED_TARGET gio-unix-2.0)
|
||||
endif()
|
||||
endif()
|
||||
pkg_check_modules(LIBCDIO IMPORTED_TARGET libcdio)
|
||||
pkg_check_modules(GSTREAMER REQUIRED IMPORTED_TARGET gstreamer-1.0)
|
||||
|
@ -327,12 +329,10 @@ optional_component(UDISKS2 ON "Devices: UDisks2 backend"
|
|||
|
||||
optional_component(GIO ON "Devices: GIO device backend"
|
||||
DEPENDS "libgio" GIO_FOUND
|
||||
DEPENDS "Unix or Windows" "NOT APPLE"
|
||||
)
|
||||
|
||||
optional_component(GIO_UNIX ON "Devices: GIO device backend (Unix support)"
|
||||
DEPENDS "libgio-unix" GIO_UNIX_FOUND
|
||||
DEPENDS "Unix or Windows" "NOT APPLE"
|
||||
)
|
||||
|
||||
optional_component(AUDIOCD ON "Devices: Audio CD support"
|
||||
|
@ -404,14 +404,11 @@ endif()
|
|||
|
||||
set(SOURCES
|
||||
src/core/logging.cpp
|
||||
src/core/mainwindow.cpp
|
||||
src/core/application.cpp
|
||||
src/core/player.cpp
|
||||
src/core/commandlineoptions.cpp
|
||||
src/core/database.cpp
|
||||
src/core/memorydatabase.cpp
|
||||
src/core/sqlquery.cpp
|
||||
src/core/sqlrow.cpp
|
||||
src/core/metatypes.cpp
|
||||
src/core/deletefiles.cpp
|
||||
src/core/filesystemmusicstorage.cpp
|
||||
src/core/filesystemwatcherinterface.cpp
|
||||
|
@ -427,20 +424,29 @@ set(SOURCES
|
|||
src/core/settingsprovider.cpp
|
||||
src/core/signalchecker.cpp
|
||||
src/core/song.cpp
|
||||
src/core/songloader.cpp
|
||||
src/core/stylehelper.cpp
|
||||
src/core/stylesheetloader.cpp
|
||||
src/core/taskmanager.cpp
|
||||
src/core/thread.cpp
|
||||
src/core/urlhandlers.cpp
|
||||
src/core/urlhandler.cpp
|
||||
src/core/iconloader.cpp
|
||||
src/core/standarditemiconloader.cpp
|
||||
src/core/scopedtransaction.cpp
|
||||
src/core/translations.cpp
|
||||
src/translations/translations.cpp
|
||||
src/core/systemtrayicon.cpp
|
||||
src/core/localredirectserver.cpp
|
||||
src/core/mimedata.cpp
|
||||
src/core/temporaryfile.cpp
|
||||
|
||||
src/application/mainwindow.cpp
|
||||
src/application/application.cpp
|
||||
src/application/songloader.cpp
|
||||
src/application/metatypes.cpp
|
||||
|
||||
src/player/playerinterface.cpp
|
||||
src/player/player.cpp
|
||||
|
||||
src/utilities/strutils.cpp
|
||||
src/utilities/envutils.cpp
|
||||
src/utilities/colorutils.cpp
|
||||
|
@ -749,14 +755,24 @@ set(SOURCES
|
|||
src/transcoder/transcoderoptionsaac.cpp
|
||||
src/transcoder/transcoderoptionsasf.cpp
|
||||
src/transcoder/transcoderoptionsmp3.cpp
|
||||
|
||||
src/device/connecteddevice.cpp
|
||||
src/device/devicedatabasebackend.cpp
|
||||
src/device/devicelister.cpp
|
||||
src/device/devicemanager.cpp
|
||||
src/device/devicestatefiltermodel.cpp
|
||||
src/device/filesystemdevice.cpp
|
||||
src/device/deviceviewcontainer.cpp
|
||||
src/device/deviceview.cpp
|
||||
src/device/deviceproperties.cpp
|
||||
src/device/deviceinfo.cpp
|
||||
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
src/core/logging.h
|
||||
src/core/mainwindow.h
|
||||
src/core/application.h
|
||||
src/core/player.h
|
||||
src/core/database.h
|
||||
src/core/memorydatabase.h
|
||||
src/core/deletefiles.h
|
||||
src/core/filesystemwatcherinterface.h
|
||||
src/core/mergedproxymodel.h
|
||||
|
@ -766,15 +782,21 @@ set(HEADERS
|
|||
src/core/networktimeouts.h
|
||||
src/core/qtfslistener.h
|
||||
src/core/settings.h
|
||||
src/core/songloader.h
|
||||
src/core/taskmanager.h
|
||||
src/core/thread.h
|
||||
src/core/urlhandlers.h
|
||||
src/core/urlhandler.h
|
||||
src/core/standarditemiconloader.h
|
||||
src/core/mimedata.h
|
||||
src/core/stylesheetloader.h
|
||||
src/core/localredirectserver.h
|
||||
|
||||
src/application/mainwindow.h
|
||||
src/application/application.h
|
||||
src/application/songloader.h
|
||||
src/player/playerinterface.h
|
||||
src/player/player.h
|
||||
|
||||
src/tagreader/tagreaderclient.h
|
||||
src/tagreader/tagreaderreply.h
|
||||
src/tagreader/tagreaderreadfilereply.h
|
||||
|
@ -1020,11 +1042,22 @@ set(HEADERS
|
|||
src/transcoder/transcoderoptionsaac.h
|
||||
src/transcoder/transcoderoptionsasf.h
|
||||
src/transcoder/transcoderoptionsmp3.h
|
||||
|
||||
src/device/connecteddevice.h
|
||||
src/device/devicedatabasebackend.h
|
||||
src/device/devicelister.h
|
||||
src/device/devicemanager.h
|
||||
src/device/devicestatefiltermodel.h
|
||||
src/device/filesystemdevice.h
|
||||
src/device/deviceviewcontainer.h
|
||||
src/device/deviceview.h
|
||||
src/device/deviceproperties.h
|
||||
|
||||
)
|
||||
|
||||
set(UI
|
||||
|
||||
src/core/mainwindow.ui
|
||||
src/application/mainwindow.ui
|
||||
|
||||
src/collection/groupbydialog.ui
|
||||
src/collection/collectionfilterwidget.ui
|
||||
|
@ -1106,6 +1139,10 @@ set(UI
|
|||
src/transcoder/transcoderoptionsspeex.ui
|
||||
src/transcoder/transcoderoptionsasf.ui
|
||||
src/transcoder/transcoderoptionsmp3.ui
|
||||
|
||||
src/device/deviceproperties.ui
|
||||
src/device/deviceviewcontainer.ui
|
||||
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
|
@ -1234,33 +1271,6 @@ if(HAVE_MATE_GLOBALSHORTCUTS)
|
|||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.mate.SettingsDaemon.MediaKeys.xml matesettingsdaemon)
|
||||
endif()
|
||||
|
||||
optional_source(UNIX
|
||||
SOURCES
|
||||
src/device/connecteddevice.cpp
|
||||
src/device/devicedatabasebackend.cpp
|
||||
src/device/devicelister.cpp
|
||||
src/device/devicemanager.cpp
|
||||
src/device/devicestatefiltermodel.cpp
|
||||
src/device/filesystemdevice.cpp
|
||||
src/device/deviceviewcontainer.cpp
|
||||
src/device/deviceview.cpp
|
||||
src/device/deviceproperties.cpp
|
||||
src/device/deviceinfo.cpp
|
||||
HEADERS
|
||||
src/device/connecteddevice.h
|
||||
src/device/devicedatabasebackend.h
|
||||
src/device/devicelister.h
|
||||
src/device/devicemanager.h
|
||||
src/device/devicestatefiltermodel.h
|
||||
src/device/filesystemdevice.h
|
||||
src/device/deviceviewcontainer.h
|
||||
src/device/deviceview.h
|
||||
src/device/deviceproperties.h
|
||||
UI
|
||||
src/device/deviceproperties.ui
|
||||
src/device/deviceviewcontainer.ui
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
optional_source(HAVE_GIO SOURCES src/device/giolister.cpp HEADERS src/device/giolister.h)
|
||||
endif()
|
||||
|
|
|
@ -34,17 +34,16 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "lazy.h"
|
||||
#include "database.h"
|
||||
#include "taskmanager.h"
|
||||
#include "player.h"
|
||||
#include "networkaccessmanager.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/lazy.h"
|
||||
#include "core/database.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "player/player.h"
|
||||
#include "tagreader/tagreaderclient.h"
|
||||
#include "engine/devicefinders.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "device/devicemanager.h"
|
||||
#endif
|
||||
#include "core/urlhandlers.h"
|
||||
#include "device/devicemanager.h"
|
||||
#include "collection/collection.h"
|
||||
#include "playlist/playlistbackend.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
|
@ -120,42 +119,41 @@ class ApplicationImpl {
|
|||
return client;
|
||||
}),
|
||||
database_([app]() {
|
||||
Database *db = new Database(app);
|
||||
app->MoveToNewThread(db);
|
||||
QTimer::singleShot(30s, db, &Database::DoBackup);
|
||||
return db;
|
||||
Database *database = new Database(app->task_manager());
|
||||
app->MoveToNewThread(database);
|
||||
QTimer::singleShot(30s, database, &Database::DoBackup);
|
||||
return database;
|
||||
}),
|
||||
task_manager_([]() { return new TaskManager(); }),
|
||||
player_([app]() { return new Player(app); }),
|
||||
player_([app]() { return new Player(app->task_manager(), app->url_handlers(), app->playlist_manager()); }),
|
||||
network_([]() { return new NetworkAccessManager(); }),
|
||||
device_finders_([]() { return new DeviceFinders(); }),
|
||||
#ifndef Q_OS_WIN
|
||||
device_manager_([app]() { return new DeviceManager(app); }),
|
||||
#endif
|
||||
collection_([app]() { return new SCollection(app); }),
|
||||
url_handlers_([]() { return new UrlHandlers(); }),
|
||||
device_manager_([app]() { return new DeviceManager(app->task_manager(), app->database()); }),
|
||||
collection_([app]() { return new SCollection(app->database(), app->task_manager(), app->album_cover_loader()); }),
|
||||
playlist_backend_([this, app]() {
|
||||
PlaylistBackend *backend = new PlaylistBackend(app);
|
||||
app->MoveToThread(backend, database_->thread());
|
||||
return backend;
|
||||
PlaylistBackend *playlist_backend = new PlaylistBackend(app->database(), app->collection_backend());
|
||||
app->MoveToThread(playlist_backend, database_->thread());
|
||||
return playlist_backend;
|
||||
}),
|
||||
playlist_manager_([app]() { return new PlaylistManager(app); }),
|
||||
playlist_manager_([app]() { return new PlaylistManager(app->player(), app->url_handlers()); }),
|
||||
cover_providers_([app]() {
|
||||
CoverProviders *cover_providers = new CoverProviders();
|
||||
// Initialize the repository of cover providers.
|
||||
cover_providers->AddProvider(new LastFmCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new MusicbrainzCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new DiscogsCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new DeezerCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new MusixmatchCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new OpenTidalCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new LastFmCoverProvider(app->network()));
|
||||
cover_providers->AddProvider(new MusicbrainzCoverProvider(app->network()));
|
||||
cover_providers->AddProvider(new DiscogsCoverProvider(app->network()));
|
||||
cover_providers->AddProvider(new DeezerCoverProvider(app->network()));
|
||||
cover_providers->AddProvider(new MusixmatchCoverProvider(app->network()));
|
||||
cover_providers->AddProvider(new OpenTidalCoverProvider(app->network()));
|
||||
#ifdef HAVE_TIDAL
|
||||
cover_providers->AddProvider(new TidalCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new TidalCoverProvider(app->streaming_services()->Service<TidalService>(), app->network()));
|
||||
#endif
|
||||
#ifdef HAVE_SPOTIFY
|
||||
cover_providers->AddProvider(new SpotifyCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new SpotifyCoverProvider(app->streaming_services()->Service<SpotifyService>(), app->network()));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
cover_providers->AddProvider(new QobuzCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new QobuzCoverProvider(app->streaming_services()->Service<QobuzService>(), app->network()));
|
||||
#endif
|
||||
cover_providers->ReloadSettings();
|
||||
return cover_providers;
|
||||
|
@ -165,7 +163,7 @@ class ApplicationImpl {
|
|||
app->MoveToNewThread(loader);
|
||||
return loader;
|
||||
}),
|
||||
current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app); }),
|
||||
current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app->album_cover_loader()); }),
|
||||
lyrics_providers_([app]() {
|
||||
LyricsProviders *lyrics_providers = new LyricsProviders(app);
|
||||
// Initialize the repository of lyrics providers.
|
||||
|
@ -185,33 +183,33 @@ class ApplicationImpl {
|
|||
streaming_services_([app]() {
|
||||
StreamingServices *streaming_services = new StreamingServices();
|
||||
#ifdef HAVE_SUBSONIC
|
||||
streaming_services->AddService(make_shared<SubsonicService>(app));
|
||||
streaming_services->AddService(make_shared<SubsonicService>(app->task_manager(), app->database(), app->url_handlers(), app->album_cover_loader()));
|
||||
#endif
|
||||
#ifdef HAVE_TIDAL
|
||||
streaming_services->AddService(make_shared<TidalService>(app));
|
||||
streaming_services->AddService(make_shared<TidalService>(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->album_cover_loader()));
|
||||
#endif
|
||||
#ifdef HAVE_SPOTIFY
|
||||
streaming_services->AddService(make_shared<SpotifyService>(app));
|
||||
streaming_services->AddService(make_shared<SpotifyService>(app->task_manager(), app->database(), app->network(), app->album_cover_loader()));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
streaming_services->AddService(make_shared<QobuzService>(app));
|
||||
streaming_services->AddService(make_shared<QobuzService>(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->album_cover_loader()));
|
||||
#endif
|
||||
return streaming_services;
|
||||
}),
|
||||
radio_services_([app]() { return new RadioServices(app); }),
|
||||
radio_services_([app]() { return new RadioServices(app->task_manager(), app->network(), app->database(), app->album_cover_loader()); }),
|
||||
scrobbler_([app]() {
|
||||
AudioScrobbler *scrobbler = new AudioScrobbler(app);
|
||||
scrobbler->AddService(make_shared<LastFMScrobbler>(scrobbler->settings(), app->network()));
|
||||
scrobbler->AddService(make_shared<LibreFMScrobbler>(scrobbler->settings(), app->network()));
|
||||
scrobbler->AddService(make_shared<ListenBrainzScrobbler>(scrobbler->settings(), app->network()));
|
||||
#ifdef HAVE_SUBSONIC
|
||||
scrobbler->AddService(make_shared<SubsonicScrobbler>(scrobbler->settings(), app));
|
||||
scrobbler->AddService(make_shared<SubsonicScrobbler>(scrobbler->settings(), app->streaming_services()->Service<SubsonicService>(), app));
|
||||
#endif
|
||||
return scrobbler;
|
||||
}),
|
||||
#ifdef HAVE_MOODBAR
|
||||
moodbar_loader_([app]() { return new MoodbarLoader(app); }),
|
||||
moodbar_controller_([app]() { return new MoodbarController(app); }),
|
||||
moodbar_controller_([app]() { return new MoodbarController(app->player(), app->moodbar_loader()); }),
|
||||
#endif
|
||||
lastfm_import_([app]() { return new LastFMImport(app->network()); })
|
||||
{}
|
||||
|
@ -222,9 +220,8 @@ class ApplicationImpl {
|
|||
Lazy<Player> player_;
|
||||
Lazy<NetworkAccessManager> network_;
|
||||
Lazy<DeviceFinders> device_finders_;
|
||||
#ifndef Q_OS_WIN
|
||||
Lazy<UrlHandlers> url_handlers_;
|
||||
Lazy<DeviceManager> device_manager_;
|
||||
#endif
|
||||
Lazy<SCollection> collection_;
|
||||
Lazy<PlaylistBackend> playlist_backend_;
|
||||
Lazy<PlaylistManager> playlist_manager_;
|
||||
|
@ -252,7 +249,7 @@ Application::Application(QObject *parent)
|
|||
collection()->Init();
|
||||
tag_reader_client();
|
||||
|
||||
QObject::connect(&*database(), &Database::Error, this, &Application::ErrorAdded);
|
||||
//QObject::connect(&*database(), &Database::Error, this, &Application::ErrorAdded);
|
||||
|
||||
}
|
||||
|
||||
|
@ -298,9 +295,7 @@ void Application::Exit() {
|
|||
<< &*collection()
|
||||
<< &*playlist_backend()
|
||||
<< &*album_cover_loader()
|
||||
#ifndef Q_OS_WIN
|
||||
<< &*device_manager()
|
||||
#endif
|
||||
<< &*streaming_services()
|
||||
<< &*radio_services()->radio_backend();
|
||||
|
||||
|
@ -316,10 +311,8 @@ void Application::Exit() {
|
|||
QObject::connect(&*album_cover_loader(), &AlbumCoverLoader::ExitFinished, this, &Application::ExitReceived);
|
||||
album_cover_loader()->ExitAsync();
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
QObject::connect(&*device_manager(), &DeviceManager::ExitFinished, this, &Application::ExitReceived);
|
||||
device_manager()->Exit();
|
||||
#endif
|
||||
|
||||
QObject::connect(&*streaming_services(), &StreamingServices::ExitFinished, this, &Application::ExitReceived);
|
||||
streaming_services()->Exit();
|
||||
|
@ -345,19 +338,14 @@ void Application::ExitReceived() {
|
|||
|
||||
}
|
||||
|
||||
void Application::AddError(const QString &message) { Q_EMIT ErrorAdded(message); }
|
||||
void Application::ReloadSettings() { Q_EMIT SettingsChanged(); }
|
||||
void Application::OpenSettingsDialogAtPage(SettingsDialog::Page page) { Q_EMIT SettingsDialogRequested(page); }
|
||||
|
||||
SharedPtr<TagReaderClient> Application::tag_reader_client() const { return p_->tag_reader_client_.ptr(); }
|
||||
SharedPtr<Database> Application::database() const { return p_->database_.ptr(); }
|
||||
SharedPtr<TaskManager> Application::task_manager() const { return p_->task_manager_.ptr(); }
|
||||
SharedPtr<Player> Application::player() const { return p_->player_.ptr(); }
|
||||
SharedPtr<NetworkAccessManager> Application::network() const { return p_->network_.ptr(); }
|
||||
SharedPtr<DeviceFinders> Application::device_finders() const { return p_->device_finders_.ptr(); }
|
||||
#ifndef Q_OS_WIN
|
||||
SharedPtr<UrlHandlers> Application::url_handlers() const { return p_->url_handlers_.ptr(); }
|
||||
SharedPtr<DeviceManager> Application::device_manager() const { return p_->device_manager_.ptr(); }
|
||||
#endif
|
||||
SharedPtr<SCollection> Application::collection() const { return p_->collection_.ptr(); }
|
||||
SharedPtr<CollectionBackend> Application::collection_backend() const { return collection()->backend(); }
|
||||
CollectionModel *Application::collection_model() const { return collection()->model(); }
|
|
@ -29,10 +29,8 @@
|
|||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include "scoped_ptr.h"
|
||||
#include "shared_ptr.h"
|
||||
|
||||
#include "settings/settingsdialog.h"
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
|
||||
class QThread;
|
||||
|
||||
|
@ -41,6 +39,7 @@ class ApplicationImpl;
|
|||
class TagReaderClient;
|
||||
class Database;
|
||||
class DeviceFinders;
|
||||
class UrlHandlers;
|
||||
class Player;
|
||||
class NetworkAccessManager;
|
||||
class SCollection;
|
||||
|
@ -48,9 +47,7 @@ class CollectionBackend;
|
|||
class CollectionModel;
|
||||
class PlaylistBackend;
|
||||
class PlaylistManager;
|
||||
#ifndef Q_OS_WIN
|
||||
class DeviceManager;
|
||||
#endif
|
||||
class CoverProviders;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentAlbumCoverLoader;
|
||||
|
@ -78,9 +75,8 @@ class Application : public QObject {
|
|||
SharedPtr<Player> player() const;
|
||||
SharedPtr<NetworkAccessManager> network() const;
|
||||
SharedPtr<DeviceFinders> device_finders() const;
|
||||
#ifndef Q_OS_WIN
|
||||
SharedPtr<UrlHandlers> url_handlers() const;
|
||||
SharedPtr<DeviceManager> device_manager() const;
|
||||
#endif
|
||||
|
||||
SharedPtr<SCollection> collection() const;
|
||||
SharedPtr<CollectionBackend> collection_backend() const;
|
||||
|
@ -115,23 +111,13 @@ class Application : public QObject {
|
|||
private Q_SLOTS:
|
||||
void ExitReceived();
|
||||
|
||||
public Q_SLOTS:
|
||||
void AddError(const QString &message);
|
||||
void ReloadSettings();
|
||||
void OpenSettingsDialogAtPage(SettingsDialog::Page page);
|
||||
|
||||
Q_SIGNALS:
|
||||
void ErrorAdded(const QString &message);
|
||||
void SettingsChanged();
|
||||
void SettingsDialogRequested(const SettingsDialog::Page page);
|
||||
void ExitFinished();
|
||||
void ClearPixmapDiskCache();
|
||||
|
||||
private:
|
||||
ScopedPtr<ApplicationImpl> p_;
|
||||
QList<QThread*> threads_;
|
||||
QList<QObject*> wait_for_exit_;
|
||||
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
|
@ -84,32 +84,32 @@
|
|||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "commandlineoptions.h"
|
||||
#include "mimedata.h"
|
||||
#include "iconloader.h"
|
||||
#include "taskmanager.h"
|
||||
#include "song.h"
|
||||
#include "stylehelper.h"
|
||||
#include "stylesheetloader.h"
|
||||
#include "constants/filenameconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/commandlineoptions.h"
|
||||
#include "core/mimedata.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/song.h"
|
||||
#include "core/stylehelper.h"
|
||||
#include "core/stylesheetloader.h"
|
||||
#include "application.h"
|
||||
#include "database.h"
|
||||
#include "player.h"
|
||||
#include "filesystemmusicstorage.h"
|
||||
#include "deletefiles.h"
|
||||
#include "core/database.h"
|
||||
#include "core/filesystemmusicstorage.h"
|
||||
#include "core/deletefiles.h"
|
||||
#ifdef Q_OS_MACOS
|
||||
# include "mac_startup.h"
|
||||
# include "macsystemtrayicon.h"
|
||||
# include "core/mac_startup.h"
|
||||
# include "core/macsystemtrayicon.h"
|
||||
# include "utilities/macosutils.h"
|
||||
#else
|
||||
# include "qtsystemtrayicon.h"
|
||||
# include "core/qtsystemtrayicon.h"
|
||||
#endif
|
||||
#include "networkaccessmanager.h"
|
||||
#include "settings.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/envutils.h"
|
||||
#include "utilities/filemanagerutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "utilities/screenutils.h"
|
||||
#include "player/player.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "dialogs/errordialog.h"
|
||||
#include "dialogs/about.h"
|
||||
|
@ -205,6 +205,7 @@
|
|||
|
||||
#ifdef HAVE_MOODBAR
|
||||
# include "moodbar/moodbarcontroller.h"
|
||||
# include "moodbar/moodbarloader.h"
|
||||
# include "moodbar/moodbarproxystyle.h"
|
||||
#endif
|
||||
|
||||
|
@ -213,7 +214,7 @@
|
|||
#include "organize/organizeerrordialog.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include "windows7thumbbar.h"
|
||||
# include "core/windows7thumbbar.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_QTSPARKLE
|
||||
|
@ -226,7 +227,6 @@ using namespace std::chrono_literals;
|
|||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
const char *MainWindow::kSettingsGroup = "MainWindow";
|
||||
const char *MainWindow::kAllFilesFilterSpec = QT_TR_NOOP("All Files (*)");
|
||||
|
||||
namespace {
|
||||
const int kTrackSliderUpdateTimeMs = 200;
|
||||
|
@ -259,7 +259,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
tray_icon_(tray_icon),
|
||||
osd_(osd),
|
||||
console_([app]() {
|
||||
Console *console = new Console(app);
|
||||
Console *console = new Console(app->database());
|
||||
return console;
|
||||
}),
|
||||
edit_tag_dialog_(std::bind(&MainWindow::CreateEditTagDialog, this)),
|
||||
|
@ -277,7 +277,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
queue_view_(new QueueView(this)),
|
||||
settings_dialog_(std::bind(&MainWindow::CreateSettingsDialog, this)),
|
||||
cover_manager_([this, app]() {
|
||||
AlbumCoverManager *cover_manager = new AlbumCoverManager(app, app->collection_backend(), this);
|
||||
AlbumCoverManager *cover_manager = new AlbumCoverManager(app->network(), app->collection_backend(), app->tag_reader_client(), app->album_cover_loader(), app->current_albumcover_loader(), app->cover_providers(), app->streaming_services(), this);
|
||||
cover_manager->Init();
|
||||
|
||||
// Cover manager connections
|
||||
|
@ -300,18 +300,18 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
QObject::connect(add_stream_dialog, &AddStreamDialog::accepted, this, &MainWindow::AddStreamAccepted);
|
||||
return add_stream_dialog;
|
||||
}),
|
||||
smartplaylists_view_(new SmartPlaylistsViewContainer(app, this)),
|
||||
smartplaylists_view_(new SmartPlaylistsViewContainer(app->player(), app->playlist_manager(), app->collection_backend(), app->moodbar_loader(), app->current_albumcover_loader(), this)),
|
||||
#ifdef HAVE_SUBSONIC
|
||||
subsonic_view_(new StreamingSongsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Subsonic), QLatin1String(SubsonicSettingsPage::kSettingsGroup), SettingsDialog::Page::Subsonic, this)),
|
||||
subsonic_view_(new StreamingSongsView(app->streaming_services()->ServiceBySource(Song::Source::Subsonic), QLatin1String(SubsonicSettingsPage::kSettingsGroup), SettingsDialog::Page::Subsonic, this)),
|
||||
#endif
|
||||
#ifdef HAVE_TIDAL
|
||||
tidal_view_(new StreamingTabsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Tidal), QLatin1String(TidalSettingsPage::kSettingsGroup), SettingsDialog::Page::Tidal, this)),
|
||||
tidal_view_(new StreamingTabsView(app->streaming_services()->ServiceBySource(Song::Source::Tidal), app->album_cover_loader(), QLatin1String(TidalSettingsPage::kSettingsGroup), SettingsDialog::Page::Tidal, this)),
|
||||
#endif
|
||||
#ifdef HAVE_SPOTIFY
|
||||
spotify_view_(new StreamingTabsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Spotify), QLatin1String(SpotifySettingsPage::kSettingsGroup), SettingsDialog::Page::Spotify, this)),
|
||||
spotify_view_(new StreamingTabsView(app->streaming_services()->ServiceBySource(Song::Source::Spotify), app->album_cover_loader(), QLatin1String(SpotifySettingsPage::kSettingsGroup), SettingsDialog::Page::Spotify, this)),
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
qobuz_view_(new StreamingTabsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Qobuz), QLatin1String(QobuzSettingsPage::kSettingsGroup), SettingsDialog::Page::Qobuz, this)),
|
||||
qobuz_view_(new StreamingTabsView(app->streaming_services()->ServiceBySource(Song::Source::Qobuz), app->album_cover_loader(), QLatin1String(QobuzSettingsPage::kSettingsGroup), SettingsDialog::Page::Qobuz, this)),
|
||||
#endif
|
||||
radio_view_(new RadioViewContainer(this)),
|
||||
lastfm_import_dialog_(new LastFMImportDialog(app_->lastfm_import(), this)),
|
||||
|
@ -358,19 +358,19 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
|
||||
qLog(Debug) << "Starting";
|
||||
|
||||
QObject::connect(app, &Application::ErrorAdded, this, &MainWindow::ShowErrorDialog);
|
||||
QObject::connect(app, &Application::SettingsDialogRequested, this, &MainWindow::OpenSettingsDialogAtPage);
|
||||
|
||||
// Initialize the UI
|
||||
ui_->setupUi(this);
|
||||
|
||||
setWindowIcon(IconLoader::Load(u"strawberry"_s));
|
||||
|
||||
album_cover_choice_controller_->Init(app);
|
||||
QObject::connect(&*app->database(), &Database::Error, this, &MainWindow::ShowErrorDialog);
|
||||
//QObject::connect(app, &Application::SettingsDialogRequested, this, &MainWindow::OpenSettingsDialogAtPage);
|
||||
|
||||
album_cover_choice_controller_->Init(app->network(), app->collection()->backend(), app->album_cover_loader(), app->current_albumcover_loader(), app->cover_providers(), app->streaming_services());
|
||||
|
||||
ui_->multi_loading_indicator->SetTaskManager(app_->task_manager());
|
||||
context_view_->Init(app_, collection_view_->view(), album_cover_choice_controller_);
|
||||
ui_->widget_playing->Init(app_, album_cover_choice_controller_);
|
||||
context_view_->Init(collection_view_->view(), album_cover_choice_controller_, app_->lyrics_providers());
|
||||
ui_->widget_playing->Init(album_cover_choice_controller_);
|
||||
|
||||
// Initialize the search widget
|
||||
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
|
||||
|
@ -423,14 +423,14 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
|
||||
ui_->playlist->SetManager(app_->playlist_manager());
|
||||
|
||||
ui_->playlist->view()->Init(app_);
|
||||
ui_->playlist->view()->Init(app_->player(), app_->playlist_manager(), app_->collection_backend(), app_->moodbar_loader(), app_->current_albumcover_loader());
|
||||
|
||||
collection_view_->view()->setModel(app_->collection()->model()->filter());
|
||||
collection_view_->view()->SetApplication(app_);
|
||||
collection_view_->view()->Init(app->task_manager(), app->network(), app->device_manager());
|
||||
#ifndef Q_OS_WIN
|
||||
device_view_->view()->SetApplication(app_);
|
||||
device_view_->view()->Init(app->task_manager(), app->device_manager(), app->collection_model()->directory_model());
|
||||
#endif
|
||||
playlist_list_->SetApplication(app_);
|
||||
playlist_list_->Init(app_->task_manager(), app_->player(), app_->playlist_manager(), app_->playlist_backend(), app_->device_manager());
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->collection()->model()->directory_model());
|
||||
|
||||
|
@ -604,6 +604,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
QObject::connect(&*app_->player(), &Player::VolumeChanged, osd_, &OSDBase::VolumeChanged);
|
||||
QObject::connect(&*app_->player(), &Player::VolumeChanged, ui_->volume, &VolumeSlider::SetValue);
|
||||
QObject::connect(&*app_->player(), &Player::ForceShowOSD, this, &MainWindow::ForceShowOSD);
|
||||
QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::ThumbnailLoaded, osd_, &OSDBase::AlbumCoverLoaded);
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::AllPlaylistsLoaded, &*app->player(), &Player::PlaylistsLoaded);
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &MainWindow::SongChanged);
|
||||
|
@ -641,6 +642,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
QObject::connect(&*app_->task_manager(), &TaskManager::PauseCollectionWatchers, &*app_->collection(), &SCollection::PauseWatcher);
|
||||
QObject::connect(&*app_->task_manager(), &TaskManager::ResumeCollectionWatchers, &*app_->collection(), &SCollection::ResumeWatcher);
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, &*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::LoadAlbumCover);
|
||||
QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &MainWindow::AlbumCoverLoaded);
|
||||
QObject::connect(album_cover_choice_controller_, &AlbumCoverChoiceController::Error, this, &MainWindow::ShowErrorDialog);
|
||||
QObject::connect(album_cover_choice_controller_->cover_from_file_action(), &QAction::triggered, this, &MainWindow::LoadCoverFromFile);
|
||||
|
@ -849,11 +851,14 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page);
|
||||
QObject::connect(ui_->multi_loading_indicator, &MultiLoadingIndicator::TaskCountChange, this, &MainWindow::TaskCountChanged);
|
||||
|
||||
ui_->track_slider->SetApplication(app);
|
||||
ui_->track_slider->Init();
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
// Moodbar connections
|
||||
QObject::connect(&*app_->moodbar_controller(), &MoodbarController::CurrentMoodbarDataChanged, ui_->track_slider->moodbar_style(), &MoodbarProxyStyle::SetMoodbarData);
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, &*app_->moodbar_controller(), &MoodbarController::CurrentSongChanged);
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, &*app_->moodbar_controller(), &MoodbarController::PlaybackStopped);
|
||||
QObject::connect(ui_->track_slider->moodbar_style(), &MoodbarProxyStyle::SettingsChanged, this, &MainWindow::MoodbarSettingsChanged);
|
||||
#endif
|
||||
|
||||
// Playing widget
|
||||
|
@ -875,7 +880,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
css_loader->SetStyleSheet(this, u":/style/strawberry.css"_s);
|
||||
|
||||
// Load playlists
|
||||
app_->playlist_manager()->Init(app_->collection_backend(), app_->playlist_backend(), ui_->playlist_sequence, ui_->playlist);
|
||||
app_->playlist_manager()->Init(app_->task_manager(), app->url_handlers(), app_->collection_backend(), app_->playlist_backend(), app_->current_albumcover_loader(), ui_->playlist_sequence, ui_->playlist);
|
||||
|
||||
queue_view_->SetPlaylistManager(app_->playlist_manager());
|
||||
|
||||
|
@ -902,6 +907,8 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::FinishedWithError, lastfm_import_dialog_, &LastFMImportDialog::FinishedWithError);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateTotal, lastfm_import_dialog_, &LastFMImportDialog::UpdateTotal);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateProgress, lastfm_import_dialog_, &LastFMImportDialog::UpdateProgress);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateLastPlayed, &*app_->collection_backend(), &CollectionBackend::UpdateLastPlayed);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdatePlayCount, &*app_->collection_backend(), &CollectionBackend::UpdatePlayCount);
|
||||
|
||||
// Load settings
|
||||
qLog(Debug) << "Loading settings";
|
||||
|
@ -1208,7 +1215,7 @@ void MainWindow::ReloadAllSettings() {
|
|||
ReloadSettings();
|
||||
|
||||
// Other settings
|
||||
app_->ReloadSettings();
|
||||
//app_->ReloadSettings();
|
||||
app_->collection()->ReloadSettings();
|
||||
app_->player()->ReloadSettings();
|
||||
collection_view_->ReloadSettings();
|
||||
|
@ -1228,18 +1235,30 @@ void MainWindow::ReloadAllSettings() {
|
|||
app_->lyrics_providers()->ReloadSettings();
|
||||
#ifdef HAVE_MOODBAR
|
||||
app_->moodbar_controller()->ReloadSettings();
|
||||
app_->moodbar_loader()->ReloadSettings();
|
||||
ui_->track_slider->moodbar_style()->ReloadSettings();
|
||||
#endif
|
||||
#ifdef HAVE_SUBSONIC
|
||||
subsonic_view_->ReloadSettings();
|
||||
#endif
|
||||
#ifdef HAVE_TIDAL
|
||||
tidal_view_->ReloadSettings();
|
||||
tidal_view_->search_view()->ReloadSettings();
|
||||
#endif
|
||||
#ifdef HAVE_SPOTIFY
|
||||
spotify_view_->ReloadSettings();
|
||||
spotify_view_->search_view()->ReloadSettings();
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
qobuz_view_->ReloadSettings();
|
||||
qobuz_view_->search_view()->ReloadSettings();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::MoodbarSettingsChanged() {
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -2810,7 +2829,7 @@ void MainWindow::ShowEqualizer() {
|
|||
|
||||
SettingsDialog *MainWindow::CreateSettingsDialog() {
|
||||
|
||||
SettingsDialog *settings_dialog = new SettingsDialog(app_, osd_, this);
|
||||
SettingsDialog *settings_dialog = new SettingsDialog(app_->player(), app_->device_finders(), app_->collection(), app_->cover_providers(), app_->lyrics_providers(), app_->scrobbler(), app_->streaming_services(), osd_, this);
|
||||
#ifdef HAVE_GLOBALSHORTCUTS
|
||||
settings_dialog->SetGlobalShortcutManager(globalshortcuts_manager_);
|
||||
#endif
|
||||
|
@ -2838,7 +2857,7 @@ void MainWindow::OpenSettingsDialogAtPage(SettingsDialog::Page page) {
|
|||
|
||||
EditTagDialog *MainWindow::CreateEditTagDialog() {
|
||||
|
||||
EditTagDialog *edit_tag_dialog = new EditTagDialog(app_);
|
||||
EditTagDialog *edit_tag_dialog = new EditTagDialog(app_->network(), app_->collection_backend(), app_->album_cover_loader(), app_->current_albumcover_loader(), app_->cover_providers(), app_->lyrics_providers());
|
||||
QObject::connect(edit_tag_dialog, &EditTagDialog::accepted, this, &MainWindow::EditTagDialogAccepted);
|
||||
QObject::connect(edit_tag_dialog, &EditTagDialog::Error, this, &MainWindow::ShowErrorDialog);
|
||||
return edit_tag_dialog;
|
|
@ -46,12 +46,12 @@
|
|||
#include <QSettings>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "scoped_ptr.h"
|
||||
#include "shared_ptr.h"
|
||||
#include "lazy.h"
|
||||
#include "platforminterface.h"
|
||||
#include "song.h"
|
||||
#include "settings.h"
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/lazy.h"
|
||||
#include "core/platforminterface.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "tagreader/tagreaderclient.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "osd/osdbase.h"
|
||||
|
@ -108,7 +108,6 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||
~MainWindow() override;
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
static const char *kAllFilesFilterSpec;
|
||||
|
||||
void SetHiddenInTray(const bool hidden);
|
||||
void CommandlineOptionsReceived(const CommandlineOptions &options);
|
||||
|
@ -205,6 +204,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||
void ShowCollectionConfig();
|
||||
void ReloadSettings();
|
||||
void ReloadAllSettings();
|
||||
void MoodbarSettingsChanged();
|
||||
void RefreshStyleSheet();
|
||||
void SetHiddenInTray() { SetHiddenInTray(true); }
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
# include <QDBusArgument>
|
||||
#endif
|
||||
|
||||
#include "song.h"
|
||||
#include "core/song.h"
|
||||
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginemetadata.h"
|
||||
|
@ -57,7 +57,7 @@
|
|||
#include "equalizer/equalizer.h"
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
# include "dbus_metatypes.h"
|
||||
# include "core/dbus_metatypes.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MPRIS2
|
|
@ -40,13 +40,13 @@
|
|||
#include <QEventLoop>
|
||||
|
||||
#include "core/logging.h"
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "signalchecker.h"
|
||||
#include "player.h"
|
||||
#include "song.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/signalchecker.h"
|
||||
#include "core/song.h"
|
||||
#include "core/database.h"
|
||||
#include "core/urlhandlers.h"
|
||||
#include "songloader.h"
|
||||
#include "database.h"
|
||||
#include "player/player.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "tagreader/tagreaderclient.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
|
@ -66,8 +66,9 @@ constexpr int kDefaultTimeout = 5000;
|
|||
|
||||
QSet<QString> SongLoader::sRawUriSchemes;
|
||||
|
||||
SongLoader::SongLoader(SharedPtr<CollectionBackendInterface> collection_backend, const SharedPtr<Player> player, QObject *parent)
|
||||
SongLoader::SongLoader(const SharedPtr<UrlHandlers> url_handlers, const SharedPtr<Player> player, const SharedPtr<CollectionBackendInterface> collection_backend, QObject *parent)
|
||||
: QObject(parent),
|
||||
url_handlers_(url_handlers),
|
||||
player_(player),
|
||||
collection_backend_(collection_backend),
|
||||
timeout_timer_(new QTimer(this)),
|
||||
|
@ -114,7 +115,7 @@ SongLoader::Result SongLoader::Load(const QUrl &url) {
|
|||
return LoadLocal(url_.toLocalFile());
|
||||
}
|
||||
|
||||
if (sRawUriSchemes.contains(url_.scheme()) || player_->HandlerForUrl(url)) {
|
||||
if (sRawUriSchemes.contains(url_.scheme()) || url_handlers_->CanHandle(url)) {
|
||||
// The URI scheme indicates that it can't possibly be a playlist,
|
||||
// or we have a custom handler for the URL, so add it as a raw stream.
|
||||
AddAsRawStream();
|
|
@ -38,10 +38,11 @@
|
|||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "song.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
|
||||
class QTimer;
|
||||
class UrlHandlers;
|
||||
class Player;
|
||||
class CollectionBackendInterface;
|
||||
class PlaylistParser;
|
||||
|
@ -56,7 +57,7 @@ class SongLoader : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SongLoader(SharedPtr<CollectionBackendInterface> collection_backend, const SharedPtr<Player> player, QObject *parent = nullptr);
|
||||
explicit SongLoader(const SharedPtr<UrlHandlers> url_handlers, const SharedPtr<Player> player, const SharedPtr<CollectionBackendInterface> collection_backend, QObject *parent = nullptr);
|
||||
~SongLoader() override;
|
||||
|
||||
enum class Result {
|
||||
|
@ -137,8 +138,9 @@ class SongLoader : public QObject {
|
|||
QUrl url_;
|
||||
SongList songs_;
|
||||
|
||||
const SharedPtr<UrlHandlers> url_handlers_;
|
||||
const SharedPtr<Player> player_;
|
||||
SharedPtr<CollectionBackendInterface> collection_backend_;
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend_;
|
||||
QTimer *timeout_timer_;
|
||||
PlaylistParser *playlist_parser_;
|
||||
CueParser *cue_parser_;
|
|
@ -30,7 +30,6 @@
|
|||
#include <QSettings>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/database.h"
|
||||
#include "core/thread.h"
|
||||
|
@ -43,7 +42,6 @@
|
|||
#include "collectionwatcher.h"
|
||||
#include "collectionbackend.h"
|
||||
#include "collectionmodel.h"
|
||||
#include "scrobbler/lastfmimport.h"
|
||||
#include "settings/collectionsettingspage.h"
|
||||
|
||||
using std::make_shared;
|
||||
|
@ -52,9 +50,9 @@ const char *SCollection::kSongsTable = "songs";
|
|||
const char *SCollection::kDirsTable = "directories";
|
||||
const char *SCollection::kSubdirsTable = "subdirectories";
|
||||
|
||||
SCollection::SCollection(Application *app, QObject *parent)
|
||||
SCollection::SCollection(SharedPtr<Database> database, SharedPtr<TaskManager> task_manager, SharedPtr<AlbumCoverLoader> album_cover_loader, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
task_manager_(task_manager),
|
||||
backend_(nullptr),
|
||||
model_(nullptr),
|
||||
watcher_(nullptr),
|
||||
|
@ -68,12 +66,12 @@ SCollection::SCollection(Application *app, QObject *parent)
|
|||
original_thread_ = thread();
|
||||
|
||||
backend_ = make_shared<CollectionBackend>();
|
||||
backend()->moveToThread(app->database()->thread());
|
||||
qLog(Debug) << &*backend_ << "moved to thread" << app->database()->thread();
|
||||
backend()->moveToThread(database->thread());
|
||||
qLog(Debug) << &*backend_ << "moved to thread" << database->thread();
|
||||
|
||||
backend_->Init(app->database(), app->task_manager(), Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable));
|
||||
backend_->Init(database, task_manager, Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable));
|
||||
|
||||
model_ = new CollectionModel(backend_, app_, this);
|
||||
model_ = new CollectionModel(backend_, album_cover_loader, this);
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
|
@ -107,7 +105,7 @@ void SCollection::Init() {
|
|||
watcher_thread_->start(QThread::IdlePriority);
|
||||
|
||||
watcher_->set_backend(backend_);
|
||||
watcher_->set_task_manager(app_->task_manager());
|
||||
watcher_->set_task_manager(task_manager_);
|
||||
|
||||
QObject::connect(&*backend_, &CollectionBackend::Error, this, &SCollection::Error);
|
||||
QObject::connect(&*backend_, &CollectionBackend::DirectoryAdded, watcher_, &CollectionWatcher::AddDirectory);
|
||||
|
@ -125,9 +123,6 @@ void SCollection::Init() {
|
|||
QObject::connect(watcher_, &CollectionWatcher::CompilationsNeedUpdating, &*backend_, &CollectionBackend::CompilationsNeedUpdating);
|
||||
QObject::connect(watcher_, &CollectionWatcher::UpdateLastSeen, &*backend_, &CollectionBackend::UpdateLastSeen);
|
||||
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateLastPlayed, &*backend_, &CollectionBackend::UpdateLastPlayed);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdatePlayCount, &*backend_, &CollectionBackend::UpdatePlayCount);
|
||||
|
||||
// This will start the watcher checking for updates
|
||||
backend_->LoadDirectoriesAsync();
|
||||
|
||||
|
@ -198,8 +193,8 @@ void SCollection::SyncPlaycountAndRatingToFilesAsync() {
|
|||
|
||||
void SCollection::SyncPlaycountAndRatingToFiles() {
|
||||
|
||||
const int task_id = app_->task_manager()->StartTask(tr("Saving playcounts and ratings"));
|
||||
app_->task_manager()->SetTaskBlocksCollectionScans(task_id);
|
||||
const int task_id = task_manager_->StartTask(tr("Saving playcounts and ratings"));
|
||||
task_manager_->SetTaskBlocksCollectionScans(task_id);
|
||||
|
||||
const SongList songs = backend_->GetAllSongs();
|
||||
const qint64 nb_songs = songs.size();
|
||||
|
@ -207,16 +202,16 @@ void SCollection::SyncPlaycountAndRatingToFiles() {
|
|||
for (const Song &song : songs) {
|
||||
(void)TagReaderClient::Instance()->SaveSongPlaycountBlocking(song.url().toLocalFile(), song.playcount());
|
||||
(void)TagReaderClient::Instance()->SaveSongRatingBlocking(song.url().toLocalFile(), song.rating());
|
||||
app_->task_manager()->SetTaskProgress(task_id, ++i, nb_songs);
|
||||
task_manager_->SetTaskProgress(task_id, ++i, nb_songs);
|
||||
}
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
|
||||
}
|
||||
|
||||
void SCollection::SongsPlaycountChanged(const SongList &songs, const bool save_tags) {
|
||||
|
||||
if (save_tags || save_playcounts_to_files_) {
|
||||
app_->tag_reader_client()->SaveSongsPlaycountAsync(songs);
|
||||
TagReaderClient::Instance()->SaveSongsPlaycountAsync(songs);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -224,7 +219,7 @@ void SCollection::SongsPlaycountChanged(const SongList &songs, const bool save_t
|
|||
void SCollection::SongsRatingChanged(const SongList &songs, const bool save_tags) {
|
||||
|
||||
if (save_tags || save_ratings_to_files_) {
|
||||
app_->tag_reader_client()->SaveSongsRatingAsync(songs);
|
||||
TagReaderClient::Instance()->SaveSongsRatingAsync(songs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,17 +33,19 @@
|
|||
#include "core/song.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class Thread;
|
||||
class CollectionBackend;
|
||||
class CollectionModel;
|
||||
class CollectionWatcher;
|
||||
class AlbumCoverLoader;
|
||||
|
||||
class SCollection : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SCollection(Application *app, QObject *parent = nullptr);
|
||||
explicit SCollection(SharedPtr<Database> database, SharedPtr<TaskManager> task_manager, SharedPtr<AlbumCoverLoader> album_cover_loader, QObject *parent = nullptr);
|
||||
~SCollection() override;
|
||||
|
||||
static const char *kSongsTable;
|
||||
|
@ -86,7 +88,7 @@ class SCollection : public QObject {
|
|||
void ExitFinished();
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<CollectionBackend> backend_;
|
||||
CollectionModel *model_;
|
||||
|
||||
|
|
|
@ -55,11 +55,9 @@
|
|||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/database.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/sqlrow.h"
|
||||
#include "core/settings.h"
|
||||
#include "collectionfilteroptions.h"
|
||||
#include "collectionquery.h"
|
||||
|
@ -85,12 +83,10 @@ constexpr char kPixmapDiskCacheDir[] = "pixmapcache";
|
|||
constexpr char kVariousArtists[] = QT_TR_NOOP("Various artists");
|
||||
} // namespace
|
||||
|
||||
QNetworkDiskCache *CollectionModel::sIconCache = nullptr;
|
||||
|
||||
CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, Application *app, QObject *parent)
|
||||
CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, SharedPtr<AlbumCoverLoader> album_cover_loader, QObject *parent)
|
||||
: SimpleTreeModel<CollectionItem>(new CollectionItem(this), parent),
|
||||
backend_(backend),
|
||||
app_(app),
|
||||
album_cover_loader_(album_cover_loader),
|
||||
dir_model_(new CollectionDirectoryModel(backend, this)),
|
||||
filter_(new CollectionFilter(this)),
|
||||
timer_reload_(new QTimer(this)),
|
||||
|
@ -100,7 +96,8 @@ CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, Applicati
|
|||
total_song_count_(0),
|
||||
total_artist_count_(0),
|
||||
total_album_count_(0),
|
||||
loading_(false) {
|
||||
loading_(false),
|
||||
icon_disk_cache_(nullptr) {
|
||||
|
||||
setObjectName(backend_->source() == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(backend_->source()), QLatin1String(metaObject()->className())));
|
||||
|
||||
|
@ -108,8 +105,8 @@ CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, Applicati
|
|||
filter_->setSortRole(Role_SortText);
|
||||
filter_->sort(0);
|
||||
|
||||
if (app_) {
|
||||
QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded);
|
||||
if (album_cover_loader_) {
|
||||
QObject::connect(&*album_cover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded);
|
||||
}
|
||||
|
||||
QIcon nocover = IconLoader::Load(u"cdcase"_s);
|
||||
|
@ -118,10 +115,9 @@ CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, Applicati
|
|||
pixmap_no_cover_ = nocover.pixmap(nocover_sizes.last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
if (app_ && !sIconCache) {
|
||||
sIconCache = new QNetworkDiskCache(this);
|
||||
sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir));
|
||||
QObject::connect(app_, &Application::ClearPixmapDiskCache, this, &CollectionModel::ClearDiskCache);
|
||||
if (!qgetenv("DISPLAY").isEmpty() && !icon_disk_cache_) {
|
||||
icon_disk_cache_ = new QNetworkDiskCache(this);
|
||||
icon_disk_cache_->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir) + u'-' + Song::TextForSource(backend_->source()));
|
||||
}
|
||||
|
||||
QObject::connect(&*backend_, &CollectionBackend::SongsAdded, this, &CollectionModel::AddReAddOrUpdate);
|
||||
|
@ -238,8 +234,8 @@ void CollectionModel::ReloadSettings() {
|
|||
|
||||
use_disk_cache_ = settings.value(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool();
|
||||
QPixmapCache::setCacheLimit(static_cast<int>(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit, CollectionSettingsPage::kSettingsCacheSizeDefault) / 1024));
|
||||
if (sIconCache) {
|
||||
sIconCache->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault));
|
||||
if (icon_disk_cache_) {
|
||||
icon_disk_cache_->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault));
|
||||
}
|
||||
|
||||
settings.endGroup();
|
||||
|
@ -258,7 +254,7 @@ void CollectionModel::ReloadSettings() {
|
|||
}
|
||||
|
||||
if (!use_disk_cache_) {
|
||||
ClearDiskCache();
|
||||
ClearIconDiskCache();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -778,7 +774,7 @@ void CollectionModel::CreateSongItem(const Song &song, CollectionItem *parent) {
|
|||
|
||||
}
|
||||
|
||||
void CollectionModel::SetSongItemData(CollectionItem *item, const Song &song) {
|
||||
void CollectionModel::SetSongItemData(CollectionItem *item, const Song &song) const {
|
||||
|
||||
item->display_text = song.TitleWithCompilationArtist();
|
||||
item->sort_text = HasParentAlbumGroupBy(item->parent) ? SortTextForSong(song) : SortText(song.title());
|
||||
|
@ -879,7 +875,7 @@ void CollectionModel::ClearItemPixmapCache(CollectionItem *item) {
|
|||
// Remove from pixmap cache
|
||||
const QString cache_key = AlbumIconPixmapCacheKey(ItemToIndex(item));
|
||||
QPixmapCache::remove(cache_key);
|
||||
if (use_disk_cache_ && sIconCache) sIconCache->remove(AlbumIconPixmapDiskCacheKey(cache_key));
|
||||
if (use_disk_cache_ && icon_disk_cache_) icon_disk_cache_->remove(AlbumIconPixmapDiskCacheKey(cache_key));
|
||||
if (pending_cache_keys_.contains(cache_key)) {
|
||||
pending_cache_keys_.remove(cache_key);
|
||||
}
|
||||
|
@ -910,8 +906,8 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) {
|
|||
}
|
||||
|
||||
// Try to load it from the disk cache
|
||||
if (use_disk_cache_ && sIconCache) {
|
||||
ScopedPtr<QIODevice> disk_cache_img(sIconCache->data(AlbumIconPixmapDiskCacheKey(cache_key)));
|
||||
if (use_disk_cache_ && icon_disk_cache_) {
|
||||
ScopedPtr<QIODevice> disk_cache_img(icon_disk_cache_->data(AlbumIconPixmapDiskCacheKey(cache_key)));
|
||||
if (disk_cache_img) {
|
||||
QImage cached_image;
|
||||
if (cached_image.load(&*disk_cache_img, "XPM")) {
|
||||
|
@ -932,7 +928,7 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) {
|
|||
AlbumCoverLoaderOptions cover_loader_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage);
|
||||
cover_loader_options.desired_scaled_size = QSize(kPrettyCoverSize, kPrettyCoverSize);
|
||||
cover_loader_options.types = cover_types_;
|
||||
const quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options, songs.first());
|
||||
const quint64 id = album_cover_loader_->LoadImageAsync(cover_loader_options, songs.first());
|
||||
pending_art_[id] = ItemAndCacheKey(item, cache_key);
|
||||
pending_cache_keys_.insert(cache_key);
|
||||
}
|
||||
|
@ -965,19 +961,19 @@ void CollectionModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderR
|
|||
}
|
||||
|
||||
// If we have a valid cover not already in the disk cache
|
||||
if (use_disk_cache_ && sIconCache && result.success && !result.image_scaled.isNull()) {
|
||||
if (use_disk_cache_ && icon_disk_cache_ && result.success && !result.image_scaled.isNull()) {
|
||||
const QUrl disk_cache_key = AlbumIconPixmapDiskCacheKey(cache_key);
|
||||
ScopedPtr<QIODevice> disk_cache_img(sIconCache->data(disk_cache_key));
|
||||
ScopedPtr<QIODevice> disk_cache_img(icon_disk_cache_->data(disk_cache_key));
|
||||
if (!disk_cache_img) {
|
||||
QNetworkCacheMetaData disk_cache_metadata;
|
||||
disk_cache_metadata.setSaveToDisk(true);
|
||||
disk_cache_metadata.setUrl(disk_cache_key);
|
||||
// Qt 6 now ignores any entry without headers, so add a fake header.
|
||||
disk_cache_metadata.setRawHeaders(QNetworkCacheMetaData::RawHeaderList() << qMakePair(QByteArray("collection-thumbnail"), cache_key.toUtf8()));
|
||||
QIODevice *device_iconcache = sIconCache->prepare(disk_cache_metadata);
|
||||
QIODevice *device_iconcache = icon_disk_cache_->prepare(disk_cache_metadata);
|
||||
if (device_iconcache) {
|
||||
result.image_scaled.save(device_iconcache, "XPM");
|
||||
sIconCache->insert(device_iconcache);
|
||||
icon_disk_cache_->insert(device_iconcache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1553,8 +1549,11 @@ void CollectionModel::TotalAlbumCountUpdatedSlot(const int count) {
|
|||
|
||||
}
|
||||
|
||||
void CollectionModel::ClearDiskCache() {
|
||||
if (sIconCache) sIconCache->clear();
|
||||
void CollectionModel::ClearIconDiskCache() {
|
||||
|
||||
if (icon_disk_cache_) icon_disk_cache_->clear();
|
||||
QPixmapCache::clear();
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::RowsInserted(const QModelIndex &parent, const int first, const int last) {
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "core/shared_ptr.h"
|
||||
#include "core/simpletreemodel.h"
|
||||
#include "core/song.h"
|
||||
#include "core/sqlrow.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
#include "collectionmodelupdate.h"
|
||||
|
@ -57,16 +56,16 @@
|
|||
class QTimer;
|
||||
class Settings;
|
||||
|
||||
class Application;
|
||||
class CollectionBackend;
|
||||
class CollectionDirectoryModel;
|
||||
class CollectionFilter;
|
||||
class AlbumCoverLoader;
|
||||
|
||||
class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CollectionModel(SharedPtr<CollectionBackend> backend, Application *app, QObject *parent = nullptr);
|
||||
explicit CollectionModel(SharedPtr<CollectionBackend> backend, SharedPtr<AlbumCoverLoader> album_cover_loader, QObject *parent = nullptr);
|
||||
~CollectionModel() override;
|
||||
|
||||
static const int kPrettyCoverSize;
|
||||
|
@ -156,7 +155,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||
int total_artist_count() const { return total_artist_count_; }
|
||||
int total_album_count() const { return total_album_count_; }
|
||||
|
||||
quint64 icon_cache_disk_size() { return sIconCache->cacheSize(); }
|
||||
quint64 icon_disk_cache_size() { return icon_disk_cache_->cacheSize(); }
|
||||
|
||||
const CollectionModel::Grouping GetGroupBy() const { return options_current_.group_by; }
|
||||
void SetGroupBy(const CollectionModel::Grouping g, const std::optional<bool> separate_albums_by_grouping = std::optional<bool>());
|
||||
|
@ -218,6 +217,8 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||
void AddReAddOrUpdate(const SongList &songs);
|
||||
void RemoveSongs(const SongList &songs);
|
||||
|
||||
void ClearIconDiskCache();
|
||||
|
||||
private:
|
||||
void Clear();
|
||||
void BeginReset();
|
||||
|
@ -238,7 +239,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||
void CreateDividerItem(const QString ÷r_key, const QString &display_text, CollectionItem *parent);
|
||||
CollectionItem *CreateContainerItem(const GroupBy group_by, const int container_level, const QString &container_key, const Song &song, CollectionItem *parent);
|
||||
void CreateSongItem(const Song &song, CollectionItem *parent);
|
||||
void SetSongItemData(CollectionItem *item, const Song &song);
|
||||
void SetSongItemData(CollectionItem *item, const Song &song) const;
|
||||
CollectionItem *CreateCompilationArtistNode(CollectionItem *parent);
|
||||
|
||||
void LoadSongsFromSqlAsync();
|
||||
|
@ -267,15 +268,12 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||
void TotalArtistCountUpdatedSlot(const int count);
|
||||
void TotalAlbumCountUpdatedSlot(const int count);
|
||||
|
||||
static void ClearDiskCache();
|
||||
|
||||
void RowsInserted(const QModelIndex &parent, const int first, const int last);
|
||||
void RowsRemoved(const QModelIndex &parent, const int first, const int last);
|
||||
|
||||
private:
|
||||
static QNetworkDiskCache *sIconCache;
|
||||
SharedPtr<CollectionBackend> backend_;
|
||||
Application *app_;
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader_;
|
||||
CollectionDirectoryModel *dir_model_;
|
||||
CollectionFilter *filter_;
|
||||
QTimer *timer_reload_;
|
||||
|
@ -310,6 +308,8 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||
using ItemAndCacheKey = QPair<CollectionItem*, QString>;
|
||||
QMap<quint64, ItemAndCacheKey> pending_art_;
|
||||
QSet<QString> pending_cache_keys_;
|
||||
|
||||
QNetworkDiskCache *icon_disk_cache_;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(CollectionModel::Grouping)
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include <QKeyEvent>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/mimedata.h"
|
||||
#include "core/musicstorage.h"
|
||||
|
@ -80,7 +79,6 @@ using namespace Qt::Literals::StringLiterals;
|
|||
|
||||
CollectionView::CollectionView(QWidget *parent)
|
||||
: AutoExpandingTreeView(parent),
|
||||
app_(nullptr),
|
||||
filter_(nullptr),
|
||||
total_song_count_(-1),
|
||||
total_artist_count_(-1),
|
||||
|
@ -123,6 +121,30 @@ CollectionView::CollectionView(QWidget *parent)
|
|||
|
||||
CollectionView::~CollectionView() = default;
|
||||
|
||||
void CollectionView::Init(SharedPtr<TaskManager> task_manager,
|
||||
SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<DeviceManager> device_manager) {
|
||||
|
||||
task_manager_ = task_manager;
|
||||
network_ = network;
|
||||
device_manager_ = device_manager;
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
||||
QSortFilterProxyModel *CollectionView::sort_filter_proxy_model() const {
|
||||
|
||||
return qobject_cast<QSortFilterProxyModel*>(model());
|
||||
|
||||
}
|
||||
|
||||
CollectionModel *CollectionView::collection_model() const {
|
||||
|
||||
return qobject_cast<CollectionModel*>(sort_filter_proxy_model()->sourceModel());
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::SaveFocus() {
|
||||
|
||||
const QModelIndex current = currentIndex();
|
||||
|
@ -142,8 +164,8 @@ void CollectionView::SaveFocus() {
|
|||
|
||||
switch (item_type) {
|
||||
case CollectionItem::Type::Song:{
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
SongList songs = app_->collection_model()->GetChildSongs(index);
|
||||
QModelIndex index = sort_filter_proxy_model()->mapToSource(current);
|
||||
SongList songs = collection_model()->GetChildSongs(index);
|
||||
if (!songs.isEmpty()) {
|
||||
last_selected_song_ = songs.last();
|
||||
}
|
||||
|
@ -210,8 +232,8 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) {
|
|||
break;
|
||||
case CollectionItem::Type::Song:
|
||||
if (!last_selected_song_.url().isEmpty()) {
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
const SongList songs = app_->collection_model()->GetChildSongs(index);
|
||||
QModelIndex index = sort_filter_proxy_model()->mapToSource(current);
|
||||
const SongList songs = collection_model()->GetChildSongs(index);
|
||||
if (std::any_of(songs.begin(), songs.end(), [this](const Song &song) { return song == last_selected_song_; })) {
|
||||
setCurrentIndex(current);
|
||||
return true;
|
||||
|
@ -241,6 +263,7 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
@ -255,14 +278,6 @@ void CollectionView::ReloadSettings() {
|
|||
|
||||
}
|
||||
|
||||
void CollectionView::SetApplication(Application *app) {
|
||||
|
||||
app_ = app;
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::SetFilter(CollectionFilterWidget *filter) { filter_ = filter; }
|
||||
|
||||
void CollectionView::TotalSongCountUpdated(const int count) {
|
||||
|
@ -417,8 +432,8 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
|||
context_menu_->addMenu(filter_->menu());
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
action_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0);
|
||||
QObject::connect(app_->device_manager()->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, action_copy_to_device_, &QAction::setDisabled);
|
||||
action_copy_to_device_->setDisabled(device_manager_->connected_devices_model()->rowCount() == 0);
|
||||
QObject::connect(device_manager_->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, action_copy_to_device_, &QAction::setDisabled);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -426,16 +441,16 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
|||
context_menu_index_ = indexAt(e->pos());
|
||||
if (!context_menu_index_.isValid()) return;
|
||||
|
||||
context_menu_index_ = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(context_menu_index_);
|
||||
context_menu_index_ = sort_filter_proxy_model()->mapToSource(context_menu_index_);
|
||||
|
||||
const QModelIndexList selected_indexes = qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
const QModelIndexList selected_indexes = sort_filter_proxy_model()->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
|
||||
int regular_elements = 0;
|
||||
int regular_editable = 0;
|
||||
|
||||
for (const QModelIndex &idx : selected_indexes) {
|
||||
++regular_elements;
|
||||
if (app_->collection_model()->data(idx, CollectionModel::Role_Editable).toBool()) {
|
||||
if (collection_model()->data(idx, CollectionModel::Role_Editable).toBool()) {
|
||||
++regular_editable;
|
||||
}
|
||||
}
|
||||
|
@ -502,7 +517,7 @@ void CollectionView::SetShowInVarious(const bool on) {
|
|||
if (on && albums.keys().count() == 1) {
|
||||
const QStringList albums_list = albums.keys();
|
||||
const QString album = albums_list.first();
|
||||
const SongList all_of_album = app_->collection_backend()->GetSongsByAlbum(album);
|
||||
const SongList all_of_album = collection_model()->backend()->GetSongsByAlbum(album);
|
||||
QSet<QString> other_artists;
|
||||
for (const Song &s : all_of_album) {
|
||||
if (!albums.contains(album, s.artist()) && !other_artists.contains(s.artist())) {
|
||||
|
@ -520,7 +535,7 @@ void CollectionView::SetShowInVarious(const bool on) {
|
|||
|
||||
const QSet<QString> albums_set = QSet<QString>(albums.keyBegin(), albums.keyEnd());
|
||||
for (const QString &album : albums_set) {
|
||||
app_->collection_backend()->ForceCompilation(album, albums.values(album), on);
|
||||
collection_model()->backend()->ForceCompilation(album, albums.values(album), on);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -584,11 +599,12 @@ void CollectionView::SearchForThis() {
|
|||
return;
|
||||
}
|
||||
QString search;
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
|
||||
QModelIndex index = sort_filter_proxy_model()->mapToSource(current);
|
||||
|
||||
switch (item_type) {
|
||||
case CollectionItem::Type::Song:{
|
||||
SongList songs = app_->collection_model()->GetChildSongs(index);
|
||||
SongList songs = collection_model()->GetChildSongs(index);
|
||||
if (!songs.isEmpty()) {
|
||||
last_selected_song_ = songs.last();
|
||||
}
|
||||
|
@ -601,8 +617,8 @@ void CollectionView::SearchForThis() {
|
|||
}
|
||||
|
||||
case CollectionItem::Type::Container:{
|
||||
CollectionItem *item = app_->collection_model()->IndexToItem(index);
|
||||
const CollectionModel::GroupBy group_by = app_->collection_model()->GetGroupBy()[item->container_level];
|
||||
CollectionItem *item = collection_model()->IndexToItem(index);
|
||||
const CollectionModel::GroupBy group_by = collection_model()->GetGroupBy()[item->container_level];
|
||||
while (!item->children.isEmpty()) {
|
||||
item = item->children.constFirst();
|
||||
}
|
||||
|
@ -688,18 +704,18 @@ void CollectionView::scrollTo(const QModelIndex &idx, ScrollHint hint) {
|
|||
|
||||
SongList CollectionView::GetSelectedSongs() const {
|
||||
|
||||
QModelIndexList selected_indexes = qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
return app_->collection_model()->GetChildSongs(selected_indexes);
|
||||
QModelIndexList selected_indexes = sort_filter_proxy_model()->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
return collection_model()->GetChildSongs(selected_indexes);
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::Organize() {
|
||||
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(app_->task_manager(), app_->collection_backend(), this);
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(task_manager_, collection_model()->backend(), this);
|
||||
}
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model());
|
||||
organize_dialog_->SetDestinationModel(collection_model()->directory_model());
|
||||
organize_dialog_->SetCopy(false);
|
||||
const SongList songs = GetSelectedSongs();
|
||||
if (organize_dialog_->SetSongs(songs)) {
|
||||
|
@ -714,7 +730,7 @@ void CollectionView::Organize() {
|
|||
void CollectionView::EditTracks() {
|
||||
|
||||
if (!edit_tag_dialog_) {
|
||||
edit_tag_dialog_ = make_unique<EditTagDialog>(app_, this);
|
||||
edit_tag_dialog_ = make_unique<EditTagDialog>(network_, collection_model()->backend(), albumcover_loader_, current_albumcover_loader_, cover_providers_, lyrics_providers_, this);
|
||||
QObject::connect(&*edit_tag_dialog_, &EditTagDialog::Error, this, &CollectionView::EditTagError);
|
||||
}
|
||||
const SongList songs = GetSelectedSongs();
|
||||
|
@ -729,7 +745,7 @@ void CollectionView::EditTagError(const QString &message) {
|
|||
|
||||
void CollectionView::RescanSongs() {
|
||||
|
||||
app_->collection()->Rescan(GetSelectedSongs());
|
||||
//collection_->Rescan(GetSelectedSongs());
|
||||
|
||||
}
|
||||
|
||||
|
@ -737,10 +753,10 @@ void CollectionView::CopyToDevice() {
|
|||
|
||||
#ifndef Q_OS_WIN
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(app_->task_manager(), nullptr, this);
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(task_manager_, nullptr, this);
|
||||
}
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->device_manager()->connected_devices_model(), true);
|
||||
organize_dialog_->SetDestinationModel(device_manager_->connected_devices_model(), true);
|
||||
organize_dialog_->SetCopy(true);
|
||||
organize_dialog_->SetSongs(GetSelectedSongs());
|
||||
organize_dialog_->show();
|
||||
|
@ -812,9 +828,9 @@ void CollectionView::Delete() {
|
|||
if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return;
|
||||
|
||||
// We can cheat and always take the storage of the first directory, since they'll all be FilesystemMusicStorage in a collection and deleting doesn't check the actual directory.
|
||||
SharedPtr<MusicStorage> storage = app_->collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value<SharedPtr<MusicStorage>>();
|
||||
SharedPtr<MusicStorage> storage = collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value<SharedPtr<MusicStorage>>();
|
||||
|
||||
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, true);
|
||||
DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, true);
|
||||
QObject::connect(delete_files, &DeleteFiles::Finished, this, &CollectionView::DeleteFilesFinished);
|
||||
delete_files->Start(songs);
|
||||
|
||||
|
|
|
@ -31,9 +31,11 @@
|
|||
#include <QSet>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
#include "widgets/autoexpandingtreeview.h"
|
||||
|
||||
class QSortFilterProxyModel;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
class QContextMenuEvent;
|
||||
|
@ -41,8 +43,15 @@ class QMouseEvent;
|
|||
class QPaintEvent;
|
||||
class QKeyEvent;
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class NetworkAccessManager;
|
||||
class CollectionModel;
|
||||
class CollectionFilterWidget;
|
||||
class DeviceManager;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class CoverProviders;
|
||||
class LyricsProviders;
|
||||
class EditTagDialog;
|
||||
class OrganizeDialog;
|
||||
|
||||
|
@ -57,7 +66,10 @@ class CollectionView : public AutoExpandingTreeView {
|
|||
// Please note that the selection is recursive meaning that if for example an album is selected this will return all of it's songs.
|
||||
SongList GetSelectedSongs() const;
|
||||
|
||||
void SetApplication(Application *app);
|
||||
void Init(SharedPtr<TaskManager> task_manager,
|
||||
SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<DeviceManager> device_manager);
|
||||
|
||||
void SetFilter(CollectionFilterWidget *filter);
|
||||
|
||||
// QTreeView
|
||||
|
@ -114,15 +126,24 @@ class CollectionView : public AutoExpandingTreeView {
|
|||
void DeleteFilesFinished(const SongList &songs_with_errors);
|
||||
|
||||
private:
|
||||
QSortFilterProxyModel *sort_filter_proxy_model() const;
|
||||
CollectionModel *collection_model() const;
|
||||
void RecheckIsEmpty();
|
||||
void SetShowInVarious(const bool on);
|
||||
bool RestoreLevelFocus(const QModelIndex &parent = QModelIndex());
|
||||
void SaveContainerPath(const QModelIndex &child);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
CollectionFilterWidget *filter_;
|
||||
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
SharedPtr<DeviceManager> device_manager_;
|
||||
SharedPtr<AlbumCoverLoader> albumcover_loader_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
SharedPtr<CoverProviders> cover_providers_;
|
||||
SharedPtr<LyricsProviders> lyrics_providers_;
|
||||
|
||||
int total_song_count_;
|
||||
int total_artist_count_;
|
||||
int total_album_count_;
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "core/taskmanager.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/imageutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "tagreader/tagreaderclient.h"
|
||||
#include "collectiondirectory.h"
|
||||
#include "collectionbackend.h"
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef FILENAMECONSTANTS_H
|
||||
#define FILENAMECONSTANTS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "core/arraysize.h"
|
||||
|
||||
constexpr char kProblematicCharactersRegex[] = "[:?*\"<>|]";
|
||||
|
@ -27,5 +29,6 @@ constexpr char kInvalidFatCharactersRegex[] = "[^a-zA-Z0-9!#\\$%&'()\\-@\\^_`{}~
|
|||
constexpr char kInvalidDirCharactersRegex[] = "[/\\\\]";
|
||||
constexpr char kInvalidPrefixCharacters[] = ".";
|
||||
constexpr int kInvalidPrefixCharactersCount = arraysize(kInvalidPrefixCharacters) - 1;
|
||||
constexpr char kAllFilesFilterSpec[] = QT_TR_NOOP("All Files (*)");
|
||||
|
||||
#endif // FILENAMECONSTANTS_H
|
|
@ -50,8 +50,6 @@
|
|||
#include <QDragEnterEvent>
|
||||
#include <QDropEvent>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/strutils.h"
|
||||
|
@ -73,7 +71,6 @@ constexpr int kWidgetSpacing = 50;
|
|||
|
||||
ContextView::ContextView(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
app_(nullptr),
|
||||
collectionview_(nullptr),
|
||||
album_cover_choice_controller_(nullptr),
|
||||
lyrics_fetcher_(nullptr),
|
||||
|
@ -241,14 +238,13 @@ ContextView::ContextView(QWidget *parent)
|
|||
|
||||
}
|
||||
|
||||
void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller) {
|
||||
void ContextView::Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr<LyricsProviders> lyrics_providers) {
|
||||
|
||||
app_ = app;
|
||||
collectionview_ = collectionview;
|
||||
album_cover_choice_controller_ = album_cover_choice_controller;
|
||||
|
||||
widget_album_->Init(this, album_cover_choice_controller_);
|
||||
lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this);
|
||||
lyrics_fetcher_ = new LyricsFetcher(lyrics_providers, this);
|
||||
|
||||
QObject::connect(collectionview_, &CollectionView::TotalSongCountUpdated_, this, &ContextView::UpdateNoSong);
|
||||
QObject::connect(collectionview_, &CollectionView::TotalArtistCountUpdated_, this, &ContextView::UpdateNoSong);
|
||||
|
|
|
@ -46,9 +46,9 @@ class QDragEnterEvent;
|
|||
class QDropEvent;
|
||||
|
||||
class ResizableTextEdit;
|
||||
class Application;
|
||||
class CollectionView;
|
||||
class AlbumCoverChoiceController;
|
||||
class LyricsProviders;
|
||||
class LyricsFetcher;
|
||||
|
||||
class ContextView : public QWidget {
|
||||
|
@ -57,7 +57,7 @@ class ContextView : public QWidget {
|
|||
public:
|
||||
explicit ContextView(QWidget *parent = nullptr);
|
||||
|
||||
void Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller);
|
||||
void Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr<LyricsProviders> lyrics_providers);
|
||||
|
||||
ContextAlbum *album_widget() const { return widget_album_; }
|
||||
bool album_enabled() const { return action_show_album_->isChecked(); }
|
||||
|
@ -101,7 +101,6 @@ class ContextView : public QWidget {
|
|||
void AlbumCoverLoaded(const Song &song, const QImage &image);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
CollectionView *collectionview_;
|
||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||
LyricsFetcher *lyrics_fetcher_;
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "core/logging.h"
|
||||
#include "taskmanager.h"
|
||||
#include "database.h"
|
||||
#include "application.h"
|
||||
#include "sqlquery.h"
|
||||
#include "scopedtransaction.h"
|
||||
|
||||
|
@ -62,9 +61,9 @@ constexpr char kMagicAllSongsTables[] = "%allsongstables";
|
|||
int Database::sNextConnectionId = 1;
|
||||
QMutex Database::sNextConnectionIdMutex;
|
||||
|
||||
Database::Database(Application *app, QObject *parent, const QString &database_name) :
|
||||
Database::Database(SharedPtr<TaskManager> task_manager, QObject *parent, const QString &database_name) :
|
||||
QObject(parent),
|
||||
app_(app),
|
||||
task_manager_(task_manager),
|
||||
injected_database_name_(database_name),
|
||||
query_hash_(0),
|
||||
startup_schema_version_(-1),
|
||||
|
@ -145,7 +144,7 @@ QSqlDatabase Database::Connect() {
|
|||
}
|
||||
|
||||
if (!db.open()) {
|
||||
app_->AddError(u"Database: "_s + db.lastError().text());
|
||||
Q_EMIT Error(u"Database: "_s + db.lastError().text());
|
||||
return db;
|
||||
}
|
||||
|
||||
|
@ -492,7 +491,7 @@ void Database::ReportErrors(const SqlQuery &query) {
|
|||
bool Database::IntegrityCheck(const QSqlDatabase &db) {
|
||||
|
||||
qLog(Debug) << "Starting database integrity check";
|
||||
const int task_id = app_->task_manager()->StartTask(tr("Integrity check"));
|
||||
const int task_id = task_manager_->StartTask(tr("Integrity check"));
|
||||
|
||||
bool ok = false;
|
||||
// Ask for 10 error messages at most.
|
||||
|
@ -509,8 +508,8 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) {
|
|||
break;
|
||||
}
|
||||
else {
|
||||
if (!error_reported) { app_->AddError(tr("Database corruption detected.")); }
|
||||
app_->AddError(u"Database: "_s + message);
|
||||
if (!error_reported) { Q_EMIT Error(tr("Database corruption detected.")); }
|
||||
Q_EMIT Error(u"Database: "_s + message);
|
||||
error_reported = true;
|
||||
}
|
||||
}
|
||||
|
@ -519,7 +518,7 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) {
|
|||
ReportErrors(q);
|
||||
}
|
||||
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
|
||||
return ok;
|
||||
|
||||
|
@ -563,7 +562,7 @@ void Database::BackupFile(const QString &filename) {
|
|||
|
||||
qLog(Debug) << "Starting database backup";
|
||||
QString dest_filename = QStringLiteral("%1.bak").arg(filename);
|
||||
const int task_id = app_->task_manager()->StartTask(tr("Backing up database"));
|
||||
const int task_id = task_manager_->StartTask(tr("Backing up database"));
|
||||
|
||||
sqlite3 *source_connection = nullptr;
|
||||
sqlite3 *dest_connection = nullptr;
|
||||
|
@ -575,7 +574,7 @@ void Database::BackupFile(const QString &filename) {
|
|||
if (dest_connection) {
|
||||
sqlite3_close(dest_connection);
|
||||
}
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
});
|
||||
|
||||
bool success = OpenDatabase(filename, &source_connection);
|
||||
|
@ -599,7 +598,7 @@ void Database::BackupFile(const QString &filename) {
|
|||
do {
|
||||
ret = sqlite3_backup_step(backup, 16);
|
||||
const int page_count = sqlite3_backup_pagecount(backup);
|
||||
app_->task_manager()->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count);
|
||||
task_manager_->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count);
|
||||
}
|
||||
while (ret == SQLITE_OK);
|
||||
|
||||
|
|
|
@ -36,16 +36,17 @@
|
|||
#include <QStringList>
|
||||
#include <QRecursiveMutex>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "sqlquery.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class TaskManager;
|
||||
|
||||
class Database : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Database(Application *app, QObject *parent = nullptr, const QString &database_name = QString());
|
||||
explicit Database(SharedPtr<TaskManager> task_manager, QObject *parent = nullptr, const QString &database_name = QString());
|
||||
~Database() override;
|
||||
|
||||
static const int kSchemaVersion;
|
||||
|
@ -102,7 +103,7 @@ class Database : public QObject {
|
|||
void BackupFile(const QString &filename);
|
||||
static bool OpenDatabase(const QString &filename, sqlite3 **connection);
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
|
||||
// Alias -> filename
|
||||
QMap<QString, AttachedDatabase> attached_databases_;
|
||||
|
@ -130,16 +131,4 @@ class Database : public QObject {
|
|||
|
||||
};
|
||||
|
||||
class MemoryDatabase : public Database {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MemoryDatabase(Application *app, QObject *parent = nullptr)
|
||||
: Database(app, parent, QStringLiteral(":memory:")) {}
|
||||
~MemoryDatabase() override {
|
||||
// Make sure Qt doesn't reuse the same database
|
||||
QSqlDatabase::removeDatabase(Connect().connectionName());
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DATABASE_H
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "memorydatabase.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
MemoryDatabase::MemoryDatabase(SharedPtr<TaskManager> task_manager, QObject *parent)
|
||||
: Database(task_manager, parent, u":memory:"_s) {}
|
||||
|
||||
MemoryDatabase::~MemoryDatabase() {
|
||||
// Make sure Qt doesn't reuse the same database
|
||||
Close();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MEMORYDATABASE_H
|
||||
#define MEMORYDATABASE_H
|
||||
|
||||
#include "shared_ptr.h"
|
||||
|
||||
class TaskManager;
|
||||
|
||||
#include "database.h"
|
||||
|
||||
class MemoryDatabase : public Database {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MemoryDatabase(SharedPtr<TaskManager> task_manager, QObject *parent = nullptr);
|
||||
~MemoryDatabase() override;
|
||||
};
|
||||
|
||||
#endif // MEMORYDATABASE_H
|
|
@ -55,7 +55,7 @@
|
|||
#include "utilities/strutils.h"
|
||||
#include "utilities/timeutils.h"
|
||||
#include "utilities/coverutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "utilities/sqlhelper.h"
|
||||
|
||||
#include "song.h"
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "core/logging.h"
|
||||
|
||||
#include "urlhandlers.h"
|
||||
#include "urlhandler.h"
|
||||
|
||||
UrlHandlers::UrlHandlers(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void UrlHandlers::Register(UrlHandler *url_handler) {
|
||||
|
||||
const QString scheme = url_handler->scheme();
|
||||
|
||||
if (url_handlers_.contains(scheme)) {
|
||||
qLog(Warning) << "Tried to register a URL handler for" << scheme << "but one was already registered";
|
||||
return;
|
||||
}
|
||||
|
||||
qLog(Info) << "Registered URL handler for" << scheme;
|
||||
url_handlers_.insert(scheme, url_handler);
|
||||
QObject::connect(url_handler, &UrlHandler::destroyed, this, &UrlHandlers::Destroyed);
|
||||
|
||||
Q_EMIT Registered(url_handler);
|
||||
|
||||
}
|
||||
|
||||
void UrlHandlers::Unregister(UrlHandler *url_handler) {
|
||||
|
||||
const QString scheme = url_handlers_.key(url_handler);
|
||||
if (scheme.isEmpty()) {
|
||||
qLog(Warning) << "Tried to unregister a URL handler for" << url_handler->scheme() << "that wasn't registered";
|
||||
return;
|
||||
}
|
||||
|
||||
qLog(Info) << "Unregistered URL handler for" << scheme;
|
||||
url_handlers_.remove(scheme);
|
||||
QObject::disconnect(url_handler, &UrlHandler::destroyed, this, &UrlHandlers::Destroyed);
|
||||
QObject::disconnect(url_handler, &UrlHandler::AsyncLoadComplete, nullptr, nullptr);
|
||||
|
||||
}
|
||||
|
||||
void UrlHandlers::Destroyed(QObject *object) {
|
||||
|
||||
UrlHandler *handler = static_cast<UrlHandler*>(object);
|
||||
const QString scheme = url_handlers_.key(handler);
|
||||
if (!scheme.isEmpty()) {
|
||||
url_handlers_.remove(scheme);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool UrlHandlers::CanHandle(const QString &scheme) const {
|
||||
|
||||
return url_handlers_.contains(scheme);
|
||||
|
||||
}
|
||||
|
||||
bool UrlHandlers::CanHandle(const QUrl &url) const {
|
||||
|
||||
return url_handlers_.contains(url.scheme());
|
||||
|
||||
}
|
||||
|
||||
UrlHandler *UrlHandlers::GetUrlHandler(const QString &scheme) const {
|
||||
|
||||
if (!CanHandle(scheme)) return nullptr;
|
||||
|
||||
return url_handlers_.value(scheme);
|
||||
|
||||
}
|
||||
|
||||
UrlHandler *UrlHandlers::GetUrlHandler(const QUrl &url) const {
|
||||
|
||||
return GetUrlHandler(url.scheme());
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef URLHANDLERS_H
|
||||
#define URLHANDLERS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
class UrlHandler;
|
||||
|
||||
class UrlHandlers : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UrlHandlers(QObject *parent = nullptr);
|
||||
|
||||
void Register(UrlHandler *url_handler);
|
||||
void Unregister(UrlHandler *url_handler);
|
||||
void Destroyed(QObject *object);
|
||||
|
||||
bool CanHandle(const QString &scheme) const;
|
||||
bool CanHandle(const QUrl &url) const;
|
||||
|
||||
UrlHandler *GetUrlHandler(const QString &scheme) const;
|
||||
UrlHandler *GetUrlHandler(const QUrl &url) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void Registered(UrlHandler *url_handler);
|
||||
void UnRegistered(UrlHandler *url_handler);
|
||||
|
||||
private:
|
||||
QMap<QString, UrlHandler*> url_handlers_;
|
||||
};
|
||||
|
||||
#endif // URLHANDLERS_H
|
|
@ -54,13 +54,12 @@
|
|||
#include <QSettings>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "utilities/filenameconstants.h"
|
||||
#include "constants/filenameconstants.h"
|
||||
#include "utilities/strutils.h"
|
||||
#include "utilities/mimeutils.h"
|
||||
#include "utilities/coveroptions.h"
|
||||
#include "utilities/coverutils.h"
|
||||
#include "utilities/screenutils.h"
|
||||
#include "core/application.h"
|
||||
#include "core/song.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/settings.h"
|
||||
|
@ -88,7 +87,6 @@ QSet<QString> *AlbumCoverChoiceController::sImageExtensions = nullptr;
|
|||
|
||||
AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
app_(nullptr),
|
||||
cover_searcher_(nullptr),
|
||||
cover_fetcher_(nullptr),
|
||||
save_file_dialog_(nullptr),
|
||||
|
@ -130,12 +128,20 @@ AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget *parent)
|
|||
|
||||
AlbumCoverChoiceController::~AlbumCoverChoiceController() = default;
|
||||
|
||||
void AlbumCoverChoiceController::Init(Application *app) {
|
||||
void AlbumCoverChoiceController::Init(SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<CollectionBackend> collection_backend,
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader,
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
SharedPtr<CoverProviders> cover_providers,
|
||||
SharedPtr<StreamingServices> streaming_services) {
|
||||
|
||||
app_ = app;
|
||||
network_ = network;
|
||||
collection_backend_ = collection_backend;
|
||||
current_albumcover_loader_ = current_albumcover_loader;
|
||||
streaming_services_ = streaming_services;
|
||||
|
||||
cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), app->network(), this);
|
||||
cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), app, this);
|
||||
cover_fetcher_ = new AlbumCoverFetcher(cover_providers, network, this);
|
||||
cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), album_cover_loader, this);
|
||||
cover_searcher_->Init(cover_fetcher_);
|
||||
|
||||
QObject::connect(cover_fetcher_, &AlbumCoverFetcher::AlbumCoverFetched, this, &AlbumCoverChoiceController::AlbumCoverFetched);
|
||||
|
@ -316,7 +322,7 @@ void AlbumCoverChoiceController::LoadCoverFromURL(Song *song) {
|
|||
|
||||
AlbumCoverImageResult AlbumCoverChoiceController::LoadImageFromURL() {
|
||||
|
||||
if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(app_->network(), this); }
|
||||
if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(network_, this); }
|
||||
|
||||
return cover_from_url_dialog_->Exec();
|
||||
|
||||
|
@ -548,11 +554,11 @@ void AlbumCoverChoiceController::SaveArtEmbeddedToSong(Song *song, const bool ar
|
|||
song->set_art_unset(false);
|
||||
|
||||
if (song->source() == Song::Source::Collection) {
|
||||
app_->collection_backend()->UpdateEmbeddedAlbumArtAsync(song->effective_albumartist(), song->album(), art_embedded);
|
||||
collection_backend_->UpdateEmbeddedAlbumArtAsync(song->effective_albumartist(), song->album(), art_embedded);
|
||||
}
|
||||
|
||||
if (*song == app_->current_albumcover_loader()->last_song()) {
|
||||
app_->current_albumcover_loader()->LoadAlbumCover(*song);
|
||||
if (*song == current_albumcover_loader_->last_song()) {
|
||||
current_albumcover_loader_->LoadAlbumCover(*song);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -567,7 +573,7 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art
|
|||
// Update the backends.
|
||||
switch (song->source()) {
|
||||
case Song::Source::Collection:
|
||||
app_->collection_backend()->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual);
|
||||
collection_backend_->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual);
|
||||
break;
|
||||
case Song::Source::LocalFile:
|
||||
case Song::Source::CDDA:
|
||||
|
@ -581,7 +587,7 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art
|
|||
case Song::Source::Tidal:
|
||||
case Song::Source::Spotify:
|
||||
case Song::Source::Qobuz:
|
||||
StreamingServicePtr service = app_->streaming_services()->ServiceBySource(song->source());
|
||||
StreamingServicePtr service = streaming_services_->ServiceBySource(song->source());
|
||||
if (!service) break;
|
||||
if (service->artists_collection_backend()) {
|
||||
service->artists_collection_backend()->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual);
|
||||
|
@ -595,8 +601,8 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art
|
|||
break;
|
||||
}
|
||||
|
||||
if (*song == app_->current_albumcover_loader()->last_song()) {
|
||||
app_->current_albumcover_loader()->LoadAlbumCover(*song);
|
||||
if (*song == current_albumcover_loader_->last_song()) {
|
||||
current_albumcover_loader_->LoadAlbumCover(*song);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -611,11 +617,11 @@ void AlbumCoverChoiceController::ClearAlbumCoverForSong(Song *song) {
|
|||
song->clear_art_manual();
|
||||
|
||||
if (song->source() == Song::Source::Collection) {
|
||||
app_->collection_backend()->ClearAlbumArtAsync(song->effective_albumartist(), song->album(), false);
|
||||
collection_backend_->ClearAlbumArtAsync(song->effective_albumartist(), song->album(), false);
|
||||
}
|
||||
|
||||
if (*song == app_->current_albumcover_loader()->last_song()) {
|
||||
app_->current_albumcover_loader()->LoadAlbumCover(*song);
|
||||
if (*song == current_albumcover_loader_->last_song()) {
|
||||
current_albumcover_loader_->LoadAlbumCover(*song);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -630,11 +636,11 @@ void AlbumCoverChoiceController::UnsetAlbumCoverForSong(Song *song) {
|
|||
song->clear_art_automatic();
|
||||
|
||||
if (song->source() == Song::Source::Collection) {
|
||||
app_->collection_backend()->UnsetAlbumArtAsync(song->effective_albumartist(), song->album());
|
||||
collection_backend_->UnsetAlbumArtAsync(song->effective_albumartist(), song->album());
|
||||
}
|
||||
|
||||
if (*song == app_->current_albumcover_loader()->last_song()) {
|
||||
app_->current_albumcover_loader()->LoadAlbumCover(*song);
|
||||
if (*song == current_albumcover_loader_->last_song()) {
|
||||
current_albumcover_loader_->LoadAlbumCover(*song);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -718,7 +724,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToCollectionSongs(const Song &
|
|||
|
||||
void AlbumCoverChoiceController::SaveCoverEmbeddedToCollectionSongs(const QString &effective_albumartist, const QString &effective_album, const QString &cover_filename, const QByteArray &image_data, const QString &mime_type) {
|
||||
|
||||
QFuture<SongList> future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, app_->collection_backend(), effective_albumartist, effective_album, CollectionFilterOptions());
|
||||
QFuture<SongList> future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, collection_backend_, effective_albumartist, effective_album, CollectionFilterOptions());
|
||||
QFutureWatcher<SongList> *watcher = new QFutureWatcher<SongList>();
|
||||
QObject::connect(watcher, &QFutureWatcher<SongList>::finished, this, [this, watcher, cover_filename, image_data, mime_type]() {
|
||||
const SongList collection_songs = watcher->result();
|
||||
|
@ -736,7 +742,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToSong(const Song &song, const
|
|||
QMutexLocker l(&mutex_cover_save_tasks_);
|
||||
cover_save_tasks_.append(song);
|
||||
const bool art_embedded = !image_data.isNull();
|
||||
TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(song.url().toLocalFile(), SaveTagCoverData(cover_filename, image_data, mime_type));
|
||||
TagReaderReplyPtr reply = TagReaderClient::Instance()->SaveCoverAsync(song.url().toLocalFile(), SaveTagCoverData(cover_filename, image_data, mime_type));
|
||||
QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, song, art_embedded]() { SaveEmbeddedCoverFinished(reply, song, art_embedded); });
|
||||
|
||||
}
|
||||
|
|
|
@ -50,11 +50,16 @@ class QMenu;
|
|||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
class CollectionBackend;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class CoverProviders;
|
||||
class AlbumCoverFetcher;
|
||||
class AlbumCoverSearcher;
|
||||
class CoverFromURLDialog;
|
||||
struct CoverSearchStatistics;
|
||||
class StreamingServices;
|
||||
|
||||
// Controller for the common album cover related menu options.
|
||||
class AlbumCoverChoiceController : public QWidget {
|
||||
|
@ -68,7 +73,13 @@ class AlbumCoverChoiceController : public QWidget {
|
|||
explicit AlbumCoverChoiceController(QWidget *parent = nullptr);
|
||||
~AlbumCoverChoiceController() override;
|
||||
|
||||
void Init(Application *app);
|
||||
void Init(SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<CollectionBackend> collection_backend,
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader,
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
SharedPtr<CoverProviders> cover_providers,
|
||||
SharedPtr<StreamingServices> streaming_services);
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
CoverOptions::CoverType get_save_album_cover_type() const { return (save_embedded_cover_override_ ? CoverOptions::CoverType::Embedded : cover_options_.cover_type); }
|
||||
|
@ -172,7 +183,11 @@ class AlbumCoverChoiceController : public QWidget {
|
|||
static bool IsKnownImageExtension(const QString &suffix);
|
||||
static QSet<QString> *sImageExtensions;
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
SharedPtr<StreamingServices> streaming_services_;
|
||||
|
||||
AlbumCoverSearcher *cover_searcher_;
|
||||
AlbumCoverFetcher *cover_fetcher_;
|
||||
|
||||
|
|
|
@ -64,10 +64,10 @@
|
|||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/application.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/database.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/database.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "utilities/strutils.h"
|
||||
#include "utilities/fileutils.h"
|
||||
#include "utilities/imageutils.h"
|
||||
|
@ -79,7 +79,6 @@
|
|||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionquery.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "coverproviders.h"
|
||||
#include "albumcovermanager.h"
|
||||
#include "albumcoversearcher.h"
|
||||
#include "albumcoverchoicecontroller.h"
|
||||
|
@ -88,6 +87,7 @@
|
|||
#include "albumcoverfetcher.h"
|
||||
#include "albumcoverloader.h"
|
||||
#include "albumcoverloaderresult.h"
|
||||
#include "coverproviders.h"
|
||||
#include "coversearchstatistics.h"
|
||||
#include "coversearchstatisticsdialog.h"
|
||||
#include "albumcoverimageresult.h"
|
||||
|
@ -102,18 +102,28 @@ constexpr char kSettingsGroup[] = "CoverManager";
|
|||
constexpr int kThumbnailSize = 120;
|
||||
}
|
||||
|
||||
AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtr<CollectionBackend> collection_backend, QMainWindow *mainwindow, QWidget *parent)
|
||||
AlbumCoverManager::AlbumCoverManager(SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<CollectionBackend> collection_backend,
|
||||
SharedPtr<TagReaderClient> tagreader_client,
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader,
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
SharedPtr<CoverProviders> cover_providers,
|
||||
SharedPtr<StreamingServices> streaming_services,
|
||||
QMainWindow *mainwindow, QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
ui_(new Ui_CoverManager),
|
||||
mainwindow_(mainwindow),
|
||||
app_(app),
|
||||
network_(network),
|
||||
collection_backend_(collection_backend),
|
||||
tagreader_client_(tagreader_client),
|
||||
album_cover_loader_(album_cover_loader),
|
||||
cover_providers_(cover_providers),
|
||||
album_cover_choice_controller_(new AlbumCoverChoiceController(this)),
|
||||
timer_album_cover_load_(new QTimer(this)),
|
||||
filter_all_(nullptr),
|
||||
filter_with_covers_(nullptr),
|
||||
filter_without_covers_(nullptr),
|
||||
cover_fetcher_(new AlbumCoverFetcher(app_->cover_providers(), app_->network(), this)),
|
||||
cover_fetcher_(new AlbumCoverFetcher(cover_providers, network, this)),
|
||||
cover_searcher_(nullptr),
|
||||
cover_export_(nullptr),
|
||||
cover_exporter_(new AlbumCoverExporter(this)),
|
||||
|
@ -142,9 +152,9 @@ AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtr<CollectionBacke
|
|||
ui_->action_add_to_playlist->setIcon(IconLoader::Load(u"media-playback-start"_s));
|
||||
ui_->action_load->setIcon(IconLoader::Load(u"media-playback-start"_s));
|
||||
|
||||
album_cover_choice_controller_->Init(app_);
|
||||
album_cover_choice_controller_->Init(network, collection_backend, album_cover_loader, current_albumcover_loader, cover_providers, streaming_services);
|
||||
|
||||
cover_searcher_ = new AlbumCoverSearcher(icon_nocover_item_, app_, this);
|
||||
cover_searcher_ = new AlbumCoverSearcher(icon_nocover_item_, album_cover_loader_, this);
|
||||
cover_export_ = new AlbumCoverExport(this);
|
||||
|
||||
// Set up the status bar
|
||||
|
@ -241,7 +251,7 @@ void AlbumCoverManager::Init() {
|
|||
|
||||
s.endGroup();
|
||||
|
||||
QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverManager::AlbumCoverLoaded);
|
||||
QObject::connect(&*album_cover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverManager::AlbumCoverLoaded);
|
||||
|
||||
cover_searcher_->Init(cover_fetcher_);
|
||||
|
||||
|
@ -320,7 +330,7 @@ void AlbumCoverManager::SaveSettings() {
|
|||
|
||||
void AlbumCoverManager::CancelRequests() {
|
||||
|
||||
app_->album_cover_loader()->CancelTasks(QSet<quint64>(cover_loading_tasks_.keyBegin(), cover_loading_tasks_.keyEnd()));
|
||||
album_cover_loader_->CancelTasks(QSet<quint64>(cover_loading_tasks_.keyBegin(), cover_loading_tasks_.keyEnd()));
|
||||
cover_loading_pending_.clear();
|
||||
cover_loading_tasks_.clear();
|
||||
cover_save_tasks_.clear();
|
||||
|
@ -363,7 +373,7 @@ void AlbumCoverManager::Reset() {
|
|||
}
|
||||
|
||||
void AlbumCoverManager::EnableCoversButtons() {
|
||||
ui_->button_fetch->setEnabled(app_->cover_providers()->HasAnyProviders());
|
||||
ui_->button_fetch->setEnabled(cover_providers_->HasAnyProviders());
|
||||
ui_->export_covers->setEnabled(true);
|
||||
}
|
||||
|
||||
|
@ -466,7 +476,7 @@ void AlbumCoverManager::LoadAlbumCoverAsync(AlbumItem *album_item) {
|
|||
cover_options.types = cover_types_;
|
||||
cover_options.desired_scaled_size = QSize(kThumbnailSize, kThumbnailSize);
|
||||
cover_options.device_pixel_ratio = devicePixelRatioF();
|
||||
quint64 cover_load_id = app_->album_cover_loader()->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst());
|
||||
quint64 cover_load_id = album_cover_loader_->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst());
|
||||
cover_loading_tasks_.insert(cover_load_id, album_item);
|
||||
|
||||
}
|
||||
|
@ -643,7 +653,7 @@ bool AlbumCoverManager::eventFilter(QObject *obj, QEvent *e) {
|
|||
album_cover_choice_controller_->cover_to_file_action()->setEnabled(some_with_covers);
|
||||
album_cover_choice_controller_->cover_from_file_action()->setEnabled(context_menu_items_.size() == 1);
|
||||
album_cover_choice_controller_->cover_from_url_action()->setEnabled(context_menu_items_.size() == 1);
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(app_->cover_providers()->HasAnyProviders());
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(cover_providers_->HasAnyProviders());
|
||||
album_cover_choice_controller_->unset_cover_action()->setEnabled(some_with_covers || some_clear);
|
||||
album_cover_choice_controller_->clear_cover_action()->setEnabled(some_with_covers || some_unset);
|
||||
album_cover_choice_controller_->delete_cover_action()->setEnabled(some_with_covers);
|
||||
|
@ -844,7 +854,7 @@ void AlbumCoverManager::SaveImageToAlbums(Song *song, const AlbumCoverImageResul
|
|||
case CoverOptions::CoverType::Embedded:{
|
||||
for (const QUrl &url : std::as_const(album_item->urls)) {
|
||||
const bool art_embedded = !result.image_data.isEmpty();
|
||||
TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.image_data, result.mime_type));
|
||||
TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.image_data, result.mime_type));
|
||||
QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, album_item, url, art_embedded]() {
|
||||
SaveEmbeddedCoverFinished(reply, album_item, url, art_embedded);
|
||||
});
|
||||
|
@ -994,7 +1004,7 @@ void AlbumCoverManager::SaveAndSetCover(AlbumItem *album_item, const AlbumCoverI
|
|||
if (album_cover_choice_controller_->get_save_album_cover_type() == CoverOptions::CoverType::Embedded && Song::save_embedded_cover_supported(filetype) && !has_cue) {
|
||||
for (const QUrl &url : urls) {
|
||||
const bool art_embedded = !result.image_data.isEmpty();
|
||||
TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.cover_url.isValid() ? result.cover_url.toLocalFile() : QString(), result.image_data, result.mime_type));
|
||||
TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.cover_url.isValid() ? result.cover_url.toLocalFile() : QString(), result.image_data, result.mime_type));
|
||||
QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, album_item, url, art_embedded]() {
|
||||
SaveEmbeddedCoverFinished(reply, album_item, url, art_embedded);
|
||||
});
|
||||
|
|
|
@ -55,8 +55,11 @@ class QEvent;
|
|||
class QCloseEvent;
|
||||
class QShowEvent;
|
||||
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
class CollectionBackend;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class CoverProviders;
|
||||
class SongMimeData;
|
||||
class AlbumCoverExport;
|
||||
class AlbumCoverExporter;
|
||||
|
@ -78,7 +81,15 @@ class AlbumCoverManager : public QMainWindow {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AlbumCoverManager(Application *app, SharedPtr<CollectionBackend> collection_backend, QMainWindow *mainwindow, QWidget *parent = nullptr);
|
||||
explicit AlbumCoverManager(SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<CollectionBackend> collection_backend,
|
||||
SharedPtr<TagReaderClient> tagreader_client,
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader,
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
SharedPtr<CoverProviders> cover_providers,
|
||||
SharedPtr<StreamingServices> streaming_services,
|
||||
QMainWindow *mainwindow,
|
||||
QWidget *parent = nullptr);
|
||||
~AlbumCoverManager() override;
|
||||
|
||||
void Reset();
|
||||
|
@ -190,8 +201,11 @@ class AlbumCoverManager : public QMainWindow {
|
|||
private:
|
||||
Ui_CoverManager *ui_;
|
||||
QMainWindow *mainwindow_;
|
||||
Application *app_;
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
SharedPtr<TagReaderClient> tagreader_client_;
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader_;
|
||||
SharedPtr<CoverProviders> cover_providers_;
|
||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||
QTimer *timer_album_cover_load_;
|
||||
|
||||
|
|
|
@ -47,9 +47,7 @@
|
|||
#include <QKeySequence>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "utilities/strutils.h"
|
||||
#include "utilities/timeutils.h"
|
||||
#include "utilities/mimeutils.h"
|
||||
#include "widgets/busyindicator.h"
|
||||
#include "widgets/forcescrollperpixel.h"
|
||||
|
@ -114,10 +112,10 @@ void SizeOverlayDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o
|
|||
|
||||
}
|
||||
|
||||
AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, Application *app, QWidget *parent)
|
||||
AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, SharedPtr<AlbumCoverLoader> album_cover_loader, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui_(new Ui_AlbumCoverSearcher),
|
||||
app_(app),
|
||||
album_cover_loader_(album_cover_loader),
|
||||
model_(new QStandardItemModel(this)),
|
||||
no_cover_icon_(no_cover_icon),
|
||||
fetcher_(nullptr),
|
||||
|
@ -132,7 +130,7 @@ AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, Application *
|
|||
ui_->covers->setItemDelegate(new SizeOverlayDelegate(this));
|
||||
ui_->covers->setModel(model_);
|
||||
|
||||
QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverSearcher::AlbumCoverLoaded);
|
||||
QObject::connect(&*album_cover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverSearcher::AlbumCoverLoaded);
|
||||
QObject::connect(ui_->search, &QPushButton::clicked, this, &AlbumCoverSearcher::Search);
|
||||
QObject::connect(ui_->covers, &GroupedIconView::doubleClicked, this, &AlbumCoverSearcher::CoverDoubleClicked);
|
||||
|
||||
|
@ -220,7 +218,7 @@ void AlbumCoverSearcher::SearchFinished(const quint64 id, const CoverProviderSea
|
|||
|
||||
AlbumCoverLoaderOptions cover_options(AlbumCoverLoaderOptions::Option::RawImageData | AlbumCoverLoaderOptions::Option::OriginalImage | AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage);
|
||||
cover_options.desired_scaled_size = ui_->covers->iconSize(), ui_->covers->iconSize();
|
||||
quint64 new_id = app_->album_cover_loader()->LoadImageAsync(cover_options, false, result.image_url, QUrl(), false);
|
||||
quint64 new_id = album_cover_loader_->LoadImageAsync(cover_options, false, result.image_url, QUrl(), false);
|
||||
|
||||
QStandardItem *item = new QStandardItem;
|
||||
item->setIcon(no_cover_icon_);
|
||||
|
|
|
@ -48,7 +48,7 @@ class QPainter;
|
|||
class QModelIndex;
|
||||
class QKeyEvent;
|
||||
|
||||
class Application;
|
||||
class AlbumCoverLoader;
|
||||
class Ui_AlbumCoverSearcher;
|
||||
|
||||
class SizeOverlayDelegate : public QStyledItemDelegate {
|
||||
|
@ -65,7 +65,7 @@ class AlbumCoverSearcher : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AlbumCoverSearcher(const QIcon &no_cover_icon, Application *app, QWidget *parent);
|
||||
explicit AlbumCoverSearcher(const QIcon &no_cover_icon, SharedPtr<AlbumCoverLoader> album_cover_loader, QWidget *parent);
|
||||
~AlbumCoverSearcher() override;
|
||||
|
||||
enum Role {
|
||||
|
@ -95,7 +95,7 @@ class AlbumCoverSearcher : public QDialog {
|
|||
private:
|
||||
Ui_AlbumCoverSearcher *ui_;
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader_;
|
||||
QStandardItemModel *model_;
|
||||
|
||||
QIcon no_cover_icon_;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <QString>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "coverprovider.h"
|
||||
|
||||
CoverProvider::CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent) : QObject(parent), app_(app), network_(network), name_(name), enabled_(enabled), order_(0), authentication_required_(authentication_required), quality_(quality), batch_(batch), allow_missing_album_(allow_missing_album) {}
|
||||
CoverProvider::CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, SharedPtr<NetworkAccessManager> network, QObject *parent) : QObject(parent), network_(network), name_(name), enabled_(enabled), order_(0), authentication_required_(authentication_required), quality_(quality), batch_(batch), allow_missing_album_(allow_missing_album) {}
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "core/shared_ptr.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
|
||||
// Each implementation of this interface downloads covers from one online service.
|
||||
|
@ -42,7 +41,7 @@ class CoverProvider : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent);
|
||||
explicit CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, SharedPtr<NetworkAccessManager> network, QObject *parent);
|
||||
|
||||
// A name (very short description) of this provider, like "last.fm".
|
||||
QString name() const { return name_; }
|
||||
|
@ -79,7 +78,6 @@ class CoverProvider : public QObject {
|
|||
using Param = QPair<QString, QString>;
|
||||
using ParamList = QList<Param>;
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
QString name_;
|
||||
bool enabled_;
|
||||
|
|
|
@ -29,10 +29,9 @@
|
|||
#include <QImage>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/song.h"
|
||||
#include "core/temporaryfile.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "albumcoverloader.h"
|
||||
#include "albumcoverloaderresult.h"
|
||||
#include "currentalbumcoverloader.h"
|
||||
|
@ -40,9 +39,9 @@
|
|||
using std::make_unique;
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(Application *app, QObject *parent)
|
||||
CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(SharedPtr<AlbumCoverLoader> albumcover_loader, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
albumcover_loader_(albumcover_loader),
|
||||
temp_file_pattern_(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + u"/strawberry-cover-XXXXXX.jpg"_s),
|
||||
id_(0) {
|
||||
|
||||
|
@ -52,8 +51,7 @@ CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(Application *app, QObject *pare
|
|||
options_.desired_scaled_size = QSize(120, 120);
|
||||
options_.default_cover = u":/pictures/cdcase.png"_s;
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &CurrentAlbumCoverLoader::LoadAlbumCover);
|
||||
QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CurrentAlbumCoverLoader::AlbumCoverReady);
|
||||
QObject::connect(&*albumcover_loader, &AlbumCoverLoader::AlbumCoverLoaded, this, &CurrentAlbumCoverLoader::AlbumCoverReady);
|
||||
|
||||
ReloadSettingsAsync();
|
||||
|
||||
|
@ -76,7 +74,7 @@ void CurrentAlbumCoverLoader::ReloadSettings() {
|
|||
void CurrentAlbumCoverLoader::LoadAlbumCover(const Song &song) {
|
||||
|
||||
last_song_ = song;
|
||||
id_ = app_->album_cover_loader()->LoadImageAsync(options_, last_song_);
|
||||
id_ = albumcover_loader_->LoadImageAsync(options_, last_song_);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -30,18 +30,19 @@
|
|||
#include <QImage>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/temporaryfile.h"
|
||||
#include "core/song.h"
|
||||
#include "albumcoverloaderoptions.h"
|
||||
#include "albumcoverloaderresult.h"
|
||||
|
||||
class Application;
|
||||
class AlbumCoverLoader;
|
||||
|
||||
class CurrentAlbumCoverLoader : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CurrentAlbumCoverLoader(Application *app, QObject *parent = nullptr);
|
||||
explicit CurrentAlbumCoverLoader(SharedPtr<AlbumCoverLoader> albumcover_loader, QObject *parent = nullptr);
|
||||
~CurrentAlbumCoverLoader() override;
|
||||
|
||||
const AlbumCoverLoaderOptions &options() const { return options_; }
|
||||
|
@ -61,7 +62,7 @@ class CurrentAlbumCoverLoader : public QObject {
|
|||
void AlbumCoverReady(const quint64 id, AlbumCoverLoaderResult result);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<AlbumCoverLoader> albumcover_loader_;
|
||||
AlbumCoverLoaderOptions options_;
|
||||
|
||||
QString temp_file_pattern_;
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/song.h"
|
||||
|
@ -55,8 +54,8 @@ constexpr char kApiUrl[] = "https://api.deezer.com";
|
|||
constexpr int kLimit = 10;
|
||||
}
|
||||
|
||||
DeezerCoverProvider::DeezerCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Deezer"_s, true, false, 2.0, true, true, app, network, parent) {}
|
||||
DeezerCoverProvider::DeezerCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Deezer"_s, true, false, 2.0, true, true, network, parent) {}
|
||||
|
||||
DeezerCoverProvider::~DeezerCoverProvider() {
|
||||
|
||||
|
|
|
@ -34,13 +34,12 @@
|
|||
|
||||
class NetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class Application;
|
||||
|
||||
class DeezerCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeezerCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit DeezerCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~DeezerCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include <QJsonArray>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "utilities/cryptutils.h"
|
||||
|
@ -58,8 +57,8 @@ const char *DiscogsCoverProvider::kAccessKeyB64 = "dGh6ZnljUGJlZ1NEeXBuSFFxSVk="
|
|||
const char *DiscogsCoverProvider::kSecretKeyB64 = "ZkFIcmlaSER4aHhRSlF2U3d0bm5ZVmdxeXFLWUl0UXI=";
|
||||
const int DiscogsCoverProvider::kRequestsDelay = 1000;
|
||||
|
||||
DiscogsCoverProvider::DiscogsCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Discogs"_s, false, false, 0.0, false, false, app, network, parent),
|
||||
DiscogsCoverProvider::DiscogsCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Discogs"_s, false, false, 0.0, false, false, network, parent),
|
||||
timer_flush_requests_(new QTimer(this)) {
|
||||
|
||||
timer_flush_requests_->setInterval(kRequestsDelay);
|
||||
|
|
|
@ -42,13 +42,12 @@
|
|||
class NetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QTimer;
|
||||
class Application;
|
||||
|
||||
class DiscogsCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DiscogsCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit DiscogsCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~DiscogsCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -26,15 +26,14 @@
|
|||
#include <QJsonObject>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "coverprovider.h"
|
||||
#include "jsoncoverprovider.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
JsonCoverProvider::JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: CoverProvider(name, enabled, authentication_required, quality, batch, allow_missing_album, app, network, parent) {}
|
||||
JsonCoverProvider::JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: CoverProvider(name, enabled, authentication_required, quality, batch, allow_missing_album, network, parent) {}
|
||||
|
||||
QJsonObject JsonCoverProvider::ExtractJsonObj(const QByteArray &data) {
|
||||
|
||||
|
|
|
@ -30,14 +30,13 @@
|
|||
#include "core/shared_ptr.h"
|
||||
#include "coverprovider.h"
|
||||
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
|
||||
class JsonCoverProvider : public CoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent);
|
||||
explicit JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, SharedPtr<NetworkAccessManager> network, QObject *parent);
|
||||
|
||||
protected:
|
||||
QJsonObject ExtractJsonObj(const QByteArray &data);
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <QJsonArray>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
|
||||
|
@ -55,8 +54,8 @@ constexpr char kApiKey[] = "211990b4c96782c05d1536e7219eb56e";
|
|||
constexpr char kSecret[] = "80fd738f49596e9709b1bf9319c444a8";
|
||||
} // namespace
|
||||
|
||||
LastFmCoverProvider::LastFmCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Last.fm"_s, true, false, 1.0, true, false, app, network, parent) {}
|
||||
LastFmCoverProvider::LastFmCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Last.fm"_s, true, false, 1.0, true, false, network, parent) {}
|
||||
|
||||
LastFmCoverProvider::~LastFmCoverProvider() {
|
||||
|
||||
|
|
|
@ -34,13 +34,12 @@
|
|||
|
||||
class NetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class Application;
|
||||
|
||||
class LastFmCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LastFmCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit LastFmCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~LastFmCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <QJsonArray>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
|
@ -53,8 +52,8 @@ constexpr int kLimit = 8;
|
|||
constexpr int kRequestsDelay = 1000;
|
||||
} // namespace
|
||||
|
||||
MusicbrainzCoverProvider::MusicbrainzCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"MusicBrainz"_s, true, false, 1.5, true, false, app, network, parent),
|
||||
MusicbrainzCoverProvider::MusicbrainzCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"MusicBrainz"_s, true, false, 1.5, true, false, network, parent),
|
||||
timer_flush_requests_(new QTimer(this)) {
|
||||
|
||||
timer_flush_requests_->setInterval(kRequestsDelay);
|
||||
|
|
|
@ -35,14 +35,13 @@
|
|||
|
||||
class QNetworkReply;
|
||||
class QTimer;
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
|
||||
class MusicbrainzCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MusicbrainzCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit MusicbrainzCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~MusicbrainzCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
MusixmatchCoverProvider::MusixmatchCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Musixmatch"_s, true, false, 1.0, true, false, app, network, parent) {}
|
||||
MusixmatchCoverProvider::MusixmatchCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Musixmatch"_s, true, false, 1.0, true, false, network, parent) {}
|
||||
|
||||
MusixmatchCoverProvider::~MusixmatchCoverProvider() {
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class MusixmatchCoverProvider : public JsonCoverProvider, MusixmatchProvider {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MusixmatchCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit MusixmatchCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~MusixmatchCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -38,11 +38,11 @@
|
|||
#include <QTimer>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "core/song.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
#include "jsoncoverprovider.h"
|
||||
#include "opentidalcoverprovider.h"
|
||||
|
@ -61,8 +61,8 @@ constexpr const int kRequestsDelay = 1000;
|
|||
|
||||
using std::make_shared;
|
||||
|
||||
OpenTidalCoverProvider::OpenTidalCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"OpenTidal"_s, true, false, 2.5, true, false, app, network, parent),
|
||||
OpenTidalCoverProvider::OpenTidalCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"OpenTidal"_s, true, false, 2.5, true, false, network, parent),
|
||||
login_timer_(new QTimer(this)),
|
||||
timer_flush_requests_(new QTimer(this)),
|
||||
login_in_progress_(false),
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "jsoncoverprovider.h"
|
||||
|
||||
class QNetworkReply;
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
class QTimer;
|
||||
|
||||
|
@ -44,7 +43,7 @@ class OpenTidalCoverProvider : public JsonCoverProvider {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OpenTidalCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit OpenTidalCoverProvider(SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~OpenTidalCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <QJsonArray>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/song.h"
|
||||
|
@ -53,9 +52,9 @@ namespace {
|
|||
constexpr int kLimit = 10;
|
||||
}
|
||||
|
||||
QobuzCoverProvider::QobuzCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Qobuz"_s, true, true, 2.0, true, true, app, network, parent),
|
||||
service_(app->streaming_services()->Service<QobuzService>()) {}
|
||||
QobuzCoverProvider::QobuzCoverProvider(QobuzServicePtr service, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Qobuz"_s, true, true, 2.0, true, true, network, parent),
|
||||
service_(service) {}
|
||||
|
||||
QobuzCoverProvider::~QobuzCoverProvider() {
|
||||
|
||||
|
|
|
@ -35,14 +35,13 @@
|
|||
#include "qobuz/qobuzservice.h"
|
||||
|
||||
class QNetworkReply;
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
|
||||
class QobuzCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QobuzCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit QobuzCoverProvider(QobuzServicePtr service, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~QobuzCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -39,10 +39,8 @@
|
|||
#include <QMessageBox>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "streaming/streamingservices.h"
|
||||
#include "spotify/spotifyservice.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
#include "jsoncoverprovider.h"
|
||||
|
@ -55,9 +53,9 @@ constexpr char kApiUrl[] = "https://api.spotify.com/v1";
|
|||
constexpr int kLimit = 10;
|
||||
} // namespace
|
||||
|
||||
SpotifyCoverProvider::SpotifyCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Spotify"_s, true, true, 2.5, true, true, app, network, parent),
|
||||
service_(app->streaming_services()->Service<SpotifyService>()) {}
|
||||
SpotifyCoverProvider::SpotifyCoverProvider(SpotifyServicePtr service, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Spotify"_s, true, true, 2.5, true, true, network, parent),
|
||||
service_(service) {}
|
||||
|
||||
SpotifyCoverProvider::~SpotifyCoverProvider() {
|
||||
|
||||
|
|
|
@ -39,14 +39,13 @@
|
|||
#include "spotify/spotifyservice.h"
|
||||
|
||||
class QNetworkReply;
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
|
||||
class SpotifyCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SpotifyCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit SpotifyCoverProvider(SpotifyServicePtr service, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~SpotifyCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -35,11 +35,9 @@
|
|||
#include <QJsonArray>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/song.h"
|
||||
#include "streaming/streamingservices.h"
|
||||
#include "tidal/tidalservice.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
#include "jsoncoverprovider.h"
|
||||
|
@ -51,9 +49,9 @@ namespace {
|
|||
constexpr int kLimit = 10;
|
||||
}
|
||||
|
||||
TidalCoverProvider::TidalCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Tidal"_s, true, true, 2.5, true, true, app, network, parent),
|
||||
service_(app->streaming_services()->Service<TidalService>()) {}
|
||||
TidalCoverProvider::TidalCoverProvider(TidalServicePtr service, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: JsonCoverProvider(u"Tidal"_s, true, true, 2.5, true, true, network, parent),
|
||||
service_(service) {}
|
||||
|
||||
TidalCoverProvider::~TidalCoverProvider() {
|
||||
|
||||
|
|
|
@ -37,14 +37,13 @@
|
|||
#include "tidal/tidalservice.h"
|
||||
|
||||
class QNetworkReply;
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
|
||||
class TidalCoverProvider : public JsonCoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TidalCoverProvider(Application *app, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
explicit TidalCoverProvider(TidalServicePtr service, SharedPtr<NetworkAccessManager> network, QObject *parent = nullptr);
|
||||
~TidalCoverProvider() override;
|
||||
|
||||
bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override;
|
||||
|
|
|
@ -30,12 +30,11 @@
|
|||
#include "connecteddevice.h"
|
||||
#include "cddadevice.h"
|
||||
|
||||
class Application;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
|
||||
CddaDevice::CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, int database_id, bool first_time, QObject *parent)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent),
|
||||
CddaDevice::CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, int database_id, bool first_time, QObject *parent)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, task_manager, database, album_cover_loader, database_id, first_time, parent),
|
||||
cdda_song_loader_(url) {
|
||||
|
||||
QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsLoaded, this, &CddaDevice::SongsLoaded);
|
||||
|
|
|
@ -24,22 +24,23 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <cdio/cdio.h>
|
||||
#include <gst/audio/gstaudiocdsrc.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
// These must come after Qt includes
|
||||
#include <cdio/cdio.h>
|
||||
#include <gst/audio/gstaudiocdsrc.h>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
#include "core/musicstorage.h"
|
||||
#include "cddasongloader.h"
|
||||
#include "connecteddevice.h"
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class AlbumCoverLoader;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
|
||||
|
@ -47,7 +48,7 @@ class CddaDevice : public ConnectedDevice {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE explicit CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
Q_INVOKABLE explicit CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
|
||||
bool Init() override;
|
||||
void Refresh() override;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
|
||||
using std::make_shared;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/database.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
|
@ -41,9 +41,8 @@
|
|||
using namespace Qt::Literals::StringLiterals;
|
||||
using std::make_shared;
|
||||
|
||||
ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent)
|
||||
ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
url_(url),
|
||||
first_time_(first_time),
|
||||
lister_(lister),
|
||||
|
@ -58,22 +57,22 @@ ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QS
|
|||
|
||||
// Create the backend in the database thread.
|
||||
backend_ = make_shared<CollectionBackend>();
|
||||
backend_->moveToThread(app_->database()->thread());
|
||||
qLog(Debug) << &*backend_ << "for device" << unique_id_ << "moved to thread" << app_->database()->thread();
|
||||
backend_->moveToThread(database->thread());
|
||||
qLog(Debug) << &*backend_ << "for device" << unique_id_ << "moved to thread" << database->thread();
|
||||
|
||||
if (url_.scheme() != "cdda"_L1) {
|
||||
QObject::connect(&*backend_, &CollectionBackend::TotalSongCountUpdated, this, &ConnectedDevice::BackendTotalSongCountUpdated);
|
||||
}
|
||||
|
||||
backend_->Init(app_->database(),
|
||||
app_->task_manager(),
|
||||
backend_->Init(database,
|
||||
task_manager,
|
||||
Song::Source::Device,
|
||||
QStringLiteral("device_%1_songs").arg(database_id),
|
||||
QStringLiteral("device_%1_directories").arg(database_id),
|
||||
QStringLiteral("device_%1_subdirectories").arg(database_id));
|
||||
|
||||
// Create the model
|
||||
model_ = new CollectionModel(backend_, app_, this);
|
||||
model_ = new CollectionModel(backend_, album_cover_loader, this);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,13 @@
|
|||
#include "core/musicstorage.h"
|
||||
#include "core/song.h"
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class CollectionBackend;
|
||||
class CollectionModel;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
class AlbumCoverLoader;
|
||||
|
||||
using std::enable_shared_from_this;
|
||||
|
||||
|
@ -46,7 +48,7 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
explicit ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
|
||||
Song::Source source() const override { return Song::Source::Device; }
|
||||
|
||||
|
@ -81,13 +83,12 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab
|
|||
void SongCountUpdated(const int count);
|
||||
void DeviceConnectFinished(const QString &id, const bool success);
|
||||
void DeviceCloseFinished(const QString &id);
|
||||
void AddError(const QString &error);
|
||||
|
||||
protected:
|
||||
void InitBackendDirectory(const QString &mount_point, const bool first_time, const bool rewrite_path = true);
|
||||
|
||||
protected:
|
||||
Application *app_;
|
||||
|
||||
QUrl url_;
|
||||
bool first_time_;
|
||||
DeviceLister *lister_;
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "core/logging.h"
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/database.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/musicstorage.h"
|
||||
|
@ -88,20 +87,20 @@ using std::make_unique;
|
|||
const int DeviceManager::kDeviceIconSize = 32;
|
||||
const int DeviceManager::kDeviceIconOverlaySize = 16;
|
||||
|
||||
DeviceManager::DeviceManager(Application *app, QObject *parent)
|
||||
DeviceManager::DeviceManager(SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, QObject *parent)
|
||||
: SimpleTreeModel<DeviceInfo>(new DeviceInfo(this), parent),
|
||||
app_(app),
|
||||
task_manager_(task_manager),
|
||||
not_connected_overlay_(IconLoader::Load(u"edit-delete"_s)) {
|
||||
|
||||
setObjectName(QLatin1String(metaObject()->className()));
|
||||
|
||||
thread_pool_.setMaxThreadCount(1);
|
||||
QObject::connect(&*app_->task_manager(), &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged);
|
||||
QObject::connect(&*task_manager, &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged);
|
||||
|
||||
// Create the backend in the database thread
|
||||
backend_ = make_unique<DeviceDatabaseBackend>();
|
||||
backend_->moveToThread(app_->database()->thread());
|
||||
backend_->Init(app_->database());
|
||||
backend_->moveToThread(database->thread());
|
||||
backend_->Init(database);
|
||||
|
||||
QObject::connect(this, &DeviceManager::DeviceCreatedFromDB, this, &DeviceManager::AddDeviceFromDB);
|
||||
|
||||
|
@ -363,7 +362,7 @@ QVariant DeviceManager::data(const QModelIndex &idx, int role) const {
|
|||
|
||||
QString ret = info->device_->url().path();
|
||||
#ifdef Q_OS_WIN32
|
||||
if (ret.startsWith('/')) ret.remove(0, 1);
|
||||
if (ret.startsWith(u'/')) ret.remove(0, 1);
|
||||
#endif
|
||||
return QDir::toNativeSeparators(ret);
|
||||
}
|
||||
|
@ -627,7 +626,7 @@ SharedPtr<ConnectedDevice> DeviceManager::Connect(DeviceInfo *info) {
|
|||
url_strings << url.toString();
|
||||
}
|
||||
|
||||
app_->AddError(tr("This type of device is not supported: %1").arg(url_strings.join(", "_L1)));
|
||||
Q_EMIT AddError(tr("This type of device is not supported: %1").arg(url_strings.join(", "_L1)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -636,8 +635,10 @@ SharedPtr<ConnectedDevice> DeviceManager::Connect(DeviceInfo *info) {
|
|||
Q_ARG(QUrl, device_url),
|
||||
Q_ARG(DeviceLister*, info->BestBackend()->lister_),
|
||||
Q_ARG(QString, info->BestBackend()->unique_id_),
|
||||
Q_ARG(SharedPtr<DeviceManager>, app_->device_manager()),
|
||||
Q_ARG(Application*, app_),
|
||||
Q_ARG(SharedPtr<DeviceManager>, SharedPtr<DeviceManager>(this)),
|
||||
Q_ARG(SharedPtr<TaskManager>, task_manager_),
|
||||
Q_ARG(SharedPtr<Database>, database_),
|
||||
Q_ARG(SharedPtr<AlbumCoverLoader>, album_cover_loader_),
|
||||
Q_ARG(int, info->database_id_),
|
||||
Q_ARG(bool, first_time));
|
||||
|
||||
|
@ -842,7 +843,7 @@ void DeviceManager::DeviceTaskStarted(const int id) {
|
|||
|
||||
void DeviceManager::TasksChanged() {
|
||||
|
||||
const QList<TaskManager::Task> tasks = app_->task_manager()->GetTasks();
|
||||
const QList<TaskManager::Task> tasks = task_manager_->GetTasks();
|
||||
QList<QPersistentModelIndex> finished_tasks = active_tasks_.values();
|
||||
|
||||
for (const TaskManager::Task &task : tasks) {
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
class QModelIndex;
|
||||
class QPersistentModelIndex;
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class ConnectedDevice;
|
||||
class DeviceLister;
|
||||
class DeviceStateFilterModel;
|
||||
|
@ -58,7 +59,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeviceManager(Application *app, QObject *parent = nullptr);
|
||||
explicit DeviceManager(SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, QObject *parent = nullptr);
|
||||
~DeviceManager() override;
|
||||
|
||||
enum Role {
|
||||
|
@ -123,6 +124,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
|
|||
void DeviceConnected(const QModelIndex idx);
|
||||
void DeviceDisconnected(const QModelIndex idx);
|
||||
void DeviceCreatedFromDB(DeviceInfo *info);
|
||||
void AddError(const QString &error);
|
||||
|
||||
private Q_SLOTS:
|
||||
void PhysicalDeviceAdded(const QString &id);
|
||||
|
@ -152,7 +154,10 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
|
|||
void CloseBackend();
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<Database> database_;
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader_;
|
||||
|
||||
ScopedPtr<DeviceDatabaseBackend> backend_;
|
||||
|
||||
DeviceStateFilterModel *connected_devices_model_;
|
||||
|
|
|
@ -48,9 +48,9 @@
|
|||
#include <QMessageBox>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/application.h"
|
||||
#include "core/deletefiles.h"
|
||||
#include "core/mergedproxymodel.h"
|
||||
#include "core/mimedata.h"
|
||||
|
@ -61,8 +61,8 @@
|
|||
#include "collection/collectiondirectorymodel.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "collection/collectionitemdelegate.h"
|
||||
#include "connecteddevice.h"
|
||||
#include "devicelister.h"
|
||||
#include "connecteddevice.h"
|
||||
#include "devicemanager.h"
|
||||
#include "deviceproperties.h"
|
||||
#include "deviceview.h"
|
||||
|
@ -175,7 +175,6 @@ void DeviceItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||
|
||||
DeviceView::DeviceView(QWidget *parent)
|
||||
: AutoExpandingTreeView(parent),
|
||||
app_(nullptr),
|
||||
merged_model_(nullptr),
|
||||
sort_model_(nullptr),
|
||||
properties_dialog_(new DeviceProperties),
|
||||
|
@ -202,16 +201,16 @@ DeviceView::DeviceView(QWidget *parent)
|
|||
|
||||
DeviceView::~DeviceView() = default;
|
||||
|
||||
void DeviceView::SetApplication(Application *app) {
|
||||
void DeviceView::Init(SharedPtr<TaskManager> task_manager, SharedPtr<DeviceManager> device_manager, CollectionDirectoryModel *collection_directory_model) {
|
||||
|
||||
Q_ASSERT(app_ == nullptr);
|
||||
app_ = app;
|
||||
task_manager_ = task_manager;
|
||||
device_manager_ = device_manager;
|
||||
|
||||
QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceConnected, this, &DeviceView::DeviceConnected);
|
||||
QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceDisconnected, this, &DeviceView::DeviceDisconnected);
|
||||
QObject::connect(&*device_manager_, &DeviceManager::DeviceConnected, this, &DeviceView::DeviceConnected);
|
||||
QObject::connect(&*device_manager_, &DeviceManager::DeviceDisconnected, this, &DeviceView::DeviceDisconnected);
|
||||
|
||||
sort_model_ = new QSortFilterProxyModel(this);
|
||||
sort_model_->setSourceModel(&*app_->device_manager());
|
||||
sort_model_->setSourceModel(&*device_manager_);
|
||||
sort_model_->setDynamicSortFilter(true);
|
||||
sort_model_->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
sort_model_->sort(0);
|
||||
|
@ -222,10 +221,10 @@ void DeviceView::SetApplication(Application *app) {
|
|||
|
||||
QObject::connect(merged_model_, &MergedProxyModel::SubModelReset, this, &AutoExpandingTreeView::RecursivelyExpandSlot);
|
||||
|
||||
properties_dialog_->SetDeviceManager(app_->device_manager());
|
||||
properties_dialog_->SetDeviceManager(device_manager_);
|
||||
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(app_->task_manager(), nullptr, this);
|
||||
organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model());
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(task_manager, nullptr, this);
|
||||
organize_dialog_->SetDestinationModel(collection_directory_model);
|
||||
|
||||
}
|
||||
|
||||
|
@ -257,8 +256,8 @@ void DeviceView::contextMenuEvent(QContextMenuEvent *e) {
|
|||
const QModelIndex collection_index = MapToCollection(menu_index_);
|
||||
|
||||
if (device_index.isValid()) {
|
||||
const bool is_plugged_in = app_->device_manager()->GetLister(device_index);
|
||||
const bool is_remembered = app_->device_manager()->GetDatabaseId(device_index) != -1;
|
||||
const bool is_plugged_in = device_manager_->GetLister(device_index);
|
||||
const bool is_remembered = device_manager_->GetDatabaseId(device_index) != -1;
|
||||
|
||||
forget_action_->setEnabled(is_remembered);
|
||||
eject_action_->setEnabled(is_plugged_in);
|
||||
|
@ -270,7 +269,7 @@ void DeviceView::contextMenuEvent(QContextMenuEvent *e) {
|
|||
|
||||
bool is_filesystem_device = false;
|
||||
if (parent_device_index.isValid()) {
|
||||
SharedPtr<ConnectedDevice> device = app_->device_manager()->GetConnectedDevice(parent_device_index);
|
||||
SharedPtr<ConnectedDevice> device = device_manager_->GetConnectedDevice(parent_device_index);
|
||||
if (device && !device->LocalPath().isEmpty()) is_filesystem_device = true;
|
||||
}
|
||||
|
||||
|
@ -309,14 +308,14 @@ QModelIndex DeviceView::MapToCollection(const QModelIndex &merged_model_index) c
|
|||
|
||||
void DeviceView::Connect() {
|
||||
QModelIndex device_idx = MapToDevice(menu_index_);
|
||||
app_->device_manager()->data(device_idx, MusicStorage::Role_StorageForceConnect);
|
||||
device_manager_->data(device_idx, MusicStorage::Role_StorageForceConnect);
|
||||
}
|
||||
|
||||
void DeviceView::DeviceConnected(const QModelIndex &idx) {
|
||||
|
||||
if (!idx.isValid()) return;
|
||||
|
||||
SharedPtr<ConnectedDevice> device = app_->device_manager()->GetConnectedDevice(idx);
|
||||
SharedPtr<ConnectedDevice> device = device_manager_->GetConnectedDevice(idx);
|
||||
if (!device) return;
|
||||
|
||||
QModelIndex sort_idx = sort_model_->mapFromSource(idx);
|
||||
|
@ -341,8 +340,8 @@ void DeviceView::DeviceDisconnected(const QModelIndex &idx) {
|
|||
void DeviceView::Forget() {
|
||||
|
||||
QModelIndex device_idx = MapToDevice(menu_index_);
|
||||
QString unique_id = app_->device_manager()->data(device_idx, DeviceManager::Role_UniqueId).toString();
|
||||
if (app_->device_manager()->GetLister(device_idx) && app_->device_manager()->GetLister(device_idx)->AskForScan(unique_id)) {
|
||||
QString unique_id = device_manager_->data(device_idx, DeviceManager::Role_UniqueId).toString();
|
||||
if (device_manager_->GetLister(device_idx) && device_manager_->GetLister(device_idx)->AskForScan(unique_id)) {
|
||||
ScopedPtr<QMessageBox> dialog(new QMessageBox(
|
||||
QMessageBox::Question, tr("Forget device"),
|
||||
tr("Forgetting a device will remove it from this list and Strawberry will have to rescan all the songs again next time you connect it."),
|
||||
|
@ -353,7 +352,7 @@ void DeviceView::Forget() {
|
|||
if (dialog->clickedButton() != forget) return;
|
||||
}
|
||||
|
||||
app_->device_manager()->Forget(device_idx);
|
||||
device_manager_->Forget(device_idx);
|
||||
|
||||
}
|
||||
|
||||
|
@ -368,7 +367,7 @@ void DeviceView::mouseDoubleClickEvent(QMouseEvent *e) {
|
|||
QModelIndex merged_index = indexAt(e->pos());
|
||||
QModelIndex device_index = MapToDevice(merged_index);
|
||||
if (device_index.isValid()) {
|
||||
if (!app_->device_manager()->GetConnectedDevice(device_index)) {
|
||||
if (!device_manager_->GetConnectedDevice(device_index)) {
|
||||
menu_index_ = merged_index;
|
||||
Connect();
|
||||
}
|
||||
|
@ -433,7 +432,7 @@ void DeviceView::Delete() {
|
|||
|
||||
SharedPtr<MusicStorage> storage = device_index.data(MusicStorage::Role_Storage).value<SharedPtr<MusicStorage>>();
|
||||
|
||||
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, false);
|
||||
DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, false);
|
||||
QObject::connect(delete_files, &DeleteFiles::Finished, this, &DeviceView::DeleteFinished);
|
||||
delete_files->Start(GetSelectedSongs());
|
||||
|
||||
|
@ -456,7 +455,7 @@ void DeviceView::Organize() {
|
|||
|
||||
void DeviceView::Unmount() {
|
||||
QModelIndex device_idx = MapToDevice(menu_index_);
|
||||
app_->device_manager()->Unmount(device_idx);
|
||||
device_manager_->Unmount(device_idx);
|
||||
}
|
||||
|
||||
void DeviceView::DeleteFinished(const SongList &songs_with_errors) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <QString>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
#include "collection/collectionitemdelegate.h"
|
||||
#include "widgets/autoexpandingtreeview.h"
|
||||
|
@ -43,8 +44,10 @@ class QAction;
|
|||
class QMouseEvent;
|
||||
class QContextMenuEvent;
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class DeviceManager;
|
||||
class DeviceProperties;
|
||||
class CollectionDirectoryModel;
|
||||
class MergedProxyModel;
|
||||
class OrganizeDialog;
|
||||
|
||||
|
@ -67,7 +70,7 @@ class DeviceView : public AutoExpandingTreeView {
|
|||
explicit DeviceView(QWidget *parent = nullptr);
|
||||
~DeviceView() override;
|
||||
|
||||
void SetApplication(Application *app);
|
||||
void Init(SharedPtr<TaskManager> task_manager, SharedPtr<DeviceManager> device_manager, CollectionDirectoryModel *collection_directory_model);
|
||||
|
||||
// AutoExpandingTreeView
|
||||
bool CanRecursivelyExpand(const QModelIndex &idx) const override;
|
||||
|
@ -102,7 +105,8 @@ class DeviceView : public AutoExpandingTreeView {
|
|||
SongList GetSelectedSongs() const;
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<DeviceManager> device_manager_;
|
||||
MergedProxyModel *merged_model_;
|
||||
QSortFilterProxyModel *sort_model_;
|
||||
|
||||
|
|
|
@ -27,21 +27,25 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/song.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/database.h"
|
||||
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "collection/collectionwatcher.h"
|
||||
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
|
||||
#include "connecteddevice.h"
|
||||
#include "devicemanager.h"
|
||||
#include "filesystemdevice.h"
|
||||
|
||||
class DeviceLister;
|
||||
|
||||
FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent)
|
||||
FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent)
|
||||
: FilesystemMusicStorage(Song::Source::Device, url.toLocalFile()),
|
||||
ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent),
|
||||
ConnectedDevice(url, lister, unique_id, manager, task_manager, database, album_cover_loader, database_id, first_time, parent),
|
||||
watcher_(new CollectionWatcher(Song::Source::Device)),
|
||||
watcher_thread_(new QThread(this)) {
|
||||
|
||||
|
@ -51,7 +55,7 @@ FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const
|
|||
|
||||
watcher_->set_device_name(manager->DeviceNameByID(unique_id));
|
||||
watcher_->set_backend(backend_);
|
||||
watcher_->set_task_manager(app_->task_manager());
|
||||
watcher_->set_task_manager(task_manager);
|
||||
|
||||
QObject::connect(&*backend_, &CollectionBackend::DirectoryAdded, watcher_, &CollectionWatcher::AddDirectory);
|
||||
QObject::connect(&*backend_, &CollectionBackend::DirectoryDeleted, watcher_, &CollectionWatcher::RemoveDirectory);
|
||||
|
|
|
@ -35,16 +35,18 @@
|
|||
#include "connecteddevice.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class CollectionWatcher;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
class AlbumCoverLoader;
|
||||
|
||||
class FilesystemDevice : public ConnectedDevice, public virtual FilesystemMusicStorage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
Q_INVOKABLE FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
~FilesystemDevice() override;
|
||||
|
||||
Song::Source source() const final { return Song::Source::Device; }
|
||||
|
|
|
@ -40,10 +40,12 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/temporaryfile.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/database.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "connecteddevice.h"
|
||||
#include "gpoddevice.h"
|
||||
#include "gpodloader.h"
|
||||
|
@ -54,8 +56,9 @@ class DeviceManager;
|
|||
using std::make_shared;
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
GPodDevice::GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent),
|
||||
GPodDevice::GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, task_manager, database, album_cover_loader, database_id, first_time, parent),
|
||||
task_manager_(task_manager),
|
||||
loader_(nullptr),
|
||||
loader_thread_(nullptr),
|
||||
db_(nullptr),
|
||||
|
@ -66,7 +69,7 @@ bool GPodDevice::Init() {
|
|||
InitBackendDirectory(url_.path(), first_time_);
|
||||
model_->Init();
|
||||
|
||||
loader_ = new GPodLoader(url_.path(), app_->task_manager(), backend_, shared_from_this());
|
||||
loader_ = new GPodLoader(url_.path(), task_manager_, backend_, shared_from_this());
|
||||
loader_thread_ = new QThread();
|
||||
loader_->moveToThread(loader_thread_);
|
||||
|
||||
|
@ -135,7 +138,9 @@ void GPodDevice::LoadFinished(Itdb_iTunesDB *db, const bool success) {
|
|||
|
||||
}
|
||||
|
||||
void GPodDevice::LoaderError(const QString &message) { app_->AddError(message); }
|
||||
void GPodDevice::LoaderError(const QString &message) {
|
||||
Q_EMIT AddError(message);
|
||||
}
|
||||
|
||||
void GPodDevice::Start() {
|
||||
|
||||
|
@ -240,7 +245,7 @@ bool GPodDevice::CopyToStorage(const CopyJob &job, QString &error_text) {
|
|||
error_text = tr("Could not copy %1 to %2: %3").arg(job.metadata_.url().toLocalFile(), url_.path(), QString::fromUtf8(error->message));
|
||||
g_error_free(error);
|
||||
qLog(Error) << error_text;
|
||||
app_->AddError(error_text);
|
||||
Q_EMIT AddError(error_text);
|
||||
|
||||
// Need to remove the track from the db again
|
||||
itdb_track_remove(track);
|
||||
|
@ -286,7 +291,7 @@ bool GPodDevice::WriteDatabase(QString &error_text) {
|
|||
else {
|
||||
error_text = tr("Writing database failed.");
|
||||
}
|
||||
app_->AddError(error_text);
|
||||
Q_EMIT AddError(error_text);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "gpodloader.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
|
||||
|
@ -50,7 +49,7 @@ class GPodDevice : public ConnectedDevice, public virtual MusicStorage {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
Q_INVOKABLE GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
~GPodDevice() override;
|
||||
|
||||
bool Init() override;
|
||||
|
@ -86,6 +85,7 @@ class GPodDevice : public ConnectedDevice, public virtual MusicStorage {
|
|||
bool WriteDatabase(QString &error_text);
|
||||
|
||||
protected:
|
||||
SharedPtr <TaskManager> task_manager_;
|
||||
GPodLoader *loader_;
|
||||
QThread *loader_thread_;
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/musicstorage.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
|
@ -46,13 +45,17 @@
|
|||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class AlbumCoverLoader;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
|
||||
bool MtpDevice::sInitializedLibMTP = false;
|
||||
|
||||
MtpDevice::MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent),
|
||||
MtpDevice::MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, task_manager, database, album_cover_loader, database_id, first_time, parent),
|
||||
task_manager_(task_manager),
|
||||
loader_(nullptr),
|
||||
loader_thread_(nullptr),
|
||||
closing_(false) {
|
||||
|
@ -81,7 +84,7 @@ bool MtpDevice::Init() {
|
|||
InitBackendDirectory(u"/"_s, first_time_, false);
|
||||
model_->Init();
|
||||
|
||||
loader_ = new MtpLoader(url_, app_->task_manager(), backend_);
|
||||
loader_ = new MtpLoader(url_, task_manager_, backend_);
|
||||
loader_thread_ = new QThread();
|
||||
loader_->moveToThread(loader_thread_);
|
||||
|
||||
|
@ -132,7 +135,7 @@ void MtpDevice::LoadFinished(const bool success, MtpConnection *connection) {
|
|||
}
|
||||
|
||||
void MtpDevice::LoaderError(const QString &message) {
|
||||
app_->AddError(message);
|
||||
Q_EMIT AddError(message);
|
||||
}
|
||||
|
||||
bool MtpDevice::StartCopy(QList<Song::FileType> *supported_types) {
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
#include "connecteddevice.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class Database;
|
||||
class AlbumCoverLoader;
|
||||
class DeviceLister;
|
||||
class DeviceManager;
|
||||
class MtpLoader;
|
||||
|
@ -48,7 +50,7 @@ class MtpDevice : public ConnectedDevice {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
Q_INVOKABLE MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr<DeviceManager> manager, SharedPtr<TaskManager> task_manager, SharedPtr<Database> database, SharedPtr<AlbumCoverLoader> album_cover_loader, const int database_id, const bool first_time, QObject *parent = nullptr);
|
||||
~MtpDevice() override;
|
||||
|
||||
static QStringList url_schemes() { return QStringList() << QStringLiteral("mtp"); }
|
||||
|
@ -82,6 +84,8 @@ class MtpDevice : public ConnectedDevice {
|
|||
private:
|
||||
static bool sInitializedLibMTP;
|
||||
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
|
||||
MtpLoader *loader_;
|
||||
QThread *loader_thread_;
|
||||
bool closing_;
|
||||
|
|
|
@ -36,13 +36,14 @@
|
|||
#include <QTextBrowser>
|
||||
|
||||
#include "console.h"
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/application.h"
|
||||
#include "core/database.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
Console::Console(Application *app, QWidget *parent) : QDialog(parent), ui_{}, app_(app) {
|
||||
Console::Console(SharedPtr<Database> database, QWidget *parent) : QDialog(parent), ui_{}, database_(database) {
|
||||
|
||||
ui_.setupUi(this);
|
||||
|
||||
|
@ -60,7 +61,7 @@ Console::Console(Application *app, QWidget *parent) : QDialog(parent), ui_{}, ap
|
|||
|
||||
void Console::RunQuery() {
|
||||
|
||||
QSqlDatabase db = app_->database()->Connect();
|
||||
QSqlDatabase db = database_->Connect();
|
||||
QSqlQuery query(db);
|
||||
if (!query.prepare(ui_.query->text())) {
|
||||
qLog(Error) << query.lastError();
|
||||
|
|
|
@ -31,20 +31,22 @@
|
|||
|
||||
#include "ui_console.h"
|
||||
|
||||
class Application;
|
||||
#include "core/shared_ptr.h"
|
||||
|
||||
class Database;
|
||||
|
||||
class Console : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Console(Application *app, QWidget *parent = nullptr);
|
||||
explicit Console(SharedPtr<Database> database, QWidget *parent = nullptr);
|
||||
|
||||
private Q_SLOTS:
|
||||
void RunQuery();
|
||||
|
||||
private:
|
||||
Ui::Console ui_;
|
||||
Application *app_;
|
||||
SharedPtr<Database> database_;
|
||||
};
|
||||
|
||||
#endif // CONSOLE_H
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
#include <QSettings>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/settings.h"
|
||||
|
@ -110,16 +109,25 @@ constexpr int kSmallImageSize = 128;
|
|||
const char EditTagDialog::kTagsDifferentHintText[] = QT_TR_NOOP("(different across multiple songs)");
|
||||
const char EditTagDialog::kArtDifferentHintText[] = QT_TR_NOOP("Different art across multiple songs.");
|
||||
|
||||
EditTagDialog::EditTagDialog(Application *app, QWidget *parent)
|
||||
EditTagDialog::EditTagDialog(SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<CollectionBackend> collection_backend,
|
||||
SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
SharedPtr<CoverProviders> cover_providers,
|
||||
SharedPtr<LyricsProviders> lyrics_providers,
|
||||
QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui_(new Ui_EditTagDialog),
|
||||
app_(app),
|
||||
collection_backend_(collection_backend),
|
||||
album_cover_loader_(albumcover_loader),
|
||||
current_albumcover_loader_(current_albumcover_loader),
|
||||
cover_providers_(cover_providers),
|
||||
album_cover_choice_controller_(new AlbumCoverChoiceController(this)),
|
||||
#ifdef HAVE_MUSICBRAINZ
|
||||
tag_fetcher_(new TagFetcher(app->network(), this)),
|
||||
tag_fetcher_(new TagFetcher(network, this)),
|
||||
results_dialog_(new TrackSelectionDialog(this)),
|
||||
#endif
|
||||
lyrics_fetcher_(new LyricsFetcher(app->lyrics_providers(), this)),
|
||||
lyrics_fetcher_(new LyricsFetcher(lyrics_providers, this)),
|
||||
cover_menu_(new QMenu(this)),
|
||||
image_no_cover_thumbnail_(ImageUtils::GenerateNoCoverImage(QSize(128, 128), devicePixelRatioF())),
|
||||
loading_(false),
|
||||
|
@ -130,7 +138,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent)
|
|||
save_tag_pending_(0),
|
||||
lyrics_id_(-1) {
|
||||
|
||||
QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &EditTagDialog::AlbumCoverLoaded);
|
||||
QObject::connect(&*album_cover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &EditTagDialog::AlbumCoverLoaded);
|
||||
|
||||
#ifdef HAVE_MUSICBRAINZ
|
||||
QObject::connect(tag_fetcher_, &TagFetcher::ResultAvailable, results_dialog_, &TrackSelectionDialog::FetchTagFinished, Qt::QueuedConnection);
|
||||
|
@ -140,7 +148,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent)
|
|||
#endif
|
||||
QObject::connect(lyrics_fetcher_, &LyricsFetcher::LyricsFetched, this, &EditTagDialog::UpdateLyrics);
|
||||
|
||||
album_cover_choice_controller_->Init(app_);
|
||||
//album_cover_choice_controller_->Init(app_);
|
||||
|
||||
ui_->setupUi(this);
|
||||
ui_->splitter->setSizes(QList<int>() << 200 << width() - 200);
|
||||
|
@ -259,13 +267,13 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent)
|
|||
QKeySequence(QKeySequence::Forward).toString(QKeySequence::NativeText),
|
||||
QKeySequence(QKeySequence::MoveToNextPage).toString(QKeySequence::NativeText)));
|
||||
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::Artist, ui_->artist);
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::Album, ui_->album);
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::AlbumArtist, ui_->albumartist);
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::Genre, ui_->genre);
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::Composer, ui_->composer);
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::Performer, ui_->performer);
|
||||
new TagCompleter(app_->collection_backend(), Playlist::Column::Grouping, ui_->grouping);
|
||||
new TagCompleter(collection_backend, Playlist::Column::Artist, ui_->artist);
|
||||
new TagCompleter(collection_backend, Playlist::Column::Album, ui_->album);
|
||||
new TagCompleter(collection_backend, Playlist::Column::AlbumArtist, ui_->albumartist);
|
||||
new TagCompleter(collection_backend, Playlist::Column::Genre, ui_->genre);
|
||||
new TagCompleter(collection_backend, Playlist::Column::Composer, ui_->composer);
|
||||
new TagCompleter(collection_backend, Playlist::Column::Performer, ui_->performer);
|
||||
new TagCompleter(collection_backend, Playlist::Column::Grouping, ui_->grouping);
|
||||
|
||||
}
|
||||
|
||||
|
@ -725,7 +733,7 @@ void EditTagDialog::SelectionChanged() {
|
|||
album_cover_choice_controller_->cover_to_file_action()->setEnabled(first_song.has_valid_art() && !first_song.art_unset());
|
||||
album_cover_choice_controller_->cover_from_file_action()->setEnabled(enable_change_art);
|
||||
album_cover_choice_controller_->cover_from_url_action()->setEnabled(enable_change_art);
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(app_->cover_providers()->HasAnyProviders() && enable_change_art);
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(cover_providers_->HasAnyProviders() && enable_change_art);
|
||||
album_cover_choice_controller_->unset_cover_action()->setEnabled(enable_change_art && !first_song.art_unset());
|
||||
album_cover_choice_controller_->clear_cover_action()->setEnabled(enable_change_art && (!first_song.art_manual().isEmpty() || first_song.art_unset()));
|
||||
album_cover_choice_controller_->delete_cover_action()->setEnabled(enable_change_art && (first_song.art_embedded() || !first_song.art_automatic().isEmpty() || !first_song.art_manual().isEmpty()));
|
||||
|
@ -734,10 +742,10 @@ void EditTagDialog::SelectionChanged() {
|
|||
cover_options.desired_scaled_size = QSize(kSmallImageSize, kSmallImageSize);
|
||||
cover_options.device_pixel_ratio = devicePixelRatioF();
|
||||
if (data_.value(indexes.first().row()).cover_action_ == UpdateCoverAction::None) {
|
||||
tags_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, first_song);
|
||||
tags_cover_art_id_ = album_cover_loader_->LoadImageAsync(cover_options, first_song);
|
||||
}
|
||||
else {
|
||||
tags_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, data_[indexes.first().row()].cover_result_);
|
||||
tags_cover_art_id_ = album_cover_loader_->LoadImageAsync(cover_options, data_[indexes.first().row()].cover_result_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -788,7 +796,7 @@ void EditTagDialog::UpdateSummaryTab(const Song &song) {
|
|||
cover_options.types = cover_types_;
|
||||
cover_options.desired_scaled_size = QSize(kSmallImageSize, kSmallImageSize);
|
||||
cover_options.device_pixel_ratio = devicePixelRatioF();
|
||||
summary_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, song);
|
||||
summary_cover_art_id_ = album_cover_loader_->LoadImageAsync(cover_options, song);
|
||||
|
||||
ui_->summary->setText(u"<p><b>"_s + song.PrettyTitleWithArtist().toHtmlEscaped() + u"</b></p>"_s);
|
||||
|
||||
|
@ -1307,8 +1315,8 @@ void EditTagDialog::SaveData() {
|
|||
if (ref.current_.is_collection_song()) {
|
||||
collection_songs_.insert(ref.current_.id(), ref.current_);
|
||||
}
|
||||
if (ref.current_ == app_->current_albumcover_loader()->last_song()) {
|
||||
app_->current_albumcover_loader()->LoadAlbumCover(ref.current_);
|
||||
if (ref.current_ == current_albumcover_loader_->last_song()) {
|
||||
current_albumcover_loader_->LoadAlbumCover(ref.current_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1321,7 +1329,7 @@ void EditTagDialog::SaveData() {
|
|||
void EditTagDialog::SaveDataFinished() {
|
||||
|
||||
if (!collection_songs_.isEmpty()) {
|
||||
app_->collection_backend()->AddOrUpdateSongsAsync(collection_songs_.values());
|
||||
collection_backend_->AddOrUpdateSongsAsync(collection_songs_.values());
|
||||
collection_songs_.clear();
|
||||
}
|
||||
|
||||
|
@ -1483,8 +1491,8 @@ void EditTagDialog::SongSaveTagsComplete(TagReaderReplyPtr reply, const QString
|
|||
}
|
||||
collection_songs_.insert(song.id(), song);
|
||||
}
|
||||
if (cover_action != UpdateCoverAction::None && song == app_->current_albumcover_loader()->last_song()) {
|
||||
app_->current_albumcover_loader()->LoadAlbumCover(song);
|
||||
if (cover_action != UpdateCoverAction::None && song == current_albumcover_loader_->last_song()) {
|
||||
current_albumcover_loader_->LoadAlbumCover(song);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -51,7 +51,12 @@ class QEvent;
|
|||
class QShowEvent;
|
||||
class QHideEvent;
|
||||
|
||||
class Application;
|
||||
class NetworkAccessManager;
|
||||
class CollectionBackend;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class CoverProviders;
|
||||
class LyricsProviders;
|
||||
class AlbumCoverChoiceController;
|
||||
class Ui_EditTagDialog;
|
||||
#ifdef HAVE_MUSICBRAINZ
|
||||
|
@ -64,7 +69,13 @@ class EditTagDialog : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EditTagDialog(Application *app, QWidget *parent = nullptr);
|
||||
explicit EditTagDialog(SharedPtr<NetworkAccessManager> network,
|
||||
SharedPtr<CollectionBackend> collection_backend,
|
||||
SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
SharedPtr<CoverProviders> cover_providers,
|
||||
SharedPtr<LyricsProviders> lyrics_providers,
|
||||
QWidget *parent = nullptr);
|
||||
~EditTagDialog() override;
|
||||
|
||||
void SetSongs(const SongList &songs, const PlaylistItemPtrList &items = PlaylistItemPtrList());
|
||||
|
@ -180,7 +191,11 @@ class EditTagDialog : public QDialog {
|
|||
|
||||
Ui_EditTagDialog *ui_;
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
SharedPtr<CoverProviders> cover_providers_;
|
||||
|
||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||
#ifdef HAVE_MUSICBRAINZ
|
||||
TagFetcher *tag_fetcher_;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/mainwindow.h"
|
||||
#include "application/mainwindow.h"
|
||||
#include "utilities/screenutils.h"
|
||||
|
||||
#include "snapdialog.h"
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <QSettings>
|
||||
|
||||
#include "utilities/envutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "core/networkproxyfactory.h"
|
||||
#include "core/settings.h"
|
||||
#include "enginebase.h"
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#include "core/logging.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/signalchecker.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "enginebase.h"
|
||||
#include "gstengine.h"
|
||||
#include "gstenginepipeline.h"
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/signalchecker.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "settings/backendsettingspage.h"
|
||||
#include "gstengine.h"
|
||||
#include "gstenginepipeline.h"
|
||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -87,11 +87,11 @@
|
|||
#ifdef HAVE_MPRIS2
|
||||
# include "mpris2/mpris2.h"
|
||||
#endif
|
||||
#include "core/metatypes.h"
|
||||
#include "application/metatypes.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/mainwindow.h"
|
||||
#include "application/mainwindow.h"
|
||||
#include "core/commandlineoptions.h"
|
||||
#include "core/application.h"
|
||||
#include "application/application.h"
|
||||
#include "core/networkproxyfactory.h"
|
||||
#ifdef Q_OS_MACOS
|
||||
# include "core/macsystemtrayicon.h"
|
||||
|
@ -99,7 +99,7 @@
|
|||
# include "core/qtsystemtrayicon.h"
|
||||
#endif
|
||||
#ifdef HAVE_TRANSLATIONS
|
||||
# include "core/translations.h"
|
||||
# include "translations/translations.h"
|
||||
#endif
|
||||
#include "settings/behavioursettingspage.h"
|
||||
#include "settings/appearancesettingspage.h"
|
||||
|
@ -307,7 +307,7 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_MPRIS2
|
||||
mpris::Mpris2 mpris2(&app);
|
||||
mpris::Mpris2 mpris2(app.player(), app.playlist_manager(), app.current_albumcover_loader());
|
||||
#endif
|
||||
|
||||
// Window
|
||||
|
|
|
@ -23,26 +23,22 @@
|
|||
#include <QByteArray>
|
||||
#include <QUrl>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "player/player.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "settings/moodbarsettingspage.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
|
||||
#include "moodbarcontroller.h"
|
||||
#include "moodbarloader.h"
|
||||
#include "moodbarpipeline.h"
|
||||
|
||||
MoodbarController::MoodbarController(Application *app, QObject *parent)
|
||||
MoodbarController::MoodbarController(SharedPtr<Player> player, SharedPtr<MoodbarLoader> moodbar_loader, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
player_(player),
|
||||
moodbar_loader_(moodbar_loader),
|
||||
enabled_(false) {
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &MoodbarController::CurrentSongChanged);
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, this, &MoodbarController::PlaybackStopped);
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
@ -62,7 +58,7 @@ void MoodbarController::CurrentSongChanged(const Song &song) {
|
|||
|
||||
QByteArray data;
|
||||
MoodbarPipeline *pipeline = nullptr;
|
||||
const MoodbarLoader::Result result = app_->moodbar_loader()->Load(song.url(), song.has_cue(), &data, &pipeline);
|
||||
const MoodbarLoader::Result result = moodbar_loader_->Load(song.url(), song.has_cue(), &data, &pipeline);
|
||||
|
||||
switch (result) {
|
||||
case MoodbarLoader::Result::CannotLoad:
|
||||
|
@ -95,12 +91,12 @@ void MoodbarController::PlaybackStopped() {
|
|||
void MoodbarController::AsyncLoadComplete(MoodbarPipeline *pipeline, const QUrl &url) {
|
||||
|
||||
// Is this song still playing?
|
||||
PlaylistItemPtr current_item = app_->player()->GetCurrentItem();
|
||||
PlaylistItemPtr current_item = player_->GetCurrentItem();
|
||||
if (current_item && current_item->Url() != url) {
|
||||
return;
|
||||
}
|
||||
// Did we stop the song?
|
||||
switch (app_->player()->GetState()) {
|
||||
switch (player_->GetState()) {
|
||||
case EngineBase::State::Error:
|
||||
case EngineBase::State::Empty:
|
||||
case EngineBase::State::Idle:
|
||||
|
|
|
@ -27,28 +27,34 @@
|
|||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
class Application;
|
||||
#include "core/shared_ptr.h"
|
||||
|
||||
class MoodbarLoader;
|
||||
class MoodbarPipeline;
|
||||
class Song;
|
||||
class Player;
|
||||
|
||||
class MoodbarController : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MoodbarController(Application *app, QObject *parent = nullptr);
|
||||
explicit MoodbarController(SharedPtr<Player> player, SharedPtr<MoodbarLoader> moodbar_loader, QObject *parent = nullptr);
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
Q_SIGNALS:
|
||||
void CurrentMoodbarDataChanged(const QByteArray &data);
|
||||
|
||||
private Q_SLOTS:
|
||||
public Q_SLOTS:
|
||||
void CurrentSongChanged(const Song &song);
|
||||
void PlaybackStopped();
|
||||
|
||||
private Q_SLOTS:
|
||||
void AsyncLoadComplete(MoodbarPipeline *pipeline, const QUrl &url);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<Player> player_;
|
||||
SharedPtr<MoodbarLoader> moodbar_loader_;
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <QPainter>
|
||||
#include <QRect>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/settings.h"
|
||||
#include "playlist/playlist.h"
|
||||
#include "playlist/playlistview.h"
|
||||
|
@ -51,14 +50,15 @@
|
|||
|
||||
MoodbarItemDelegate::Data::Data() : state_(State::None) {}
|
||||
|
||||
MoodbarItemDelegate::MoodbarItemDelegate(Application *app, PlaylistView *view, QObject *parent)
|
||||
MoodbarItemDelegate::MoodbarItemDelegate(SharedPtr<MoodbarLoader> moodbar_loader, PlaylistView *playlist_view, QObject *parent)
|
||||
: QItemDelegate(parent),
|
||||
app_(app),
|
||||
view_(view),
|
||||
moodbar_loader_(moodbar_loader),
|
||||
playlist_view_(playlist_view),
|
||||
enabled_(false),
|
||||
style_(MoodbarRenderer::MoodbarStyle::Normal) {
|
||||
|
||||
QObject::connect(app_, &Application::SettingsChanged, this, &MoodbarItemDelegate::ReloadSettings);
|
||||
QObject::connect(&*moodbar_loader, &MoodbarLoader::SettingsReloaded, this, &MoodbarItemDelegate::ReloadSettings);
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ void MoodbarItemDelegate::StartLoadingData(const QUrl &url, const bool has_cue,
|
|||
// Load a mood file for this song and generate some colors from it
|
||||
QByteArray bytes;
|
||||
MoodbarPipeline *pipeline = nullptr;
|
||||
switch (app_->moodbar_loader()->Load(url, has_cue, &bytes, &pipeline)) {
|
||||
switch (moodbar_loader_->Load(url, has_cue, &bytes, &pipeline)) {
|
||||
case MoodbarLoader::Result::CannotLoad:
|
||||
data->state_ = Data::State::CannotLoad;
|
||||
break;
|
||||
|
@ -278,7 +278,7 @@ void MoodbarItemDelegate::ImageLoaded(const QUrl &url, const QImage &image) {
|
|||
data->pixmap_ = QPixmap::fromImage(image);
|
||||
data->state_ = Data::State::Loaded;
|
||||
|
||||
Playlist *playlist = view_->playlist();
|
||||
Playlist *playlist = playlist_view_->playlist();
|
||||
const PlaylistFilter *filter = playlist->filter();
|
||||
|
||||
// Update all the indices with the new pixmap.
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
#include <QSize>
|
||||
#include <QStyleOption>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
|
||||
class QPainter;
|
||||
class QModelIndex;
|
||||
class QPersistentModelIndex;
|
||||
class Application;
|
||||
class MoodbarLoader;
|
||||
class MoodbarPipeline;
|
||||
class PlaylistView;
|
||||
|
||||
|
@ -47,7 +47,7 @@ class MoodbarItemDelegate : public QItemDelegate {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MoodbarItemDelegate(Application *app, PlaylistView *view, QObject *parent = nullptr);
|
||||
explicit MoodbarItemDelegate(SharedPtr<MoodbarLoader> moodbar_loader, PlaylistView *view, QObject *parent = nullptr);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const override;
|
||||
|
||||
|
@ -90,8 +90,8 @@ class MoodbarItemDelegate : public QItemDelegate {
|
|||
void ReloadAllColors();
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
PlaylistView *view_;
|
||||
SharedPtr<MoodbarLoader> moodbar_loader_;
|
||||
PlaylistView *playlist_view_;
|
||||
QCache<QUrl, Data> data_;
|
||||
|
||||
bool enabled_;
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
#include "moodbarpipeline.h"
|
||||
|
@ -57,7 +56,7 @@ using namespace Qt::Literals::StringLiterals;
|
|||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
MoodbarLoader::MoodbarLoader(Application *app, QObject *parent)
|
||||
MoodbarLoader::MoodbarLoader(QObject *parent)
|
||||
: QObject(parent),
|
||||
cache_(new QNetworkDiskCache(this)),
|
||||
thread_(new QThread(this)),
|
||||
|
@ -67,7 +66,6 @@ MoodbarLoader::MoodbarLoader(Application *app, QObject *parent)
|
|||
cache_->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u"/moodbar"_s);
|
||||
cache_->setMaximumCacheSize(60LL * 1024LL * 1024LL); // 60MB - enough for 20,000 moodbars
|
||||
|
||||
QObject::connect(app, &Application::SettingsChanged, this, &MoodbarLoader::ReloadSettings);
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
@ -86,6 +84,8 @@ void MoodbarLoader::ReloadSettings() {
|
|||
|
||||
MaybeTakeNextRequest();
|
||||
|
||||
Q_EMIT SettingsReloaded();
|
||||
|
||||
}
|
||||
|
||||
QStringList MoodbarLoader::MoodFilenames(const QString &song_filename) {
|
||||
|
|
|
@ -33,14 +33,13 @@
|
|||
class QThread;
|
||||
class QByteArray;
|
||||
class QNetworkDiskCache;
|
||||
class Application;
|
||||
class MoodbarPipeline;
|
||||
|
||||
class MoodbarLoader : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MoodbarLoader(Application *app, QObject *parent = nullptr);
|
||||
explicit MoodbarLoader(QObject *parent = nullptr);
|
||||
~MoodbarLoader() override;
|
||||
|
||||
enum class Result {
|
||||
|
@ -56,11 +55,11 @@ class MoodbarLoader : public QObject {
|
|||
WillLoadAsync
|
||||
};
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
Result Load(const QUrl &url, const bool has_cue, QByteArray *data, MoodbarPipeline **async_pipeline);
|
||||
|
||||
private Q_SLOTS:
|
||||
void ReloadSettings();
|
||||
|
||||
void RequestFinished(MoodbarPipeline *request, const QUrl &url);
|
||||
void MaybeTakeNextRequest();
|
||||
|
||||
|
@ -68,6 +67,9 @@ class MoodbarLoader : public QObject {
|
|||
static QStringList MoodFilenames(const QString &song_filename);
|
||||
static QUrl CacheUrlEntry(const QString &filename);
|
||||
|
||||
Q_SIGNALS:
|
||||
void SettingsReloaded();
|
||||
|
||||
private:
|
||||
QNetworkDiskCache *cache_;
|
||||
QThread *thread_;
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <QEvent>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
#include "moodbarproxystyle.h"
|
||||
|
@ -54,9 +53,8 @@ constexpr int kArrowWidth = 17;
|
|||
constexpr int kArrowHeight = 13;
|
||||
} // namespace
|
||||
|
||||
MoodbarProxyStyle::MoodbarProxyStyle(Application *app, QSlider *slider, QObject *parent)
|
||||
MoodbarProxyStyle::MoodbarProxyStyle(QSlider *slider, QObject *parent)
|
||||
: QProxyStyle(nullptr),
|
||||
app_(app),
|
||||
slider_(slider),
|
||||
enabled_(true),
|
||||
moodbar_style_(MoodbarRenderer::MoodbarStyle::Normal),
|
||||
|
@ -75,8 +73,6 @@ MoodbarProxyStyle::MoodbarProxyStyle(Application *app, QSlider *slider, QObject
|
|||
|
||||
QObject::connect(fade_timeline_, &QTimeLine::valueChanged, this, &MoodbarProxyStyle::FaderValueChanged);
|
||||
|
||||
QObject::connect(app, &Application::SettingsChanged, this, &MoodbarProxyStyle::ReloadSettings);
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
@ -121,7 +117,7 @@ void MoodbarProxyStyle::SetMoodbarEnabled(const bool enabled) {
|
|||
s.setValue("show", enabled);
|
||||
s.endGroup();
|
||||
|
||||
app_->ReloadSettings();
|
||||
Q_EMIT SettingsChanged();
|
||||
|
||||
}
|
||||
|
||||
|
@ -417,6 +413,6 @@ void MoodbarProxyStyle::ChangeStyle(QAction *action) {
|
|||
s.setValue("style", action->data().toInt());
|
||||
s.endGroup();
|
||||
|
||||
app_->ReloadSettings();
|
||||
//app_->ReloadSettings();
|
||||
|
||||
}
|
||||
|
|
|
@ -46,13 +46,13 @@ class QTimeLine;
|
|||
class QWidget;
|
||||
class QEvent;
|
||||
|
||||
class Application;
|
||||
|
||||
class MoodbarProxyStyle : public QProxyStyle {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MoodbarProxyStyle(Application *app, QSlider *slider, QObject *parent = nullptr);
|
||||
explicit MoodbarProxyStyle(QSlider *slider, QObject *parent = nullptr);
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
// QProxyStyle
|
||||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const override;
|
||||
|
@ -87,12 +87,13 @@ class MoodbarProxyStyle : public QProxyStyle {
|
|||
static QPixmap MoodbarPixmap(const ColorVector &colors, const QSize size, const QPalette &palette, const QStyleOptionSlider *opt);
|
||||
|
||||
private Q_SLOTS:
|
||||
void ReloadSettings();
|
||||
void FaderValueChanged(qreal value);
|
||||
void ChangeStyle(QAction *action);
|
||||
|
||||
Q_SIGNALS:
|
||||
void SettingsChanged();
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
QSlider *slider_;
|
||||
|
||||
bool enabled_;
|
||||
|
|
|
@ -46,10 +46,9 @@
|
|||
#include "mpris_common.h"
|
||||
#include "mpris2.h"
|
||||
|
||||
#include "constants/timeconstants.h"
|
||||
#include "core/song.h"
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "player/player.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "playlist/playlist.h"
|
||||
#include "playlist/playlistitem.h"
|
||||
|
@ -100,9 +99,11 @@ constexpr char kMprisObjectPath[] = "/org/mpris/MediaPlayer2";
|
|||
constexpr char kServiceName[] = "org.mpris.MediaPlayer2.strawberry";
|
||||
constexpr char kFreedesktopPath[] = "org.freedesktop.DBus.Properties";
|
||||
|
||||
Mpris2::Mpris2(Application *app, QObject *parent)
|
||||
Mpris2::Mpris2(SharedPtr<Player> player, SharedPtr<PlaylistManager> playlist_manager, SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
player_(player),
|
||||
playlist_manager_(playlist_manager),
|
||||
current_albumcover_loader_(current_albumcover_loader),
|
||||
app_name_(QCoreApplication::applicationName()) {
|
||||
|
||||
new Mpris2Root(this);
|
||||
|
@ -120,16 +121,16 @@ Mpris2::Mpris2(Application *app, QObject *parent)
|
|||
return;
|
||||
}
|
||||
|
||||
QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &Mpris2::AlbumCoverLoaded);
|
||||
QObject::connect(&*current_albumcover_loader_, &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &Mpris2::AlbumCoverLoaded);
|
||||
|
||||
QObject::connect(&*app_->player()->engine(), &EngineBase::StateChanged, this, &Mpris2::EngineStateChanged);
|
||||
QObject::connect(&*app_->player(), &Player::VolumeChanged, this, &Mpris2::VolumeChanged);
|
||||
QObject::connect(&*app_->player(), &Player::Seeked, this, &Mpris2::Seeked);
|
||||
QObject::connect(&*player_->engine(), &EngineBase::StateChanged, this, &Mpris2::EngineStateChanged);
|
||||
QObject::connect(&*player_, &Player::VolumeChanged, this, &Mpris2::VolumeChanged);
|
||||
QObject::connect(&*player_, &Player::Seeked, this, &Mpris2::Seeked);
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::PlaylistManagerInitialized, this, &Mpris2::PlaylistManagerInitialized);
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &Mpris2::CurrentSongChanged);
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::PlaylistChanged, this, &Mpris2::PlaylistChangedSlot);
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentChanged, this, &Mpris2::PlaylistCollectionChanged);
|
||||
QObject::connect(&*playlist_manager_, &PlaylistManager::PlaylistManagerInitialized, this, &Mpris2::PlaylistManagerInitialized);
|
||||
QObject::connect(&*playlist_manager_, &PlaylistManager::CurrentSongChanged, this, &Mpris2::CurrentSongChanged);
|
||||
QObject::connect(&*playlist_manager_, &PlaylistManager::PlaylistChanged, this, &Mpris2::PlaylistChangedSlot);
|
||||
QObject::connect(&*playlist_manager_, &PlaylistManager::CurrentChanged, this, &Mpris2::PlaylistCollectionChanged);
|
||||
|
||||
app_name_[0] = app_name_[0].toUpper();
|
||||
|
||||
|
@ -159,8 +160,8 @@ Mpris2::Mpris2(Application *app, QObject *parent)
|
|||
|
||||
// when PlaylistManager gets it ready, we connect PlaylistSequence with this
|
||||
void Mpris2::PlaylistManagerInitialized() {
|
||||
QObject::connect(app_->playlist_manager()->sequence(), &PlaylistSequence::ShuffleModeChanged, this, &Mpris2::ShuffleModeChanged);
|
||||
QObject::connect(app_->playlist_manager()->sequence(), &PlaylistSequence::RepeatModeChanged, this, &Mpris2::RepeatModeChanged);
|
||||
QObject::connect(playlist_manager_->sequence(), &PlaylistSequence::ShuffleModeChanged, this, &Mpris2::ShuffleModeChanged);
|
||||
QObject::connect(playlist_manager_->sequence(), &PlaylistSequence::RepeatModeChanged, this, &Mpris2::RepeatModeChanged);
|
||||
}
|
||||
|
||||
void Mpris2::EngineStateChanged(EngineBase::State newState) {
|
||||
|
@ -295,7 +296,7 @@ void Mpris2::Raise() { Q_EMIT RaiseMainWindow(); }
|
|||
void Mpris2::Quit() { QCoreApplication::quit(); }
|
||||
|
||||
QString Mpris2::PlaybackStatus() const {
|
||||
return PlaybackStatus(app_->player()->GetState());
|
||||
return PlaybackStatus(player_->GetState());
|
||||
}
|
||||
|
||||
QString Mpris2::PlaybackStatus(EngineBase::State state) const {
|
||||
|
@ -310,11 +311,11 @@ QString Mpris2::PlaybackStatus(EngineBase::State state) const {
|
|||
|
||||
QString Mpris2::LoopStatus() const {
|
||||
|
||||
if (!app_->playlist_manager()->sequence()) {
|
||||
if (!playlist_manager_->sequence()) {
|
||||
return u"None"_s;
|
||||
}
|
||||
|
||||
switch (app_->playlist_manager()->active() ? app_->playlist_manager()->active()->RepeatMode() : app_->playlist_manager()->sequence()->repeat_mode()) {
|
||||
switch (playlist_manager_->active() ? playlist_manager_->active()->RepeatMode() : playlist_manager_->sequence()->repeat_mode()) {
|
||||
case PlaylistSequence::RepeatMode::Album:
|
||||
case PlaylistSequence::RepeatMode::Playlist: return u"Playlist"_s;
|
||||
case PlaylistSequence::RepeatMode::Track: return u"Track"_s;
|
||||
|
@ -337,7 +338,7 @@ void Mpris2::SetLoopStatus(const QString &value) {
|
|||
mode = PlaylistSequence::RepeatMode::Playlist;
|
||||
}
|
||||
|
||||
app_->playlist_manager()->active()->sequence()->SetRepeatMode(mode);
|
||||
playlist_manager_->active()->sequence()->SetRepeatMode(mode);
|
||||
|
||||
}
|
||||
|
||||
|
@ -346,26 +347,26 @@ double Mpris2::Rate() const { return 1.0; }
|
|||
void Mpris2::SetRate(double rate) {
|
||||
|
||||
if (rate == 0) {
|
||||
app_->player()->Pause();
|
||||
player_->Pause();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Mpris2::Shuffle() const {
|
||||
|
||||
const PlaylistSequence::ShuffleMode shuffle_mode = app_->playlist_manager()->active() ? app_->playlist_manager()->active()->ShuffleMode() : app_->playlist_manager()->sequence()->shuffle_mode();
|
||||
const PlaylistSequence::ShuffleMode shuffle_mode = playlist_manager_->active() ? playlist_manager_->active()->ShuffleMode() : playlist_manager_->sequence()->shuffle_mode();
|
||||
return shuffle_mode != PlaylistSequence::ShuffleMode::Off;
|
||||
|
||||
}
|
||||
|
||||
void Mpris2::SetShuffle(bool enable) {
|
||||
app_->playlist_manager()->active()->sequence()->SetShuffleMode(enable ? PlaylistSequence::ShuffleMode::All : PlaylistSequence::ShuffleMode::Off);
|
||||
playlist_manager_->active()->sequence()->SetShuffleMode(enable ? PlaylistSequence::ShuffleMode::All : PlaylistSequence::ShuffleMode::Off);
|
||||
}
|
||||
|
||||
QVariantMap Mpris2::Metadata() const { return last_metadata_; }
|
||||
|
||||
double Mpris2::Rating() const {
|
||||
float rating = app_->playlist_manager()->active()->current_item_metadata().rating();
|
||||
float rating = playlist_manager_->active()->current_item_metadata().rating();
|
||||
return (rating <= 0) ? 0 : rating;
|
||||
}
|
||||
|
||||
|
@ -378,12 +379,12 @@ void Mpris2::SetRating(double rating) {
|
|||
rating = -1.0;
|
||||
}
|
||||
|
||||
app_->playlist_manager()->RateCurrentSong(static_cast<float>(rating));
|
||||
playlist_manager_->RateCurrentSong(static_cast<float>(rating));
|
||||
|
||||
}
|
||||
|
||||
QDBusObjectPath Mpris2::current_track_id() const {
|
||||
return QDBusObjectPath(QStringLiteral("/org/strawberrymusicplayer/strawberry/Track/%1").arg(QString::number(app_->playlist_manager()->active()->current_row())));
|
||||
return QDBusObjectPath(QStringLiteral("/org/strawberrymusicplayer/strawberry/Track/%1").arg(QString::number(playlist_manager_->active()->current_row())));
|
||||
}
|
||||
|
||||
// We send Metadata change notification as soon as the process of changing song starts...
|
||||
|
@ -433,15 +434,15 @@ void Mpris2::AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResult &re
|
|||
}
|
||||
|
||||
double Mpris2::Volume() const {
|
||||
return app_->player()->GetVolume() / 100.0;
|
||||
return player_->GetVolume() / 100.0;
|
||||
}
|
||||
|
||||
void Mpris2::SetVolume(const double volume) {
|
||||
app_->player()->SetVolume(static_cast<uint>(qBound(0L, lround(volume * 100.0), 100L)));
|
||||
player_->SetVolume(static_cast<uint>(qBound(0L, lround(volume * 100.0), 100L)));
|
||||
}
|
||||
|
||||
qint64 Mpris2::Position() const {
|
||||
return app_->player()->engine()->position_nanosec() / kNsecPerUsec;
|
||||
return player_->engine()->position_nanosec() / kNsecPerUsec;
|
||||
}
|
||||
|
||||
double Mpris2::MaximumRate() const { return 1.0; }
|
||||
|
@ -449,66 +450,66 @@ double Mpris2::MaximumRate() const { return 1.0; }
|
|||
double Mpris2::MinimumRate() const { return 1.0; }
|
||||
|
||||
bool Mpris2::CanGoNext() const {
|
||||
return app_->playlist_manager()->active() && app_->playlist_manager()->active()->next_row() != -1;
|
||||
return playlist_manager_->active() && playlist_manager_->active()->next_row() != -1;
|
||||
}
|
||||
|
||||
bool Mpris2::CanGoPrevious() const {
|
||||
return app_->playlist_manager()->active() && (app_->playlist_manager()->active()->previous_row() != -1 || app_->player()->PreviousWouldRestartTrack());
|
||||
return playlist_manager_->active() && (playlist_manager_->active()->previous_row() != -1 || player_->PreviousWouldRestartTrack());
|
||||
}
|
||||
|
||||
bool Mpris2::CanPlay() const {
|
||||
return app_->playlist_manager()->active() && app_->playlist_manager()->active()->rowCount() != 0;
|
||||
return playlist_manager_->active() && playlist_manager_->active()->rowCount() != 0;
|
||||
}
|
||||
|
||||
// This one's a bit different than MPRIS 1 - we want this to be true even when the song is already paused or stopped.
|
||||
bool Mpris2::CanPause() const {
|
||||
return (app_->player()->GetCurrentItem() && app_->player()->GetState() == EngineBase::State::Playing && !(app_->player()->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused"_L1 || PlaybackStatus() == "Stopped"_L1;
|
||||
return (player_->GetCurrentItem() && player_->GetState() == EngineBase::State::Playing && !(player_->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused"_L1 || PlaybackStatus() == "Stopped"_L1;
|
||||
}
|
||||
|
||||
bool Mpris2::CanSeek() const { return CanSeek(app_->player()->GetState()); }
|
||||
bool Mpris2::CanSeek() const { return CanSeek(player_->GetState()); }
|
||||
|
||||
bool Mpris2::CanSeek(EngineBase::State state) const {
|
||||
return app_->player()->GetCurrentItem() && state != EngineBase::State::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream();
|
||||
return player_->GetCurrentItem() && state != EngineBase::State::Empty && !player_->GetCurrentItem()->Metadata().is_stream();
|
||||
}
|
||||
|
||||
bool Mpris2::CanControl() const { return true; }
|
||||
|
||||
void Mpris2::Next() {
|
||||
if (CanGoNext()) {
|
||||
app_->player()->Next();
|
||||
player_->Next();
|
||||
}
|
||||
}
|
||||
|
||||
void Mpris2::Previous() {
|
||||
if (CanGoPrevious()) {
|
||||
app_->player()->Previous();
|
||||
player_->Previous();
|
||||
}
|
||||
}
|
||||
|
||||
void Mpris2::Pause() {
|
||||
if (CanPause() && app_->player()->GetState() != EngineBase::State::Paused) {
|
||||
app_->player()->Pause();
|
||||
if (CanPause() && player_->GetState() != EngineBase::State::Paused) {
|
||||
player_->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void Mpris2::PlayPause() {
|
||||
if (CanPause()) {
|
||||
app_->player()->PlayPause();
|
||||
player_->PlayPause();
|
||||
}
|
||||
}
|
||||
|
||||
void Mpris2::Stop() { app_->player()->Stop(); }
|
||||
void Mpris2::Stop() { player_->Stop(); }
|
||||
|
||||
void Mpris2::Play() {
|
||||
if (CanPlay()) {
|
||||
app_->player()->Play();
|
||||
player_->Play();
|
||||
}
|
||||
}
|
||||
|
||||
void Mpris2::Seek(qint64 offset) {
|
||||
|
||||
if (CanSeek()) {
|
||||
app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + offset / kUsecPerSec);
|
||||
player_->SeekTo(player_->engine()->position_nanosec() / kNsecPerSec + offset / kUsecPerSec);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -518,15 +519,15 @@ void Mpris2::SetPosition(const QDBusObjectPath &trackId, qint64 offset) {
|
|||
if (CanSeek() && trackId == current_track_id() && offset >= 0) {
|
||||
offset *= kNsecPerUsec;
|
||||
|
||||
if (offset < app_->player()->GetCurrentItem()->Metadata().length_nanosec()) {
|
||||
app_->player()->SeekTo(offset / kNsecPerSec);
|
||||
if (offset < player_->GetCurrentItem()->Metadata().length_nanosec()) {
|
||||
player_->SeekTo(offset / kNsecPerSec);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Mpris2::OpenUri(const QString &uri) {
|
||||
app_->playlist_manager()->active()->InsertUrls(QList<QUrl>() << QUrl(uri), -1, true);
|
||||
playlist_manager_->active()->InsertUrls(QList<QUrl>() << QUrl(uri), -1, true);
|
||||
}
|
||||
|
||||
Track_Ids Mpris2::Tracks() const {
|
||||
|
@ -566,7 +567,7 @@ void Mpris2::GoTo(const QDBusObjectPath &trackId) {
|
|||
}
|
||||
|
||||
quint32 Mpris2::PlaylistCount() const {
|
||||
return app_->playlist_manager()->GetAllPlaylists().size();
|
||||
return playlist_manager_->GetAllPlaylists().size();
|
||||
}
|
||||
|
||||
QStringList Mpris2::Orderings() const { return QStringList() << u"User"_s; }
|
||||
|
@ -582,14 +583,14 @@ QDBusObjectPath MakePlaylistPath(int id) {
|
|||
MaybePlaylist Mpris2::ActivePlaylist() const {
|
||||
|
||||
MaybePlaylist maybe_playlist;
|
||||
Playlist *current_playlist = app_->playlist_manager()->current();
|
||||
Playlist *current_playlist = playlist_manager_->current();
|
||||
maybe_playlist.valid = current_playlist;
|
||||
if (!current_playlist) {
|
||||
return maybe_playlist;
|
||||
}
|
||||
|
||||
maybe_playlist.playlist.id = MakePlaylistPath(current_playlist->id());
|
||||
maybe_playlist.playlist.name = app_->playlist_manager()->GetPlaylistName(current_playlist->id());
|
||||
maybe_playlist.playlist.name = playlist_manager_->GetPlaylistName(current_playlist->id());
|
||||
return maybe_playlist;
|
||||
|
||||
}
|
||||
|
@ -606,12 +607,12 @@ void Mpris2::ActivatePlaylist(const QDBusObjectPath &playlist_id) {
|
|||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
if (!app_->playlist_manager()->IsPlaylistOpen(p)) {
|
||||
if (!playlist_manager_->IsPlaylistOpen(p)) {
|
||||
qLog(Error) << "Playlist isn't opened!";
|
||||
return;
|
||||
}
|
||||
app_->playlist_manager()->SetActivePlaylist(p);
|
||||
app_->player()->Next();
|
||||
playlist_manager_->SetActivePlaylist(p);
|
||||
player_->Next();
|
||||
|
||||
}
|
||||
|
||||
|
@ -620,13 +621,13 @@ MprisPlaylistList Mpris2::GetPlaylists(quint32 index, quint32 max_count, const Q
|
|||
|
||||
Q_UNUSED(order);
|
||||
|
||||
const QList<Playlist*> playlists = app_->playlist_manager()->GetAllPlaylists();
|
||||
const QList<Playlist*> playlists = playlist_manager_->GetAllPlaylists();
|
||||
MprisPlaylistList ret;
|
||||
ret.reserve(playlists.count());
|
||||
for (Playlist *p : playlists) {
|
||||
MprisPlaylist mpris_playlist;
|
||||
mpris_playlist.id = MakePlaylistPath(p->id());
|
||||
mpris_playlist.name = app_->playlist_manager()->GetPlaylistName(p->id());
|
||||
mpris_playlist.name = playlist_manager_->GetPlaylistName(p->id());
|
||||
ret << mpris_playlist;
|
||||
}
|
||||
|
||||
|
@ -642,7 +643,7 @@ void Mpris2::PlaylistChangedSlot(Playlist *playlist) {
|
|||
|
||||
MprisPlaylist mpris_playlist;
|
||||
mpris_playlist.id = MakePlaylistPath(playlist->id());
|
||||
mpris_playlist.name = app_->playlist_manager()->GetPlaylistName(playlist->id());
|
||||
mpris_playlist.name = playlist_manager_->GetPlaylistName(playlist->id());
|
||||
|
||||
Q_EMIT PlaylistChanged(mpris_playlist);
|
||||
|
||||
|
|
|
@ -37,10 +37,13 @@
|
|||
#include <QDBusArgument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
|
||||
class Application;
|
||||
class Player;
|
||||
class PlaylistManager;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class Song;
|
||||
class Playlist;
|
||||
|
||||
|
@ -75,7 +78,7 @@ class Mpris2 : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Mpris2(Application *app, QObject *parent = nullptr);
|
||||
explicit Mpris2(SharedPtr<Player> player, SharedPtr<PlaylistManager> playlist_manager, SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader, QObject *parent = nullptr);
|
||||
|
||||
// org.mpris.MediaPlayer2 MPRIS 2.0 Root interface
|
||||
Q_PROPERTY(bool CanQuit READ CanQuit)
|
||||
|
@ -231,7 +234,9 @@ class Mpris2 : public QObject {
|
|||
QString DesktopEntryAbsolutePath() const;
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<Player> player_;
|
||||
SharedPtr<PlaylistManager> playlist_manager_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
|
||||
QString app_name_;
|
||||
QString desktopfilepath_;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "core/shared_ptr.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/networktimeouts.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
|
||||
#include "acoustidclient.h"
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "engine/chromaprinter.h"
|
||||
#include "acoustidclient.h"
|
||||
#include "musicbrainzclient.h"
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#include <QFileInfo>
|
||||
#include <QValidator>
|
||||
|
||||
#include "utilities/filenameconstants.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "constants/filenameconstants.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "utilities/transliterate.h"
|
||||
#include "core/song.h"
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "osdpretty.h"
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/settings.h"
|
||||
#ifdef Q_OS_MACOS
|
||||
|
@ -41,15 +40,13 @@
|
|||
# include "core/qtsystemtrayicon.h"
|
||||
#endif
|
||||
#include "utilities/strutils.h"
|
||||
#include "covermanager/currentalbumcoverloader.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
const char *OSDBase::kSettingsGroup = "OSD";
|
||||
|
||||
OSDBase::OSDBase(SharedPtr<SystemTrayIcon> tray_icon, Application *app, QObject *parent)
|
||||
OSDBase::OSDBase(SharedPtr<SystemTrayIcon> tray_icon, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
tray_icon_(tray_icon),
|
||||
pretty_popup_(new OSDPretty(OSDPretty::Mode::Popup)),
|
||||
app_name_(QCoreApplication::applicationName()),
|
||||
|
@ -65,8 +62,6 @@ OSDBase::OSDBase(SharedPtr<SystemTrayIcon> tray_icon, Application *app, QObject
|
|||
ignore_next_stopped_(false),
|
||||
playing_(false) {
|
||||
|
||||
QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::ThumbnailLoaded, this, &OSDBase::AlbumCoverLoaded);
|
||||
|
||||
app_name_[0] = app_name_[0].toUpper();
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "core/song.h"
|
||||
#include "playlist/playlistsequence.h"
|
||||
|
||||
class Application;
|
||||
class OSDPretty;
|
||||
class SystemTrayIcon;
|
||||
|
||||
|
@ -43,7 +42,7 @@ class OSDBase : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OSDBase(SharedPtr<SystemTrayIcon> tray_icon, Application *app, QObject *parent = nullptr);
|
||||
explicit OSDBase(SharedPtr<SystemTrayIcon> tray_icon, QObject *parent = nullptr);
|
||||
~OSDBase() override;
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
|
@ -81,6 +80,8 @@ class OSDBase : public QObject {
|
|||
|
||||
void ShowPreview(const OSDBase::Behaviour type, const QString &line1, const QString &line2, const Song &song);
|
||||
|
||||
void AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image);
|
||||
|
||||
private:
|
||||
enum class MessageType {
|
||||
Summary,
|
||||
|
@ -91,11 +92,7 @@ class OSDBase : public QObject {
|
|||
QString ReplaceMessage(const MessageType type, const QString &message, const Song &song);
|
||||
virtual void ShowMessageNative(const QString &summary, const QString &message, const QString &icon = QString(), const QImage &image = QImage());
|
||||
|
||||
private Q_SLOTS:
|
||||
void AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
SharedPtr<SystemTrayIcon> tray_icon_;
|
||||
OSDPretty *pretty_popup_;
|
||||
|
||||
|
|
|
@ -105,8 +105,8 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QImage &image) {
|
|||
|
||||
}
|
||||
|
||||
OSDDBus::OSDDBus(SharedPtr<SystemTrayIcon> tray_icon, Application *app, QObject *parent)
|
||||
: OSDBase(tray_icon, app, parent),
|
||||
OSDDBus::OSDDBus(SharedPtr<SystemTrayIcon> tray_icon, QObject *parent)
|
||||
: OSDBase(tray_icon, parent),
|
||||
version_(1, 1),
|
||||
notification_id_(0) {
|
||||
|
||||
|
|
|
@ -39,14 +39,13 @@
|
|||
class OrgFreedesktopNotificationsInterface;
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
class Application;
|
||||
class SystemTrayIcon;
|
||||
|
||||
class OSDDBus : public OSDBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OSDDBus(SharedPtr<SystemTrayIcon> tray_icon, Application *app, QObject *parent = nullptr);
|
||||
explicit OSDDBus(SharedPtr<SystemTrayIcon> tray_icon, QObject *parent = nullptr);
|
||||
~OSDDBus() override;
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
|
|
|
@ -37,7 +37,7 @@ class OSDMac : public OSDBase {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OSDMac(SharedPtr<SystemTrayIcon> tray_icon, Application *app, QObject *parent = nullptr);
|
||||
explicit OSDMac(SharedPtr<SystemTrayIcon> tray_icon, QObject *parent = nullptr);
|
||||
~OSDMac() override;
|
||||
|
||||
bool SupportsNativeNotifications() override;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue