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