diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ccc45c6d5..863263bbf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,9 +176,11 @@ if(UNIX AND NOT APPLE) endif() pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GOBJECT REQUIRED IMPORTED_TARGET gobject-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) -if(GIO_FOUND AND UNIX) - pkg_check_modules(GIO_UNIX IMPORTED_TARGET gio-unix-2.0) +if(UNIX AND NOT APPLE) + pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + if(GIO_FOUND AND UNIX) + pkg_check_modules(GIO_UNIX IMPORTED_TARGET gio-unix-2.0) + endif() endif() pkg_check_modules(LIBCDIO IMPORTED_TARGET libcdio) pkg_check_modules(GSTREAMER REQUIRED IMPORTED_TARGET gstreamer-1.0) @@ -327,12 +329,10 @@ optional_component(UDISKS2 ON "Devices: UDisks2 backend" optional_component(GIO ON "Devices: GIO device backend" DEPENDS "libgio" GIO_FOUND - DEPENDS "Unix or Windows" "NOT APPLE" ) optional_component(GIO_UNIX ON "Devices: GIO device backend (Unix support)" DEPENDS "libgio-unix" GIO_UNIX_FOUND - DEPENDS "Unix or Windows" "NOT APPLE" ) optional_component(AUDIOCD ON "Devices: Audio CD support" @@ -406,6 +406,7 @@ set(SOURCES src/core/logging.cpp src/core/mainwindow.cpp src/core/application.cpp + src/core/playerinterface.cpp src/core/player.cpp src/core/commandlineoptions.cpp src/core/database.cpp @@ -433,14 +434,18 @@ set(SOURCES src/core/taskmanager.cpp src/core/thread.cpp src/core/urlhandler.cpp + src/core/urlhandlers.cpp src/core/iconloader.cpp src/core/standarditemiconloader.cpp src/core/scopedtransaction.cpp src/core/translations.cpp - src/core/systemtrayicon.cpp src/core/localredirectserver.cpp src/core/mimedata.cpp src/core/temporaryfile.cpp + src/core/enginemetadata.cpp + src/core/songmimedata.cpp + src/core/platforminterface.cpp + src/utilities/strutils.cpp src/utilities/envutils.cpp src/utilities/colorutils.cpp @@ -459,6 +464,7 @@ set(SOURCES src/utilities/coverutils.cpp src/utilities/screenutils.cpp src/utilities/textencodingutils.cpp + src/utilities/coveroptions.cpp src/tagreader/tagreaderclient.cpp src/tagreader/tagreaderresult.cpp @@ -483,12 +489,45 @@ set(SOURCES src/filterparser/filterparser.cpp src/filterparser/filtertree.cpp + src/filterparser/filtertreeand.cpp + src/filterparser/filtertreecolumnterm.cpp + src/filterparser/filtertreenop.cpp + src/filterparser/filtertreenot.cpp + src/filterparser/filtertreeor.cpp + src/filterparser/filtertreeterm.cpp + src/filterparser/filterparserfloateqcomparator.cpp + src/filterparser/filterparserfloatgecomparator.cpp + src/filterparser/filterparserfloatgtcomparator.cpp + src/filterparser/filterparserfloatlecomparator.cpp + src/filterparser/filterparserfloatltcomparator.cpp + src/filterparser/filterparserfloatnecomparator.cpp + src/filterparser/filterparserint64eqcomparator.cpp + src/filterparser/filterparserint64gecomparator.cpp + src/filterparser/filterparserint64gtcomparator.cpp + src/filterparser/filterparserint64lecomparator.cpp + src/filterparser/filterparserint64ltcomparator.cpp + src/filterparser/filterparserint64necomparator.cpp + src/filterparser/filterparserinteqcomparator.cpp + src/filterparser/filterparserintgecomparator.cpp + src/filterparser/filterparserintgtcomparator.cpp + src/filterparser/filterparserintlecomparator.cpp + src/filterparser/filterparserintltcomparator.cpp + src/filterparser/filterparserintnecomparator.cpp + src/filterparser/filterparsersearchtermcomparator.cpp + src/filterparser/filterparsertextcontainscomparator.cpp + src/filterparser/filterparsertexteqcomparator.cpp + src/filterparser/filterparsertextnecomparator.cpp + src/filterparser/filterparseruinteqcomparator.cpp + src/filterparser/filterparseruintgecomparator.cpp + src/filterparser/filterparseruintgtcomparator.cpp + src/filterparser/filterparseruintlecomparator.cpp + src/filterparser/filterparseruintltcomparator.cpp + src/filterparser/filterparseruintnecomparator.cpp src/engine/enginebase.cpp src/engine/enginedevice.cpp src/engine/devicefinders.cpp src/engine/devicefinder.cpp - src/engine/enginemetadata.cpp src/engine/gststartup.cpp src/engine/gstengine.cpp src/engine/gstenginepipeline.cpp @@ -509,11 +548,12 @@ set(SOURCES src/context/contextview.cpp src/context/contextalbum.cpp - src/collection/collection.cpp + src/collection/collectionlibrary.cpp src/collection/collectionmodel.cpp src/collection/collectionbackend.cpp src/collection/collectionwatcher.cpp src/collection/collectionview.cpp + src/collection/collectionitem.cpp src/collection/collectionitemdelegate.cpp src/collection/collectionviewcontainer.cpp src/collection/collectiondirectorymodel.cpp @@ -539,17 +579,23 @@ set(SOURCES src/playlist/playlistlistmodel.cpp src/playlist/playlistlistsortfiltermodel.cpp src/playlist/playlistlistview.cpp + src/playlist/playlistmanagerinterface.cpp src/playlist/playlistmanager.cpp src/playlist/playlistsaveoptionsdialog.cpp src/playlist/playlistsequence.cpp src/playlist/playlisttabbar.cpp - src/playlist/playlistundocommands.cpp src/playlist/playlistview.cpp src/playlist/playlistproxystyle.cpp - src/playlist/songmimedata.cpp src/playlist/songloaderinserter.cpp src/playlist/songplaylistitem.cpp src/playlist/dynamicplaylistcontrols.cpp + src/playlist/playlistundocommandbase.cpp + src/playlist/playlistundocommandinsertitems.cpp + src/playlist/playlistundocommandremoveitems.cpp + src/playlist/playlistundocommandmoveitems.cpp + src/playlist/playlistundocommandreorderitems.cpp + src/playlist/playlistundocommandsortitems.cpp + src/playlist/playlistundocommandshuffleitems.cpp src/queue/queue.cpp src/queue/queueview.cpp @@ -667,8 +713,6 @@ set(SOURCES src/widgets/fancytabbar.cpp src/widgets/fancytabdata.cpp src/widgets/favoritewidget.cpp - src/widgets/fileview.cpp - src/widgets/fileviewlist.cpp src/widgets/forcescrollperpixel.cpp src/widgets/freespacebar.cpp src/widgets/groupediconview.cpp @@ -719,7 +763,7 @@ set(SOURCES src/radios/radiomimedata.cpp src/scrobbler/audioscrobbler.cpp - src/scrobbler/scrobblersettings.cpp + src/scrobbler/scrobblersettingsservice.cpp src/scrobbler/scrobblerservice.cpp src/scrobbler/scrobblercache.cpp src/scrobbler/scrobblercacheitem.cpp @@ -749,6 +793,11 @@ set(SOURCES src/transcoder/transcoderoptionsaac.cpp src/transcoder/transcoderoptionsasf.cpp src/transcoder/transcoderoptionsmp3.cpp + + src/systemtrayicon/systemtrayicon.cpp + + src/fileview/fileview.cpp + src/fileview/fileviewlist.cpp ) set(HEADERS @@ -756,6 +805,7 @@ set(HEADERS src/core/mainwindow.h src/core/application.h src/core/player.h + src/core/playerinterface.h src/core/database.h src/core/deletefiles.h src/core/filesystemwatcherinterface.h @@ -769,11 +819,13 @@ set(HEADERS src/core/songloader.h src/core/taskmanager.h src/core/thread.h + src/core/urlhandlers.h src/core/urlhandler.h src/core/standarditemiconloader.h src/core/mimedata.h src/core/stylesheetloader.h src/core/localredirectserver.h + src/core/songmimedata.h src/tagreader/tagreaderclient.h src/tagreader/tagreaderreply.h @@ -802,7 +854,7 @@ set(HEADERS src/context/contextview.h src/context/contextalbum.h - src/collection/collection.h + src/collection/collectionlibrary.h src/collection/collectionmodel.h src/collection/collectionbackend.h src/collection/collectionwatcher.h @@ -825,6 +877,7 @@ set(HEADERS src/playlist/playlistlistmodel.h src/playlist/playlistlistview.h src/playlist/playlistlistsortfiltermodel.h + src/playlist/playlistmanagerinterface.h src/playlist/playlistmanager.h src/playlist/playlistsaveoptionsdialog.h src/playlist/playlistsequence.h @@ -833,7 +886,6 @@ set(HEADERS src/playlist/playlistproxystyle.h src/playlist/playlistitemmimedata.h src/playlist/songloaderinserter.h - src/playlist/songmimedata.h src/playlist/dynamicplaylistcontrols.h src/queue/queue.h @@ -944,8 +996,6 @@ set(HEADERS src/widgets/fancytabbar.h src/widgets/fancytabdata.h src/widgets/favoritewidget.h - src/widgets/fileview.h - src/widgets/fileviewlist.h src/widgets/freespacebar.h src/widgets/groupediconview.h src/widgets/lineedit.h @@ -993,7 +1043,7 @@ set(HEADERS src/radios/radioparadiseservice.h src/scrobbler/audioscrobbler.h - src/scrobbler/scrobblersettings.h + src/scrobbler/scrobblersettingsservice.h src/scrobbler/scrobblerservice.h src/scrobbler/scrobblercache.h src/scrobbler/scrobblingapi20.h @@ -1020,6 +1070,9 @@ set(HEADERS src/transcoder/transcoderoptionsaac.h src/transcoder/transcoderoptionsasf.h src/transcoder/transcoderoptionsmp3.h + + src/fileview/fileview.h + src/fileview/fileviewlist.h ) set(UI @@ -1081,7 +1134,6 @@ set(UI src/dialogs/saveplaylistsdialog.ui src/widgets/trackslider.ui - src/widgets/fileview.ui src/widgets/loginstatewidget.ui src/osd/osdpretty.ui @@ -1106,6 +1158,8 @@ set(UI src/transcoder/transcoderoptionsspeex.ui src/transcoder/transcoderoptionsasf.ui src/transcoder/transcoderoptionsmp3.ui + + src/fileview/fileview.ui ) if(APPLE) @@ -1114,27 +1168,27 @@ if(APPLE) src/utilities/macosutils.mm src/core/scoped_nsautorelease_pool.mm src/core/mac_startup.mm - src/core/macsystemtrayicon.mm + src/systemtrayicon/macsystemtrayicon.mm src/osd/osdmac.mm src/widgets/searchfield_mac.mm src/engine/macosdevicefinder.cpp src/device/macosdevicelister.mm HEADERS - src/core/macsystemtrayicon.h + src/systemtrayicon/macsystemtrayicon.h src/osd/osdmac.h src/device/macosdevicelister.h ) else() - list(APPEND SOURCES src/core/qtsystemtrayicon.cpp src/widgets/searchfield_qt.cpp src/widgets/searchfield_qt_private.cpp) - list(APPEND HEADERS src/core/qtsystemtrayicon.h src/widgets/searchfield_qt_private.h) + list(APPEND SOURCES src/systemtrayicon/qtsystemtrayicon.cpp src/widgets/searchfield_qt.cpp src/widgets/searchfield_qt_private.cpp) + list(APPEND HEADERS src/systemtrayicon/qtsystemtrayicon.h src/widgets/searchfield_qt_private.h) endif() optional_source(WIN32 SOURCES + src/utilities/scopedwchararray.cpp src/utilities/winutils.cpp src/engine/directsounddevicefinder.cpp src/engine/mmdevicefinder.cpp - src/core/scopedwchararray.cpp src/core/windows7thumbbar.cpp HEADERS src/core/windows7thumbbar.h @@ -1207,8 +1261,8 @@ optional_source(HAVE_MOODBAR src/moodbar/moodbarpipeline.cpp src/moodbar/moodbarproxystyle.cpp src/moodbar/moodbarrenderer.cpp - src/moodbar/gstfastspectrumplugin.cpp - src/moodbar/gstfastspectrum.cpp + src/engine/gstfastspectrumplugin.cpp + src/engine/gstfastspectrum.cpp src/settings/moodbarsettingspage.cpp HEADERS src/moodbar/moodbarcontroller.h @@ -1267,11 +1321,11 @@ endif() if(HAVE_UDISKS2) optional_source(HAVE_UDISKS2 SOURCES src/device/udisks2lister.cpp HEADERS src/device/udisks2lister.h) - set_source_files_properties(src/device/org.freedesktop.DBus.ObjectManager.xml PROPERTIES NO_NAMESPACE objectmanager INCLUDE core/dbus_metatypes.h) - set_source_files_properties(src/device/org.freedesktop.UDisks2.Filesystem.xml PROPERTIES NO_NAMESPACE udisks2filesystem INCLUDE core/dbus_metatypes.h) - set_source_files_properties(src/device/org.freedesktop.UDisks2.Block.xml PROPERTIES NO_NAMESPACE udisks2block INCLUDE core/dbus_metatypes.h) - set_source_files_properties(src/device/org.freedesktop.UDisks2.Drive.xml PROPERTIES NO_NAMESPACE udisks2drive INCLUDE core/dbus_metatypes.h) - set_source_files_properties(src/device/org.freedesktop.UDisks2.Job.xml PROPERTIES NO_NAMESPACE udisks2job INCLUDE core/dbus_metatypes.h) + set_source_files_properties(src/device/org.freedesktop.DBus.ObjectManager.xml PROPERTIES NO_NAMESPACE objectmanager INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(src/device/org.freedesktop.UDisks2.Filesystem.xml PROPERTIES NO_NAMESPACE udisks2filesystem INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(src/device/org.freedesktop.UDisks2.Block.xml PROPERTIES NO_NAMESPACE udisks2block INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(src/device/org.freedesktop.UDisks2.Drive.xml PROPERTIES NO_NAMESPACE udisks2drive INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(src/device/org.freedesktop.UDisks2.Job.xml PROPERTIES NO_NAMESPACE udisks2job INCLUDE includes/dbus_metatypes.h) qt_add_dbus_interface(SOURCES src/device/org.freedesktop.DBus.ObjectManager.xml objectmanager) qt_add_dbus_interface(SOURCES src/device/org.freedesktop.UDisks2.Filesystem.xml udisks2filesystem) qt_add_dbus_interface(SOURCES src/device/org.freedesktop.UDisks2.Block.xml udisks2block) @@ -1420,7 +1474,7 @@ if(LINUX AND LSB_RELEASE_EXEC AND DPKG_BUILDPACKAGE) endif() if(HAVE_TRANSLATIONS) - qt_add_lupdate(strawberry TS_FILES "${CMAKE_SOURCE_DIR}/src/translations/strawberry_en_US.ts" OPTIONS -locations none -no-ui-lines -no-obsolete) + qt_add_lupdate(strawberry_lib TS_FILES "${CMAKE_SOURCE_DIR}/src/translations/strawberry_en_US.ts" OPTIONS -locations none -no-ui-lines -no-obsolete) file(GLOB_RECURSE ts_files ${CMAKE_SOURCE_DIR}/src/translations/*.ts) set_source_files_properties(${ts_files} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/data") qt_add_lrelease(strawberry TS_FILES ${ts_files} QM_FILES_OUTPUT_VARIABLE INSTALL_TRANSLATIONS_FILES) @@ -1429,14 +1483,7 @@ if(HAVE_TRANSLATIONS) endif() endif() -target_include_directories(strawberry PRIVATE - ${CMAKE_SOURCE_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_BINARY_DIR}/src -) - -target_include_directories(strawberry_lib PRIVATE +target_include_directories(strawberry_lib PUBLIC ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src @@ -1444,14 +1491,14 @@ target_include_directories(strawberry_lib PRIVATE ) if(SINGLEAPPLICATION_INCLUDE_DIRS) - target_include_directories(strawberry SYSTEM PRIVATE ${SINGLEAPPLICATION_INCLUDE_DIRS}) + target_include_directories(strawberry_lib SYSTEM PRIVATE ${SINGLEAPPLICATION_INCLUDE_DIRS}) endif() if(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H) target_include_directories(strawberry_lib SYSTEM PRIVATE ${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) endif() -target_link_libraries(strawberry_lib PRIVATE +target_link_libraries(strawberry_lib PUBLIC ${CMAKE_THREAD_LIBS_INIT} PkgConfig::GLIB PkgConfig::GOBJECT @@ -1487,10 +1534,11 @@ target_link_libraries(strawberry_lib PRIVATE $<$:execinfo> $<$:dsound dwmapi getopt-win::getopt> $<$:WindowsApp> + ${SINGLEAPPLICATION_LIBRARIES} ) if(APPLE) - target_link_libraries(strawberry_lib PRIVATE + target_link_libraries(strawberry_lib PUBLIC "-framework Foundation" "-framework AppKit" "-framework Carbon" @@ -1502,19 +1550,7 @@ if(APPLE) ) endif() -target_link_libraries(strawberry PRIVATE - ${CMAKE_THREAD_LIBS_INIT} - PkgConfig::GLIB - PkgConfig::GOBJECT - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Widgets - $<$:Qt${QT_VERSION_MAJOR}::DBus> - ${SINGLEAPPLICATION_LIBRARIES} - strawberry_lib -) +target_link_libraries(strawberry PUBLIC strawberry_lib) if(NOT APPLE) install(TARGETS strawberry RUNTIME DESTINATION bin) diff --git a/src/analyzer/analyzerbase.h b/src/analyzer/analyzerbase.h index de8c9bdf5f..b7263e608d 100644 --- a/src/analyzer/analyzerbase.h +++ b/src/analyzer/analyzerbase.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "analyzer/fht.h" #include "engine/enginebase.h" diff --git a/src/analyzer/analyzercontainer.cpp b/src/analyzer/analyzercontainer.cpp index 3ead830e44..1b4c33cb7b 100644 --- a/src/analyzer/analyzercontainer.cpp +++ b/src/analyzer/analyzercontainer.cpp @@ -44,8 +44,8 @@ #include "waverubberanalyzer.h" #include "rainbowanalyzer.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/settings.h" #include "engine/enginebase.h" diff --git a/src/analyzer/analyzercontainer.h b/src/analyzer/analyzercontainer.h index 94ddaa70c3..20f36eafac 100644 --- a/src/analyzer/analyzercontainer.h +++ b/src/analyzer/analyzercontainer.h @@ -30,7 +30,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "engine/enginebase.h" class QTimer; diff --git a/src/collection/collectionbackend.cpp b/src/collection/collectionbackend.cpp index d573f721ad..45ed9e8fd7 100644 --- a/src/collection/collectionbackend.cpp +++ b/src/collection/collectionbackend.cpp @@ -45,13 +45,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/database.h" #include "core/scopedtransaction.h" #include "core/song.h" -#include "core/sqlrow.h" -#include "smartplaylists/smartplaylistsearch.h" #include "collectiondirectory.h" #include "collectionbackend.h" @@ -1932,37 +1930,26 @@ void CollectionBackend::DeleteAll() { } -SongList CollectionBackend::SmartPlaylistsFindSongs(const SmartPlaylistSearch &search) { +SongList CollectionBackend::ExecuteQuery(const QString &sql) { QMutexLocker l(db_->Mutex()); QSqlDatabase db(db_->Connect()); - // Build the query - QString sql = search.ToSql(songs_table()); - - // Run the query - SongList ret; SqlQuery query(db); query.prepare(sql); if (!query.Exec()) { db_->ReportErrors(query); - return ret; + return SongList(); } - // Read the results + SongList songs; while (query.next()) { Song song; song.InitFromQuery(query, true); - ret << song; + songs << song; } - return ret; - -} - -SongList CollectionBackend::SmartPlaylistsGetAllSongs() { - // Get all the songs! - return SmartPlaylistsFindSongs(SmartPlaylistSearch(SmartPlaylistSearch::SearchType::All, SmartPlaylistSearch::TermList(), SmartPlaylistSearch::SortType::FieldAsc, SmartPlaylistSearchTerm::Field::Artist, -1)); + return songs; } diff --git a/src/collection/collectionbackend.h b/src/collection/collectionbackend.h index eeaa159ac9..0e996cf087 100644 --- a/src/collection/collectionbackend.h +++ b/src/collection/collectionbackend.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "collectionfilteroptions.h" #include "collectionquery.h" @@ -45,7 +45,6 @@ class QThread; class TaskManager; class Database; -class SmartPlaylistSearch; class CollectionBackendInterface : public QObject { Q_OBJECT @@ -227,8 +226,7 @@ class CollectionBackend : public CollectionBackendInterface { SongList GetSongsByFingerprint(const QString &fingerprint) override; - SongList SmartPlaylistsGetAllSongs(); - SongList SmartPlaylistsFindSongs(const SmartPlaylistSearch &search); + SongList ExecuteQuery(const QString &sql); void AddOrUpdateSongsAsync(const SongList &songs); void UpdateSongsBySongIDAsync(const SongMap &new_songs); diff --git a/src/collection/collectiondirectorymodel.cpp b/src/collection/collectiondirectorymodel.cpp index a83727f9db..029f15953e 100644 --- a/src/collection/collectiondirectorymodel.cpp +++ b/src/collection/collectiondirectorymodel.cpp @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/filesystemmusicstorage.h" #include "core/iconloader.h" #include "core/musicstorage.h" diff --git a/src/collection/collectiondirectorymodel.h b/src/collection/collectiondirectorymodel.h index dae601fc11..0d0da2c68d 100644 --- a/src/collection/collectiondirectorymodel.h +++ b/src/collection/collectiondirectorymodel.h @@ -33,7 +33,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "collectiondirectory.h" class QModelIndex; diff --git a/src/collection/collectionfilter.cpp b/src/collection/collectionfilter.cpp index b43d3a8b90..910ed8fa41 100644 --- a/src/collection/collectionfilter.cpp +++ b/src/collection/collectionfilter.cpp @@ -28,10 +28,9 @@ #include #include "core/song.h" +#include "core/songmimedata.h" #include "filterparser/filterparser.h" #include "filterparser/filtertree.h" -#include "playlist/songmimedata.h" -#include "playlist/playlistmanager.h" #include "collectionbackend.h" #include "collectionfilter.h" #include "collectionmodel.h" @@ -95,7 +94,7 @@ QMimeData *CollectionFilter::mimeData(const QModelIndexList &indexes) const { } data->setUrls(urls); - data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs); + data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs); return data; diff --git a/src/collection/collectionfilterwidget.cpp b/src/collection/collectionfilterwidget.cpp index 3a650f73ce..78030e5941 100644 --- a/src/collection/collectionfilterwidget.cpp +++ b/src/collection/collectionfilterwidget.cpp @@ -55,8 +55,8 @@ #include "groupbydialog.h" #include "ui_collectionfilterwidget.h" #include "widgets/searchfield.h" -#include "settings/collectionsettingspage.h" -#include "settings/appearancesettingspage.h" +#include "constants/collectionsettings.h" +#include "constants/appearancesettings.h" using namespace Qt::Literals::StringLiterals; @@ -204,8 +204,8 @@ void CollectionFilterWidget::setFilter(CollectionFilter *filter) { void CollectionFilterWidget::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeConfigureButtons, 20).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeConfigureButtons, 20).toInt(); s.endGroup(); ui_->options->setIconSize(QSize(iconsize, iconsize)); ui_->search_field->setIconSize(iconsize); @@ -345,7 +345,7 @@ void CollectionFilterWidget::SaveGroupBy() { qLog(Debug) << "Saving current grouping to" << name; Settings s; - if (settings_group_.isEmpty() || settings_group_ == QLatin1String(CollectionSettingsPage::kSettingsGroup)) { + if (settings_group_.isEmpty() || settings_group_ == QLatin1String(CollectionSettings::kSettingsGroup)) { s.beginGroup(SavedGroupingManager::kSavedGroupingsSettingsGroup); } else { diff --git a/src/collection/collectionitem.cpp b/src/collection/collectionitem.cpp new file mode 100644 index 0000000000..20987b75c1 --- /dev/null +++ b/src/collection/collectionitem.cpp @@ -0,0 +1,32 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "collectionitem.h" + +CollectionItem::CollectionItem(SimpleTreeModel *_model) + : SimpleTreeItem(_model), + type(Type::Root), + container_level(-1), + compilation_artist_node_(nullptr) {} + +CollectionItem::CollectionItem(const Type _type, CollectionItem *_parent) + : SimpleTreeItem(_parent), + type(_type), + container_level(-1), + compilation_artist_node_(nullptr) {} diff --git a/src/collection/collectionitem.h b/src/collection/collectionitem.h index 14655ee961..4c6017a143 100644 --- a/src/collection/collectionitem.h +++ b/src/collection/collectionitem.h @@ -1,8 +1,6 @@ /* * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2018-2021, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +20,6 @@ #ifndef COLLECTIONITEM_H #define COLLECTIONITEM_H -#include "config.h" - #include "core/simpletreeitem.h" #include "core/song.h" @@ -37,17 +33,8 @@ class CollectionItem : public SimpleTreeItem { LoadingIndicator, }; - explicit CollectionItem(SimpleTreeModel *_model) - : SimpleTreeItem(_model), - type(Type::Root), - container_level(-1), - compilation_artist_node_(nullptr) {} - - explicit CollectionItem(const Type _type, CollectionItem *_parent = nullptr) - : SimpleTreeItem(_parent), - type(_type), - container_level(-1), - compilation_artist_node_(nullptr) {} + explicit CollectionItem(SimpleTreeModel *_model); + explicit CollectionItem(const Type _type, CollectionItem *_parent = nullptr); Type type; int container_level; diff --git a/src/collection/collection.cpp b/src/collection/collectionlibrary.cpp similarity index 61% rename from src/collection/collection.cpp rename to src/collection/collectionlibrary.cpp index 9546c597e5..71325edec2 100644 --- a/src/collection/collection.cpp +++ b/src/collection/collectionlibrary.cpp @@ -30,7 +30,6 @@ #include #include -#include "core/application.h" #include "core/taskmanager.h" #include "core/database.h" #include "core/thread.h" @@ -39,22 +38,26 @@ #include "core/settings.h" #include "tagreader/tagreaderclient.h" #include "utilities/threadutils.h" -#include "collection.h" +#include "collectionlibrary.h" #include "collectionwatcher.h" #include "collectionbackend.h" #include "collectionmodel.h" -#include "scrobbler/lastfmimport.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" using std::make_shared; -const char *SCollection::kSongsTable = "songs"; -const char *SCollection::kDirsTable = "directories"; -const char *SCollection::kSubdirsTable = "subdirectories"; +const char *CollectionLibrary::kSongsTable = "songs"; +const char *CollectionLibrary::kDirsTable = "directories"; +const char *CollectionLibrary::kSubdirsTable = "subdirectories"; -SCollection::SCollection(Application *app, QObject *parent) +CollectionLibrary::CollectionLibrary(SharedPtr database, + SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + QObject *parent) : QObject(parent), - app_(app), + task_manager_(task_manager), + tagreader_client_(tagreader_client), backend_(nullptr), model_(nullptr), watcher_(nullptr), @@ -68,18 +71,18 @@ SCollection::SCollection(Application *app, QObject *parent) original_thread_ = thread(); backend_ = make_shared(); - backend()->moveToThread(app->database()->thread()); - qLog(Debug) << &*backend_ << "moved to thread" << app->database()->thread(); + backend()->moveToThread(database->thread()); + qLog(Debug) << &*backend_ << "moved to thread" << database->thread(); - backend_->Init(app->database(), app->task_manager(), Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable)); + backend_->Init(database, task_manager, Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable)); - model_ = new CollectionModel(backend_, app_, this); + model_ = new CollectionModel(backend_, albumcover_loader, this); ReloadSettings(); } -SCollection::~SCollection() { +CollectionLibrary::~CollectionLibrary() { if (watcher_) { watcher_->Abort(); @@ -92,9 +95,9 @@ SCollection::~SCollection() { } -void SCollection::Init() { +void CollectionLibrary::Init() { - watcher_ = new CollectionWatcher(Song::Source::Collection); + watcher_ = new CollectionWatcher(Song::Source::Collection, task_manager_, tagreader_client_, backend_); watcher_thread_ = new Thread(this); watcher_thread_->setObjectName(watcher_->objectName()); @@ -107,13 +110,13 @@ void SCollection::Init() { watcher_thread_->start(QThread::IdlePriority); watcher_->set_backend(backend_); - watcher_->set_task_manager(app_->task_manager()); + watcher_->set_task_manager(task_manager_); - QObject::connect(&*backend_, &CollectionBackend::Error, this, &SCollection::Error); + QObject::connect(&*backend_, &CollectionBackend::Error, this, &CollectionLibrary::Error); QObject::connect(&*backend_, &CollectionBackend::DirectoryAdded, watcher_, &CollectionWatcher::AddDirectory); QObject::connect(&*backend_, &CollectionBackend::DirectoryDeleted, watcher_, &CollectionWatcher::RemoveDirectory); - QObject::connect(&*backend_, &CollectionBackend::SongsRatingChanged, this, &SCollection::SongsRatingChanged); - QObject::connect(&*backend_, &CollectionBackend::SongsStatisticsChanged, this, &SCollection::SongsPlaycountChanged); + QObject::connect(&*backend_, &CollectionBackend::SongsRatingChanged, this, &CollectionLibrary::SongsRatingChanged); + QObject::connect(&*backend_, &CollectionBackend::SongsStatisticsChanged, this, &CollectionLibrary::SongsPlaycountChanged); QObject::connect(watcher_, &CollectionWatcher::NewOrUpdatedSongs, &*backend_, &CollectionBackend::AddOrUpdateSongs); QObject::connect(watcher_, &CollectionWatcher::SongsMTimeUpdated, &*backend_, &CollectionBackend::UpdateMTimesOnly); @@ -125,30 +128,27 @@ void SCollection::Init() { QObject::connect(watcher_, &CollectionWatcher::CompilationsNeedUpdating, &*backend_, &CollectionBackend::CompilationsNeedUpdating); QObject::connect(watcher_, &CollectionWatcher::UpdateLastSeen, &*backend_, &CollectionBackend::UpdateLastSeen); - QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateLastPlayed, &*backend_, &CollectionBackend::UpdateLastPlayed); - QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdatePlayCount, &*backend_, &CollectionBackend::UpdatePlayCount); - // This will start the watcher checking for updates backend_->LoadDirectoriesAsync(); } -void SCollection::Exit() { +void CollectionLibrary::Exit() { wait_for_exit_ << &*backend_ << watcher_; QObject::disconnect(&*backend_, nullptr, watcher_, nullptr); QObject::disconnect(watcher_, nullptr, &*backend_, nullptr); - QObject::connect(&*backend_, &CollectionBackend::ExitFinished, this, &SCollection::ExitReceived); - QObject::connect(watcher_, &CollectionWatcher::ExitFinished, this, &SCollection::ExitReceived); + QObject::connect(&*backend_, &CollectionBackend::ExitFinished, this, &CollectionLibrary::ExitReceived); + QObject::connect(watcher_, &CollectionWatcher::ExitFinished, this, &CollectionLibrary::ExitReceived); backend_->ExitAsync(); watcher_->Abort(); watcher_->ExitAsync(); } -void SCollection::ExitReceived() { +void CollectionLibrary::ExitReceived() { QObject *obj = sender(); QObject::disconnect(obj, nullptr, this, nullptr); @@ -158,13 +158,13 @@ void SCollection::ExitReceived() { } -void SCollection::IncrementalScan() { watcher_->IncrementalScanAsync(); } +void CollectionLibrary::IncrementalScan() { watcher_->IncrementalScanAsync(); } -void SCollection::FullScan() { watcher_->FullScanAsync(); } +void CollectionLibrary::FullScan() { watcher_->FullScanAsync(); } -void SCollection::StopScan() { watcher_->Stop(); } +void CollectionLibrary::StopScan() { watcher_->Stop(); } -void SCollection::Rescan(const SongList &songs) { +void CollectionLibrary::Rescan(const SongList &songs) { qLog(Debug) << "Rescan" << songs.size() << "songs"; if (!songs.isEmpty()) { @@ -173,58 +173,58 @@ void SCollection::Rescan(const SongList &songs) { } -void SCollection::PauseWatcher() { watcher_->SetRescanPausedAsync(true); } +void CollectionLibrary::PauseWatcher() { watcher_->SetRescanPausedAsync(true); } -void SCollection::ResumeWatcher() { watcher_->SetRescanPausedAsync(false); } +void CollectionLibrary::ResumeWatcher() { watcher_->SetRescanPausedAsync(false); } -void SCollection::ReloadSettings() { +void CollectionLibrary::ReloadSettings() { watcher_->ReloadSettingsAsync(); model_->ReloadSettings(); Settings s; - s.beginGroup(CollectionSettingsPage::kSettingsGroup); - save_playcounts_to_files_ = s.value("save_playcounts", false).toBool(); - save_ratings_to_files_ = s.value("save_ratings", false).toBool(); + s.beginGroup(CollectionSettings::kSettingsGroup); + save_playcounts_to_files_ = s.value(CollectionSettings::kSavePlayCounts, false).toBool(); + save_ratings_to_files_ = s.value(CollectionSettings::kSaveRatings, false).toBool(); s.endGroup(); } -void SCollection::SyncPlaycountAndRatingToFilesAsync() { +void CollectionLibrary::SyncPlaycountAndRatingToFilesAsync() { - (void)QtConcurrent::run(&SCollection::SyncPlaycountAndRatingToFiles, this); + (void)QtConcurrent::run(&CollectionLibrary::SyncPlaycountAndRatingToFiles, this); } -void SCollection::SyncPlaycountAndRatingToFiles() { +void CollectionLibrary::SyncPlaycountAndRatingToFiles() { - const int task_id = app_->task_manager()->StartTask(tr("Saving playcounts and ratings")); - app_->task_manager()->SetTaskBlocksCollectionScans(task_id); + const int task_id = task_manager_->StartTask(tr("Saving playcounts and ratings")); + task_manager_->SetTaskBlocksCollectionScans(task_id); const SongList songs = backend_->GetAllSongs(); const qint64 nb_songs = songs.size(); int i = 0; for (const Song &song : songs) { - (void)TagReaderClient::Instance()->SaveSongPlaycountBlocking(song.url().toLocalFile(), song.playcount()); - (void)TagReaderClient::Instance()->SaveSongRatingBlocking(song.url().toLocalFile(), song.rating()); - app_->task_manager()->SetTaskProgress(task_id, ++i, nb_songs); + (void)tagreader_client_->SaveSongPlaycountBlocking(song.url().toLocalFile(), song.playcount()); + (void)tagreader_client_->SaveSongRatingBlocking(song.url().toLocalFile(), song.rating()); + 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 CollectionLibrary::SongsPlaycountChanged(const SongList &songs, const bool save_tags) const { if (save_tags || save_playcounts_to_files_) { - app_->tag_reader_client()->SaveSongsPlaycountAsync(songs); + tagreader_client_->SaveSongsPlaycountAsync(songs); } } -void SCollection::SongsRatingChanged(const SongList &songs, const bool save_tags) { +void CollectionLibrary::SongsRatingChanged(const SongList &songs, const bool save_tags) const { if (save_tags || save_ratings_to_files_) { - app_->tag_reader_client()->SaveSongsRatingAsync(songs); + tagreader_client_->SaveSongsRatingAsync(songs); } } diff --git a/src/collection/collection.h b/src/collection/collectionlibrary.h similarity index 79% rename from src/collection/collection.h rename to src/collection/collectionlibrary.h index 62db686cb8..cef46fc96e 100644 --- a/src/collection/collection.h +++ b/src/collection/collectionlibrary.h @@ -29,22 +29,29 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QThread; -class Application; class Thread; +class TaskManager; +class Database; +class TagReaderClient; class CollectionBackend; class CollectionModel; class CollectionWatcher; +class AlbumCoverLoader; -class SCollection : public QObject { +class CollectionLibrary : public QObject { Q_OBJECT public: - explicit SCollection(Application *app, QObject *parent = nullptr); - ~SCollection() override; + explicit CollectionLibrary(SharedPtr database, + SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + QObject *parent = nullptr); + ~CollectionLibrary() override; static const char *kSongsTable; static const char *kFtsTable; @@ -78,15 +85,17 @@ class SCollection : public QObject { private Q_SLOTS: void ExitReceived(); - void SongsPlaycountChanged(const SongList &songs, const bool save_tags = false); - void SongsRatingChanged(const SongList &songs, const bool save_tags = false); + void SongsPlaycountChanged(const SongList &songs, const bool save_tags = false) const; + void SongsRatingChanged(const SongList &songs, const bool save_tags = false) const; Q_SIGNALS: void Error(const QString &error); void ExitFinished(); private: - Application *app_; + const SharedPtr task_manager_; + const SharedPtr tagreader_client_; + SharedPtr backend_; CollectionModel *model_; diff --git a/src/collection/collectionmodel.cpp b/src/collection/collectionmodel.cpp index 37a403fcb3..d34480ae10 100644 --- a/src/collection/collectionmodel.cpp +++ b/src/collection/collectionmodel.cpp @@ -53,14 +53,13 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/database.h" #include "core/iconloader.h" #include "core/logging.h" -#include "core/sqlrow.h" #include "core/settings.h" +#include "core/songmimedata.h" #include "collectionfilteroptions.h" #include "collectionquery.h" #include "collectionbackend.h" @@ -69,12 +68,10 @@ #include "collectionmodel.h" #include "collectionmodelupdate.h" #include "collectionfilter.h" -#include "playlist/playlistmanager.h" -#include "playlist/songmimedata.h" #include "covermanager/albumcoverloaderoptions.h" #include "covermanager/albumcoverloaderresult.h" #include "covermanager/albumcoverloader.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" using namespace std::chrono_literals; using namespace Qt::Literals::StringLiterals; @@ -85,12 +82,10 @@ constexpr char kPixmapDiskCacheDir[] = "pixmapcache"; constexpr char kVariousArtists[] = QT_TR_NOOP("Various artists"); } // namespace -QNetworkDiskCache *CollectionModel::sIconCache = nullptr; - -CollectionModel::CollectionModel(SharedPtr backend, Application *app, QObject *parent) +CollectionModel::CollectionModel(SharedPtr backend, SharedPtr albumcover_loader, QObject *parent) : SimpleTreeModel(new CollectionItem(this), parent), backend_(backend), - app_(app), + albumcover_loader_(albumcover_loader), dir_model_(new CollectionDirectoryModel(backend, this)), filter_(new CollectionFilter(this)), timer_reload_(new QTimer(this)), @@ -100,7 +95,8 @@ CollectionModel::CollectionModel(SharedPtr backend, Applicati total_song_count_(0), total_artist_count_(0), total_album_count_(0), - loading_(false) { + loading_(false), + icon_disk_cache_(nullptr) { setObjectName(backend_->source() == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(backend_->source()), QLatin1String(metaObject()->className()))); @@ -108,8 +104,8 @@ CollectionModel::CollectionModel(SharedPtr backend, Applicati filter_->setSortRole(Role_SortText); filter_->sort(0); - if (app_) { - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded); + if (albumcover_loader_) { + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded); } QIcon nocover = IconLoader::Load(u"cdcase"_s); @@ -118,10 +114,9 @@ CollectionModel::CollectionModel(SharedPtr backend, Applicati pixmap_no_cover_ = nocover.pixmap(nocover_sizes.last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } - if (app_ && !sIconCache) { - sIconCache = new QNetworkDiskCache(this); - sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir)); - QObject::connect(app_, &Application::ClearPixmapDiskCache, this, &CollectionModel::ClearDiskCache); + if (!qgetenv("DISPLAY").isEmpty() && !icon_disk_cache_) { + icon_disk_cache_ = new QNetworkDiskCache(this); + icon_disk_cache_->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir) + u'-' + Song::TextForSource(backend_->source())); } QObject::connect(&*backend_, &CollectionBackend::SongsAdded, this, &CollectionModel::AddReAddOrUpdate); @@ -230,16 +225,16 @@ void CollectionModel::ScheduleReset() { void CollectionModel::ReloadSettings() { Settings settings; - settings.beginGroup(CollectionSettingsPage::kSettingsGroup); - const bool show_pretty_covers = settings.value("pretty_covers", true).toBool(); - const bool show_dividers= settings.value("show_dividers", true).toBool(); - const bool show_various_artists = settings.value("various_artists", true).toBool(); - const bool sort_skips_articles = settings.value("sort_skips_articles", true).toBool(); - - use_disk_cache_ = settings.value(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool(); - QPixmapCache::setCacheLimit(static_cast(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit, CollectionSettingsPage::kSettingsCacheSizeDefault) / 1024)); - if (sIconCache) { - sIconCache->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault)); + settings.beginGroup(CollectionSettings::kSettingsGroup); + const bool show_pretty_covers = settings.value(CollectionSettings::kPrettyCovers, true).toBool(); + const bool show_dividers= settings.value(CollectionSettings::kShowDividers, true).toBool(); + const bool show_various_artists = settings.value(CollectionSettings::kVariousArtists, true).toBool(); + const bool sort_skips_articles = settings.value(CollectionSettings::kSortSkipsArticles, true).toBool(); + + use_disk_cache_ = settings.value(CollectionSettings::kSettingsDiskCacheEnable, false).toBool(); + QPixmapCache::setCacheLimit(static_cast(MaximumCacheSize(&settings, CollectionSettings::kSettingsCacheSize, CollectionSettings::kSettingsCacheSizeUnit, CollectionSettings::kSettingsCacheSizeDefault) / 1024)); + if (icon_disk_cache_) { + icon_disk_cache_->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettings::kSettingsDiskCacheSize, CollectionSettings::kSettingsDiskCacheSizeUnit, CollectionSettings::kSettingsDiskCacheSizeDefault)); } settings.endGroup(); @@ -258,7 +253,7 @@ void CollectionModel::ReloadSettings() { } if (!use_disk_cache_) { - ClearDiskCache(); + ClearIconDiskCache(); } } @@ -427,7 +422,7 @@ QMimeData *CollectionModel::mimeData(const QModelIndexList &indexes) const { } data->setUrls(urls); - data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs); + data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs); return data; @@ -778,7 +773,7 @@ void CollectionModel::CreateSongItem(const Song &song, CollectionItem *parent) { } -void CollectionModel::SetSongItemData(CollectionItem *item, const Song &song) { +void CollectionModel::SetSongItemData(CollectionItem *item, const Song &song) const { item->display_text = song.TitleWithCompilationArtist(); item->sort_text = HasParentAlbumGroupBy(item->parent) ? SortTextForSong(song) : SortText(song.title()); @@ -879,7 +874,7 @@ void CollectionModel::ClearItemPixmapCache(CollectionItem *item) { // Remove from pixmap cache const QString cache_key = AlbumIconPixmapCacheKey(ItemToIndex(item)); QPixmapCache::remove(cache_key); - if (use_disk_cache_ && sIconCache) sIconCache->remove(AlbumIconPixmapDiskCacheKey(cache_key)); + if (use_disk_cache_ && icon_disk_cache_) icon_disk_cache_->remove(AlbumIconPixmapDiskCacheKey(cache_key)); if (pending_cache_keys_.contains(cache_key)) { pending_cache_keys_.remove(cache_key); } @@ -910,8 +905,8 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) { } // Try to load it from the disk cache - if (use_disk_cache_ && sIconCache) { - ScopedPtr disk_cache_img(sIconCache->data(AlbumIconPixmapDiskCacheKey(cache_key))); + if (use_disk_cache_ && icon_disk_cache_) { + ScopedPtr disk_cache_img(icon_disk_cache_->data(AlbumIconPixmapDiskCacheKey(cache_key))); if (disk_cache_img) { QImage cached_image; if (cached_image.load(&*disk_cache_img, "XPM")) { @@ -932,7 +927,7 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) { AlbumCoverLoaderOptions cover_loader_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage); cover_loader_options.desired_scaled_size = QSize(kPrettyCoverSize, kPrettyCoverSize); cover_loader_options.types = cover_types_; - const quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options, songs.first()); + const quint64 id = albumcover_loader_->LoadImageAsync(cover_loader_options, songs.first()); pending_art_[id] = ItemAndCacheKey(item, cache_key); pending_cache_keys_.insert(cache_key); } @@ -965,19 +960,19 @@ void CollectionModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderR } // If we have a valid cover not already in the disk cache - if (use_disk_cache_ && sIconCache && result.success && !result.image_scaled.isNull()) { + if (use_disk_cache_ && icon_disk_cache_ && result.success && !result.image_scaled.isNull()) { const QUrl disk_cache_key = AlbumIconPixmapDiskCacheKey(cache_key); - ScopedPtr disk_cache_img(sIconCache->data(disk_cache_key)); + ScopedPtr disk_cache_img(icon_disk_cache_->data(disk_cache_key)); if (!disk_cache_img) { QNetworkCacheMetaData disk_cache_metadata; disk_cache_metadata.setSaveToDisk(true); disk_cache_metadata.setUrl(disk_cache_key); // Qt 6 now ignores any entry without headers, so add a fake header. disk_cache_metadata.setRawHeaders(QNetworkCacheMetaData::RawHeaderList() << qMakePair(QByteArray("collection-thumbnail"), cache_key.toUtf8())); - QIODevice *device_iconcache = sIconCache->prepare(disk_cache_metadata); + QIODevice *device_iconcache = icon_disk_cache_->prepare(disk_cache_metadata); if (device_iconcache) { result.image_scaled.save(device_iconcache, "XPM"); - sIconCache->insert(device_iconcache); + icon_disk_cache_->insert(device_iconcache); } } } @@ -1450,7 +1445,7 @@ bool CollectionModel::HasParentAlbumGroupBy(CollectionItem *item) const { qint64 CollectionModel::MaximumCacheSize(Settings *s, const char *size_id, const char *size_unit_id, const qint64 cache_size_default) { qint64 size = s->value(size_id, cache_size_default).toInt(); - int unit = s->value(size_unit_id, static_cast(CollectionSettingsPage::CacheSizeUnit::MB)).toInt() + 1; + int unit = s->value(size_unit_id, static_cast(CollectionSettings::CacheSizeUnit::MB)).toInt() + 1; do { size *= 1024; @@ -1553,8 +1548,11 @@ void CollectionModel::TotalAlbumCountUpdatedSlot(const int count) { } -void CollectionModel::ClearDiskCache() { - if (sIconCache) sIconCache->clear(); +void CollectionModel::ClearIconDiskCache() { + + if (icon_disk_cache_) icon_disk_cache_->clear(); + QPixmapCache::clear(); + } void CollectionModel::RowsInserted(const QModelIndex &parent, const int first, const int last) { diff --git a/src/collection/collectionmodel.h b/src/collection/collectionmodel.h index d9bab5fc1e..915d220588 100644 --- a/src/collection/collectionmodel.h +++ b/src/collection/collectionmodel.h @@ -44,10 +44,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/simpletreemodel.h" #include "core/song.h" -#include "core/sqlrow.h" #include "covermanager/albumcoverloaderoptions.h" #include "covermanager/albumcoverloaderresult.h" #include "collectionmodelupdate.h" @@ -57,16 +56,16 @@ class QTimer; class Settings; -class Application; class CollectionBackend; class CollectionDirectoryModel; class CollectionFilter; +class AlbumCoverLoader; class CollectionModel : public SimpleTreeModel { Q_OBJECT public: - explicit CollectionModel(SharedPtr backend, Application *app, QObject *parent = nullptr); + explicit CollectionModel(SharedPtr backend, SharedPtr albumcover_loader, QObject *parent = nullptr); ~CollectionModel() override; static const int kPrettyCoverSize; @@ -156,7 +155,7 @@ class CollectionModel : public SimpleTreeModel { int total_artist_count() const { return total_artist_count_; } int total_album_count() const { return total_album_count_; } - quint64 icon_cache_disk_size() { return sIconCache->cacheSize(); } + quint64 icon_disk_cache_size() { return icon_disk_cache_->cacheSize(); } const CollectionModel::Grouping GetGroupBy() const { return options_current_.group_by; } void SetGroupBy(const CollectionModel::Grouping g, const std::optional separate_albums_by_grouping = std::optional()); @@ -218,6 +217,8 @@ class CollectionModel : public SimpleTreeModel { void AddReAddOrUpdate(const SongList &songs); void RemoveSongs(const SongList &songs); + void ClearIconDiskCache(); + private: void Clear(); void BeginReset(); @@ -238,7 +239,7 @@ class CollectionModel : public SimpleTreeModel { void CreateDividerItem(const QString ÷r_key, const QString &display_text, CollectionItem *parent); CollectionItem *CreateContainerItem(const GroupBy group_by, const int container_level, const QString &container_key, const Song &song, CollectionItem *parent); void CreateSongItem(const Song &song, CollectionItem *parent); - void SetSongItemData(CollectionItem *item, const Song &song); + void SetSongItemData(CollectionItem *item, const Song &song) const; CollectionItem *CreateCompilationArtistNode(CollectionItem *parent); void LoadSongsFromSqlAsync(); @@ -267,15 +268,12 @@ class CollectionModel : public SimpleTreeModel { void TotalArtistCountUpdatedSlot(const int count); void TotalAlbumCountUpdatedSlot(const int count); - static void ClearDiskCache(); - void RowsInserted(const QModelIndex &parent, const int first, const int last); void RowsRemoved(const QModelIndex &parent, const int first, const int last); private: - static QNetworkDiskCache *sIconCache; SharedPtr backend_; - Application *app_; + SharedPtr albumcover_loader_; CollectionDirectoryModel *dir_model_; CollectionFilter *filter_; QTimer *timer_reload_; @@ -310,6 +308,8 @@ class CollectionModel : public SimpleTreeModel { using ItemAndCacheKey = QPair; QMap pending_art_; QSet pending_cache_keys_; + + QNetworkDiskCache *icon_disk_cache_; }; Q_DECLARE_METATYPE(CollectionModel::Grouping) diff --git a/src/collection/collectiontask.cpp b/src/collection/collectiontask.cpp index 78eee232f9..c7ca2c9b55 100644 --- a/src/collection/collectiontask.cpp +++ b/src/collection/collectiontask.cpp @@ -19,7 +19,7 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/taskmanager.h" #include "collectiontask.h" diff --git a/src/collection/collectiontask.h b/src/collection/collectiontask.h index c93e828d01..5a3dd223e7 100644 --- a/src/collection/collectiontask.h +++ b/src/collection/collectiontask.h @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class TaskManager; diff --git a/src/collection/collectionview.cpp b/src/collection/collectionview.cpp index bff8db2f24..50ea3e9fb9 100644 --- a/src/collection/collectionview.cpp +++ b/src/collection/collectionview.cpp @@ -50,14 +50,13 @@ #include #include -#include "core/application.h" #include "core/iconloader.h" #include "core/mimedata.h" #include "core/musicstorage.h" #include "core/deletefiles.h" #include "core/settings.h" #include "utilities/filemanagerutils.h" -#include "collection.h" +#include "collectionlibrary.h" #include "collectionbackend.h" #include "collectiondirectorymodel.h" #include "collectionfilterwidget.h" @@ -73,14 +72,13 @@ #include "dialogs/deleteconfirmationdialog.h" #include "organize/organizedialog.h" #include "organize/organizeerrordialog.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" using std::make_unique; using namespace Qt::Literals::StringLiterals; CollectionView::CollectionView(QWidget *parent) : AutoExpandingTreeView(parent), - app_(nullptr), filter_(nullptr), total_song_count_(-1), total_artist_count_(-1), @@ -123,6 +121,44 @@ CollectionView::CollectionView(QWidget *parent) CollectionView::~CollectionView() = default; +void CollectionView::Init(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr network, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr lyrics_providers, + SharedPtr collection, + SharedPtr device_manager, + SharedPtr streaming_services) { + + task_manager_ = task_manager; + tagreader_client_ = tagreader_client; + network_ = network; + albumcover_loader_ = albumcover_loader; + current_albumcover_loader_ = current_albumcover_loader; + cover_providers_ = cover_providers; + lyrics_providers_ = lyrics_providers; + collection_ = collection; + device_manager_ = device_manager; + streaming_services_ = streaming_services; + + ReloadSettings(); + +} + +QSortFilterProxyModel *CollectionView::sort_filter_proxy_model() const { + + return qobject_cast(model()); + +} + +CollectionModel *CollectionView::collection_model() const { + + return qobject_cast(sort_filter_proxy_model()->sourceModel()); + +} + void CollectionView::SaveFocus() { const QModelIndex current = currentIndex(); @@ -142,8 +178,8 @@ void CollectionView::SaveFocus() { switch (item_type) { case CollectionItem::Type::Song:{ - QModelIndex index = qobject_cast(model())->mapToSource(current); - SongList songs = app_->collection_model()->GetChildSongs(index); + QModelIndex index = sort_filter_proxy_model()->mapToSource(current); + SongList songs = collection_model()->GetChildSongs(index); if (!songs.isEmpty()) { last_selected_song_ = songs.last(); } @@ -210,8 +246,8 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) { break; case CollectionItem::Type::Song: if (!last_selected_song_.url().isEmpty()) { - QModelIndex index = qobject_cast(model())->mapToSource(current); - const SongList songs = app_->collection_model()->GetChildSongs(index); + QModelIndex index = sort_filter_proxy_model()->mapToSource(current); + const SongList songs = collection_model()->GetChildSongs(index); if (std::any_of(songs.begin(), songs.end(), [this](const Song &song) { return song == last_selected_song_; })) { setCurrentIndex(current); return true; @@ -241,6 +277,7 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) { } } } + return false; } @@ -248,21 +285,13 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) { void CollectionView::ReloadSettings() { Settings settings; - settings.beginGroup(CollectionSettingsPage::kSettingsGroup); - SetAutoOpen(settings.value("auto_open", false).toBool()); - delete_files_ = settings.value("delete_files", false).toBool(); + settings.beginGroup(CollectionSettings::kSettingsGroup); + SetAutoOpen(settings.value(CollectionSettings::kAutoOpen, false).toBool()); + delete_files_ = settings.value(CollectionSettings::kDeleteFiles, false).toBool(); settings.endGroup(); } -void CollectionView::SetApplication(Application *app) { - - app_ = app; - - ReloadSettings(); - -} - void CollectionView::SetFilter(CollectionFilterWidget *filter) { filter_ = filter; } void CollectionView::TotalSongCountUpdated(const int count) { @@ -353,7 +382,7 @@ void CollectionView::mouseReleaseEvent(QMouseEvent *e) { QTreeView::mouseReleaseEvent(e); if (total_song_count_ == 0) { - Q_EMIT ShowConfigDialog(); + Q_EMIT ShowSettingsDialog(); } } @@ -417,8 +446,8 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) { context_menu_->addMenu(filter_->menu()); #ifndef Q_OS_WIN - action_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0); - QObject::connect(app_->device_manager()->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, action_copy_to_device_, &QAction::setDisabled); + action_copy_to_device_->setDisabled(device_manager_->connected_devices_model()->rowCount() == 0); + QObject::connect(device_manager_->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, action_copy_to_device_, &QAction::setDisabled); #endif } @@ -426,16 +455,16 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) { context_menu_index_ = indexAt(e->pos()); if (!context_menu_index_.isValid()) return; - context_menu_index_ = qobject_cast(model())->mapToSource(context_menu_index_); + context_menu_index_ = sort_filter_proxy_model()->mapToSource(context_menu_index_); - const QModelIndexList selected_indexes = qobject_cast(model())->mapSelectionToSource(selectionModel()->selection()).indexes(); + const QModelIndexList selected_indexes = sort_filter_proxy_model()->mapSelectionToSource(selectionModel()->selection()).indexes(); int regular_elements = 0; int regular_editable = 0; for (const QModelIndex &idx : selected_indexes) { ++regular_elements; - if (app_->collection_model()->data(idx, CollectionModel::Role_Editable).toBool()) { + if (collection_model()->data(idx, CollectionModel::Role_Editable).toBool()) { ++regular_editable; } } @@ -502,7 +531,7 @@ void CollectionView::SetShowInVarious(const bool on) { if (on && albums.keys().count() == 1) { const QStringList albums_list = albums.keys(); const QString album = albums_list.first(); - const SongList all_of_album = app_->collection_backend()->GetSongsByAlbum(album); + const SongList all_of_album = collection_model()->backend()->GetSongsByAlbum(album); QSet other_artists; for (const Song &s : all_of_album) { if (!albums.contains(album, s.artist()) && !other_artists.contains(s.artist())) { @@ -520,7 +549,7 @@ void CollectionView::SetShowInVarious(const bool on) { const QSet albums_set = QSet(albums.keyBegin(), albums.keyEnd()); for (const QString &album : albums_set) { - app_->collection_backend()->ForceCompilation(album, albums.values(album), on); + collection_model()->backend()->ForceCompilation(album, albums.values(album), on); } } @@ -584,11 +613,12 @@ void CollectionView::SearchForThis() { return; } QString search; - QModelIndex index = qobject_cast(model())->mapToSource(current); + + QModelIndex index = sort_filter_proxy_model()->mapToSource(current); switch (item_type) { case CollectionItem::Type::Song:{ - SongList songs = app_->collection_model()->GetChildSongs(index); + SongList songs = collection_model()->GetChildSongs(index); if (!songs.isEmpty()) { last_selected_song_ = songs.last(); } @@ -601,8 +631,8 @@ void CollectionView::SearchForThis() { } case CollectionItem::Type::Container:{ - CollectionItem *item = app_->collection_model()->IndexToItem(index); - const CollectionModel::GroupBy group_by = app_->collection_model()->GetGroupBy()[item->container_level]; + CollectionItem *item = collection_model()->IndexToItem(index); + const CollectionModel::GroupBy group_by = collection_model()->GetGroupBy()[item->container_level]; while (!item->children.isEmpty()) { item = item->children.constFirst(); } @@ -688,18 +718,18 @@ void CollectionView::scrollTo(const QModelIndex &idx, ScrollHint hint) { SongList CollectionView::GetSelectedSongs() const { - QModelIndexList selected_indexes = qobject_cast(model())->mapSelectionToSource(selectionModel()->selection()).indexes(); - return app_->collection_model()->GetChildSongs(selected_indexes); + QModelIndexList selected_indexes = sort_filter_proxy_model()->mapSelectionToSource(selectionModel()->selection()).indexes(); + return collection_model()->GetChildSongs(selected_indexes); } void CollectionView::Organize() { if (!organize_dialog_) { - organize_dialog_ = make_unique(app_->task_manager(), app_->collection_backend(), this); + organize_dialog_ = make_unique(task_manager_, tagreader_client_, collection_model()->backend(), this); } - organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model()); + organize_dialog_->SetDestinationModel(collection_model()->directory_model()); organize_dialog_->SetCopy(false); const SongList songs = GetSelectedSongs(); if (organize_dialog_->SetSongs(songs)) { @@ -714,7 +744,7 @@ void CollectionView::Organize() { void CollectionView::EditTracks() { if (!edit_tag_dialog_) { - edit_tag_dialog_ = make_unique(app_, this); + edit_tag_dialog_ = make_unique(network_, tagreader_client_, collection_model()->backend(), albumcover_loader_, current_albumcover_loader_, cover_providers_, lyrics_providers_, streaming_services_, this); QObject::connect(&*edit_tag_dialog_, &EditTagDialog::Error, this, &CollectionView::EditTagError); } const SongList songs = GetSelectedSongs(); @@ -729,7 +759,7 @@ void CollectionView::EditTagError(const QString &message) { void CollectionView::RescanSongs() { - app_->collection()->Rescan(GetSelectedSongs()); + collection_->Rescan(GetSelectedSongs()); } @@ -737,10 +767,10 @@ void CollectionView::CopyToDevice() { #ifndef Q_OS_WIN if (!organize_dialog_) { - organize_dialog_ = make_unique(app_->task_manager(), nullptr, this); + organize_dialog_ = make_unique(task_manager_, tagreader_client_, nullptr, this); } - organize_dialog_->SetDestinationModel(app_->device_manager()->connected_devices_model(), true); + organize_dialog_->SetDestinationModel(device_manager_->connected_devices_model(), true); organize_dialog_->SetCopy(true); organize_dialog_->SetSongs(GetSelectedSongs()); organize_dialog_->show(); @@ -812,9 +842,9 @@ void CollectionView::Delete() { if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return; // We can cheat and always take the storage of the first directory, since they'll all be FilesystemMusicStorage in a collection and deleting doesn't check the actual directory. - SharedPtr storage = app_->collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value>(); + SharedPtr storage = collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value>(); - DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, true); + DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, true); QObject::connect(delete_files, &DeleteFiles::Finished, this, &CollectionView::DeleteFilesFinished); delete_files->Start(songs); diff --git a/src/collection/collectionview.h b/src/collection/collectionview.h index 4959c00616..33cf2cf3e1 100644 --- a/src/collection/collectionview.h +++ b/src/collection/collectionview.h @@ -30,10 +30,12 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "widgets/autoexpandingtreeview.h" +class QSortFilterProxyModel; class QMenu; class QAction; class QContextMenuEvent; @@ -41,8 +43,18 @@ class QMouseEvent; class QPaintEvent; class QKeyEvent; -class Application; +class TaskManager; +class TagReaderClient; +class NetworkAccessManager; +class CollectionLibrary; +class CollectionModel; class CollectionFilterWidget; +class DeviceManager; +class StreamingServices; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; +class LyricsProviders; class EditTagDialog; class OrganizeDialog; @@ -57,7 +69,17 @@ class CollectionView : public AutoExpandingTreeView { // Please note that the selection is recursive meaning that if for example an album is selected this will return all of it's songs. SongList GetSelectedSongs() const; - void SetApplication(Application *app); + void Init(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr network, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr lyrics_providers, + SharedPtr collection, + SharedPtr device_manager, + SharedPtr streaming_services); + void SetFilter(CollectionFilterWidget *filter); // QTreeView @@ -82,7 +104,7 @@ class CollectionView : public AutoExpandingTreeView { void EditTagError(const QString &message); Q_SIGNALS: - void ShowConfigDialog(); + void ShowSettingsDialog(); void TotalSongCountUpdated_(); void TotalArtistCountUpdated_(); @@ -114,15 +136,27 @@ class CollectionView : public AutoExpandingTreeView { void DeleteFilesFinished(const SongList &songs_with_errors); private: + QSortFilterProxyModel *sort_filter_proxy_model() const; + CollectionModel *collection_model() const; void RecheckIsEmpty(); void SetShowInVarious(const bool on); bool RestoreLevelFocus(const QModelIndex &parent = QModelIndex()); void SaveContainerPath(const QModelIndex &child); private: - Application *app_; CollectionFilterWidget *filter_; + SharedPtr task_manager_; + SharedPtr tagreader_client_; + SharedPtr network_; + SharedPtr device_manager_; + SharedPtr albumcover_loader_; + SharedPtr current_albumcover_loader_; + SharedPtr collection_; + SharedPtr cover_providers_; + SharedPtr lyrics_providers_; + SharedPtr streaming_services_; + int total_song_count_; int total_artist_count_; int total_album_count_; diff --git a/src/collection/collectionwatcher.cpp b/src/collection/collectionwatcher.cpp index 0672b8b89e..4c954c322c 100644 --- a/src/collection/collectionwatcher.cpp +++ b/src/collection/collectionwatcher.cpp @@ -50,13 +50,13 @@ #include "core/taskmanager.h" #include "core/settings.h" #include "utilities/imageutils.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "tagreader/tagreaderclient.h" #include "collectiondirectory.h" #include "collectionbackend.h" #include "collectionwatcher.h" #include "playlistparsers/cueparser.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" #include "engine/ebur128measures.h" #ifdef HAVE_SONGFINGERPRINTING # include "engine/chromaprinter.h" @@ -75,11 +75,16 @@ using namespace Qt::Literals::StringLiterals; QStringList CollectionWatcher::sValidImages = QStringList() << u"jpg"_s << u"png"_s << u"gif"_s << u"jpeg"_s; -CollectionWatcher::CollectionWatcher(const Song::Source source, QObject *parent) +CollectionWatcher::CollectionWatcher(const Song::Source source, + SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr backend, + QObject *parent) : QObject(parent), source_(source), - backend_(nullptr), - task_manager_(nullptr), + task_manager_(task_manager), + tagreader_client_(tagreader_client), + backend_(backend), fs_watcher_(FileSystemWatcherInterface::Create(this)), original_thread_(nullptr), scan_on_startup_(true), @@ -96,7 +101,7 @@ CollectionWatcher::CollectionWatcher(const Song::Source source, QObject *parent) periodic_scan_timer_(new QTimer(this)), rescan_paused_(false), total_watches_(0), - cue_parser_(new CueParser(backend_, this)), + cue_parser_(new CueParser(tagreader_client, backend, this)), last_scan_time_(0) { setObjectName(source_ == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(source_), QLatin1String(metaObject()->className()))); @@ -196,29 +201,29 @@ void CollectionWatcher::ReloadSettings() { const bool was_monitoring_before = monitor_; Settings s; - s.beginGroup(CollectionSettingsPage::kSettingsGroup); + s.beginGroup(CollectionSettings::kSettingsGroup); if (source_ == Song::Source::Collection) { - scan_on_startup_ = s.value("startup_scan", true).toBool(); - monitor_ = s.value("monitor", true).toBool(); + scan_on_startup_ = s.value(CollectionSettings::kStartupScan, true).toBool(); + monitor_ = s.value(CollectionSettings::kMonitor, true).toBool(); } else { scan_on_startup_ = true; monitor_ = true; } - const QStringList filters = s.value("cover_art_patterns", QStringList() << u"front"_s << u"cover"_s).toStringList(); + const QStringList filters = s.value(CollectionSettings::kCoverArtPatterns, QStringList() << u"front"_s << u"cover"_s).toStringList(); if (source_ == Song::Source::Collection) { - song_tracking_ = s.value("song_tracking", false).toBool(); - song_ebur128_loudness_analysis_ = s.value("song_ebur128_loudness_analysis", false).toBool(); - mark_songs_unavailable_ = song_tracking_ ? true : s.value("mark_songs_unavailable", true).toBool(); + song_tracking_ = s.value(CollectionSettings::kSongTracking, false).toBool(); + song_ebur128_loudness_analysis_ = s.value(CollectionSettings::kSongENUR128LoudnessAnalysis, false).toBool(); + mark_songs_unavailable_ = song_tracking_ ? true : s.value(CollectionSettings::kMarkSongsUnavailable, true).toBool(); } else { song_tracking_ = false; song_ebur128_loudness_analysis_ = false; mark_songs_unavailable_ = false; } - expire_unavailable_songs_days_ = s.value("expire_unavailable_songs", 60).toInt(); - overwrite_playcount_ = s.value("overwrite_playcount", false).toBool(); - overwrite_rating_ = s.value("overwrite_rating", false).toBool(); + expire_unavailable_songs_days_ = s.value(CollectionSettings::kExpireUnavailableSongs, 60).toInt(); + overwrite_playcount_ = s.value(CollectionSettings::kOverwritePlaycount, false).toBool(); + overwrite_rating_ = s.value(CollectionSettings::kOverwriteRating, false).toBool(); s.endGroup(); best_art_filters_.clear(); @@ -575,7 +580,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu album_art[dir_part] << child; t->AddToProgress(1); } - else if (TagReaderClient::Instance()->IsMediaFileBlocking(child)) { + else if (tagreader_client_->IsMediaFileBlocking(child)) { files_on_disk << child; } else { @@ -874,7 +879,7 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, } Song song_on_disk(source_); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(file, &song_on_disk); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(file, &song_on_disk); if (result.success() && song_on_disk.is_valid()) { song_on_disk.set_source(source_); song_on_disk.set_directory_id(t->dir()); @@ -927,7 +932,7 @@ SongList CollectionWatcher::ScanNewFile(const QString &file, const QString &path } else { // It's a normal media file Song song(source_); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(file, &song); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(file, &song); if (result.success() && song.is_valid()) { song.set_source(source_); PerformEBUR128Analysis(song); diff --git a/src/collection/collectionwatcher.h b/src/collection/collectionwatcher.h index e6a1cdfba3..f48db242ef 100644 --- a/src/collection/collectionwatcher.h +++ b/src/collection/collectionwatcher.h @@ -36,22 +36,28 @@ #include #include "collectiondirectory.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QThread; class QTimer; +class TaskManager; +class TagReaderClient; class CollectionBackend; class FileSystemWatcherInterface; -class TaskManager; class CueParser; class CollectionWatcher : public QObject { Q_OBJECT public: - explicit CollectionWatcher(const Song::Source source, QObject *parent = nullptr); + explicit CollectionWatcher(const Song::Source source, + SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr backend, + QObject *parent = nullptr); + ~CollectionWatcher(); Song::Source source() { return source_; } @@ -214,8 +220,11 @@ class CollectionWatcher : public QObject { private: Song::Source source_; - SharedPtr backend_; + SharedPtr task_manager_; + SharedPtr tagreader_client_; + SharedPtr backend_; + QString device_name_; FileSystemWatcherInterface *fs_watcher_; diff --git a/src/collection/groupbydialog.h b/src/collection/groupbydialog.h index 1f5987885c..cc1b97de86 100644 --- a/src/collection/groupbydialog.h +++ b/src/collection/groupbydialog.h @@ -28,13 +28,13 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" #include "collectionmodel.h" -#include "ui_groupbydialog.h" class QWidget; class GroupByDialogPrivate; +class Ui_GroupByDialog; class GroupByDialog : public QDialog { Q_OBJECT diff --git a/src/collection/savedgroupingmanager.cpp b/src/collection/savedgroupingmanager.cpp index ddb3bb6daa..e1449c5aa9 100644 --- a/src/collection/savedgroupingmanager.cpp +++ b/src/collection/savedgroupingmanager.cpp @@ -39,7 +39,7 @@ #include "core/logging.h" #include "core/iconloader.h" #include "core/settings.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" #include "collectionmodel.h" #include "savedgroupingmanager.h" #include "ui_savedgroupingmanager.h" @@ -77,7 +77,7 @@ SavedGroupingManager::~SavedGroupingManager() { QString SavedGroupingManager::GetSavedGroupingsSettingsGroup(const QString &settings_group) { - if (settings_group.isEmpty() || settings_group == QLatin1String(CollectionSettingsPage::kSettingsGroup)) { + if (settings_group.isEmpty() || settings_group == QLatin1String(CollectionSettings::kSettingsGroup)) { return QLatin1String(kSavedGroupingsSettingsGroup); } diff --git a/src/constants/appearancesettings.h b/src/constants/appearancesettings.h new file mode 100644 index 0000000000..4efaf809d0 --- /dev/null +++ b/src/constants/appearancesettings.h @@ -0,0 +1,75 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef APPEARANCESETTINGS_H +#define APPEARANCESETTINGS_H + +namespace AppearanceSettings { + +constexpr char kSettingsGroup[] = "Appearance"; + +constexpr char kStyle[] = "style"; +constexpr char kSystemThemeIcons[] = "system_icons"; + +constexpr char kBackgroundImageType[] = "background_image_type"; +constexpr char kBackgroundImageFilename[] = "background_image_file"; +constexpr char kBackgroundImagePosition[] = "background_image_position"; +constexpr char kBackgroundImageStretch[] = "background_image_stretch"; +constexpr char kBackgroundImageDoNotCut[] = "background_image_do_not_cut"; +constexpr char kBackgroundImageKeepAspectRatio[] = "background_image_keep_aspect_ratio"; +constexpr char kBackgroundImageMaxSize[] = "background_image_max_size"; + +constexpr char kBlurRadius[] = "blur_radius"; +constexpr char kOpacityLevel[] = "opacity_level"; + +constexpr int kDefaultBlurRadius = 0; +constexpr int kDefaultOpacityLevel = 40; + +constexpr char kTabBarSystemColor[] = "tab_system_color"; +constexpr char kTabBarGradient[] = "tab_gradient"; +constexpr char kTabBarColor[] = "tab_color"; + +constexpr char kIconSizeTabbarSmallMode[] = "icon_size_tabbar_small_mode"; +constexpr char kIconSizeTabbarLargeMode[] = "icon_size_tabbar_large_mode"; +constexpr char kIconSizePlayControlButtons[] = "icon_size_play_control_buttons"; +constexpr char kIconSizePlaylistButtons[] = "icon_size_playlist_buttons"; +constexpr char kIconSizeLeftPanelButtons[] = "icon_size_left_panel_buttons"; +constexpr char kIconSizeConfigureButtons[] = "icon_size_configure_buttons"; + +constexpr char kPlaylistPlayingSongColor[] = "playlist_playing_song_color"; + +enum class BackgroundImageType { + Default, + None, + Custom, + Album, + Strawbs +}; + +enum class BackgroundImagePosition { + UpperLeft = 1, + UpperRight = 2, + Middle = 3, + BottomLeft = 4, + BottomRight = 5 +}; + +} // namespace + +#endif // APPEARANCESETTINGS_H diff --git a/src/constants/backendsettings.h b/src/constants/backendsettings.h new file mode 100644 index 0000000000..37734e8148 --- /dev/null +++ b/src/constants/backendsettings.h @@ -0,0 +1,64 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef BACKENDSETTINGS_H +#define BACKENDSETTINGS_H + +#include + +namespace BackendSettings { + +constexpr char kSettingsGroup[] = "Backend"; + +constexpr char kEngine[] = "Engine"; +constexpr char kOutput[] = "Output"; +constexpr char kDevice[] = "Device"; +constexpr char kALSAPlugin[] = "alsaplugin"; +constexpr char kExclusiveMode[] = "exclusive_mode"; +constexpr char kVolumeControl[] = "volume_control"; +constexpr char kChannelsEnabled[] = "channels_enabled"; +constexpr char kChannels[] = "channels"; +constexpr char kBS2B[] = "bs2b"; +constexpr char kHTTP2[] = "http2"; +constexpr char kStrictSSL[] = "strict_ssl"; +constexpr char kBufferDuration[] = "bufferduration"; +constexpr char kBufferLowWatermark[] = "bufferlowwatermark"; +constexpr char kBufferHighWatermark[] = "bufferhighwatermark"; +constexpr char kRgEnabled[] = "rgenabled"; +constexpr char kRgMode[] = "rgmode"; +constexpr char kRgPreamp[] = "rgpreamp"; +constexpr char kRgFallbackGain[] = "rgfallbackgain"; +constexpr char kRgCompression[] = "rgcompression"; +constexpr char kEBUR128LoudnessNormalization[] = "ebur128_loudness_normalization"; +constexpr char kEBUR128TargetLevelLUFS[] = "ebur128_target_level_lufs"; +constexpr char kFadeoutEnabled[] = "FadeoutEnabled"; +constexpr char kCrossfadeEnabled[] = "CrossfadeEnabled"; +constexpr char kAutoCrossfadeEnabled[] = "AutoCrossfadeEnabled"; +constexpr char kNoCrossfadeSameAlbum[] = "NoCrossfadeSameAlbum"; +constexpr char kFadeoutPauseEnabled[] = "FadeoutPauseEnabled"; +constexpr char kFadeoutDuration[] = "FadeoutDuration"; +constexpr char kFadeoutPauseDuration[] = "FadeoutPauseDuration"; + +constexpr qint64 kDefaultBufferDuration = 4000; +constexpr double kDefaultBufferLowWatermark = 0.33; +constexpr double kDefaultBufferHighWatermark = 0.99; + +} // namespace + +#endif // BACKENDSETTINGS_H diff --git a/src/constants/behavioursettings.h b/src/constants/behavioursettings.h new file mode 100644 index 0000000000..14dd80a070 --- /dev/null +++ b/src/constants/behavioursettings.h @@ -0,0 +1,76 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef BEHAVIOURSETTINGS_H +#define BEHAVIOURSETTINGS_H + +namespace BehaviourSettings { + +constexpr char kSettingsGroup[] = "Behaviour"; + +enum class StartupBehaviour { + Remember = 1, + Show = 2, + Hide = 3, + ShowMaximized = 4, + ShowMinimized = 5 +}; + +enum class PlayBehaviour { + Never = 1, + IfStopped = 2, + Always = 3 +}; + +enum class PreviousBehaviour { + DontRestart = 1, + Restart = 2 +}; + +enum class AddBehaviour { + Append = 1, + Enqueue = 2, + Load = 3, + OpenInNew = 4 +}; + +enum class PlaylistAddBehaviour { + Play = 1, + Enqueue = 2 +}; + +constexpr char kKeepRunning[] = "keeprunning"; +constexpr char kShowTrayIcon[] = "showtrayicon"; +constexpr char kTrayIconProgress[] = "trayicon_progress"; +constexpr char kTaskbarProgress[] = "taskbar_progress"; +constexpr char kResumePlayback[] = "resumeplayback"; +constexpr char kPlayingWidget[] = "playing_widget"; +constexpr char kStartupBehaviour[] = "startupbehaviour"; +constexpr char kLanguage[] = "language"; +constexpr char kMenuPlayMode[] = "menu_playmode"; +constexpr char kMenuPreviousMode[] = "menu_previousmode"; +constexpr char kDoubleClickAddMode[] = "doubleclick_addmode"; +constexpr char kDoubleClickPlayMode[] = "doubleclick_playmode"; +constexpr char kDoubleClickPlaylistAddMode[] = "doubleclick_playlist_addmode"; +constexpr char kSeekStepSec[] = "seek_step_sec"; +constexpr char kVolumeIncrement[] = "volume_increment"; + +} // namespace + +#endif // BEHAVIOURSETTINGS_H diff --git a/src/constants/collectionsettings.h b/src/constants/collectionsettings.h new file mode 100644 index 0000000000..94f89c7e33 --- /dev/null +++ b/src/constants/collectionsettings.h @@ -0,0 +1,62 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef COLLECTIONSETTINGS_H +#define COLLECTIONSETTINGS_H + +namespace CollectionSettings { + +constexpr char kSettingsGroup[] = "Collection"; + +constexpr char kAutoOpen[] = "auto_open"; +constexpr char kShowDividers[] = "show_dividers"; +constexpr char kPrettyCovers[] = "pretty_covers"; +constexpr char kVariousArtists[] = "various_artists"; +constexpr char kSortSkipsArticles[] = "sort_skips_articles"; +constexpr char kStartupScan[] = "startup_scan"; +constexpr char kMonitor[] = "monitor"; +constexpr char kSongTracking[] = "song_tracking"; +constexpr char kSongENUR128LoudnessAnalysis[] = "song_ebur128_loudness_analysis"; +constexpr char kMarkSongsUnavailable[] = "mark_songs_unavailable"; +constexpr char kExpireUnavailableSongs[] = "expire_unavailable_songs"; +constexpr char kCoverArtPatterns[] = "cover_art_patterns"; +constexpr char kSettingsCacheSize[] = "cache_size"; +constexpr char kSettingsCacheSizeUnit[] = "cache_size_unit"; +constexpr char kSettingsDiskCacheEnable[] = "disk_cache_enable"; +constexpr char kSettingsDiskCacheSize[] = "disk_cache_size"; +constexpr char kSettingsDiskCacheSizeUnit[] = "disk_cache_size_unit"; +constexpr int kSettingsCacheSizeDefault = 160; +constexpr int kSettingsDiskCacheSizeDefault = 360; +constexpr char kSavePlayCounts[] = "save_playcounts"; +constexpr char kSaveRatings[] = "save_ratings"; +constexpr char kOverwritePlaycount[] = "overwrite_playcount"; +constexpr char kOverwriteRating[] = "overwrite_rating"; +constexpr char kDeleteFiles[] = "delete_files"; +constexpr char kLastPath[] = "last_path"; + +enum class CacheSizeUnit { + KB, + MB, + GB, + TB +}; + +} // namespace + +#endif // COLLECTIONSETTINGS_H diff --git a/src/constants/contextsettings.h b/src/constants/contextsettings.h new file mode 100644 index 0000000000..74d894c432 --- /dev/null +++ b/src/constants/contextsettings.h @@ -0,0 +1,48 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef CONTEXTSETTINGS_H +#define CONTEXTSETTINGS_H + +#include + +namespace ContextSettings { + +constexpr char kSettingsGroup[] = "Context"; + +constexpr char kAlbum[] = "AlbumEnable"; +constexpr char kTechnicalData[] = "TechnicalDataEnable"; +constexpr char kSongLyrics[] = "SongLyricsEnable"; +constexpr char kSearchCover[] = "SearchCoverEnable"; +constexpr char kSearchLyrics[] = "SearchLyricsEnable"; + +constexpr char kFontHeadline[] = "font_headline"; +constexpr char kFontNormal[] = "font_normal"; +constexpr char kFontSizeHeadline[] = "font_size_headline"; +constexpr char kFontSizeNormal[] = "font_size_normal"; + +constexpr char kSettingsTitleFmt[] = "TitleFmt"; +constexpr char kSettingsSummaryFmt[] = "SummaryFmt"; + +constexpr char kDefaultFontFamily[] = "Noto Sans"; +constexpr qreal kDefaultFontSizeHeadline = 11; + +} // namespace + +#endif // CONTEXTSETTINGS_H diff --git a/src/constants/coverssettings.h b/src/constants/coverssettings.h new file mode 100644 index 0000000000..2cef4f872d --- /dev/null +++ b/src/constants/coverssettings.h @@ -0,0 +1,37 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef COVERSSETTINGS_H +#define COVERSSETTINGS_H + +namespace CoversSettings { + +constexpr char kSettingsGroup[] = "Covers"; +constexpr char kProviders[] = "providers"; +constexpr char kTypes[] = "types"; +constexpr char kSaveType[] = "save_type"; +constexpr char kSaveFilename[] = "save_filename"; +constexpr char kSavePattern[] = "save_pattern"; +constexpr char kSaveOverwrite[] = "save_overwrite"; +constexpr char kSaveLowercase[] = "save_lowercase"; +constexpr char kSaveReplaceSpaces[] = "save_replace_spaces"; + +} // namespace + +#endif // COVERSSETTINGS_H diff --git a/src/constants/filefilterconstants.h b/src/constants/filefilterconstants.h new file mode 100644 index 0000000000..09ff7c30ad --- /dev/null +++ b/src/constants/filefilterconstants.h @@ -0,0 +1,39 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef FILEFILTERCONSTANTS_H +#define FILEFILTERCONSTANTS_H + +#include + +constexpr char kAllFilesFilterSpec[] = QT_TRANSLATE_NOOP("FileFilter", "All Files (*)"); + +constexpr char kFileFilter[] = + "*.wav *.flac *.wv *.ogg *.oga *.opus *.spx *.ape *.mpc " + "*.mp2 *.mp3 *.m4a *.mp4 *.aac *.asf *.asx *.wma " + "*.aif *.aiff *.mka *.tta *.dsf *.dsd " + "*.cue *.m3u *.m3u8 *.pls *.xspf *.asxini " + "*.ac3 *.dts " + "*.mod *.s3m *.xm *.it" + "*.spc *.vgm"; + +constexpr char kLoadImageFileFilter[] = QT_TRANSLATE_NOOP("FileFilter", "Images (*.png *.jpg *.jpeg *.bmp *.gif *.xpm *.pbm *.pgm *.ppm *.xbm)"); +constexpr char kSaveImageFileFilter[] = QT_TRANSLATE_NOOP("FileFilter", "Images (*.png *.jpg *.jpeg *.bmp *.xpm *.pbm *.ppm *.xbm)"); + +#endif // FILEFILTERCONSTANTS_H diff --git a/src/utilities/filenameconstants.h b/src/constants/filenameconstants.h similarity index 97% rename from src/utilities/filenameconstants.h rename to src/constants/filenameconstants.h index e442bcad48..61cb727ede 100644 --- a/src/utilities/filenameconstants.h +++ b/src/constants/filenameconstants.h @@ -20,7 +20,7 @@ #ifndef FILENAMECONSTANTS_H #define FILENAMECONSTANTS_H -#include "core/arraysize.h" +#include "includes/arraysize.h" constexpr char kProblematicCharactersRegex[] = "[:?*\"<>|]"; constexpr char kInvalidFatCharactersRegex[] = "[^a-zA-Z0-9!#\\$%&'()\\-@\\^_`{}~/. ]"; diff --git a/src/constants/globalshortcutssettings.h b/src/constants/globalshortcutssettings.h new file mode 100644 index 0000000000..143736d7f8 --- /dev/null +++ b/src/constants/globalshortcutssettings.h @@ -0,0 +1,33 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef GLOBALSHORTCUTSSETTINGS_H +#define GLOBALSHORTCUTSSETTINGS_H + +namespace GlobalShortcutsSettings { + +constexpr char kSettingsGroup[] = "GlobalShortcuts"; +constexpr char kUseKDE[] = "use_kde"; +constexpr char kUseGnome[] = "use_gnome"; +constexpr char kUseMate[] = "use_mate"; +constexpr char kUseX11[] = "use_x11"; + +} // namespace + +#endif // GLOBALSHORTCUTSSETTINGS_H diff --git a/src/constants/lyricssettings.h b/src/constants/lyricssettings.h new file mode 100644 index 0000000000..d539601b6c --- /dev/null +++ b/src/constants/lyricssettings.h @@ -0,0 +1,30 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef LYRICSSETTINGS_H +#define LYRICSSETTINGS_H + +namespace LyricsSettings { + +constexpr char kSettingsGroup[] = "Lyrics"; +constexpr char kProviders[] = "providers"; + +} // namespace + +#endif // LYRICSSETTINGS_H diff --git a/src/constants/mainwindowsettings.h b/src/constants/mainwindowsettings.h new file mode 100644 index 0000000000..bf83af4af2 --- /dev/null +++ b/src/constants/mainwindowsettings.h @@ -0,0 +1,37 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef MAINWINDOWSETTINGS_H +#define MAINWINDOWSETTINGS_H + +namespace MainWindowSettings { + +constexpr char kSettingsGroup[] = "MainWindow"; +constexpr char kSearchForCoverAuto[] = "search_for_cover_auto"; +constexpr char kShowSidebar[] = "show_sidebar"; +constexpr char kMaximized[] = "maximized"; +constexpr char kMinimized[] = "minimized"; +constexpr char kHidden[] = "hidden"; +constexpr char kGeometry[] = "geometry"; +constexpr char kSplitterState[] = "splitter_state"; +constexpr char kDoNotShowSponsorMessage[] = "do_not_show_sponsor_message"; + +} // namespace + +#endif // MAINWINDOWSETTINGS_H diff --git a/src/constants/moodbarsettings.h b/src/constants/moodbarsettings.h new file mode 100644 index 0000000000..9a7bd529d1 --- /dev/null +++ b/src/constants/moodbarsettings.h @@ -0,0 +1,43 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef MOODBARSETTINGS_H +#define MOODBARSETTINGS_H + +namespace MoodbarSettings { + +constexpr char kSettingsGroup[] = "Moodbar"; + +enum class Style { + Normal = 0, + Angry, + Frozen, + Happy, + SystemPalette, + StyleCount +}; + +constexpr char kEnabled[] = "enabled"; +constexpr char kShow[] = "show"; +constexpr char kStyle[] = "style"; +constexpr char kSave[] = "save"; + +} // namespace + +#endif // MOODBARSETTINGS_H diff --git a/src/constants/networkproxysettings.h b/src/constants/networkproxysettings.h new file mode 100644 index 0000000000..fe45e40fb4 --- /dev/null +++ b/src/constants/networkproxysettings.h @@ -0,0 +1,37 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef NETWORKPROXYSETTINGS_H +#define NETWORKPROXYSETTINGS_H + +namespace NetworkProxySettings { + +constexpr char kSettingsGroup[] = "NetworkProxy"; + +constexpr char kType[] = "type"; +constexpr char kHostname[] = "hostname"; +constexpr char kPort[] = "port"; +constexpr char kUseAuthentication[] = "use_authentication"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kEngine[] = "engine"; + +} // namespace + +#endif // NETWORKPROXYSETTINGS_H diff --git a/src/constants/notificationssettings.h b/src/constants/notificationssettings.h new file mode 100644 index 0000000000..cd4e958883 --- /dev/null +++ b/src/constants/notificationssettings.h @@ -0,0 +1,68 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef NOTIFICATIONSSETTINGS_H +#define NOTIFICATIONSSETTINGS_H + +#include + +namespace OSDSettings { + +constexpr char kSettingsGroup[] = "OSD"; + +constexpr char kType[] = "Behaviour"; + +enum class Type { + Disabled = 0, + Native, + TrayPopup, + Pretty +}; + +constexpr char kTimeout[] = "Timeout"; +constexpr char kShowOnVolumeChange[] = "ShowOnVolumeChange"; +constexpr char kShowOnPlayModeChange[] = "ShowOnPlayModeChange"; +constexpr char kShowOnPausePlayback[] = "ShowOnPausePlayback"; +constexpr char kShowOnResumePlayback[] = "ShowOnResumePlayback"; +constexpr char kShowArt[] = "ShowArt"; +constexpr char kCustomTextEnabled[] = "CustomTextEnabled"; +constexpr char kCustomText1[] = "CustomText1"; +constexpr char kCustomText2[] = "CustomText2"; + +} // namespace + +namespace OSDPrettySettings { + +constexpr char kSettingsGroup[] = "OSDPretty"; + +constexpr char kForegroundColor[] = "foreground_color"; +constexpr char kBackgroundColor[] = "background_color"; +constexpr char kBackgroundOpacity[] = "background_opacity"; +constexpr char kPopupScreen[] = "popup_screen"; +constexpr char kPopupPos[] = "popup_pos"; +constexpr char kFont[] = "font"; +constexpr char kDisableDuration[] = "disable_duration"; +constexpr char kFading[] = "fading"; + +constexpr QRgb kPresetBlue = qRgb(102, 150, 227); +constexpr QRgb kPresetRed = qRgb(202, 22, 16); + +} // namespace + +#endif // NOTIFICATIONSSETTINGS_H diff --git a/src/constants/playlistsettings.h b/src/constants/playlistsettings.h new file mode 100644 index 0000000000..7c43ec87cf --- /dev/null +++ b/src/constants/playlistsettings.h @@ -0,0 +1,70 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef PLAYLISTSETTINGS_H +#define PLAYLISTSETTINGS_H + +#include + +namespace PlaylistSettings { + +constexpr char kSettingsGroup[] = "Playlist"; + +enum class PathType { + Automatic = 0, // Automatically select path type + Absolute, // Always use absolute paths + Relative, // Always use relative paths + Ask_User // Only used in preferences: to ask user which of the previous values he wants to use. +}; + +constexpr char kAlternatingRowColors[] = "alternating_row_colors"; +constexpr char kShowBars[] = "show_bars"; +constexpr char kGlowEffect[] = "glow_effect"; +constexpr char kWarnClosePlaylist[] = "warn_close_playlist"; +constexpr char kContinueOnError[] = "continue_on_error"; +constexpr char kGreyoutSongsStartup[] = "greyout_songs_startup"; +constexpr char kGreyoutSongsPlay[] = "greyout_songs_play"; +constexpr char kSelectTrack[] = "select_track"; +constexpr char kShowToolbar[] = "show_toolbar"; +constexpr char kPlaylistClear[] = "playlist_clear"; +constexpr char kAutoSort[] = "auto_sort"; + +constexpr char kPathType[] = "path_type"; + +constexpr char kEditMetadataInline[] = "editmetadatainline"; +constexpr char kWriteMetadata[] = "write_metadata"; +constexpr char kDeleteFiles[] = "delete_files"; + +constexpr char kStateVersion[] = "state_version"; +constexpr char kState[] = "state"; +constexpr char kColumnAlignments[] = "column_alignments"; +constexpr char kRatingLocked[] = "rating_locked"; + +constexpr char kLastSaveFilter[] = "last_save_filter"; +constexpr char kLastSavePath[] = "last_save_path"; +constexpr char kLastSaveExtension[] = "last_save_extension"; + +constexpr char kLastSaveAllPath[] = "last_save_all_path"; +constexpr char kLastSaveAllExtension[] = "last_save_all_extension"; + +} // namespace + +Q_DECLARE_METATYPE(PlaylistSettings::PathType) + +#endif // PLAYLISTSETTINGS_H diff --git a/src/constants/qobuzsettings.h b/src/constants/qobuzsettings.h new file mode 100644 index 0000000000..f4f52b82b8 --- /dev/null +++ b/src/constants/qobuzsettings.h @@ -0,0 +1,47 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef QOBUZSETTINGS_H +#define QOBUZSETTINGS_H + +namespace QobuzSettings { + +constexpr char kSettingsGroup[] = "Qobuz"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kAppId[] = "app_id"; +constexpr char kAppSecret[] = "app_secret"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kFormat[] = "format"; +constexpr char kSearchDelay[] = "searchdelay"; +constexpr char kArtistsSearchLimit[] = "artistssearchlimit"; +constexpr char kAlbumsSearchLimit[] = "albumssearchlimit"; +constexpr char kSongsSearchLimit[] = "songssearchlimit"; +constexpr char kBase64Secret[] = "base64secret"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; + +constexpr char kUserId[] = "user_id"; +constexpr char kCredentialsId[] = "credentials_id"; +constexpr char kDeviceId[] = "device_id"; +constexpr char kUserAuthToken[] = "user_auth_token"; + +} // namespace + +#endif // QOBUZSETTINGS_H diff --git a/src/constants/scrobblersettings.h b/src/constants/scrobblersettings.h new file mode 100644 index 0000000000..5f1719eb7d --- /dev/null +++ b/src/constants/scrobblersettings.h @@ -0,0 +1,40 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef SCROBBLERSETTINGS_H +#define SCROBBLERSETTINGS_H + +namespace ScrobblerSettings { + +constexpr char kSettingsGroup[] = "Scrobbler"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kScrobbleButton[] = "scrobble_button"; +constexpr char kLoveButton[] = "love_button"; +constexpr char kOffline[] = "offline"; +constexpr char kSubmit[] = "submit"; +constexpr char kAlbumArtist[] = "albumartist"; +constexpr char kShowErrorDialog[] = "show_error_dialog"; +constexpr char kStripRemastered[] = "strip_remastered"; +constexpr char kSources[] = "sources"; +constexpr char kUserToken[] = "user_token"; + +} // namespace + +#endif // SCROBBLERSETTINGS_H diff --git a/src/constants/spotifysettings.h b/src/constants/spotifysettings.h new file mode 100644 index 0000000000..7d1090ac8a --- /dev/null +++ b/src/constants/spotifysettings.h @@ -0,0 +1,42 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef SPOTIFYSETTINGS_H +#define SPOTIFYSETTINGS_H + +namespace SpotifySettings { + +constexpr char kSettingsGroup[] = "Spotify"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kSearchDelay[] = "searchdelay"; +constexpr char kArtistsSearchLimit[] = "artistssearchlimit"; +constexpr char kAlbumsSearchLimit[] = "albumssearchlimit"; +constexpr char kSongsSearchLimit[] = "songssearchlimit"; +constexpr char kFetchAlbums[] = "fetchalbums"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; + +constexpr char kAccessToken[] = "access_token"; +constexpr char kRefreshToken[] = "refresh_token"; +constexpr char kExpiresIn[] = "expires_in"; +constexpr char kLoginTime[] = "login_time"; + +} // namespace + +#endif // SPOTIFYSETTINGS_H diff --git a/src/constants/subsonicsettings.h b/src/constants/subsonicsettings.h new file mode 100644 index 0000000000..f3841549cb --- /dev/null +++ b/src/constants/subsonicsettings.h @@ -0,0 +1,45 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + + +#ifndef SUBSONICETTINGS_H +#define SUBSONICETTINGS_H + +namespace SubsonicSettings { + +constexpr char kSettingsGroup[] = "Subsonic"; + +enum class AuthMethod { + Hex, + MD5 +}; + +constexpr char kEnabled[] = "enabled"; +constexpr char kUrl[] = "url"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kHTTP2[] = "http2"; +constexpr char kVerifyCertificate[] = "verifycertificate"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; +constexpr char kServerSideScrobbling[] = "serversidescrobbling"; +constexpr char kAuthMethod[] = "authmethod"; + +} // namespace + +#endif // SUBSONICETTINGS_H diff --git a/src/constants/tidalsettings.h b/src/constants/tidalsettings.h new file mode 100644 index 0000000000..c7c83f0b87 --- /dev/null +++ b/src/constants/tidalsettings.h @@ -0,0 +1,52 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef TIDALSETTINGS_H +#define TIDALSETTINGS_H + +namespace TidalSettings { + +constexpr char kSettingsGroup[] = "Tidal"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kOAuth[] = "oauth"; +constexpr char kClientId[] = "client_id"; +constexpr char kApiToken[] = "api_token"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kQuality[] = "quality"; +constexpr char kSearchDelay[] = "searchdelay"; +constexpr char kArtistsSearchLimit[] = "artistssearchlimit"; +constexpr char kAlbumsSearchLimit[] = "albumssearchlimit"; +constexpr char kSongsSearchLimit[] = "songssearchlimit"; +constexpr char kFetchAlbums[] = "fetchalbums"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; +constexpr char kCoverSize[] = "coversize"; +constexpr char kStreamUrl[] = "streamurl"; +constexpr char kAlbumExplicit[] = "album_explicit"; + +enum class StreamUrlMethod { + StreamUrl, + UrlPostPaywall, + PlaybackInfoPostPaywall +}; + +} + +#endif // TIDALSETTINGS_H diff --git a/src/constants/timeconstants.h b/src/constants/timeconstants.h new file mode 100644 index 0000000000..a2e4b012f8 --- /dev/null +++ b/src/constants/timeconstants.h @@ -0,0 +1,34 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + +#ifndef TIMECONSTANTS_H +#define TIMECONSTANTS_H + +#include + +constexpr qint64 kMsecPerSec = 1000LL; +constexpr qint64 kUsecPerMsec = 1000LL; +constexpr qint64 kUsecPerSec = 1000000LL; +constexpr qint64 kNsecPerUsec = 1000LL; +constexpr qint64 kNsecPerMsec = 1000000LL; +constexpr qint64 kNsecPerSec = 1000000000LL; + +constexpr qint64 kSecsPerDay = 24 * 60 * 60; + +#endif // TIMECONSTANTS_H diff --git a/src/constants/transcodersettings.h b/src/constants/transcodersettings.h new file mode 100644 index 0000000000..3319984e86 --- /dev/null +++ b/src/constants/transcodersettings.h @@ -0,0 +1,29 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* 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 . +* +*/ + + +#ifndef TRANSCODERSETTINGS_H +#define TRANSCODERSETTINGS_H + +namespace TranscoderSettings { +constexpr char kSettingsGroup[] = "Transcoder"; +} + +#endif // TRANSCODERSETTINGS_H + diff --git a/src/context/contextalbum.cpp b/src/context/contextalbum.cpp index fee9a8a4ec..660d9ea0e0 100644 --- a/src/context/contextalbum.cpp +++ b/src/context/contextalbum.cpp @@ -38,7 +38,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "utilities/imageutils.h" #include "covermanager/albumcoverchoicecontroller.h" diff --git a/src/context/contextalbum.h b/src/context/contextalbum.h index 7316ce4147..e7ead2496b 100644 --- a/src/context/contextalbum.h +++ b/src/context/contextalbum.h @@ -33,8 +33,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QMenu; class QTimeLine; diff --git a/src/context/contextview.cpp b/src/context/contextview.cpp index 24e9fe0c49..d74cdc19c3 100644 --- a/src/context/contextview.cpp +++ b/src/context/contextview.cpp @@ -50,8 +50,6 @@ #include #include -#include "core/application.h" -#include "core/player.h" #include "core/song.h" #include "core/settings.h" #include "utilities/strutils.h" @@ -60,7 +58,7 @@ #include "collection/collectionview.h" #include "covermanager/albumcoverchoicecontroller.h" #include "lyrics/lyricsfetcher.h" -#include "settings/contextsettingspage.h" +#include "constants/contextsettings.h" #include "contextview.h" #include "contextalbum.h" @@ -69,11 +67,10 @@ using namespace Qt::Literals::StringLiterals; namespace { constexpr int kWidgetSpacing = 50; -} +} // namespace ContextView::ContextView(QWidget *parent) : QWidget(parent), - app_(nullptr), collectionview_(nullptr), album_cover_choice_controller_(nullptr), lyrics_fetcher_(nullptr), @@ -241,14 +238,13 @@ ContextView::ContextView(QWidget *parent) } -void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller) { +void ContextView::Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr lyrics_providers) { - app_ = app; collectionview_ = collectionview; album_cover_choice_controller_ = album_cover_choice_controller; widget_album_->Init(this, album_cover_choice_controller_); - lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this); + lyrics_fetcher_ = new LyricsFetcher(lyrics_providers, this); QObject::connect(collectionview_, &CollectionView::TotalSongCountUpdated_, this, &ContextView::UpdateNoSong); QObject::connect(collectionview_, &CollectionView::TotalArtistCountUpdated_, this, &ContextView::UpdateNoSong); @@ -295,27 +291,27 @@ void ContextView::AddActions() { void ContextView::ReloadSettings() { QString default_font; - if (QFontDatabase::families().contains(QLatin1String(ContextSettingsPage::kDefaultFontFamily))) { - default_font = QLatin1String(ContextSettingsPage::kDefaultFontFamily); + if (QFontDatabase::families().contains(QLatin1String(ContextSettings::kDefaultFontFamily))) { + default_font = QLatin1String(ContextSettings::kDefaultFontFamily); } else { default_font = font().family(); } Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - title_fmt_ = s.value(ContextSettingsPage::kSettingsTitleFmt, u"%title% - %artist%"_s).toString(); - summary_fmt_ = s.value(ContextSettingsPage::kSettingsSummaryFmt, u"%album%"_s).toString(); - action_show_album_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::ALBUM)], true).toBool()); - action_show_data_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA)], false).toBool()); - action_show_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS)], true).toBool()); - action_search_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS)], true).toBool()); - font_headline_.setFamily(s.value("font_headline", default_font).toString()); - font_headline_.setPointSizeF(s.value("font_size_headline", ContextSettingsPage::kDefaultFontSizeHeadline).toReal()); + s.beginGroup(ContextSettings::kSettingsGroup); + title_fmt_ = s.value(ContextSettings::kSettingsTitleFmt, u"%title% - %artist%"_s).toString(); + summary_fmt_ = s.value(ContextSettings::kSettingsSummaryFmt, u"%album%"_s).toString(); + action_show_album_->setChecked(s.value(ContextSettings::kAlbum, true).toBool()); + action_show_data_->setChecked(s.value(ContextSettings::kTechnicalData, false).toBool()); + action_show_lyrics_->setChecked(s.value(ContextSettings::kSongLyrics, true).toBool()); + action_search_lyrics_->setChecked(s.value(ContextSettings::kSearchLyrics, true).toBool()); + font_headline_.setFamily(s.value(ContextSettings::kFontHeadline, default_font).toString()); + font_headline_.setPointSizeF(s.value(ContextSettings::kFontSizeHeadline, ContextSettings::kDefaultFontSizeHeadline).toReal()); font_nosong_.setFamily(font_headline_.family()); font_nosong_.setPointSizeF(font_headline_.pointSizeF() * 1.6F); - font_normal_.setFamily(s.value("font_normal", default_font).toString()); - font_normal_.setPointSizeF(s.value("font_size_normal", font().pointSizeF()).toReal()); + font_normal_.setFamily(s.value(ContextSettings::kFontNormal, default_font).toString()); + font_normal_.setPointSizeF(s.value(ContextSettings::kFontSizeNormal, font().pointSizeF()).toReal()); s.endGroup(); UpdateFonts(); @@ -697,9 +693,10 @@ void ContextView::AlbumCoverLoaded(const Song &song, const QImage &image) { void ContextView::ActionShowAlbum() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::ALBUM)], action_show_album_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kAlbum, action_show_album_->isChecked()); s.endGroup(); + if (song_playing_.is_valid()) SetSong(); } @@ -707,9 +704,10 @@ void ContextView::ActionShowAlbum() { void ContextView::ActionShowData() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA)], action_show_data_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kTechnicalData, action_show_data_->isChecked()); s.endGroup(); + if (song_playing_.is_valid()) SetSong(); } @@ -717,8 +715,8 @@ void ContextView::ActionShowData() { void ContextView::ActionShowLyrics() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS)], action_show_lyrics_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kSongLyrics, action_show_lyrics_->isChecked()); s.endGroup(); if (song_playing_.is_valid()) SetSong(); @@ -730,8 +728,8 @@ void ContextView::ActionShowLyrics() { void ContextView::ActionSearchLyrics() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS)], action_search_lyrics_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kSearchLyrics, action_search_lyrics_->isChecked()); s.endGroup(); if (song_playing_.is_valid()) SetSong(); diff --git a/src/context/contextview.h b/src/context/contextview.h index ff5a0f379f..dc7c1877bf 100644 --- a/src/context/contextview.h +++ b/src/context/contextview.h @@ -46,9 +46,9 @@ class QDragEnterEvent; class QDropEvent; class ResizableTextEdit; -class Application; class CollectionView; class AlbumCoverChoiceController; +class LyricsProviders; class LyricsFetcher; class ContextView : public QWidget { @@ -57,7 +57,7 @@ class ContextView : public QWidget { public: explicit ContextView(QWidget *parent = nullptr); - void Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller); + void Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr lyrics_providers); ContextAlbum *album_widget() const { return widget_album_; } bool album_enabled() const { return action_show_album_->isChecked(); } @@ -101,7 +101,6 @@ class ContextView : public QWidget { void AlbumCoverLoaded(const Song &song, const QImage &image); private: - Application *app_; CollectionView *collectionview_; AlbumCoverChoiceController *album_cover_choice_controller_; LyricsFetcher *lyrics_fetcher_; diff --git a/src/core/application.cpp b/src/core/application.cpp index e98a789eb5..ee52e81100 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -34,18 +34,17 @@ #include "core/logging.h" -#include "shared_ptr.h" -#include "lazy.h" -#include "database.h" -#include "taskmanager.h" -#include "player.h" -#include "networkaccessmanager.h" +#include "includes/shared_ptr.h" +#include "includes/lazy.h" +#include "core/database.h" +#include "core/taskmanager.h" +#include "core/networkaccessmanager.h" +#include "core/player.h" #include "tagreader/tagreaderclient.h" #include "engine/devicefinders.h" -#ifndef Q_OS_WIN -# include "device/devicemanager.h" -#endif -#include "collection/collection.h" +#include "core/urlhandlers.h" +#include "device/devicemanager.h" +#include "collection/collectionlibrary.h" #include "playlist/playlistbackend.h" #include "playlist/playlistmanager.h" #include "covermanager/albumcoverloader.h" @@ -114,58 +113,57 @@ using namespace std::chrono_literals; class ApplicationImpl { public: explicit ApplicationImpl(Application *app) : - tag_reader_client_([app](){ + tagreader_client_([app](){ TagReaderClient *client = new TagReaderClient(); app->MoveToNewThread(client); return client; }), database_([app]() { - Database *db = new Database(app); - app->MoveToNewThread(db); - QTimer::singleShot(30s, db, &Database::DoBackup); - return db; + Database *database = new Database(app->task_manager()); + app->MoveToNewThread(database); + QTimer::singleShot(30s, database, &Database::DoBackup); + return database; }), task_manager_([]() { return new TaskManager(); }), - player_([app]() { return new Player(app); }), + player_([app]() { return new Player(app->task_manager(), app->url_handlers(), app->playlist_manager()); }), network_([]() { return new NetworkAccessManager(); }), device_finders_([]() { return new DeviceFinders(); }), -#ifndef Q_OS_WIN - device_manager_([app]() { return new DeviceManager(app); }), -#endif - collection_([app]() { return new SCollection(app); }), + url_handlers_([]() { return new UrlHandlers(); }), + device_manager_([app]() { return new DeviceManager(app->task_manager(), app->database(), app->tagreader_client(), app->albumcover_loader()); }), + collection_([app]() { return new CollectionLibrary(app->database(), app->task_manager(), app->tagreader_client(), app->albumcover_loader()); }), playlist_backend_([this, app]() { - PlaylistBackend *backend = new PlaylistBackend(app); - app->MoveToThread(backend, database_->thread()); - return backend; + PlaylistBackend *playlist_backend = new PlaylistBackend(app->database(), app->tagreader_client(), app->collection_backend()); + app->MoveToThread(playlist_backend, database_->thread()); + return playlist_backend; }), - playlist_manager_([app]() { return new PlaylistManager(app); }), + playlist_manager_([app]() { return new PlaylistManager(app->task_manager(), app->tagreader_client(), app->url_handlers(), app->playlist_backend(), app->collection_backend(), app->current_albumcover_loader()); }), cover_providers_([app]() { CoverProviders *cover_providers = new CoverProviders(); // Initialize the repository of cover providers. - cover_providers->AddProvider(new LastFmCoverProvider(app, app->network())); - cover_providers->AddProvider(new MusicbrainzCoverProvider(app, app->network())); - cover_providers->AddProvider(new DiscogsCoverProvider(app, app->network())); - cover_providers->AddProvider(new DeezerCoverProvider(app, app->network())); - cover_providers->AddProvider(new MusixmatchCoverProvider(app, app->network())); - cover_providers->AddProvider(new OpenTidalCoverProvider(app, app->network())); + cover_providers->AddProvider(new LastFmCoverProvider(app->network())); + cover_providers->AddProvider(new MusicbrainzCoverProvider(app->network())); + cover_providers->AddProvider(new DiscogsCoverProvider(app->network())); + cover_providers->AddProvider(new DeezerCoverProvider(app->network())); + cover_providers->AddProvider(new MusixmatchCoverProvider(app->network())); + cover_providers->AddProvider(new OpenTidalCoverProvider(app->network())); #ifdef HAVE_TIDAL - cover_providers->AddProvider(new TidalCoverProvider(app, app->network())); + cover_providers->AddProvider(new TidalCoverProvider(app->streaming_services()->Service(), app->network())); #endif #ifdef HAVE_SPOTIFY - cover_providers->AddProvider(new SpotifyCoverProvider(app, app->network())); + cover_providers->AddProvider(new SpotifyCoverProvider(app->streaming_services()->Service(), app->network())); #endif #ifdef HAVE_QOBUZ - cover_providers->AddProvider(new QobuzCoverProvider(app, app->network())); + cover_providers->AddProvider(new QobuzCoverProvider(app->streaming_services()->Service(), app->network())); #endif cover_providers->ReloadSettings(); return cover_providers; }), - album_cover_loader_([app]() { - AlbumCoverLoader *loader = new AlbumCoverLoader(); + albumcover_loader_([app]() { + AlbumCoverLoader *loader = new AlbumCoverLoader(app->tagreader_client()); app->MoveToNewThread(loader); return loader; }), - current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app); }), + current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app->albumcover_loader()); }), lyrics_providers_([app]() { LyricsProviders *lyrics_providers = new LyricsProviders(app); // Initialize the repository of lyrics providers. @@ -185,51 +183,50 @@ class ApplicationImpl { streaming_services_([app]() { StreamingServices *streaming_services = new StreamingServices(); #ifdef HAVE_SUBSONIC - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->url_handlers(), app->albumcover_loader())); #endif #ifdef HAVE_TIDAL - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->albumcover_loader())); #endif #ifdef HAVE_SPOTIFY - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->network(), app->albumcover_loader())); #endif #ifdef HAVE_QOBUZ - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->albumcover_loader())); #endif return streaming_services; }), - radio_services_([app]() { return new RadioServices(app); }), + radio_services_([app]() { return new RadioServices(app->task_manager(), app->network(), app->database(), app->albumcover_loader()); }), scrobbler_([app]() { AudioScrobbler *scrobbler = new AudioScrobbler(app); scrobbler->AddService(make_shared(scrobbler->settings(), app->network())); scrobbler->AddService(make_shared(scrobbler->settings(), app->network())); scrobbler->AddService(make_shared(scrobbler->settings(), app->network())); #ifdef HAVE_SUBSONIC - scrobbler->AddService(make_shared(scrobbler->settings(), app)); + scrobbler->AddService(make_shared(scrobbler->settings(), app->streaming_services()->Service(), app)); #endif return scrobbler; }), #ifdef HAVE_MOODBAR moodbar_loader_([app]() { return new MoodbarLoader(app); }), - moodbar_controller_([app]() { return new MoodbarController(app); }), + moodbar_controller_([app]() { return new MoodbarController(app->player(), app->moodbar_loader()); }), #endif lastfm_import_([app]() { return new LastFMImport(app->network()); }) {} - Lazy tag_reader_client_; + Lazy tagreader_client_; Lazy database_; Lazy task_manager_; Lazy player_; Lazy network_; Lazy device_finders_; -#ifndef Q_OS_WIN + Lazy url_handlers_; Lazy device_manager_; -#endif - Lazy collection_; + Lazy collection_; Lazy playlist_backend_; Lazy playlist_manager_; Lazy cover_providers_; - Lazy album_cover_loader_; + Lazy albumcover_loader_; Lazy current_albumcover_loader_; Lazy lyrics_providers_; Lazy streaming_services_; @@ -250,9 +247,7 @@ Application::Application(QObject *parent) device_finders()->Init(); collection()->Init(); - tag_reader_client(); - - QObject::connect(&*database(), &Database::Error, this, &Application::ErrorAdded); + tagreader_client(); } @@ -294,32 +289,28 @@ void Application::MoveToThread(QObject *object, QThread *thread) { void Application::Exit() { - wait_for_exit_ << &*tag_reader_client() + wait_for_exit_ << &*tagreader_client() << &*collection() << &*playlist_backend() - << &*album_cover_loader() -#ifndef Q_OS_WIN + << &*albumcover_loader() << &*device_manager() -#endif << &*streaming_services() << &*radio_services()->radio_backend(); - QObject::connect(&*tag_reader_client(), &TagReaderClient::ExitFinished, this, &Application::ExitReceived); - tag_reader_client()->ExitAsync(); + QObject::connect(&*tagreader_client(), &TagReaderClient::ExitFinished, this, &Application::ExitReceived); + tagreader_client()->ExitAsync(); - QObject::connect(&*collection(), &SCollection::ExitFinished, this, &Application::ExitReceived); + QObject::connect(&*collection(), &CollectionLibrary::ExitFinished, this, &Application::ExitReceived); collection()->Exit(); QObject::connect(&*playlist_backend(), &PlaylistBackend::ExitFinished, this, &Application::ExitReceived); playlist_backend()->ExitAsync(); - QObject::connect(&*album_cover_loader(), &AlbumCoverLoader::ExitFinished, this, &Application::ExitReceived); - album_cover_loader()->ExitAsync(); + QObject::connect(&*albumcover_loader(), &AlbumCoverLoader::ExitFinished, this, &Application::ExitReceived); + albumcover_loader()->ExitAsync(); -#ifndef Q_OS_WIN QObject::connect(&*device_manager(), &DeviceManager::ExitFinished, this, &Application::ExitReceived); device_manager()->Exit(); -#endif QObject::connect(&*streaming_services(), &StreamingServices::ExitFinished, this, &Application::ExitReceived); streaming_services()->Exit(); @@ -345,23 +336,18 @@ 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 Application::tag_reader_client() const { return p_->tag_reader_client_.ptr(); } +SharedPtr Application::tagreader_client() const { return p_->tagreader_client_.ptr(); } SharedPtr Application::database() const { return p_->database_.ptr(); } SharedPtr Application::task_manager() const { return p_->task_manager_.ptr(); } SharedPtr Application::player() const { return p_->player_.ptr(); } SharedPtr Application::network() const { return p_->network_.ptr(); } SharedPtr Application::device_finders() const { return p_->device_finders_.ptr(); } -#ifndef Q_OS_WIN +SharedPtr Application::url_handlers() const { return p_->url_handlers_.ptr(); } SharedPtr Application::device_manager() const { return p_->device_manager_.ptr(); } -#endif -SharedPtr Application::collection() const { return p_->collection_.ptr(); } +SharedPtr Application::collection() const { return p_->collection_.ptr(); } SharedPtr Application::collection_backend() const { return collection()->backend(); } CollectionModel *Application::collection_model() const { return collection()->model(); } -SharedPtr Application::album_cover_loader() const { return p_->album_cover_loader_.ptr(); } +SharedPtr Application::albumcover_loader() const { return p_->albumcover_loader_.ptr(); } SharedPtr Application::cover_providers() const { return p_->cover_providers_.ptr(); } SharedPtr Application::current_albumcover_loader() const { return p_->current_albumcover_loader_.ptr(); } SharedPtr Application::lyrics_providers() const { return p_->lyrics_providers_.ptr(); } diff --git a/src/core/application.h b/src/core/application.h index 901adf29a2..901d455338 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -29,10 +29,8 @@ #include #include -#include "scoped_ptr.h" -#include "shared_ptr.h" - -#include "settings/settingsdialog.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QThread; @@ -41,16 +39,15 @@ class ApplicationImpl; class TagReaderClient; class Database; class DeviceFinders; +class UrlHandlers; class Player; class NetworkAccessManager; -class SCollection; +class CollectionLibrary; class CollectionBackend; class CollectionModel; class PlaylistBackend; class PlaylistManager; -#ifndef Q_OS_WIN class DeviceManager; -#endif class CoverProviders; class AlbumCoverLoader; class CurrentAlbumCoverLoader; @@ -72,17 +69,16 @@ class Application : public QObject { explicit Application(QObject *parent = nullptr); ~Application() override; - SharedPtr tag_reader_client() const; + SharedPtr tagreader_client() const; SharedPtr database() const; SharedPtr task_manager() const; SharedPtr player() const; SharedPtr network() const; SharedPtr device_finders() const; -#ifndef Q_OS_WIN + SharedPtr url_handlers() const; SharedPtr device_manager() const; -#endif - SharedPtr collection() const; + SharedPtr collection() const; SharedPtr collection_backend() const; CollectionModel *collection_model() const; @@ -90,7 +86,7 @@ class Application : public QObject { SharedPtr playlist_manager() const; SharedPtr cover_providers() const; - SharedPtr album_cover_loader() const; + SharedPtr albumcover_loader() const; SharedPtr current_albumcover_loader() const; SharedPtr lyrics_providers() const; @@ -115,23 +111,13 @@ class Application : public QObject { private Q_SLOTS: void ExitReceived(); - public Q_SLOTS: - void AddError(const QString &message); - void ReloadSettings(); - void OpenSettingsDialogAtPage(SettingsDialog::Page page); - Q_SIGNALS: - void ErrorAdded(const QString &message); - void SettingsChanged(); - void SettingsDialogRequested(const SettingsDialog::Page page); void ExitFinished(); - void ClearPixmapDiskCache(); private: ScopedPtr p_; QList threads_; QList wait_for_exit_; - }; #endif // APPLICATION_H diff --git a/src/core/database.cpp b/src/core/database.cpp index 52b731b108..b38f59f357 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -45,7 +45,6 @@ #include "core/logging.h" #include "taskmanager.h" #include "database.h" -#include "application.h" #include "sqlquery.h" #include "scopedtransaction.h" @@ -62,9 +61,9 @@ constexpr char kMagicAllSongsTables[] = "%allsongstables"; int Database::sNextConnectionId = 1; QMutex Database::sNextConnectionIdMutex; -Database::Database(Application *app, QObject *parent, const QString &database_name) : +Database::Database(SharedPtr task_manager, QObject *parent, const QString &database_name) : QObject(parent), - app_(app), + task_manager_(task_manager), injected_database_name_(database_name), query_hash_(0), startup_schema_version_(-1), @@ -145,7 +144,7 @@ QSqlDatabase Database::Connect() { } if (!db.open()) { - app_->AddError(u"Database: "_s + db.lastError().text()); + Q_EMIT Error(u"Database: "_s + db.lastError().text()); return db; } @@ -492,7 +491,7 @@ void Database::ReportErrors(const SqlQuery &query) { bool Database::IntegrityCheck(const QSqlDatabase &db) { qLog(Debug) << "Starting database integrity check"; - const int task_id = app_->task_manager()->StartTask(tr("Integrity check")); + const int task_id = task_manager_->StartTask(tr("Integrity check")); bool ok = false; // Ask for 10 error messages at most. @@ -509,8 +508,8 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) { break; } else { - if (!error_reported) { app_->AddError(tr("Database corruption detected.")); } - app_->AddError(u"Database: "_s + message); + if (!error_reported) { Q_EMIT Error(tr("Database corruption detected.")); } + Q_EMIT Error(u"Database: "_s + message); error_reported = true; } } @@ -519,7 +518,7 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) { ReportErrors(q); } - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); return ok; @@ -563,7 +562,7 @@ void Database::BackupFile(const QString &filename) { qLog(Debug) << "Starting database backup"; QString dest_filename = QStringLiteral("%1.bak").arg(filename); - const int task_id = app_->task_manager()->StartTask(tr("Backing up database")); + const int task_id = task_manager_->StartTask(tr("Backing up database")); sqlite3 *source_connection = nullptr; sqlite3 *dest_connection = nullptr; @@ -575,7 +574,7 @@ void Database::BackupFile(const QString &filename) { if (dest_connection) { sqlite3_close(dest_connection); } - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); }); bool success = OpenDatabase(filename, &source_connection); @@ -599,7 +598,7 @@ void Database::BackupFile(const QString &filename) { do { ret = sqlite3_backup_step(backup, 16); const int page_count = sqlite3_backup_pagecount(backup); - app_->task_manager()->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count); + task_manager_->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count); } while (ret == SQLITE_OK); diff --git a/src/core/database.h b/src/core/database.h index 99aa9b91af..fdb65a9700 100644 --- a/src/core/database.h +++ b/src/core/database.h @@ -36,16 +36,17 @@ #include #include +#include "includes/shared_ptr.h" #include "sqlquery.h" class QThread; -class Application; +class TaskManager; class Database : public QObject { Q_OBJECT public: - explicit Database(Application *app, QObject *parent = nullptr, const QString &database_name = QString()); + explicit Database(SharedPtr task_manager, QObject *parent = nullptr, const QString &database_name = QString()); ~Database() override; static const int kSchemaVersion; @@ -102,7 +103,7 @@ class Database : public QObject { void BackupFile(const QString &filename); static bool OpenDatabase(const QString &filename, sqlite3 **connection); - Application *app_; + SharedPtr task_manager_; // Alias -> filename QMap 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 diff --git a/src/core/deletefiles.cpp b/src/core/deletefiles.cpp index 850b630bf8..83afb74a45 100644 --- a/src/core/deletefiles.cpp +++ b/src/core/deletefiles.cpp @@ -28,7 +28,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" #include "taskmanager.h" #include "song.h" #include "deletefiles.h" diff --git a/src/core/deletefiles.h b/src/core/deletefiles.h index f817ca7639..ebe45d5b0e 100644 --- a/src/core/deletefiles.h +++ b/src/core/deletefiles.h @@ -27,7 +27,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" #include "song.h" class QThread; diff --git a/src/engine/enginemetadata.cpp b/src/core/enginemetadata.cpp similarity index 100% rename from src/engine/enginemetadata.cpp rename to src/core/enginemetadata.cpp diff --git a/src/engine/enginemetadata.h b/src/core/enginemetadata.h similarity index 100% rename from src/engine/enginemetadata.h rename to src/core/enginemetadata.h diff --git a/src/core/iconloader.cpp b/src/core/iconloader.cpp index 1f1c09edfd..8096fef3b2 100644 --- a/src/core/iconloader.cpp +++ b/src/core/iconloader.cpp @@ -30,11 +30,11 @@ #include #include -#include "core/logging.h" +#include "logging.h" #include "settings.h" -#include "iconmapper.h" -#include "settings/appearancesettingspage.h" +#include "includes/iconmapper.h" #include "iconloader.h" +#include "constants/appearancesettings.h" using namespace Qt::Literals::StringLiterals; @@ -45,7 +45,7 @@ void IconLoader::Init() { #if !defined(Q_OS_MACOS) && !defined(Q_OS_WIN) Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); + s.beginGroup(AppearanceSettings::kSettingsGroup); system_icons_ = s.value("system_icons", false).toBool(); s.endGroup(); #endif diff --git a/src/core/mac_startup.mm b/src/core/mac_startup.mm index f21a3e0146..40d031035e 100644 --- a/src/core/mac_startup.mm +++ b/src/core/mac_startup.mm @@ -45,15 +45,6 @@ #include "config.h" -#include "platforminterface.h" -#include "mac_delegate.h" -#include "mac_startup.h" -#include "scoped_cftyperef.h" -#include "core/logging.h" -#include "scoped_nsautorelease_pool.h" -#include "globalshortcuts/globalshortcutsmanager.h" -#include "globalshortcuts/globalshortcutsbackend-macos.h" - #include #include #include @@ -61,7 +52,14 @@ #include #include -#include +#include "includes/mac_delegate.h" +#include "includes/scoped_cftyperef.h" +#include "core/scoped_nsautorelease_pool.h" +#include "core/logging.h" +#include "core/platforminterface.h" +#include "mac_startup.h" +#include "globalshortcuts/globalshortcutsmanager.h" +#include "globalshortcuts/globalshortcutsbackend-macos.h" QDebug operator<<(QDebug dbg, NSObject *object) { diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 5cf039f023..01242c12e6 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -84,52 +84,46 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -#include "shared_ptr.h" -#include "commandlineoptions.h" -#include "mimedata.h" -#include "iconloader.h" -#include "taskmanager.h" -#include "song.h" -#include "stylehelper.h" -#include "stylesheetloader.h" +#include "constants/filefilterconstants.h" +#include "constants/timeconstants.h" +#include "constants/mainwindowsettings.h" +#include "includes/shared_ptr.h" +#include "core/commandlineoptions.h" +#include "core/mimedata.h" +#include "core/iconloader.h" +#include "core/taskmanager.h" +#include "core/song.h" +#include "core/stylehelper.h" +#include "core/stylesheetloader.h" #include "application.h" -#include "database.h" -#include "player.h" -#include "filesystemmusicstorage.h" -#include "deletefiles.h" -#ifdef Q_OS_MACOS -# include "mac_startup.h" -# include "macsystemtrayicon.h" -# include "utilities/macosutils.h" -#else -# include "qtsystemtrayicon.h" -#endif -#include "networkaccessmanager.h" -#include "settings.h" +#include "core/database.h" +#include "core/filesystemmusicstorage.h" +#include "core/deletefiles.h" +#include "core/settings.h" +#include "core/player.h" #include "utilities/envutils.h" #include "utilities/filemanagerutils.h" -#include "utilities/timeconstants.h" #include "utilities/screenutils.h" #include "engine/enginebase.h" #include "dialogs/errordialog.h" #include "dialogs/about.h" #include "dialogs/console.h" -#include "dialogs/trackselectiondialog.h" -#include "dialogs/edittagdialog.h" #include "dialogs/addstreamdialog.h" #include "dialogs/deleteconfirmationdialog.h" #include "dialogs/lastfmimportdialog.h" #include "dialogs/snapdialog.h" +#include "dialogs/edittagdialog.h" +#include "dialogs/trackselectiondialog.h" #include "organize/organizedialog.h" #include "widgets/fancytabwidget.h" #include "widgets/playingwidget.h" #include "widgets/volumeslider.h" -#include "widgets/fileview.h" #include "widgets/multiloadingindicator.h" #include "widgets/trackslider.h" +#include "fileview/fileview.h" #include "osd/osdbase.h" #include "context/contextview.h" -#include "collection/collection.h" +#include "collection/collectionlibrary.h" #include "collection/collectionbackend.h" #include "collection/collectiondirectorymodel.h" #include "collection/collectionviewcontainer.h" @@ -160,30 +154,31 @@ #include "covermanager/coverproviders.h" #include "covermanager/albumcoverimageresult.h" #include "lyrics/lyricsproviders.h" +#include "device/devicemanager.h" +#include "device/devicestatefiltermodel.h" #ifndef Q_OS_WIN -# include "device/devicemanager.h" -# include "device/devicestatefiltermodel.h" # include "device/deviceview.h" # include "device/deviceviewcontainer.h" #endif #include "transcoder/transcodedialog.h" #include "settings/settingsdialog.h" -#include "settings/behavioursettingspage.h" -#include "settings/backendsettingspage.h" -#include "settings/collectionsettingspage.h" -#include "settings/playlistsettingspage.h" +#include "constants/behavioursettings.h" +#include "constants/appearancesettings.h" +#include "constants/backendsettings.h" +#include "constants/collectionsettings.h" +#include "constants/playlistsettings.h" #ifdef HAVE_SUBSONIC -# include "settings/subsonicsettingspage.h" +# include "constants/subsonicsettings.h" #endif #ifdef HAVE_TIDAL # include "tidal/tidalservice.h" -# include "settings/tidalsettingspage.h" +# include "constants/tidalsettings.h" #endif #ifdef HAVE_SPOTIFY -# include "settings/spotifysettingspage.h" +# include "constants/spotifysettings.h" #endif #ifdef HAVE_QOBUZ -# include "settings/qobuzsettingspage.h" +# include "constants/qobuzsettings.h" #endif #include "streaming/streamingservices.h" @@ -205,6 +200,7 @@ #ifdef HAVE_MOODBAR # include "moodbar/moodbarcontroller.h" +# include "moodbar/moodbarloader.h" # include "moodbar/moodbarproxystyle.h" #endif @@ -213,7 +209,15 @@ #include "organize/organizeerrordialog.h" #ifdef Q_OS_WIN -# include "windows7thumbbar.h" +# include "core/windows7thumbbar.h" +#endif + +#ifdef Q_OS_MACOS +# include "core/mac_startup.h" +# include "systemtrayicon/macsystemtrayicon.h" +# include "utilities/macosutils.h" +#else +# include "systemtrayicon/qtsystemtrayicon.h" #endif #ifdef HAVE_QTSPARKLE @@ -225,9 +229,6 @@ using std::make_shared; using namespace std::chrono_literals; using namespace Qt::Literals::StringLiterals; -const char *MainWindow::kSettingsGroup = "MainWindow"; -const char *MainWindow::kAllFilesFilterSpec = QT_TR_NOOP("All Files (*)"); - namespace { const int kTrackSliderUpdateTimeMs = 200; const int kTrackPositionUpdateTimeMs = 1000; @@ -259,7 +260,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS tray_icon_(tray_icon), osd_(osd), console_([app]() { - Console *console = new Console(app); + Console *console = new Console(app->database()); return console; }), edit_tag_dialog_(std::bind(&MainWindow::CreateEditTagDialog, this)), @@ -277,7 +278,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS queue_view_(new QueueView(this)), settings_dialog_(std::bind(&MainWindow::CreateSettingsDialog, this)), cover_manager_([this, app]() { - AlbumCoverManager *cover_manager = new AlbumCoverManager(app, app->collection_backend(), this); + AlbumCoverManager *cover_manager = new AlbumCoverManager(app->network(), app->collection_backend(), app->tagreader_client(), app->albumcover_loader(), app->current_albumcover_loader(), app->cover_providers(), app->streaming_services(), this); cover_manager->Init(); // Cover manager connections @@ -287,7 +288,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS }), equalizer_(new Equalizer), organize_dialog_([this, app]() { - OrganizeDialog *dialog = new OrganizeDialog(app->task_manager(), app->collection_backend(), this); + OrganizeDialog *dialog = new OrganizeDialog(app->task_manager(), app->tagreader_client(), app->collection_backend(), this); dialog->SetDestinationModel(app->collection()->model()->directory_model()); return dialog; }), @@ -300,18 +301,18 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(add_stream_dialog, &AddStreamDialog::accepted, this, &MainWindow::AddStreamAccepted); return add_stream_dialog; }), - smartplaylists_view_(new SmartPlaylistsViewContainer(app, this)), + smartplaylists_view_(new SmartPlaylistsViewContainer(app->player(), app->playlist_manager(), app->collection_backend(), app->moodbar_loader(), app->current_albumcover_loader(), this)), #ifdef HAVE_SUBSONIC - subsonic_view_(new StreamingSongsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Subsonic), QLatin1String(SubsonicSettingsPage::kSettingsGroup), SettingsDialog::Page::Subsonic, this)), + subsonic_view_(new StreamingSongsView(app->streaming_services()->ServiceBySource(Song::Source::Subsonic), QLatin1String(SubsonicSettings::kSettingsGroup), this)), #endif #ifdef HAVE_TIDAL - tidal_view_(new StreamingTabsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Tidal), QLatin1String(TidalSettingsPage::kSettingsGroup), SettingsDialog::Page::Tidal, this)), + tidal_view_(new StreamingTabsView(app->streaming_services()->ServiceBySource(Song::Source::Tidal), app->albumcover_loader(), QLatin1String(TidalSettings::kSettingsGroup), this)), #endif #ifdef HAVE_SPOTIFY - spotify_view_(new StreamingTabsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Spotify), QLatin1String(SpotifySettingsPage::kSettingsGroup), SettingsDialog::Page::Spotify, this)), + spotify_view_(new StreamingTabsView(app->streaming_services()->ServiceBySource(Song::Source::Spotify), app->albumcover_loader(), QLatin1String(SpotifySettings::kSettingsGroup), this)), #endif #ifdef HAVE_QOBUZ - qobuz_view_(new StreamingTabsView(app_, app->streaming_services()->ServiceBySource(Song::Source::Qobuz), QLatin1String(QobuzSettingsPage::kSettingsGroup), SettingsDialog::Page::Qobuz, this)), + qobuz_view_(new StreamingTabsView(app->streaming_services()->ServiceBySource(Song::Source::Qobuz), app->albumcover_loader(), QLatin1String(QobuzSettings::kSettingsGroup), this)), #endif radio_view_(new RadioViewContainer(this)), lastfm_import_dialog_(new LastFMImportDialog(app_->lastfm_import(), this)), @@ -345,10 +346,10 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #ifdef HAVE_DBUS taskbar_progress_(false), #endif - doubleclick_addmode_(BehaviourSettingsPage::AddBehaviour::Append), - doubleclick_playmode_(BehaviourSettingsPage::PlayBehaviour::Never), - doubleclick_playlist_addmode_(BehaviourSettingsPage::PlaylistAddBehaviour::Play), - menu_playmode_(BehaviourSettingsPage::PlayBehaviour::Never), + doubleclick_addmode_(BehaviourSettings::AddBehaviour::Append), + doubleclick_playmode_(BehaviourSettings::PlayBehaviour::Never), + doubleclick_playlist_addmode_(BehaviourSettings::PlaylistAddBehaviour::Play), + menu_playmode_(BehaviourSettings::PlayBehaviour::Never), initialized_(false), was_maximized_(true), was_minimized_(false), @@ -358,19 +359,18 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS qLog(Debug) << "Starting"; - QObject::connect(app, &Application::ErrorAdded, this, &MainWindow::ShowErrorDialog); - QObject::connect(app, &Application::SettingsDialogRequested, this, &MainWindow::OpenSettingsDialogAtPage); - // Initialize the UI ui_->setupUi(this); setWindowIcon(IconLoader::Load(u"strawberry"_s)); - album_cover_choice_controller_->Init(app); + QObject::connect(&*app->database(), &Database::Error, this, &MainWindow::ShowErrorDialog); + + album_cover_choice_controller_->Init(app->network(), app->tagreader_client(), app->collection()->backend(), app->albumcover_loader(), app->current_albumcover_loader(), app->cover_providers(), app->streaming_services()); ui_->multi_loading_indicator->SetTaskManager(app_->task_manager()); - context_view_->Init(app_, collection_view_->view(), album_cover_choice_controller_); - ui_->widget_playing->Init(app_, album_cover_choice_controller_); + context_view_->Init(collection_view_->view(), album_cover_choice_controller_, app_->lyrics_providers()); + ui_->widget_playing->Init(album_cover_choice_controller_); // Initialize the search widget StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker()); @@ -402,7 +402,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS // Add the playing widget to the fancy tab widget ui_->tabs->AddBottomWidget(ui_->widget_playing); ui_->tabs->SetBackgroundPixmap(QPixmap(u":/pictures/sidebar-background.png"_s)); - ui_->tabs->LoadSettings(QLatin1String(kSettingsGroup)); + ui_->tabs->LoadSettings(QLatin1String(MainWindowSettings::kSettingsGroup)); track_position_timer_->setInterval(kTrackPositionUpdateTimeMs); QObject::connect(track_position_timer_, &QTimer::timeout, this, &MainWindow::UpdateTrackPosition); @@ -423,14 +423,14 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS ui_->playlist->SetManager(app_->playlist_manager()); - ui_->playlist->view()->Init(app_); + ui_->playlist->view()->Init(app_->player(), app_->playlist_manager(), app_->collection_backend(), app_->moodbar_loader(), app_->current_albumcover_loader()); collection_view_->view()->setModel(app_->collection()->model()->filter()); - collection_view_->view()->SetApplication(app_); + collection_view_->view()->Init(app->task_manager(), app->tagreader_client(), app->network(), app->albumcover_loader(), app->current_albumcover_loader(), app->cover_providers(), app->lyrics_providers(), app->collection(), app->device_manager(), app->streaming_services()); #ifndef Q_OS_WIN - device_view_->view()->SetApplication(app_); + device_view_->view()->Init(app->task_manager(), app->tagreader_client(), app->device_manager(), app->collection_model()->directory_model()); #endif - playlist_list_->SetApplication(app_); + playlist_list_->Init(app_->task_manager(), app->tagreader_client(), app_->player(), app_->playlist_manager(), app_->playlist_backend(), app_->device_manager()); organize_dialog_->SetDestinationModel(app_->collection()->model()->directory_model()); @@ -541,9 +541,9 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(ui_->action_equalizer, &QAction::triggered, this, &MainWindow::ShowEqualizer); QObject::connect(ui_->action_transcoder, &QAction::triggered, this, &MainWindow::ShowTranscodeDialog); QObject::connect(ui_->action_jump, &QAction::triggered, ui_->playlist->view(), &PlaylistView::JumpToCurrentlyPlayingTrack); - QObject::connect(ui_->action_update_collection, &QAction::triggered, &*app_->collection(), &SCollection::IncrementalScan); - QObject::connect(ui_->action_full_collection_scan, &QAction::triggered, &*app_->collection(), &SCollection::FullScan); - QObject::connect(ui_->action_stop_collection_scan, &QAction::triggered, &*app_->collection(), &SCollection::StopScan); + QObject::connect(ui_->action_update_collection, &QAction::triggered, &*app_->collection(), &CollectionLibrary::IncrementalScan); + QObject::connect(ui_->action_full_collection_scan, &QAction::triggered, &*app_->collection(), &CollectionLibrary::FullScan); + QObject::connect(ui_->action_stop_collection_scan, &QAction::triggered, &*app_->collection(), &CollectionLibrary::StopScan); QObject::connect(ui_->action_add_files_to_transcoder, &QAction::triggered, this, &MainWindow::AddFilesToTranscoder); ui_->action_add_files_to_transcoder->setIcon(IconLoader::Load(u"tools-wizard"_s)); @@ -605,6 +605,12 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(&*app_->player(), &Player::VolumeChanged, ui_->volume, &VolumeSlider::SetValue); QObject::connect(&*app_->player(), &Player::ForceShowOSD, this, &MainWindow::ForceShowOSD); + QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::ThumbnailLoaded, osd_, &OSDBase::AlbumCoverLoaded); + + QObject::connect(&*app_->player(), &Player::Paused, &*app_->playlist_manager(), &PlaylistManager::SetActivePaused); + QObject::connect(&*app_->player(), &Player::Playing, &*app_->playlist_manager(), &PlaylistManager::SetActivePlaying); + QObject::connect(&*app_->player(), &Player::Stopped, &*app_->playlist_manager(), &PlaylistManager::SetActiveStopped); + 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, &*app_->player(), &Player::CurrentMetadataChanged); @@ -628,9 +634,9 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(ui_->track_slider, &TrackSlider::Next, &*app_->player(), &Player::Next); // Collection connections - QObject::connect(&*app_->collection(), &SCollection::Error, this, &MainWindow::ShowErrorDialog); + QObject::connect(&*app_->collection(), &CollectionLibrary::Error, this, &MainWindow::ShowErrorDialog); QObject::connect(collection_view_->view(), &CollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); - QObject::connect(collection_view_->view(), &CollectionView::ShowConfigDialog, this, &MainWindow::ShowCollectionConfig); + QObject::connect(collection_view_->view(), &CollectionView::ShowSettingsDialog, this, &MainWindow::OpenCollectionSettingsDialog); QObject::connect(collection_view_->view(), &CollectionView::Error, this, &MainWindow::ShowErrorDialog); QObject::connect(app_->collection_model(), &CollectionModel::TotalSongCountUpdated, collection_view_->view(), &CollectionView::TotalSongCountUpdated); QObject::connect(app_->collection_model(), &CollectionModel::TotalArtistCountUpdated, collection_view_->view(), &CollectionView::TotalArtistCountUpdated); @@ -638,9 +644,10 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(app_->collection_model(), &CollectionModel::modelAboutToBeReset, collection_view_->view(), &CollectionView::SaveFocus); QObject::connect(app_->collection_model(), &CollectionModel::modelReset, collection_view_->view(), &CollectionView::RestoreFocus); - 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::PauseCollectionWatchers, &*app_->collection(), &CollectionLibrary::PauseWatcher); + QObject::connect(&*app_->task_manager(), &TaskManager::ResumeCollectionWatchers, &*app_->collection(), &CollectionLibrary::ResumeWatcher); + QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, &*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::LoadAlbumCover); QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &MainWindow::AlbumCoverLoaded); QObject::connect(album_cover_choice_controller_, &AlbumCoverChoiceController::Error, this, &MainWindow::ShowErrorDialog); QObject::connect(album_cover_choice_controller_->cover_from_file_action(), &QAction::triggered, this, &MainWindow::LoadCoverFromFile); @@ -674,8 +681,8 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(collection_view_group, &QActionGroup::triggered, this, &MainWindow::ChangeCollectionFilterMode); QAction *collection_config_action = new QAction(IconLoader::Load(u"configure"_s), tr("Configure collection..."), this); - QObject::connect(collection_config_action, &QAction::triggered, this, &MainWindow::ShowCollectionConfig); - collection_view_->filter_widget()->SetSettingsGroup(QLatin1String(CollectionSettingsPage::kSettingsGroup)); + QObject::connect(collection_config_action, &QAction::triggered, this, &MainWindow::OpenCollectionSettingsDialog); + collection_view_->filter_widget()->SetSettingsGroup(QLatin1String(CollectionSettings::kSettingsGroup)); collection_view_->filter_widget()->Init(app_->collection()->model(), app_->collection()->model()->filter()); QAction *separator = new QAction(this); @@ -688,13 +695,16 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS collection_view_->filter_widget()->AddMenuAction(collection_config_action); #ifdef HAVE_SUBSONIC + QObject::connect(subsonic_view_, &StreamingSongsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(subsonic_view_->view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); #endif #ifdef HAVE_TIDAL + QObject::connect(tidal_view_, &StreamingTabsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(tidal_view_->artists_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(tidal_view_->albums_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(tidal_view_->songs_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); + QObject::connect(tidal_view_->search_view(), &StreamingSearchView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(tidal_view_->search_view(), &StreamingSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist); if (TidalServicePtr tidalservice = app_->streaming_services()->Service()) { QObject::connect(this, &MainWindow::AuthorizationUrlReceived, &*tidalservice, &TidalService::AuthorizationUrlReceived); @@ -702,16 +712,20 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #endif #ifdef HAVE_QOBUZ + QObject::connect(qobuz_view_, &StreamingTabsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(qobuz_view_->artists_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(qobuz_view_->albums_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(qobuz_view_->songs_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); + QObject::connect(qobuz_view_->search_view(), &StreamingSearchView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(qobuz_view_->search_view(), &StreamingSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist); #endif #ifdef HAVE_SPOTIFY + QObject::connect(spotify_view_, &StreamingTabsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(spotify_view_->artists_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(spotify_view_->albums_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(spotify_view_->songs_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); + QObject::connect(spotify_view_->search_view(), &StreamingSearchView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(spotify_view_->search_view(), &StreamingSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist); #endif @@ -773,14 +787,15 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(ui_->playlist, &PlaylistContainer::UndoRedoActionsChanged, this, &MainWindow::PlaylistUndoRedoChanged); -#ifndef Q_OS_WIN - playlist_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0); + QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceError, this, &MainWindow::ShowErrorDialog); +#ifndef WIN32 QObject::connect(app_->device_manager()->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, playlist_copy_to_device_, &QAction::setDisabled); + playlist_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0); #endif - QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettings::ScrobblingEnabledChanged, this, &MainWindow::ScrobblingEnabledChanged); - QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettings::ScrobbleButtonVisibilityChanged, this, &MainWindow::ScrobbleButtonVisibilityChanged); - QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettings::LoveButtonVisibilityChanged, this, &MainWindow::LoveButtonVisibilityChanged); + QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettingsService::ScrobblingEnabledChanged, this, &MainWindow::ScrobblingEnabledChanged); + QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettingsService::ScrobbleButtonVisibilityChanged, this, &MainWindow::ScrobbleButtonVisibilityChanged); + QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettingsService::LoveButtonVisibilityChanged, this, &MainWindow::LoveButtonVisibilityChanged); #ifdef Q_OS_MACOS mac::SetApplicationHandler(this); @@ -849,11 +864,14 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page); QObject::connect(ui_->multi_loading_indicator, &MultiLoadingIndicator::TaskCountChange, this, &MainWindow::TaskCountChanged); - ui_->track_slider->SetApplication(app); + ui_->track_slider->Init(); #ifdef HAVE_MOODBAR // Moodbar connections - QObject::connect(&*app_->moodbar_controller(), &MoodbarController::CurrentMoodbarDataChanged, ui_->track_slider->moodbar_style(), &MoodbarProxyStyle::SetMoodbarData); + QObject::connect(&*app_->moodbar_controller(), &MoodbarController::CurrentMoodbarDataChanged, ui_->track_slider->moodbar_proxy_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_proxy_style(), &MoodbarProxyStyle::StyleChanged, &*app_->moodbar_loader(), &MoodbarLoader::StyleChanged); #endif // Playing widget @@ -875,7 +893,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS css_loader->SetStyleSheet(this, u":/style/strawberry.css"_s); // Load playlists - app_->playlist_manager()->Init(app_->collection_backend(), app_->playlist_backend(), ui_->playlist_sequence, ui_->playlist); + app_->playlist_manager()->Init(ui_->playlist_sequence, ui_->playlist); queue_view_->SetPlaylistManager(app_->playlist_manager()); @@ -902,10 +920,12 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(&*app_->lastfm_import(), &LastFMImport::FinishedWithError, lastfm_import_dialog_, &LastFMImportDialog::FinishedWithError); QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateTotal, lastfm_import_dialog_, &LastFMImportDialog::UpdateTotal); QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateProgress, lastfm_import_dialog_, &LastFMImportDialog::UpdateProgress); + QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateLastPlayed, &*app_->collection_backend(), &CollectionBackend::UpdateLastPlayed); + QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdatePlayCount, &*app_->collection_backend(), &CollectionBackend::UpdatePlayCount); // Load settings qLog(Debug) << "Loading settings"; - settings_.beginGroup(kSettingsGroup); + settings_.beginGroup(MainWindowSettings::kSettingsGroup); // Set last used geometry to position window on the correct monitor // Set window state only if the window was last maximized @@ -913,7 +933,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS restoreGeometry(settings_.value("geometry").toByteArray()); } - if (!settings_.contains("splitter_state") || !ui_->splitter->restoreState(settings_.value("splitter_state").toByteArray())) { + if (!settings_.contains(MainWindowSettings::kSplitterState) || !ui_->splitter->restoreState(settings_.value(MainWindowSettings::kSplitterState).toByteArray())) { ui_->splitter->setSizes(QList() << 20 << (width() - 20)); } @@ -941,40 +961,40 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #ifdef Q_OS_MACOS // Always show the mainwindow on startup for macOS show(); #else - BehaviourSettingsPage::StartupBehaviour startupbehaviour = BehaviourSettingsPage::StartupBehaviour::Remember; + BehaviourSettings::StartupBehaviour startupbehaviour = BehaviourSettings::StartupBehaviour::Remember; { Settings s; - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - startupbehaviour = static_cast(s.value("startupbehaviour", static_cast(BehaviourSettingsPage::StartupBehaviour::Remember)).toInt()); + s.beginGroup(BehaviourSettings::kSettingsGroup); + startupbehaviour = static_cast(s.value(BehaviourSettings::kStartupBehaviour, static_cast(BehaviourSettings::StartupBehaviour::Remember)).toInt()); s.endGroup(); } switch (startupbehaviour) { - case BehaviourSettingsPage::StartupBehaviour::Show: + case BehaviourSettings::StartupBehaviour::Show: show(); break; - case BehaviourSettingsPage::StartupBehaviour::ShowMaximized: + case BehaviourSettings::StartupBehaviour::ShowMaximized: setWindowState(windowState() | Qt::WindowMaximized); show(); break; - case BehaviourSettingsPage::StartupBehaviour::ShowMinimized: + case BehaviourSettings::StartupBehaviour::ShowMinimized: setWindowState(windowState() | Qt::WindowMinimized); show(); break; - case BehaviourSettingsPage::StartupBehaviour::Hide: + case BehaviourSettings::StartupBehaviour::Hide: if (tray_icon_->IsSystemTrayAvailable() && tray_icon_->isVisible()) { break; } [[fallthrough]]; - case BehaviourSettingsPage::StartupBehaviour::Remember: + case BehaviourSettings::StartupBehaviour::Remember: default:{ - was_maximized_ = settings_.value("maximized", true).toBool(); + was_maximized_ = settings_.value(MainWindowSettings::kMaximized, true).toBool(); if (was_maximized_) setWindowState(windowState() | Qt::WindowMaximized); - was_minimized_ = settings_.value("minimized", false).toBool(); + was_minimized_ = settings_.value(MainWindowSettings::kMinimized, false).toBool(); if (was_minimized_) setWindowState(windowState() | Qt::WindowMinimized); - if (!tray_icon_->IsSystemTrayAvailable() || !tray_icon_->isVisible() || !settings_.value("hidden", false).toBool()) { + if (!tray_icon_->IsSystemTrayAvailable() || !tray_icon_->isVisible() || !settings_.value(MainWindowSettings::kHidden, false).toBool()) { show(); } break; @@ -982,7 +1002,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS } #endif - bool show_sidebar = settings_.value("show_sidebar", true).toBool(); + bool show_sidebar = settings_.value(MainWindowSettings::kShowSidebar, true).toBool(); ui_->sidebar_layout->setVisible(show_sidebar); ui_->action_toggle_show_sidebar->setChecked(show_sidebar); @@ -1016,7 +1036,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #ifdef Q_OS_LINUX if (!Utilities::GetEnv(u"SNAP"_s).isEmpty() && !Utilities::GetEnv(u"SNAP_NAME"_s).isEmpty()) { Settings s; - s.beginGroup(kSettingsGroup); + s.beginGroup(MainWindowSettings::kSettingsGroup); const bool ignore_snap = s.value("ignore_snap", false).toBool(); s.endGroup(); if (!ignore_snap) { @@ -1030,12 +1050,12 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #if defined(Q_OS_MACOS) if (Utilities::ProcessTranslated()) { Settings s; - s.beginGroup(kSettingsGroup); + s.beginGroup(MainWindowSettings::kSettingsGroup); const bool ignore_rosetta = s.value("ignore_rosetta", false).toBool(); s.endGroup(); if (!ignore_rosetta) { MessageDialog *rosetta_message = new MessageDialog(this); - rosetta_message->set_settings_group(QLatin1String(kSettingsGroup)); + rosetta_message->set_settings_group(QLatin1String(MainWindowSettings::kSettingsGroup)); rosetta_message->set_do_not_show_message_again(u"ignore_rosetta"_s); rosetta_message->setAttribute(Qt::WA_DeleteOnClose); rosetta_message->ShowMessage(tr("Strawberry running under Rosetta"), tr("You are running Strawberry under Rosetta. Running Strawberry under Rosetta is unsupported and known to have issues. You should download Strawberry for the correct CPU architecture from %1").arg(QLatin1String("downloads.strawberrymusicplayer.org")), IconLoader::Load(u"dialog-warning"_s)); @@ -1052,14 +1072,13 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS s.endGroup(); #endif if (asked_permission) { - s.beginGroup(kSettingsGroup); - constexpr char do_not_show_sponsor_message_key[] = "do_not_show_sponsor_message"; - const bool do_not_show_sponsor_message = s.value(do_not_show_sponsor_message_key, false).toBool(); + s.beginGroup(MainWindowSettings::kSettingsGroup); + const bool do_not_show_sponsor_message = s.value(MainWindowSettings::kDoNotShowSponsorMessage, false).toBool(); s.endGroup(); if (!do_not_show_sponsor_message) { MessageDialog *sponsor_message = new MessageDialog(this); - sponsor_message->set_settings_group(QLatin1String(kSettingsGroup)); - sponsor_message->set_do_not_show_message_again(QLatin1String(do_not_show_sponsor_message_key)); + sponsor_message->set_settings_group(QLatin1String(MainWindowSettings::kSettingsGroup)); + sponsor_message->set_do_not_show_message_again(QLatin1String(MainWindowSettings::kDoNotShowSponsorMessage)); sponsor_message->setAttribute(Qt::WA_DeleteOnClose); sponsor_message->ShowMessage(tr("Sponsoring Strawberry"), tr("Strawberry is free and open source software. If you like Strawberry, please consider sponsoring the project. For more information about sponsorship see our website %1").arg(u"www.strawberrymusicplayer.org"_s), IconLoader::Load(u"dialog-information"_s)); } @@ -1083,8 +1102,8 @@ void MainWindow::ReloadSettings() { constexpr bool keeprunning_available = true; #else const bool systemtray_available = tray_icon_->IsSystemTrayAvailable(); - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - const bool showtrayicon = s.value("showtrayicon", systemtray_available).toBool(); + s.beginGroup(BehaviourSettings::kSettingsGroup); + const bool showtrayicon = s.value(BehaviourSettings::kShowTrayIcon, systemtray_available).toBool(); s.endGroup(); const bool keeprunning_available = systemtray_available && showtrayicon; if (systemtray_available) { @@ -1095,22 +1114,22 @@ void MainWindow::ReloadSettings() { } #endif - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - keep_running_ = keeprunning_available && s.value("keeprunning", false).toBool(); - playing_widget_ = s.value("playing_widget", true).toBool(); - bool trayicon_progress = s.value("trayicon_progress", false).toBool(); + s.beginGroup(BehaviourSettings::kSettingsGroup); + keep_running_ = keeprunning_available && s.value(BehaviourSettings::kKeepRunning, false).toBool(); + playing_widget_ = s.value(BehaviourSettings::kPlayingWidget, true).toBool(); + bool trayicon_progress = s.value(BehaviourSettings::kTrayIconProgress, false).toBool(); #ifdef HAVE_DBUS - const bool taskbar_progress = s.value("taskbar_progress", true).toBool(); + const bool taskbar_progress = s.value(BehaviourSettings::kTaskbarProgress, true).toBool(); #endif if (playing_widget_ != ui_->widget_playing->IsEnabled()) TabSwitched(); - doubleclick_addmode_ = static_cast(s.value("doubleclick_addmode", static_cast(BehaviourSettingsPage::AddBehaviour::Append)).toInt()); - doubleclick_playmode_ = static_cast(s.value("doubleclick_playmode", static_cast(BehaviourSettingsPage::PlayBehaviour::Never)).toInt()); - doubleclick_playlist_addmode_ = static_cast(s.value("doubleclick_playlist_addmode", static_cast(BehaviourSettingsPage::PlayBehaviour::Never)).toInt()); - menu_playmode_ = static_cast(s.value("menu_playmode", static_cast(BehaviourSettingsPage::PlayBehaviour::Never)).toInt()); + doubleclick_addmode_ = static_cast(s.value(BehaviourSettings::kDoubleClickAddMode, static_cast(BehaviourSettings::AddBehaviour::Append)).toInt()); + doubleclick_playmode_ = static_cast(s.value(BehaviourSettings::kDoubleClickPlayMode, static_cast(BehaviourSettings::PlayBehaviour::Never)).toInt()); + doubleclick_playlist_addmode_ = static_cast(s.value(BehaviourSettings::kDoubleClickPlaylistAddMode, static_cast(BehaviourSettings::PlayBehaviour::Never)).toInt()); + menu_playmode_ = static_cast(s.value(BehaviourSettings::kMenuPlayMode, static_cast(BehaviourSettings::PlayBehaviour::Never)).toInt()); s.endGroup(); - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizePlayControlButtons, 32).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizePlayControlButtons, 32).toInt(); s.endGroup(); tray_icon_->SetTrayiconProgress(trayicon_progress); @@ -1128,7 +1147,7 @@ void MainWindow::ReloadSettings() { ui_->forward_button->setIconSize(QSize(iconsize, iconsize)); ui_->button_love->setIconSize(QSize(iconsize, iconsize)); - s.beginGroup(BackendSettingsPage::kSettingsGroup); + s.beginGroup(BackendSettings::kSettingsGroup); bool volume_control = s.value("volume_control", true).toBool(); s.endGroup(); if (volume_control != ui_->volume->isEnabled()) { @@ -1143,17 +1162,17 @@ void MainWindow::ReloadSettings() { } } - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - delete_files_ = s.value("delete_files", false).toBool(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + delete_files_ = s.value(PlaylistSettings::kDeleteFiles, false).toBool(); s.endGroup(); osd_->ReloadSettings(); - album_cover_choice_controller_->search_cover_auto_action()->setChecked(settings_.value("search_for_cover_auto", true).toBool()); + album_cover_choice_controller_->search_cover_auto_action()->setChecked(settings_.value(MainWindowSettings::kSearchForCoverAuto, true).toBool()); #ifdef HAVE_SUBSONIC - s.beginGroup(SubsonicSettingsPage::kSettingsGroup); - bool enable_subsonic = s.value("enabled", false).toBool(); + s.beginGroup(SubsonicSettings::kSettingsGroup); + bool enable_subsonic = s.value(SubsonicSettings::kEnabled, false).toBool(); s.endGroup(); if (enable_subsonic) { ui_->tabs->EnableTab(subsonic_view_); @@ -1164,8 +1183,8 @@ void MainWindow::ReloadSettings() { #endif #ifdef HAVE_TIDAL - s.beginGroup(TidalSettingsPage::kSettingsGroup); - bool enable_tidal = s.value("enabled", false).toBool(); + s.beginGroup(TidalSettings::kSettingsGroup); + bool enable_tidal = s.value(TidalSettings::kEnabled, false).toBool(); s.endGroup(); if (enable_tidal) { ui_->tabs->EnableTab(tidal_view_); @@ -1176,8 +1195,8 @@ void MainWindow::ReloadSettings() { #endif #ifdef HAVE_SPOTIFY - s.beginGroup(SpotifySettingsPage::kSettingsGroup); - bool enable_spotify = s.value("enabled", false).toBool(); + s.beginGroup(SpotifySettings::kSettingsGroup); + bool enable_spotify = s.value(SpotifySettings::kEnabled, false).toBool(); s.endGroup(); if (enable_spotify) { ui_->tabs->EnableTab(spotify_view_); @@ -1188,8 +1207,8 @@ void MainWindow::ReloadSettings() { #endif #ifdef HAVE_QOBUZ - s.beginGroup(QobuzSettingsPage::kSettingsGroup); - bool enable_qobuz = s.value("enabled", false).toBool(); + s.beginGroup(QobuzSettings::kSettingsGroup); + bool enable_qobuz = s.value(QobuzSettings::kEnabled, false).toBool(); s.endGroup(); if (enable_qobuz) { ui_->tabs->EnableTab(qobuz_view_); @@ -1208,7 +1227,6 @@ void MainWindow::ReloadAllSettings() { ReloadSettings(); // Other settings - app_->ReloadSettings(); app_->collection()->ReloadSettings(); app_->player()->ReloadSettings(); collection_view_->ReloadSettings(); @@ -1228,18 +1246,23 @@ void MainWindow::ReloadAllSettings() { app_->lyrics_providers()->ReloadSettings(); #ifdef HAVE_MOODBAR app_->moodbar_controller()->ReloadSettings(); + app_->moodbar_loader()->ReloadSettings(); + ui_->track_slider->moodbar_proxy_style()->ReloadSettings(); #endif #ifdef HAVE_SUBSONIC subsonic_view_->ReloadSettings(); #endif #ifdef HAVE_TIDAL tidal_view_->ReloadSettings(); + tidal_view_->search_view()->ReloadSettings(); #endif #ifdef HAVE_SPOTIFY spotify_view_->ReloadSettings(); + spotify_view_->search_view()->ReloadSettings(); #endif #ifdef HAVE_QOBUZ qobuz_view_->ReloadSettings(); + qobuz_view_->search_view()->ReloadSettings(); #endif } @@ -1255,12 +1278,12 @@ void MainWindow::SaveSettings() { SaveGeometry(); app_->player()->SaveVolume(); app_->player()->SavePlaybackStatus(); - ui_->tabs->SaveSettings(QLatin1String(kSettingsGroup)); + ui_->tabs->SaveSettings(QLatin1String(MainWindowSettings::kSettingsGroup)); ui_->playlist->view()->SaveSettings(); app_->scrobbler()->WriteCache(); - settings_.setValue("show_sidebar", ui_->action_toggle_show_sidebar->isChecked()); - settings_.setValue("search_for_cover_auto", album_cover_choice_controller_->search_cover_auto_action()->isChecked()); + settings_.setValue(MainWindowSettings::kShowSidebar, ui_->action_toggle_show_sidebar->isChecked()); + settings_.setValue(MainWindowSettings::kSearchForCoverAuto, album_cover_choice_controller_->search_cover_auto_action()->isChecked()); } @@ -1500,23 +1523,23 @@ void MainWindow::ToggleSidebar(const bool checked) { ui_->sidebar_layout->setVisible(checked); TabSwitched(); - settings_.setValue("show_sidebar", checked); + settings_.setValue(MainWindowSettings::kShowSidebar, checked); } void MainWindow::ToggleSearchCoverAuto(const bool checked) { - settings_.setValue("search_for_cover_auto", checked); + settings_.setValue(MainWindowSettings::kSearchForCoverAuto, checked); } void MainWindow::SaveGeometry() { if (!initialized_) return; - settings_.setValue("maximized", isMaximized()); - settings_.setValue("minimized", isMinimized()); - settings_.setValue("hidden", isHidden()); - settings_.setValue("geometry", saveGeometry()); - settings_.setValue("splitter_state", ui_->splitter->saveState()); + settings_.setValue(MainWindowSettings::kMaximized, isMaximized()); + settings_.setValue(MainWindowSettings::kMinimized, isMinimized()); + settings_.setValue(MainWindowSettings::kHidden, isHidden()); + settings_.setValue(MainWindowSettings::kGeometry, saveGeometry()); + settings_.setValue(MainWindowSettings::kSplitterState, ui_->splitter->saveState()); } @@ -1546,12 +1569,12 @@ void MainWindow::PlaylistDoubleClick(const QModelIndex &idx) { } switch (doubleclick_playlist_addmode_) { - case BehaviourSettingsPage::PlaylistAddBehaviour::Play: + case BehaviourSettings::PlaylistAddBehaviour::Play: app_->playlist_manager()->SetActiveToCurrent(); app_->player()->PlayAt(source_idx.row(), false, 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true); break; - case BehaviourSettingsPage::PlaylistAddBehaviour::Enqueue: + case BehaviourSettings::PlaylistAddBehaviour::Enqueue: app_->playlist_manager()->current()->queue()->ToggleTracks(QModelIndexList() << source_idx); if (app_->player()->GetState() != EngineBase::State::Playing) { app_->playlist_manager()->SetActiveToCurrent(); @@ -1724,42 +1747,42 @@ void MainWindow::UpdateTaskbarProgress(const bool visible, const double progress } #endif -void MainWindow::ApplyAddBehaviour(const BehaviourSettingsPage::AddBehaviour b, MimeData *mimedata) { +void MainWindow::ApplyAddBehaviour(const BehaviourSettings::AddBehaviour b, MimeData *mimedata) { switch (b) { - case BehaviourSettingsPage::AddBehaviour::Append: + case BehaviourSettings::AddBehaviour::Append: mimedata->clear_first_ = false; mimedata->enqueue_now_ = false; break; - case BehaviourSettingsPage::AddBehaviour::Enqueue: + case BehaviourSettings::AddBehaviour::Enqueue: mimedata->clear_first_ = false; mimedata->enqueue_now_ = true; break; - case BehaviourSettingsPage::AddBehaviour::Load: + case BehaviourSettings::AddBehaviour::Load: mimedata->clear_first_ = true; mimedata->enqueue_now_ = false; break; - case BehaviourSettingsPage::AddBehaviour::OpenInNew: + case BehaviourSettings::AddBehaviour::OpenInNew: mimedata->open_in_new_playlist_ = true; break; } } -void MainWindow::ApplyPlayBehaviour(const BehaviourSettingsPage::PlayBehaviour b, MimeData *mimedata) const { +void MainWindow::ApplyPlayBehaviour(const BehaviourSettings::PlayBehaviour b, MimeData *mimedata) const { switch (b) { - case BehaviourSettingsPage::PlayBehaviour::Always: + case BehaviourSettings::PlayBehaviour::Always: mimedata->play_now_ = true; break; - case BehaviourSettingsPage::PlayBehaviour::Never: + case BehaviourSettings::PlayBehaviour::Never: mimedata->play_now_ = false; break; - case BehaviourSettingsPage::PlayBehaviour::IfStopped: + case BehaviourSettings::PlayBehaviour::IfStopped: mimedata->play_now_ = !(app_->player()->GetState() == EngineBase::State::Playing); break; } @@ -1814,7 +1837,7 @@ void MainWindow::AddToPlaylistFromAction(QAction *action) { // Save the current playlist to reactivate it const int current_id = app_->playlist_manager()->current_id(); // Get the name from selection - app_->playlist_manager()->New(app_->playlist_manager()->GetNameForNewPlaylist(songs)); + app_->playlist_manager()->New(Song::GetNameForNewPlaylist(songs)); if (app_->playlist_manager()->current()->id() != current_id) { // I'm sure the new playlist was created and is selected, so I can just insert items app_->playlist_manager()->current()->InsertItems(items); @@ -2161,7 +2184,7 @@ void MainWindow::RenumberTracks() { Song song = item->OriginalMetadata(); if (song.IsEditable()) { song.set_track(track); - TagReaderReplyPtr reply = TagReaderClient::Instance()->WriteFileAsync(song.url().toLocalFile(), song); + TagReaderReplyPtr reply = app_->tagreader_client()->WriteFileAsync(song.url().toLocalFile(), song); QPersistentModelIndex persistent_index = QPersistentModelIndex(source_index); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, persistent_index]() { SongSaveComplete(reply, persistent_index); }, Qt::QueuedConnection); } @@ -2192,7 +2215,7 @@ void MainWindow::SelectionSetValue() { Song song = item->OriginalMetadata(); if (!song.is_valid()) continue; if (song.url().isLocalFile() && Playlist::set_column_value(song, column, column_value)) { - TagReaderReplyPtr reply = TagReaderClient::Instance()->WriteFileAsync(song.url().toLocalFile(), song); + TagReaderReplyPtr reply = app_->tagreader_client()->WriteFileAsync(song.url().toLocalFile(), song); QPersistentModelIndex persistent_index = QPersistentModelIndex(source_index); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, persistent_index]() { SongSaveComplete(reply, persistent_index); }, Qt::QueuedConnection); } @@ -2228,10 +2251,10 @@ void MainWindow::AddFile() { // Last used directory QString directory = settings_.value("add_media_path", QDir::currentPath()).toString(); - PlaylistParser parser(app_->collection_backend()); + PlaylistParser parser(app_->tagreader_client(), app_->collection_backend()); // Show dialog - const QStringList filenames = QFileDialog::getOpenFileNames(this, tr("Add file"), directory, QStringLiteral("%1 (%2);;%3;;%4").arg(tr("Music"), QLatin1String(FileView::kFileFilter), parser.filters(PlaylistParser::Type::Load), tr(kAllFilesFilterSpec))); + const QStringList filenames = QFileDialog::getOpenFileNames(this, tr("Add file"), directory, QStringLiteral("%1 (%2);;%3;;%4").arg(tr("Music"), QLatin1String(kFileFilter), parser.filters(PlaylistParser::Type::Load), tr(kAllFilesFilterSpec))); if (filenames.isEmpty()) return; @@ -2470,7 +2493,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) { break; case CommandlineOptions::UrlListAction::CreateNew: mimedata->name_for_new_playlist_ = options.playlist_name(); - ApplyAddBehaviour(BehaviourSettingsPage::AddBehaviour::OpenInNew, mimedata); + ApplyAddBehaviour(BehaviourSettings::AddBehaviour::OpenInNew, mimedata); break; } @@ -2563,10 +2586,34 @@ void MainWindow::AddFilesToTranscoder() { } -void MainWindow::ShowCollectionConfig() { +void MainWindow::OpenCollectionSettingsDialog() { settings_dialog_->OpenAtPage(SettingsDialog::Page::Collection); } +void MainWindow::OpenServiceSettingsDialog(const Song::Source source) { + + switch (source) { + case Song::Source::Collection: + settings_dialog_->OpenAtPage(SettingsDialog::Page::Collection); + break; + case Song::Source::Subsonic: + settings_dialog_->OpenAtPage(SettingsDialog::Page::Subsonic); + break; + case Song::Source::Tidal: + settings_dialog_->OpenAtPage(SettingsDialog::Page::Tidal); + break; + case Song::Source::Qobuz: + settings_dialog_->OpenAtPage(SettingsDialog::Page::Qobuz); + break; + case Song::Source::Spotify: + settings_dialog_->OpenAtPage(SettingsDialog::Page::Spotify); + break; + default: + break; + } + +} + void MainWindow::TaskCountChanged(const int count) { if (count == 0) { @@ -2810,7 +2857,7 @@ void MainWindow::ShowEqualizer() { SettingsDialog *MainWindow::CreateSettingsDialog() { - SettingsDialog *settings_dialog = new SettingsDialog(app_, osd_, this); + SettingsDialog *settings_dialog = new SettingsDialog(app_->player(), app_->device_finders(), app_->collection(), app_->cover_providers(), app_->lyrics_providers(), app_->scrobbler(), app_->streaming_services(), osd_, this); #ifdef HAVE_GLOBALSHORTCUTS settings_dialog->SetGlobalShortcutManager(globalshortcuts_manager_); #endif @@ -2838,7 +2885,7 @@ void MainWindow::OpenSettingsDialogAtPage(SettingsDialog::Page page) { EditTagDialog *MainWindow::CreateEditTagDialog() { - EditTagDialog *edit_tag_dialog = new EditTagDialog(app_); + EditTagDialog *edit_tag_dialog = new EditTagDialog(app_->network(), app_->tagreader_client(), app_->collection_backend(), app_->albumcover_loader(), app_->current_albumcover_loader(), app_->cover_providers(), app_->lyrics_providers(), app_->streaming_services()); QObject::connect(edit_tag_dialog, &EditTagDialog::accepted, this, &MainWindow::EditTagDialogAccepted); QObject::connect(edit_tag_dialog, &EditTagDialog::Error, this, &MainWindow::ShowErrorDialog); return edit_tag_dialog; @@ -2938,7 +2985,7 @@ void MainWindow::AutoCompleteTags() { // Create the tag fetching stuff if it hasn't been already if (!tag_fetcher_) { tag_fetcher_ = make_unique(app_->network()); - track_selection_dialog_ = make_unique(); + track_selection_dialog_ = make_unique(app_->tagreader_client()); track_selection_dialog_->set_save_on_close(true); QObject::connect(&*tag_fetcher_, &TagFetcher::ResultAvailable, &*track_selection_dialog_, &TrackSelectionDialog::FetchTagFinished, Qt::QueuedConnection); @@ -2986,7 +3033,7 @@ void MainWindow::AutoCompleteTagsAccepted() { } -void MainWindow::HandleNotificationPreview(const OSDBase::Behaviour type, const QString &line1, const QString &line2) { +void MainWindow::HandleNotificationPreview(const OSDSettings::Type type, const QString &line1, const QString &line2) { if (!app_->playlist_manager()->current()->GetAllSongs().isEmpty()) { // Show a preview notification for the first song in the current playlist diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h index edd5e65546..648f165975 100644 --- a/src/core/mainwindow.h +++ b/src/core/mainwindow.h @@ -46,19 +46,19 @@ #include #include -#include "scoped_ptr.h" -#include "shared_ptr.h" -#include "lazy.h" -#include "platforminterface.h" -#include "song.h" -#include "settings.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" +#include "includes/lazy.h" +#include "core/platforminterface.h" +#include "core/song.h" +#include "core/settings.h" #include "tagreader/tagreaderclient.h" #include "engine/enginebase.h" #include "osd/osdbase.h" #include "playlist/playlist.h" #include "playlist/playlistitem.h" #include "settings/settingsdialog.h" -#include "settings/behavioursettingspage.h" +#include "constants/behavioursettings.h" #include "covermanager/albumcoverloaderresult.h" #include "covermanager/albumcoverimageresult.h" @@ -107,9 +107,6 @@ class MainWindow : public QMainWindow, public PlatformInterface { explicit MainWindow(Application *app, SharedPtr tray_icon, OSDBase *osd, const CommandlineOptions &options, QWidget *parent = nullptr); ~MainWindow() override; - static const char *kSettingsGroup; - static const char *kAllFilesFilterSpec; - void SetHiddenInTray(const bool hidden); void CommandlineOptionsReceived(const CommandlineOptions &options); @@ -202,7 +199,9 @@ class MainWindow : public QMainWindow, public PlatformInterface { void TaskCountChanged(const int count); - void ShowCollectionConfig(); + void OpenCollectionSettingsDialog(); + void OpenServiceSettingsDialog(const Song::Source source); + void ReloadSettings(); void ReloadAllSettings(); void RefreshStyleSheet(); @@ -237,7 +236,7 @@ class MainWindow : public QMainWindow, public PlatformInterface { void Exit(); void DoExit(); - void HandleNotificationPreview(const OSDBase::Behaviour type, const QString &line1, const QString &line2); + void HandleNotificationPreview(const OSDSettings::Type type, const QString &line1, const QString &line2); void ShowConsole(); @@ -274,8 +273,8 @@ class MainWindow : public QMainWindow, public PlatformInterface { void SaveSettings(); - static void ApplyAddBehaviour(const BehaviourSettingsPage::AddBehaviour b, MimeData *mimedata); - void ApplyPlayBehaviour(const BehaviourSettingsPage::PlayBehaviour b, MimeData *mimedata) const; + static void ApplyAddBehaviour(const BehaviourSettings::AddBehaviour b, MimeData *mimedata); + void ApplyPlayBehaviour(const BehaviourSettings::PlayBehaviour b, MimeData *mimedata) const; void CheckFullRescanRevisions(); @@ -385,10 +384,10 @@ class MainWindow : public QMainWindow, public PlatformInterface { #ifdef HAVE_DBUS bool taskbar_progress_; #endif - BehaviourSettingsPage::AddBehaviour doubleclick_addmode_; - BehaviourSettingsPage::PlayBehaviour doubleclick_playmode_; - BehaviourSettingsPage::PlaylistAddBehaviour doubleclick_playlist_addmode_; - BehaviourSettingsPage::PlayBehaviour menu_playmode_; + BehaviourSettings::AddBehaviour doubleclick_addmode_; + BehaviourSettings::PlayBehaviour doubleclick_playmode_; + BehaviourSettings::PlaylistAddBehaviour doubleclick_playlist_addmode_; + BehaviourSettings::PlayBehaviour menu_playmode_; bool initialized_; bool was_maximized_; diff --git a/src/core/memorydatabase.cpp b/src/core/memorydatabase.cpp new file mode 100644 index 0000000000..d4156e2eef --- /dev/null +++ b/src/core/memorydatabase.cpp @@ -0,0 +1,30 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "memorydatabase.h" + +using namespace Qt::Literals::StringLiterals; + +MemoryDatabase::MemoryDatabase(SharedPtr task_manager, QObject *parent) + : Database(task_manager, parent, u":memory:"_s) {} + +MemoryDatabase::~MemoryDatabase() { + // Make sure Qt doesn't reuse the same database + Close(); +} diff --git a/src/core/memorydatabase.h b/src/core/memorydatabase.h new file mode 100644 index 0000000000..49439a68f8 --- /dev/null +++ b/src/core/memorydatabase.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef MEMORYDATABASE_H +#define MEMORYDATABASE_H + +#include "includes/shared_ptr.h" + +class TaskManager; + +#include "database.h" + +class MemoryDatabase : public Database { + Q_OBJECT + + public: + explicit MemoryDatabase(SharedPtr task_manager, QObject *parent = nullptr); + ~MemoryDatabase() override; +}; + +#endif // MEMORYDATABASE_H diff --git a/src/core/mergedproxymodel.h b/src/core/mergedproxymodel.h index fdb6053c79..9ef897f4b9 100644 --- a/src/core/mergedproxymodel.h +++ b/src/core/mergedproxymodel.h @@ -35,7 +35,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class QMimeData; diff --git a/src/core/metatypes.cpp b/src/core/metatypes.cpp index 3f76fec6c5..551fe30878 100644 --- a/src/core/metatypes.cpp +++ b/src/core/metatypes.cpp @@ -43,10 +43,9 @@ # include #endif -#include "song.h" - +#include "core/song.h" +#include "core/enginemetadata.h" #include "engine/enginebase.h" -#include "engine/enginemetadata.h" #include "engine/gstenginepipeline.h" #include "collection/collectiondirectory.h" #include "playlist/playlistitem.h" @@ -57,7 +56,7 @@ #include "equalizer/equalizer.h" #ifdef HAVE_DBUS -# include "dbus_metatypes.h" +# include "includes/dbus_metatypes.h" #endif #ifdef HAVE_MPRIS2 @@ -74,7 +73,7 @@ # include "device/mtpconnection.h" #endif -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "smartplaylists/smartplaylistsearchterm.h" #include "smartplaylists/smartplaylistsitem.h" @@ -153,7 +152,7 @@ void RegisterMetaTypes() { qRegisterMetaType("MtpConnection*"); #endif - qRegisterMetaType("PlaylistSettingsPage::PathType"); + qRegisterMetaType("PlaylistSettings::PathType"); qRegisterMetaType("PlaylistGeneratorPtr"); qRegisterMetaType("SmartPlaylistSearchTerm::Field"); diff --git a/src/core/musicstorage.h b/src/core/musicstorage.h index 3d7e607481..afe5fafc80 100644 --- a/src/core/musicstorage.h +++ b/src/core/musicstorage.h @@ -35,7 +35,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" #include "song.h" class MusicStorage { diff --git a/src/core/platforminterface.cpp b/src/core/platforminterface.cpp new file mode 100644 index 0000000000..a6f1339f90 --- /dev/null +++ b/src/core/platforminterface.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include +#include + +#include "platforminterface.h" + +PlatformInterface::PlatformInterface() = default; +PlatformInterface::~PlatformInterface() {} diff --git a/src/core/platforminterface.h b/src/core/platforminterface.h index ed8e902734..c2188e5a18 100644 --- a/src/core/platforminterface.h +++ b/src/core/platforminterface.h @@ -1,7 +1,6 @@ /* * Strawberry Music Player - * Copyright 2010, David Sansome - * Copyright 2018-2021, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +25,8 @@ class PlatformInterface { public: - PlatformInterface() = default; - virtual ~PlatformInterface() {} + explicit PlatformInterface(); + virtual ~PlatformInterface(); // Called when the application should show itself. virtual void Activate() = 0; diff --git a/src/core/player.cpp b/src/core/player.cpp index 8c9f19506b..aa76575d3b 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -37,18 +37,21 @@ #include #include +#include "constants/behavioursettings.h" +#include "constants/backendsettings.h" +#include "constants/playlistsettings.h" +#include "constants/timeconstants.h" + +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/settings.h" -#include "utilities/timeconstants.h" - -#include "scoped_ptr.h" -#include "shared_ptr.h" -#include "song.h" -#include "urlhandler.h" -#include "application.h" +#include "core/song.h" +#include "core/urlhandlers.h" +#include "core/urlhandler.h" +#include "core/enginemetadata.h" #include "engine/enginebase.h" -#include "engine/enginemetadata.h" #include "engine/gstengine.h" #include "engine/gststartup.h" @@ -60,18 +63,22 @@ #include "playlist/playlistsequence.h" #include "equalizer/equalizer.h" #include "analyzer/analyzercontainer.h" -#include "settings/backendsettingspage.h" -#include "settings/behavioursettingspage.h" -#include "settings/playlistsettingspage.h" using namespace std::chrono_literals; -using std::make_shared; -const char *Player::kSettingsGroup = "Player"; +namespace { +constexpr char kSettingsGroup[] = "Player"; +constexpr char kVolume[] = "volume"; +constexpr char kPlaybackState[] = "playback_state"; +constexpr char kPlaybackPlaylist[] = "playback_playlist"; +constexpr char kPlaybackPosition[] = "playback_position"; +} // namespace -Player::Player(Application *app, QObject *parent) +Player::Player(SharedPtr task_manager, SharedPtr url_handlers, SharedPtr playlist_manager, QObject *parent) : PlayerInterface(parent), - app_(app), + task_manager_(task_manager), + url_handlers_(url_handlers), + playlist_manager_(playlist_manager), engine_(nullptr), gst_startup_(new GstStartup(this)), analyzer_(nullptr), @@ -89,7 +96,7 @@ Player::Player(Application *app, QObject *parent) last_pressed_previous_(QDateTime::currentDateTime()), continue_on_error_(false), greyout_(true), - menu_previousmode_(BehaviourSettingsPage::PreviousBehaviour::DontRestart), + menu_previousmode_(BehaviourSettings::PreviousBehaviour::DontRestart), seek_step_sec_(10), volume_increment_(5), play_offset_nanosec_(0) { @@ -97,8 +104,8 @@ Player::Player(Application *app, QObject *parent) setObjectName(QLatin1String(metaObject()->className())); Settings s; - s.beginGroup(BackendSettingsPage::kSettingsGroup); - EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); + s.beginGroup(BackendSettings::kSettingsGroup); + EngineBase::Type enginetype = EngineBase::TypeFromName(s.value(BackendSettings::kEngine, EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); s.endGroup(); CreateEngine(enginetype); @@ -107,6 +114,8 @@ Player::Player(Application *app, QObject *parent) timer_save_volume_->setInterval(5s); QObject::connect(timer_save_volume_, &QTimer::timeout, this, &Player::SaveVolume); + QObject::connect(&*url_handlers, &UrlHandlers::Registered, this, &Player::UrlHandlerRegistered); + } EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { @@ -118,7 +127,7 @@ EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { case EngineBase::Type::None: case EngineBase::Type::GStreamer:{ use_enginetype=EngineBase::Type::GStreamer; - ScopedPtr gst_engine(new GstEngine(app_->task_manager())); + ScopedPtr gst_engine(new GstEngine(task_manager_)); gst_engine->SetStartup(gst_startup_); engine_.reset(gst_engine.release()); break; @@ -134,10 +143,10 @@ EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { if (use_enginetype != enginetype) { // Engine was set to something else. Reset output and device. Settings s; - s.beginGroup(BackendSettingsPage::kSettingsGroup); - s.setValue("engine", EngineBase::Name(use_enginetype)); - s.setValue("output", engine_->DefaultOutput()); - s.setValue("device", QVariant()); + s.beginGroup(BackendSettings::kSettingsGroup); + s.setValue(BackendSettings::kEngine, EngineBase::Name(use_enginetype)); + s.setValue(BackendSettings::kOutput, engine_->DefaultOutput()); + s.setValue(BackendSettings::kDevice, QVariant()); s.endGroup(); } @@ -156,7 +165,7 @@ void Player::Init() { Settings s; if (!engine_) { - s.beginGroup(BackendSettingsPage::kSettingsGroup); + s.beginGroup(BackendSettings::kSettingsGroup); EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); s.endGroup(); CreateEngine(enginetype); @@ -179,10 +188,10 @@ void Player::Init() { QObject::connect(&*engine_, &EngineBase::VolumeChanged, this, &Player::SetVolumeFromEngine); // Equalizer - QObject::connect(&*equalizer_, &Equalizer::StereoBalancerEnabledChanged, &*app_->player()->engine(), &EngineBase::SetStereoBalancerEnabled); - QObject::connect(&*equalizer_, &Equalizer::StereoBalanceChanged, &*app_->player()->engine(), &EngineBase::SetStereoBalance); - QObject::connect(&*equalizer_, &Equalizer::EqualizerEnabledChanged, &*app_->player()->engine(), &EngineBase::SetEqualizerEnabled); - QObject::connect(&*equalizer_, &Equalizer::EqualizerParametersChanged, &*app_->player()->engine(), &EngineBase::SetEqualizerParameters); + QObject::connect(&*equalizer_, &Equalizer::StereoBalancerEnabledChanged, &*engine_, &EngineBase::SetStereoBalancerEnabled); + QObject::connect(&*equalizer_, &Equalizer::StereoBalanceChanged, &*engine_, &EngineBase::SetStereoBalance); + QObject::connect(&*equalizer_, &Equalizer::EqualizerEnabledChanged, &*engine_, &EngineBase::SetEqualizerEnabled); + QObject::connect(&*equalizer_, &Equalizer::EqualizerParametersChanged, &*engine_, &EngineBase::SetEqualizerParameters); engine_->SetStereoBalancerEnabled(equalizer_->is_stereo_balancer_enabled()); engine_->SetStereoBalance(equalizer_->stereo_balance()); @@ -199,26 +208,32 @@ void Player::ReloadSettings() { Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); + s.beginGroup(PlaylistSettings::kSettingsGroup); continue_on_error_ = s.value("continue_on_error", false).toBool(); greyout_ = s.value("greyout_songs_play", true).toBool(); s.endGroup(); - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - menu_previousmode_ = static_cast(s.value("menu_previousmode", static_cast(BehaviourSettingsPage::PreviousBehaviour::DontRestart)).toInt()); - seek_step_sec_ = s.value("seek_step_sec", 10).toInt(); - volume_increment_ = s.value("volume_increment", 5).toUInt(); + s.beginGroup(BehaviourSettings::kSettingsGroup); + menu_previousmode_ = static_cast(s.value(BehaviourSettings::kMenuPreviousMode, static_cast(BehaviourSettings::PreviousBehaviour::DontRestart)).toInt()); + seek_step_sec_ = s.value(BehaviourSettings::kSeekStepSec, 10).toInt(); + volume_increment_ = s.value(BehaviourSettings::kVolumeIncrement, 5).toUInt(); s.endGroup(); engine_->ReloadSettings(); } +void Player::UrlHandlerRegistered(UrlHandler *url_handler) { + + QObject::connect(url_handler, &UrlHandler::AsyncLoadComplete, this, &Player::HandleLoadResult); + +} + void Player::LoadVolume() { Settings s; s.beginGroup(kSettingsGroup); - const uint volume = s.value("volume", 100).toInt(); + const uint volume = s.value(kVolume, 100).toInt(); s.endGroup(); SetVolume(volume); @@ -229,7 +244,7 @@ void Player::SaveVolume() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("volume", volume_); + s.setValue(kVolume, volume_); s.endGroup(); } @@ -239,14 +254,14 @@ void Player::SavePlaybackStatus() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("playback_state", static_cast(app_->player()->GetState())); - if (app_->player()->GetState() == EngineBase::State::Playing || app_->player()->GetState() == EngineBase::State::Paused) { - s.setValue("playback_playlist", app_->playlist_manager()->active()->id()); - s.setValue("playback_position", app_->player()->engine()->position_nanosec() / kNsecPerSec); + s.setValue(kPlaybackState, static_cast(GetState())); + if (GetState() == EngineBase::State::Playing || GetState() == EngineBase::State::Paused) { + s.setValue(kPlaybackPlaylist, playlist_manager_->active()->id()); + s.setValue(kPlaybackPosition, engine_->position_nanosec() / kNsecPerSec); } else { - s.setValue("playback_playlist", -1); - s.setValue("playback_position", 0); + s.setValue(kPlaybackPlaylist, -1); + s.setValue(kPlaybackPosition, 0); } s.endGroup(); @@ -258,12 +273,12 @@ void Player::PlaylistsLoaded() { Settings s; - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); + s.beginGroup(BehaviourSettings::kSettingsGroup); const bool resume_playback = s.value("resumeplayback", false).toBool(); s.endGroup(); - s.beginGroup(Player::kSettingsGroup); - const EngineBase::State playback_state = static_cast(s.value("playback_state", static_cast(EngineBase::State::Empty)).toInt()); + s.beginGroup(kSettingsGroup); + const EngineBase::State playback_state = static_cast(s.value(kPlaybackState, static_cast(EngineBase::State::Empty)).toInt()); s.endGroup(); if (resume_playback && (playback_state == EngineBase::State::Playing || playback_state == EngineBase::State::Paused)) { @@ -283,14 +298,14 @@ void Player::ResumePlayback() { Settings s; s.beginGroup(kSettingsGroup); - const EngineBase::State playback_state = static_cast(s.value("playback_state", static_cast(EngineBase::State::Empty)).toInt()); - const int playback_playlist = s.value("playback_playlist", -1).toInt(); - const int playback_position = s.value("playback_position", 0).toInt(); + const EngineBase::State playback_state = static_cast(s.value(kPlaybackState, static_cast(EngineBase::State::Empty)).toInt()); + const int playback_playlist = s.value(kPlaybackPlaylist, -1).toInt(); + const int playback_position = s.value(kPlaybackPosition, 0).toInt(); s.endGroup(); - if (playback_playlist == app_->playlist_manager()->current()->id()) { + if (playback_playlist == playlist_manager_->current()->id()) { // Set active to current to resume playback on correct playlist. - app_->playlist_manager()->SetActiveToCurrent(); + playlist_manager_->SetActiveToCurrent(); if (playback_state == EngineBase::State::Playing) { Play(playback_position * kNsecPerSec); } @@ -301,9 +316,9 @@ void Player::ResumePlayback() { // Reset saved playback status so we don't resume again from the same position. s.beginGroup(kSettingsGroup); - s.setValue("playback_state", static_cast(EngineBase::State::Empty)); - s.setValue("playback_playlist", -1); - s.setValue("playback_position", 0); + s.setValue(kPlaybackState, static_cast(EngineBase::State::Empty)); + s.setValue(kPlaybackPlaylist, -1); + s.setValue(kPlaybackPosition, 0); s.endGroup(); } @@ -315,19 +330,19 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { } // Might've been an async load, so check we're still on the same item - const int current_row = app_->playlist_manager()->active()->current_row(); + const int current_row = playlist_manager_->active()->current_row(); if (current_row == -1) { return; } - PlaylistItemPtr current_item = app_->playlist_manager()->active()->current_item(); + PlaylistItemPtr current_item = playlist_manager_->active()->current_item(); if (!current_item) { return; } - int next_row = app_->playlist_manager()->active()->next_row(); + int next_row = playlist_manager_->active()->next_row(); const bool has_next_row = next_row != -1; PlaylistItemPtr next_item; if (has_next_row) { - next_item = app_->playlist_manager()->active()->item_at(next_row); + next_item = playlist_manager_->active()->item_at(next_row); } bool is_current = false; @@ -408,10 +423,10 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { if (update) { if (is_current) { - app_->playlist_manager()->active()->UpdateItemMetadata(current_row, current_item, song, true); + playlist_manager_->active()->UpdateItemMetadata(current_row, current_item, song, true); } else if (is_next) { - app_->playlist_manager()->active()->UpdateItemMetadata(next_row, next_item, song, true); + playlist_manager_->active()->UpdateItemMetadata(next_row, next_item, song, true); } } @@ -457,13 +472,13 @@ void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist: pause_time_ = QDateTime(); play_offset_nanosec_ = 0; - Playlist *active_playlist = app_->playlist_manager()->active(); + Playlist *active_playlist = playlist_manager_->active(); // If we received too many errors in auto change, with repeat enabled, we stop if (change & EngineBase::TrackChangeType::Auto) { const PlaylistSequence::RepeatMode repeat_mode = active_playlist->RepeatMode(); if (repeat_mode != PlaylistSequence::RepeatMode::Off) { - if ((repeat_mode == PlaylistSequence::RepeatMode::Track && nb_errors_received_ >= 3) || (nb_errors_received_ >= app_->playlist_manager()->active()->filter()->rowCount())) { + if ((repeat_mode == PlaylistSequence::RepeatMode::Track && nb_errors_received_ >= 3) || (nb_errors_received_ >= playlist_manager_->active()->filter()->rowCount())) { // We received too many "Error" state changes: probably looping over a playlist which contains only unavailable elements: stop now. nb_errors_received_ = 0; Stop(); @@ -482,8 +497,8 @@ void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist: int i = active_playlist->next_row(ignore_repeat_track); if (i == -1) { - app_->playlist_manager()->active()->set_current_row(i); - app_->playlist_manager()->active()->reset_last_played(); + playlist_manager_->active()->set_current_row(i); + playlist_manager_->active()->reset_last_played(); Q_EMIT PlaylistFinished(); Stop(); return; @@ -503,9 +518,9 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con play_offset_nanosec_ = 0; Playlist *playlist = nullptr; - const QList playlists = app_->playlist_manager()->GetAllPlaylists(); + const QList playlists = playlist_manager_->GetAllPlaylists(); for (Playlist *p : playlists) { - if (playlist_name == app_->playlist_manager()->GetPlaylistName(p->id())) { + if (playlist_name == playlist_manager_->GetPlaylistName(p->id())) { playlist = p; break; } @@ -516,12 +531,12 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con return; } - app_->playlist_manager()->SetActivePlaylist(playlist->id()); - app_->playlist_manager()->SetCurrentPlaylist(playlist->id()); + playlist_manager_->SetActivePlaylist(playlist->id()); + playlist_manager_->SetCurrentPlaylist(playlist->id()); if (playlist->rowCount() == 0) return; - int i = app_->playlist_manager()->active()->current_row(); - if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); + int i = playlist_manager_->active()->current_row(); + if (i == -1) i = playlist_manager_->active()->last_played_row(); if (i == -1) i = 0; PlayAt(i, false, 0, change, autoscroll, true); @@ -530,14 +545,14 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) { - if (app_->playlist_manager()->active()->stop_after_current()) { + if (playlist_manager_->active()->stop_after_current()) { // Find what the next track would've been, and mark that one as current, so it plays next time the user presses Play. - const int next_row = app_->playlist_manager()->active()->next_row(); + const int next_row = playlist_manager_->active()->next_row(); if (next_row != -1) { - app_->playlist_manager()->active()->set_current_row(next_row, autoscroll, true); + playlist_manager_->active()->set_current_row(next_row, autoscroll, true); } - app_->playlist_manager()->active()->StopAfter(-1); + playlist_manager_->active()->StopAfter(-1); Stop(true); return true; @@ -550,7 +565,7 @@ bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) { void Player::TrackEnded() { if (current_item_ && current_item_->IsLocalCollectionItem() && current_item_->Metadata().id() != -1) { - app_->playlist_manager()->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id()); + playlist_manager_->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id()); } if (HandleStopAfter(Playlist::AutoScroll::Maybe)) return; @@ -584,10 +599,10 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll case EngineBase::State::Idle:{ pause_time_ = QDateTime(); play_offset_nanosec_ = offset_nanosec; - app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id()); - if (app_->playlist_manager()->active()->rowCount() == 0) break; - int i = app_->playlist_manager()->active()->current_row(); - if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); + playlist_manager_->SetActivePlaylist(playlist_manager_->current_id()); + if (playlist_manager_->active()->rowCount() == 0) break; + int i = playlist_manager_->active()->current_row(); + if (i == -1) i = playlist_manager_->active()->last_played_row(); if (i == -1) i = 0; PlayAt(i, false, offset_nanosec, EngineBase::TrackChangeType::First, autoscroll, true); break; @@ -600,12 +615,12 @@ void Player::UnPause() { if (current_item_ && pause_time_.isValid()) { const Song &song = current_item_->Metadata(); - if (url_handlers_.contains(song.url().scheme()) && song.stream_url_can_expire()) { + if (url_handlers_->CanHandle(song.url()) && song.stream_url_can_expire()) { const quint64 time = QDateTime::currentSecsSinceEpoch() - pause_time_.toSecsSinceEpoch(); if (time >= 30) { // Stream URL might be expired. qLog(Debug) << "Re-requesting stream URL for" << song.url(); play_offset_nanosec_ = engine_->position_nanosec(); - UrlHandler *url_handler = url_handlers_.value(song.url().scheme()); + UrlHandler *url_handler = url_handlers_->GetUrlHandler(song.url()); HandleLoadResult(url_handler->StartLoading(song.url())); return; } @@ -636,8 +651,8 @@ void Player::RestartOrPrevious() { void Player::Stop(const bool stop_after) { engine_->Stop(stop_after); - app_->playlist_manager()->active()->set_current_row(-1); - app_->playlist_manager()->active()->reset_played_indexes(); + playlist_manager_->active()->set_current_row(-1); + playlist_manager_->active()->reset_played_indexes(); current_item_.reset(); pause_time_ = QDateTime(); play_offset_nanosec_ = 0; @@ -645,13 +660,13 @@ void Player::Stop(const bool stop_after) { } void Player::StopAfterCurrent() { - app_->playlist_manager()->active()->StopAfter(app_->playlist_manager()->active()->current_row()); + playlist_manager_->active()->StopAfter(playlist_manager_->active()->current_row()); } bool Player::PreviousWouldRestartTrack() const { // Check if it has been over two seconds since previous button was pressed - return menu_previousmode_ == BehaviourSettingsPage::PreviousBehaviour::Restart && last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(QDateTime::currentDateTime()) >= 2; + return menu_previousmode_ == BehaviourSettings::PreviousBehaviour::Restart && last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(QDateTime::currentDateTime()) >= 2; } @@ -664,19 +679,19 @@ void Player::PreviousItem(const EngineBase::TrackChangeFlags change) { const bool ignore_repeat_track = change & EngineBase::TrackChangeType::Manual; - if (menu_previousmode_ == BehaviourSettingsPage::PreviousBehaviour::Restart) { + if (menu_previousmode_ == BehaviourSettings::PreviousBehaviour::Restart) { // Check if it has been over two seconds since previous button was pressed QDateTime now = QDateTime::currentDateTime(); if (last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(now) >= 2) { last_pressed_previous_ = now; - PlayAt(app_->playlist_manager()->active()->current_row(), false, 0, change, Playlist::AutoScroll::Always, false, true); + PlayAt(playlist_manager_->active()->current_row(), false, 0, change, Playlist::AutoScroll::Always, false, true); return; } last_pressed_previous_ = now; } - int i = app_->playlist_manager()->active()->previous_row(ignore_repeat_track); - app_->playlist_manager()->active()->set_current_row(i, Playlist::AutoScroll::Always, false); + int i = playlist_manager_->active()->previous_row(ignore_repeat_track); + playlist_manager_->active()->set_current_row(i, Playlist::AutoScroll::Always, false); if (i == -1) { Stop(); PlayAt(i, false, 0, change, Playlist::AutoScroll::Always, true); @@ -790,22 +805,22 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano Q_EMIT TrackSkipped(current_item_); } - if (current_item_ && app_->playlist_manager()->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(app_->playlist_manager()->active()->item_at(index)->Metadata())) { + if (current_item_ && playlist_manager_->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(playlist_manager_->active()->item_at(index)->Metadata())) { change |= EngineBase::TrackChangeType::SameAlbum; } - if (reshuffle) app_->playlist_manager()->active()->ReshuffleIndices(); + if (reshuffle) playlist_manager_->active()->ReshuffleIndices(); - app_->playlist_manager()->active()->set_current_row(index, autoscroll, false, force_inform); - if (app_->playlist_manager()->active()->current_row() == -1) { + playlist_manager_->active()->set_current_row(index, autoscroll, false, force_inform); + if (playlist_manager_->active()->current_row() == -1) { // Maybe index didn't exist in the playlist. return; } - current_item_ = app_->playlist_manager()->active()->current_item(); + current_item_ = playlist_manager_->active()->current_item(); const QUrl url = current_item_->StreamUrl(); - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_->CanHandle(url)) { // It's already loading if (loading_async_.contains(url)) { return; @@ -814,7 +829,7 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano pause_ = pause; stream_change_type_ = change; autoscroll_ = autoscroll; - UrlHandler *url_handler = url_handlers_.value(url.scheme()); + UrlHandler *url_handler = url_handlers_->GetUrlHandler(url); HandleLoadResult(url_handler->StartLoading(url)); } else { @@ -844,12 +859,12 @@ void Player::SeekTo(const quint64 seconds) { engine_->Seek(nanosec); qLog(Debug) << "Track seeked to" << nanosec << "ns - updating scrobble point"; - app_->playlist_manager()->active()->UpdateScrobblePoint(nanosec); + playlist_manager_->active()->UpdateScrobblePoint(nanosec); Q_EMIT Seeked(nanosec / 1000); if (seconds == 0) { - app_->playlist_manager()->active()->InformOfCurrentSongChange(false); + playlist_manager_->active()->InformOfCurrentSongChange(false); } } @@ -865,26 +880,26 @@ void Player::SeekBackward() { void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Current) { - const int current_row = app_->playlist_manager()->active()->current_row(); + const int current_row = playlist_manager_->active()->current_row(); if (current_row != -1) { - PlaylistItemPtr item = app_->playlist_manager()->active()->current_item(); + PlaylistItemPtr item = playlist_manager_->active()->current_item(); if (item && engine_metadata.media_url == item->Url()) { Song song = item->Metadata(); song.MergeFromEngineMetadata(engine_metadata); - app_->playlist_manager()->active()->UpdateItemMetadata(current_row, item, song, true); + playlist_manager_->active()->UpdateItemMetadata(current_row, item, song, true); return; } } } if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Next) { - const int next_row = app_->playlist_manager()->active()->next_row(); + const int next_row = playlist_manager_->active()->next_row(); if (next_row != -1) { - PlaylistItemPtr next_item = app_->playlist_manager()->active()->item_at(next_row); + PlaylistItemPtr next_item = playlist_manager_->active()->item_at(next_row); if (engine_metadata.media_url == next_item->Url()) { Song song = next_item->Metadata(); song.MergeFromEngineMetadata(engine_metadata); - app_->playlist_manager()->active()->UpdateItemMetadata(next_row, next_item, song, true); + playlist_manager_->active()->UpdateItemMetadata(next_row, next_item, song, true); } } } @@ -893,9 +908,9 @@ void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { PlaylistItemPtr Player::GetItemAt(const int pos) const { - if (pos < 0 || pos >= app_->playlist_manager()->active()->rowCount()) + if (pos < 0 || pos >= playlist_manager_->active()->rowCount()) return PlaylistItemPtr(); - return app_->playlist_manager()->active()->item_at(pos); + return playlist_manager_->active()->item_at(pos); } @@ -940,10 +955,10 @@ void Player::PlayWithPause(const quint64 offset_nanosec) { pause_time_ = QDateTime(); play_offset_nanosec_ = offset_nanosec; - app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id()); - if (app_->playlist_manager()->active()->rowCount() == 0) return; - int i = app_->playlist_manager()->active()->current_row(); - if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); + playlist_manager_->SetActivePlaylist(playlist_manager_->current_id()); + if (playlist_manager_->active()->rowCount() == 0) return; + int i = playlist_manager_->active()->current_row(); + if (i == -1) i = playlist_manager_->active()->last_played_row(); if (i == -1) i = 0; PlayAt(i, true, offset_nanosec, EngineBase::TrackChangeType::First, Playlist::AutoScroll::Always, true); @@ -959,11 +974,11 @@ void Player::TogglePrettyOSD() { void Player::TrackAboutToEnd() { - const bool has_next_row = app_->playlist_manager()->active()->next_row() != -1; + const bool has_next_row = playlist_manager_->active()->next_row() != -1; PlaylistItemPtr next_item; if (has_next_row) { - next_item = app_->playlist_manager()->active()->item_at(app_->playlist_manager()->active()->next_row()); + next_item = playlist_manager_->active()->item_at(playlist_manager_->active()->next_row()); } if (engine_->is_autocrossfade_enabled()) { @@ -989,10 +1004,10 @@ void Player::TrackAboutToEnd() { QUrl url = next_item->StreamUrl(); // Get the actual track URL rather than the stream URL. - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_->CanHandle(url)) { if (loading_async_.contains(url)) return; autoscroll_ = Playlist::AutoScroll::Maybe; - UrlHandler *url_handler = url_handlers_.value(url.scheme()); + UrlHandler *url_handler = url_handlers_->GetUrlHandler(url); const UrlHandler::LoadResult result = url_handler->StartLoading(url); switch (result.type_) { case UrlHandler::LoadResult::Type::Error: @@ -1045,57 +1060,6 @@ void Player::InvalidSongRequested(const QUrl &url) { } -void Player::RegisterUrlHandler(UrlHandler *handler) { - - const QString scheme = 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, handler); - QObject::connect(handler, &UrlHandler::destroyed, this, &Player::UrlHandlerDestroyed); - QObject::connect(handler, &UrlHandler::AsyncLoadComplete, this, &Player::HandleLoadResult); - -} - -void Player::UnregisterUrlHandler(UrlHandler *handler) { - - const QString scheme = url_handlers_.key(handler); - if (scheme.isEmpty()) { - qLog(Warning) << "Tried to unregister a URL handler for" << handler->scheme() << "that wasn't registered"; - return; - } - - qLog(Info) << "Unregistered URL handler for" << scheme; - url_handlers_.remove(scheme); - QObject::disconnect(handler, &UrlHandler::destroyed, this, &Player::UrlHandlerDestroyed); - QObject::disconnect(handler, &UrlHandler::AsyncLoadComplete, this, &Player::HandleLoadResult); - -} - -const UrlHandler *Player::HandlerForUrl(const QUrl &url) const { - - QMap::const_iterator it = url_handlers_.constFind(url.scheme()); - if (it == url_handlers_.constEnd()) { - return nullptr; - } - return *it; - -} - -void Player::UrlHandlerDestroyed(QObject *object) { - - UrlHandler *handler = static_cast(object); - const QString scheme = url_handlers_.key(handler); - if (!scheme.isEmpty()) { - url_handlers_.remove(scheme); - } - -} - void Player::HandleAuthentication() { Q_EMIT Authenticated(); } diff --git a/src/core/player.h b/src/core/player.h index d14e9a76be..15a843cf81 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -31,110 +31,29 @@ #include #include -#include "shared_ptr.h" -#include "urlhandler.h" +#include "includes/shared_ptr.h" +#include "core/urlhandler.h" +#include "core/enginemetadata.h" #include "engine/enginebase.h" -#include "engine/enginemetadata.h" #include "playlist/playlist.h" #include "playlist/playlistitem.h" -#include "settings/behavioursettingspage.h" +#include "constants/behavioursettings.h" +#include "playerinterface.h" class QTimer; -class Application; class Song; +class TaskManager; +class UrlHandlers; +class PlaylistManager; class AnalyzerContainer; class Equalizer; class GstStartup; -class PlayerInterface : public QObject { - Q_OBJECT - - public: - explicit PlayerInterface(QObject *parent = nullptr) : QObject(parent) {} - - virtual SharedPtr engine() const = 0; - virtual EngineBase::State GetState() const = 0; - virtual uint GetVolume() const = 0; - - virtual PlaylistItemPtr GetCurrentItem() const = 0; - virtual PlaylistItemPtr GetItemAt(const int pos) const = 0; - - virtual void RegisterUrlHandler(UrlHandler *handler) = 0; - virtual void UnregisterUrlHandler(UrlHandler *handler) = 0; - - public Q_SLOTS: - virtual void ReloadSettings() = 0; - virtual void LoadVolume() = 0; - virtual void SaveVolume() = 0; - virtual void SavePlaybackStatus() = 0; - - virtual void PlaylistsLoaded() = 0; - - // Manual track change to the specified track - virtual void PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0; - - // If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist - virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0; - virtual void PlayPauseHelper() = 0; - virtual void RestartOrPrevious() = 0; - - // Skips this track. Might load more of the current radio station. - virtual void Next() = 0; - virtual void Previous() = 0; - virtual void PlayPlaylist(const QString &playlist_name) = 0; - virtual void SetVolumeFromEngine(const uint volume) = 0; - virtual void SetVolumeFromSlider(const int value) = 0; - virtual void SetVolume(const uint volume) = 0; - virtual void VolumeUp() = 0; - virtual void VolumeDown() = 0; - virtual void SeekTo(const quint64 seconds) = 0; - // Moves the position of the currently playing song five seconds forward. - virtual void SeekForward() = 0; - // Moves the position of the currently playing song five seconds backwards. - virtual void SeekBackward() = 0; - - virtual void CurrentMetadataChanged(const Song &metadata) = 0; - - virtual void Mute() = 0; - virtual void Pause() = 0; - virtual void Stop(const bool stop_after = false) = 0; - virtual void Play(const quint64 offset_nanosec = 0) = 0; - virtual void PlayWithPause(const quint64 offset_nanosec) = 0; - virtual void PlayHelper() = 0; - virtual void ShowOSD() = 0; - - Q_SIGNALS: - void Playing(); - void Paused(); - // Emitted only when playback is manually resumed - void Resumed(); - void Stopped(); - void Error(const QString &message = QString()); - void PlaylistFinished(); - void VolumeEnabled(const bool volume_enabled); - void VolumeChanged(const uint volume); - void TrackSkipped(PlaylistItemPtr old_track); - // Emitted when there's a manual change to the current's track position. - void Seeked(const qint64 microseconds); - - // Emitted when Player has processed a request to play another song. - // This contains the URL of the song and a flag saying whether it was able to play the song. - void SongChangeRequestProcessed(const QUrl &url, const bool valid); - - // The toggle parameter is true when user requests to toggle visibility for Pretty OSD - void ForceShowOSD(const Song &song, const bool toggle); - - void Authenticated(); - -}; - class Player : public PlayerInterface { Q_OBJECT public: - explicit Player(Application *app, QObject *parent = nullptr); - - static const char *kSettingsGroup; + explicit Player(SharedPtr task_manager, SharedPtr url_handlers, SharedPtr playlist_manager, QObject *parent = nullptr); EngineBase::Type CreateEngine(EngineBase::Type Type); void Init(); @@ -146,11 +65,6 @@ class Player : public PlayerInterface { PlaylistItemPtr GetCurrentItem() const override { return current_item_; } PlaylistItemPtr GetItemAt(const int pos) const override; - void RegisterUrlHandler(UrlHandler *handler) override; - void UnregisterUrlHandler(UrlHandler *handler) override; - - const UrlHandler *HandlerForUrl(const QUrl &url) const; - bool PreviousWouldRestartTrack() const; void SetAnalyzer(AnalyzerContainer *analyzer) { analyzer_ = analyzer; } @@ -158,6 +72,7 @@ class Player : public PlayerInterface { public Q_SLOTS: void ReloadSettings() override; + void LoadVolume() override; void SaveVolume() override; void SavePlaybackStatus() override; @@ -197,6 +112,8 @@ class Player : public PlayerInterface { void EngineChanged(const EngineBase::Type Type); private Q_SLOTS: + void UrlHandlerRegistered(UrlHandler *url_handler); + void EngineStateChanged(const EngineBase::State); void EngineMetadataReceived(const EngineMetadata &engine_metadata); void TrackAboutToEnd(); @@ -212,7 +129,6 @@ class Player : public PlayerInterface { void ValidSongRequested(const QUrl&); void InvalidSongRequested(const QUrl&); - void UrlHandlerDestroyed(QObject *object); void HandleLoadResult(const UrlHandler::LoadResult &result); private: @@ -224,7 +140,9 @@ class Player : public PlayerInterface { void UnPause(); private: - Application *app_; + SharedPtr task_manager_; + SharedPtr url_handlers_; + SharedPtr playlist_manager_; SharedPtr engine_; GstStartup *gst_startup_; AnalyzerContainer *analyzer_; @@ -242,8 +160,6 @@ class Player : public PlayerInterface { EngineBase::State last_state_; int nb_errors_received_; - QMap url_handlers_; - QList loading_async_; uint volume_; uint volume_before_mute_; @@ -251,13 +167,12 @@ class Player : public PlayerInterface { bool continue_on_error_; bool greyout_; - BehaviourSettingsPage::PreviousBehaviour menu_previousmode_; + BehaviourSettings::PreviousBehaviour menu_previousmode_; int seek_step_sec_; uint volume_increment_; QDateTime pause_time_; quint64 play_offset_nanosec_; - }; #endif // PLAYER_H diff --git a/src/core/playerinterface.cpp b/src/core/playerinterface.cpp new file mode 100644 index 0000000000..cb03a726bb --- /dev/null +++ b/src/core/playerinterface.cpp @@ -0,0 +1,24 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2010, David Sansome + * Copyright 2018-2021, Jonas Kvinge + * + * 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 . + * + */ + +#include "playerinterface.h" + +PlayerInterface::PlayerInterface(QObject *parent) : QObject(parent) {} diff --git a/src/core/playerinterface.h b/src/core/playerinterface.h new file mode 100644 index 0000000000..0e1cf5c18e --- /dev/null +++ b/src/core/playerinterface.h @@ -0,0 +1,117 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2010, David Sansome + * Copyright 2018-2021, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYERINTERFACE_H +#define PLAYERINTERFACE_H + +#include "config.h" + +#include +#include +#include + +#include "includes/shared_ptr.h" +#include "engine/enginebase.h" +#include "playlist/playlist.h" +#include "playlist/playlistitem.h" + +class QTimer; +class Song; + +class PlayerInterface : public QObject { + Q_OBJECT + + public: + explicit PlayerInterface(QObject *parent = nullptr); + + virtual SharedPtr engine() const = 0; + virtual EngineBase::State GetState() const = 0; + virtual uint GetVolume() const = 0; + + virtual PlaylistItemPtr GetCurrentItem() const = 0; + virtual PlaylistItemPtr GetItemAt(const int pos) const = 0; + + public Q_SLOTS: + virtual void ReloadSettings() = 0; + virtual void LoadVolume() = 0; + virtual void SaveVolume() = 0; + virtual void SavePlaybackStatus() = 0; + + virtual void PlaylistsLoaded() = 0; + + // Manual track change to the specified track + virtual void PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0; + + // If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist + virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0; + virtual void PlayPauseHelper() = 0; + virtual void RestartOrPrevious() = 0; + + // Skips this track. Might load more of the current radio station. + virtual void Next() = 0; + virtual void Previous() = 0; + virtual void PlayPlaylist(const QString &playlist_name) = 0; + virtual void SetVolumeFromEngine(const uint volume) = 0; + virtual void SetVolumeFromSlider(const int value) = 0; + virtual void SetVolume(const uint volume) = 0; + virtual void VolumeUp() = 0; + virtual void VolumeDown() = 0; + virtual void SeekTo(const quint64 seconds) = 0; + // Moves the position of the currently playing song five seconds forward. + virtual void SeekForward() = 0; + // Moves the position of the currently playing song five seconds backwards. + virtual void SeekBackward() = 0; + + virtual void CurrentMetadataChanged(const Song &metadata) = 0; + + virtual void Mute() = 0; + virtual void Pause() = 0; + virtual void Stop(const bool stop_after = false) = 0; + virtual void Play(const quint64 offset_nanosec = 0) = 0; + virtual void PlayWithPause(const quint64 offset_nanosec) = 0; + virtual void PlayHelper() = 0; + virtual void ShowOSD() = 0; + + Q_SIGNALS: + void Playing(); + void Paused(); + // Emitted only when playback is manually resumed + void Resumed(); + void Stopped(); + void Error(const QString &message = QString()); + void PlaylistFinished(); + void VolumeEnabled(const bool volume_enabled); + void VolumeChanged(const uint volume); + void TrackSkipped(PlaylistItemPtr old_track); + // Emitted when there's a manual change to the current's track position. + void Seeked(const qint64 microseconds); + + // Emitted when Player has processed a request to play another song. + // This contains the URL of the song and a flag saying whether it was able to play the song. + void SongChangeRequestProcessed(const QUrl &url, const bool valid); + + // The toggle parameter is true when user requests to toggle visibility for Pretty OSD + void ForceShowOSD(const Song &song, const bool toggle); + + void Authenticated(); +}; + +#endif // PLAYERINTERFACE_H diff --git a/src/core/song.cpp b/src/core/song.cpp index 3b7774c964..2f51e27325 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -51,11 +51,11 @@ #include #include "core/iconloader.h" -#include "engine/enginemetadata.h" +#include "core/enginemetadata.h" #include "utilities/strutils.h" #include "utilities/timeutils.h" #include "utilities/coverutils.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "utilities/sqlhelper.h" #include "song.h" @@ -1960,3 +1960,43 @@ QString Song::TitleRemoveMisc(const QString &title) { return StripRegexList(title, kTitleMisc); } + +QString Song::GetNameForNewPlaylist(const SongList &songs) { + + if (songs.isEmpty()) { + return QObject::tr("Playlist"); + } + + QSet artists; + QSet albums; + artists.reserve(songs.count()); + albums.reserve(songs.count()); + for (const Song &song : songs) { + artists << (song.effective_albumartist().isEmpty() ? QObject::tr("Unknown") : song.effective_albumartist()); + albums << (song.album().isEmpty() ? QObject::tr("Unknown") : song.album()); + + if (artists.size() > 1) { + break; + } + } + + bool various_artists = artists.size() > 1; + + QString result; + if (various_artists) { + result = QObject::tr("Various artists"); + } + else { + QStringList artist_names = artists.values(); + result = artist_names.first(); + } + + if (!various_artists && albums.size() == 1) { + QStringList album_names = albums.values(); + result += " - "_L1 + album_names.first(); + } + + return result; + +} + diff --git a/src/core/song.h b/src/core/song.h index fcd5136995..a0f6bc2053 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -509,6 +509,8 @@ class Song { static QString AlbumRemoveDiscMisc(const QString &album); static QString TitleRemoveMisc(const QString &title); + static QString GetNameForNewPlaylist(const QList &songs); + static inline QString TagLibStringToQString(const TagLib::String &s) { return QString::fromUtf8((s).toCString(true)); } diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index a953fc00a4..7f3c1566e1 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -39,15 +39,13 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" - -#include "shared_ptr.h" -#include "signalchecker.h" -#include "player.h" -#include "song.h" +#include "core/signalchecker.h" +#include "core/song.h" +#include "core/database.h" +#include "core/urlhandlers.h" #include "songloader.h" -#include "database.h" -#include "engine/enginebase.h" #include "tagreader/tagreaderclient.h" #include "collection/collectionbackend.h" #include "playlistparsers/cueparser.h" @@ -66,13 +64,17 @@ constexpr int kDefaultTimeout = 5000; QSet SongLoader::sRawUriSchemes; -SongLoader::SongLoader(SharedPtr collection_backend, const SharedPtr player, QObject *parent) +SongLoader::SongLoader(const SharedPtr url_handlers, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + QObject *parent) : QObject(parent), - player_(player), + url_handlers_(url_handlers), collection_backend_(collection_backend), + tagreader_client_(tagreader_client), timeout_timer_(new QTimer(this)), - playlist_parser_(new PlaylistParser(collection_backend, this)), - cue_parser_(new CueParser(collection_backend, this)), + playlist_parser_(new PlaylistParser(tagreader_client, collection_backend, this)), + cue_parser_(new CueParser(tagreader_client, collection_backend, this)), parser_(nullptr), state_(State::WaitingForType), timeout_(kDefaultTimeout), @@ -114,23 +116,16 @@ SongLoader::Result SongLoader::Load(const QUrl &url) { return LoadLocal(url_.toLocalFile()); } - if (sRawUriSchemes.contains(url_.scheme()) || player_->HandlerForUrl(url)) { + if (sRawUriSchemes.contains(url_.scheme()) || url_handlers_->CanHandle(url)) { // The URI scheme indicates that it can't possibly be a playlist, // or we have a custom handler for the URL, so add it as a raw stream. AddAsRawStream(); return Result::Success; } - if (player_->engine()->type() == EngineBase::Type::GStreamer) { - preload_func_ = std::bind(&SongLoader::LoadRemote, this); - return Result::BlockingLoadRequired; - } - else { - errors_ << tr("You need GStreamer for this URL."); - return Result::Error; - } + preload_func_ = std::bind(&SongLoader::LoadRemote, this); - return Result::Success; + return Result::BlockingLoadRequired; } @@ -165,7 +160,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) { // Assume it's just a normal file if (!Song::kRejectedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive) && - (TagReaderClient::Instance()->IsMediaFileBlocking(filename) || + (tagreader_client_->IsMediaFileBlocking(filename) || Song::kAcceptedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive))) { Song song(Song::Source::LocalFile); song.InitFromFilePartial(filename, fileinfo); @@ -183,19 +178,14 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) { SongLoader::Result SongLoader::LoadAudioCD() { #ifdef HAVE_AUDIOCD - if (player_->engine()->type() == EngineBase::Type::GStreamer) { - CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this); - QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot); - QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded); - cdda_song_loader->LoadSongs(); - return Result::Success; - } - else { -#endif - errors_ << tr("CD playback is only available with the GStreamer engine."); - return Result::Error; -#ifdef HAVE_AUDIOCD - } + CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this); + QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot); + QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded); + cdda_song_loader->LoadSongs(); + return Result::Success; +#else + errors_ << tr("Missing CDDA playback."); + return Result::Error; #endif } @@ -306,7 +296,7 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { // Assume it's just a normal file if (!Song::kRejectedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive) && - (TagReaderClient::Instance()->IsMediaFileBlocking(filename) || + (tagreader_client_->IsMediaFileBlocking(filename) || Song::kAcceptedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive))) { Song song(Song::Source::LocalFile); song.InitFromFilePartial(filename, fileinfo); @@ -346,7 +336,7 @@ void SongLoader::EffectiveSongLoad(Song *song) { else { // It's a normal media file const QString filename = song->url().toLocalFile(); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(filename, song); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(filename, song); if (!result.success()) { qLog(Error) << "Could not read file" << song->url() << result.error_string(); } diff --git a/src/core/songloader.h b/src/core/songloader.h index 1d4db35aed..0666e6827e 100644 --- a/src/core/songloader.h +++ b/src/core/songloader.h @@ -38,11 +38,12 @@ #include #include -#include "shared_ptr.h" -#include "song.h" +#include "includes/shared_ptr.h" +#include "core/song.h" class QTimer; -class Player; +class UrlHandlers; +class TagReaderClient; class CollectionBackendInterface; class PlaylistParser; class ParserBase; @@ -56,7 +57,11 @@ class SongLoader : public QObject { Q_OBJECT public: - explicit SongLoader(SharedPtr collection_backend, const SharedPtr player, QObject *parent = nullptr); + explicit SongLoader(const SharedPtr url_handlers, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + QObject *parent = nullptr); + ~SongLoader() override; enum class Result { @@ -137,8 +142,9 @@ class SongLoader : public QObject { QUrl url_; SongList songs_; - const SharedPtr player_; - SharedPtr collection_backend_; + const SharedPtr url_handlers_; + const SharedPtr collection_backend_; + const SharedPtr tagreader_client_; QTimer *timeout_timer_; PlaylistParser *playlist_parser_; CueParser *cue_parser_; diff --git a/src/playlist/songmimedata.cpp b/src/core/songmimedata.cpp similarity index 100% rename from src/playlist/songmimedata.cpp rename to src/core/songmimedata.cpp diff --git a/src/playlist/songmimedata.h b/src/core/songmimedata.h similarity index 95% rename from src/playlist/songmimedata.h rename to src/core/songmimedata.h index f206d24a1f..91f039f838 100644 --- a/src/playlist/songmimedata.h +++ b/src/core/songmimedata.h @@ -24,8 +24,8 @@ #include "config.h" -#include "core/shared_ptr.h" -#include "core/mimedata.h" +#include "includes/shared_ptr.h" +#include "mimedata.h" #include "core/song.h" class CollectionBackendInterface; diff --git a/src/core/stylesheetloader.cpp b/src/core/stylesheetloader.cpp index 73337285a0..4515ceaa03 100644 --- a/src/core/stylesheetloader.cpp +++ b/src/core/stylesheetloader.cpp @@ -35,8 +35,8 @@ #include #include -#include "shared_ptr.h" -#include "core/logging.h" +#include "includes/shared_ptr.h" +#include "logging.h" #include "stylesheetloader.h" using namespace Qt::Literals::StringLiterals; diff --git a/src/core/stylesheetloader.h b/src/core/stylesheetloader.h index b48302fedb..54fd059018 100644 --- a/src/core/stylesheetloader.h +++ b/src/core/stylesheetloader.h @@ -30,7 +30,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" class QWidget; class QEvent; diff --git a/src/core/urlhandler.cpp b/src/core/urlhandler.cpp index 2cd333f148..e12ed9ce17 100644 --- a/src/core/urlhandler.cpp +++ b/src/core/urlhandler.cpp @@ -1,8 +1,6 @@ /* * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2018, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/urlhandler.h b/src/core/urlhandler.h index 80d5a0e289..9fabbe184e 100644 --- a/src/core/urlhandler.h +++ b/src/core/urlhandler.h @@ -1,8 +1,6 @@ /* * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2018, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/urlhandlers.cpp b/src/core/urlhandlers.cpp new file mode 100644 index 0000000000..7b9916bf9f --- /dev/null +++ b/src/core/urlhandlers.cpp @@ -0,0 +1,95 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#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(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()); + +} diff --git a/src/core/urlhandlers.h b/src/core/urlhandlers.h new file mode 100644 index 0000000000..c7d7219004 --- /dev/null +++ b/src/core/urlhandlers.h @@ -0,0 +1,56 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef URLHANDLERS_H +#define URLHANDLERS_H + +#include "config.h" + +#include +#include +#include +#include + +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 url_handlers_; +}; + +#endif // URLHANDLERS_H diff --git a/src/covermanager/albumcoverchoicecontroller.cpp b/src/covermanager/albumcoverchoicecontroller.cpp index 2b09741bf6..2058997ca7 100644 --- a/src/covermanager/albumcoverchoicecontroller.cpp +++ b/src/covermanager/albumcoverchoicecontroller.cpp @@ -54,20 +54,21 @@ #include #include -#include "utilities/filenameconstants.h" +#include "constants/filenameconstants.h" +#include "constants/filefilterconstants.h" #include "utilities/strutils.h" #include "utilities/mimeutils.h" #include "utilities/coveroptions.h" #include "utilities/coverutils.h" #include "utilities/screenutils.h" -#include "core/application.h" +#include "core/logging.h" #include "core/song.h" #include "core/iconloader.h" #include "core/settings.h" #include "tagreader/tagreaderclient.h" #include "collection/collectionfilteroptions.h" #include "collection/collectionbackend.h" -#include "settings/coverssettingspage.h" +#include "constants/coverssettings.h" #include "streaming/streamingservices.h" #include "streaming/streamingservice.h" #include "albumcoverchoicecontroller.h" @@ -80,15 +81,10 @@ using namespace Qt::Literals::StringLiterals; -const char *AlbumCoverChoiceController::kLoadImageFileFilter = QT_TR_NOOP("Images (*.png *.jpg *.jpeg *.bmp *.gif *.xpm *.pbm *.pgm *.ppm *.xbm)"); -const char *AlbumCoverChoiceController::kSaveImageFileFilter = QT_TR_NOOP("Images (*.png *.jpg *.jpeg *.bmp *.xpm *.pbm *.ppm *.xbm)"); -const char *AlbumCoverChoiceController::kAllFilesFilter = QT_TR_NOOP("All files (*)"); - QSet *AlbumCoverChoiceController::sImageExtensions = nullptr; AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget *parent) : QWidget(parent), - app_(nullptr), cover_searcher_(nullptr), cover_fetcher_(nullptr), save_file_dialog_(nullptr), @@ -130,12 +126,22 @@ AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget *parent) AlbumCoverChoiceController::~AlbumCoverChoiceController() = default; -void AlbumCoverChoiceController::Init(Application *app) { - - app_ = app; - - cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), app->network(), this); - cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), app, this); +void AlbumCoverChoiceController::Init(SharedPtr network, + SharedPtr tagreader_client, + SharedPtr collection_backend, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr streaming_services) { + + network_ = network; + tagreader_client_ = tagreader_client; + collection_backend_ = collection_backend; + current_albumcover_loader_ = current_albumcover_loader; + streaming_services_ = streaming_services; + + cover_fetcher_ = new AlbumCoverFetcher(cover_providers, network, this); + cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), albumcover_loader, this); cover_searcher_->Init(cover_fetcher_); QObject::connect(cover_fetcher_, &AlbumCoverFetcher::AlbumCoverFetched, this, &AlbumCoverChoiceController::AlbumCoverFetched); @@ -145,13 +151,13 @@ void AlbumCoverChoiceController::Init(Application *app) { void AlbumCoverChoiceController::ReloadSettings() { Settings s; - s.beginGroup(CoversSettingsPage::kSettingsGroup); - cover_options_.cover_type = static_cast(s.value(CoversSettingsPage::kSaveType, static_cast(CoverOptions::CoverType::Cache)).toInt()); - cover_options_.cover_filename = static_cast(s.value(CoversSettingsPage::kSaveFilename, static_cast(CoverOptions::CoverFilename::Pattern)).toInt()); - cover_options_.cover_pattern = s.value(CoversSettingsPage::kSavePattern, u"%albumartist-%album"_s).toString(); - cover_options_.cover_overwrite = s.value(CoversSettingsPage::kSaveOverwrite, false).toBool(); - cover_options_.cover_lowercase = s.value(CoversSettingsPage::kSaveLowercase, false).toBool(); - cover_options_.cover_replace_spaces = s.value(CoversSettingsPage::kSaveReplaceSpaces, false).toBool(); + s.beginGroup(CoversSettings::kSettingsGroup); + cover_options_.cover_type = static_cast(s.value(CoversSettings::kSaveType, static_cast(CoverOptions::CoverType::Cache)).toInt()); + cover_options_.cover_filename = static_cast(s.value(CoversSettings::kSaveFilename, static_cast(CoverOptions::CoverFilename::Pattern)).toInt()); + cover_options_.cover_pattern = s.value(CoversSettings::kSavePattern, u"%albumartist-%album"_s).toString(); + cover_options_.cover_overwrite = s.value(CoversSettings::kSaveOverwrite, false).toBool(); + cover_options_.cover_lowercase = s.value(CoversSettings::kSaveLowercase, false).toBool(); + cover_options_.cover_replace_spaces = s.value(CoversSettings::kSaveReplaceSpaces, false).toBool(); s.endGroup(); cover_types_ = AlbumCoverLoaderOptions::LoadTypes(); @@ -179,7 +185,7 @@ AlbumCoverImageResult AlbumCoverChoiceController::LoadImageFromFile(Song *song) return AlbumCoverImageResult(); } - QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilter)); + QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (cover_file.isEmpty()) return AlbumCoverImageResult(); QFile file(cover_file); @@ -210,7 +216,7 @@ QUrl AlbumCoverChoiceController::LoadCoverFromFile(Song *song) { if (!song->url().isValid() || !song->url().isLocalFile() || song->effective_albumartist().isEmpty() || song->album().isEmpty()) return QUrl(); - QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilter)); + QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (cover_file.isEmpty() || QImage(cover_file).isNull()) return QUrl(); switch (get_save_album_cover_type()) { @@ -246,7 +252,7 @@ void AlbumCoverChoiceController::SaveCoverToFileManual(const Song &song, const A static const QRegularExpression regex_invalid_fat_characters(QLatin1String(kInvalidFatCharactersRegex), QRegularExpression::CaseInsensitiveOption); initial_file_name.remove(regex_invalid_fat_characters); - QString save_filename = QFileDialog::getSaveFileName(this, tr("Save album cover"), GetInitialPathForFileDialog(song, initial_file_name), tr(kSaveImageFileFilter) + u";;"_s + tr(kAllFilesFilter)); + QString save_filename = QFileDialog::getSaveFileName(this, tr("Save album cover"), GetInitialPathForFileDialog(song, initial_file_name), tr(kSaveImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (save_filename.isEmpty()) return; @@ -316,7 +322,7 @@ void AlbumCoverChoiceController::LoadCoverFromURL(Song *song) { AlbumCoverImageResult AlbumCoverChoiceController::LoadImageFromURL() { - if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(app_->network(), this); } + if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(network_, this); } return cover_from_url_dialog_->Exec(); @@ -446,7 +452,7 @@ void AlbumCoverChoiceController::ShowCover(const Song &song, const QImage &image case AlbumCoverLoaderOptions::Type::Embedded:{ if (song.art_embedded() && !song.url().isEmpty() && song.url().isValid() && song.url().isLocalFile()) { QImage image_embedded_cover; - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(song.url().toLocalFile(), image_embedded_cover); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(song.url().toLocalFile(), image_embedded_cover); if (result.success() && !image_embedded_cover.isNull()) { QPixmap pixmap = QPixmap::fromImage(image_embedded_cover); if (!pixmap.isNull()) { @@ -548,11 +554,11 @@ void AlbumCoverChoiceController::SaveArtEmbeddedToSong(Song *song, const bool ar song->set_art_unset(false); if (song->source() == Song::Source::Collection) { - app_->collection_backend()->UpdateEmbeddedAlbumArtAsync(song->effective_albumartist(), song->album(), art_embedded); + collection_backend_->UpdateEmbeddedAlbumArtAsync(song->effective_albumartist(), song->album(), art_embedded); } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -567,7 +573,7 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art // Update the backends. switch (song->source()) { case Song::Source::Collection: - app_->collection_backend()->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual); + collection_backend_->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual); break; case Song::Source::LocalFile: case Song::Source::CDDA: @@ -581,7 +587,7 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art case Song::Source::Tidal: case Song::Source::Spotify: case Song::Source::Qobuz: - StreamingServicePtr service = app_->streaming_services()->ServiceBySource(song->source()); + StreamingServicePtr service = streaming_services_->ServiceBySource(song->source()); if (!service) break; if (service->artists_collection_backend()) { service->artists_collection_backend()->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual); @@ -595,8 +601,8 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art break; } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -611,11 +617,11 @@ void AlbumCoverChoiceController::ClearAlbumCoverForSong(Song *song) { song->clear_art_manual(); if (song->source() == Song::Source::Collection) { - app_->collection_backend()->ClearAlbumArtAsync(song->effective_albumartist(), song->album(), false); + collection_backend_->ClearAlbumArtAsync(song->effective_albumartist(), song->album(), false); } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -630,11 +636,11 @@ void AlbumCoverChoiceController::UnsetAlbumCoverForSong(Song *song) { song->clear_art_automatic(); if (song->source() == Song::Source::Collection) { - app_->collection_backend()->UnsetAlbumArtAsync(song->effective_albumartist(), song->album()); + collection_backend_->UnsetAlbumArtAsync(song->effective_albumartist(), song->album()); } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -718,7 +724,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToCollectionSongs(const Song & void AlbumCoverChoiceController::SaveCoverEmbeddedToCollectionSongs(const QString &effective_albumartist, const QString &effective_album, const QString &cover_filename, const QByteArray &image_data, const QString &mime_type) { - QFuture future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, app_->collection_backend(), effective_albumartist, effective_album, CollectionFilterOptions()); + QFuture future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, collection_backend_, effective_albumartist, effective_album, CollectionFilterOptions()); QFutureWatcher *watcher = new QFutureWatcher(); QObject::connect(watcher, &QFutureWatcher::finished, this, [this, watcher, cover_filename, image_data, mime_type]() { const SongList collection_songs = watcher->result(); @@ -736,7 +742,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToSong(const Song &song, const QMutexLocker l(&mutex_cover_save_tasks_); cover_save_tasks_.append(song); const bool art_embedded = !image_data.isNull(); - TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(song.url().toLocalFile(), SaveTagCoverData(cover_filename, image_data, mime_type)); + TagReaderReplyPtr reply = tagreader_client_->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); }); } diff --git a/src/covermanager/albumcoverchoicecontroller.h b/src/covermanager/albumcoverchoicecontroller.h index 6132e21739..00c941a933 100644 --- a/src/covermanager/albumcoverchoicecontroller.h +++ b/src/covermanager/albumcoverchoicecontroller.h @@ -50,25 +50,33 @@ class QMenu; class QDragEnterEvent; class QDropEvent; -class Application; +class NetworkAccessManager; +class CollectionBackend; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; class AlbumCoverFetcher; class AlbumCoverSearcher; class CoverFromURLDialog; struct CoverSearchStatistics; +class StreamingServices; // Controller for the common album cover related menu options. class AlbumCoverChoiceController : public QWidget { Q_OBJECT public: - static const char *kLoadImageFileFilter; - static const char *kSaveImageFileFilter; - static const char *kAllFilesFilter; - explicit AlbumCoverChoiceController(QWidget *parent = nullptr); ~AlbumCoverChoiceController() override; - void Init(Application *app); + void Init(SharedPtr network, + SharedPtr tagreader_client, + SharedPtr collection_backend, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr streaming_services); + void ReloadSettings(); CoverOptions::CoverType get_save_album_cover_type() const { return (save_embedded_cover_override_ ? CoverOptions::CoverType::Embedded : cover_options_.cover_type); } @@ -172,7 +180,12 @@ class AlbumCoverChoiceController : public QWidget { static bool IsKnownImageExtension(const QString &suffix); static QSet *sImageExtensions; - Application *app_; + SharedPtr current_albumcover_loader_; + SharedPtr network_; + SharedPtr tagreader_client_; + SharedPtr collection_backend_; + SharedPtr streaming_services_; + AlbumCoverSearcher *cover_searcher_; AlbumCoverFetcher *cover_fetcher_; diff --git a/src/covermanager/albumcoverexporter.cpp b/src/covermanager/albumcoverexporter.cpp index a47e78b776..4f9682be68 100644 --- a/src/covermanager/albumcoverexporter.cpp +++ b/src/covermanager/albumcoverexporter.cpp @@ -33,8 +33,9 @@ namespace { constexpr int kMaxConcurrentRequests = 3; } -AlbumCoverExporter::AlbumCoverExporter(QObject *parent) +AlbumCoverExporter::AlbumCoverExporter(SharedPtr tagreader_client, QObject *parent) : QObject(parent), + tagreader_client_(tagreader_client), thread_pool_(new QThreadPool(this)), exported_(0), skipped_(0), @@ -52,7 +53,7 @@ void AlbumCoverExporter::SetCoverTypes(const AlbumCoverLoaderOptions::Types &cov void AlbumCoverExporter::AddExportRequest(const Song &song) { - requests_.append(new CoverExportRunnable(dialog_result_, cover_types_, song)); + requests_.append(new CoverExportRunnable(tagreader_client_, dialog_result_, cover_types_, song)); all_ = static_cast(requests_.count()); } diff --git a/src/covermanager/albumcoverexporter.h b/src/covermanager/albumcoverexporter.h index c77eb3af34..390f4a3e01 100644 --- a/src/covermanager/albumcoverexporter.h +++ b/src/covermanager/albumcoverexporter.h @@ -27,18 +27,21 @@ #include #include +#include "includes/shared_ptr.h" + #include "albumcoverloaderoptions.h" #include "albumcoverexport.h" class QThreadPool; class Song; class CoverExportRunnable; +class TagReaderClient; class AlbumCoverExporter : public QObject { Q_OBJECT public: - explicit AlbumCoverExporter(QObject *parent = nullptr); + explicit AlbumCoverExporter(SharedPtr tagreader_client, QObject *parent = nullptr); void SetDialogResult(const AlbumCoverExport::DialogResult &dialog_result); void SetCoverTypes(const AlbumCoverLoaderOptions::Types &cover_types); @@ -58,6 +61,8 @@ class AlbumCoverExporter : public QObject { private: void AddJobsToPool(); + SharedPtr tagreader_client_; + AlbumCoverLoaderOptions::Types cover_types_; AlbumCoverExport::DialogResult dialog_result_; diff --git a/src/covermanager/albumcoverfetcher.cpp b/src/covermanager/albumcoverfetcher.cpp index dae4169003..f57a1fcb53 100644 --- a/src/covermanager/albumcoverfetcher.cpp +++ b/src/covermanager/albumcoverfetcher.cpp @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "albumcoverfetcher.h" diff --git a/src/covermanager/albumcoverfetcher.h b/src/covermanager/albumcoverfetcher.h index ece2d46c32..b3a0c33e3a 100644 --- a/src/covermanager/albumcoverfetcher.h +++ b/src/covermanager/albumcoverfetcher.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "coversearchstatistics.h" #include "albumcoverimageresult.h" diff --git a/src/covermanager/albumcoverfetchersearch.cpp b/src/covermanager/albumcoverfetchersearch.cpp index e2d8ed6a08..00a739289b 100644 --- a/src/covermanager/albumcoverfetchersearch.cpp +++ b/src/covermanager/albumcoverfetchersearch.cpp @@ -36,8 +36,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/networktimeouts.h" #include "utilities/imageutils.h" diff --git a/src/covermanager/albumcoverfetchersearch.h b/src/covermanager/albumcoverfetchersearch.h index 99eb54b60c..b8d9bf60ba 100644 --- a/src/covermanager/albumcoverfetchersearch.h +++ b/src/covermanager/albumcoverfetchersearch.h @@ -35,7 +35,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "albumcoverfetcher.h" #include "coversearchstatistics.h" #include "albumcoverimageresult.h" diff --git a/src/covermanager/albumcoverloader.cpp b/src/covermanager/albumcoverloader.cpp index 6d016ac087..8cf7b2b8f6 100644 --- a/src/covermanager/albumcoverloader.cpp +++ b/src/covermanager/albumcoverloader.cpp @@ -36,6 +36,7 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" #include "core/song.h" @@ -54,8 +55,9 @@ namespace { constexpr int kMaxRedirects = 3; } -AlbumCoverLoader::AlbumCoverLoader(QObject *parent) +AlbumCoverLoader::AlbumCoverLoader(SharedPtr tagreader_client, QObject *parent) : QObject(parent), + tagreader_client_(tagreader_client), network_(new NetworkAccessManager(this)), timer_process_tasks_(new QTimer(this)), stop_requested_(false), @@ -318,7 +320,7 @@ AlbumCoverLoader::LoadImageResult AlbumCoverLoader::LoadImage(TaskPtr task, cons AlbumCoverLoader::LoadImageResult AlbumCoverLoader::LoadEmbeddedImage(TaskPtr task) { if (task->art_embedded && task->song_url.isValid() && task->song_url.isLocalFile()) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverDataBlocking(task->song_url.toLocalFile(), task->album_cover.image_data); + const TagReaderResult result = tagreader_client_->LoadCoverDataBlocking(task->song_url.toLocalFile(), task->album_cover.image_data); if (result.success() && !task->album_cover.image_data.isEmpty() && task->album_cover.image.loadFromData(task->album_cover.image_data)) { return LoadImageResult(AlbumCoverLoaderResult::Type::Embedded, LoadImageResult::Status::Success); } diff --git a/src/covermanager/albumcoverloader.h b/src/covermanager/albumcoverloader.h index 6ea2117b54..7cc7fa6a96 100644 --- a/src/covermanager/albumcoverloader.h +++ b/src/covermanager/albumcoverloader.h @@ -32,7 +32,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "albumcoverloaderoptions.h" #include "albumcoverloaderresult.h" @@ -42,12 +42,13 @@ class QThread; class QTimer; class QNetworkReply; class NetworkAccessManager; +class TagReaderClient; class AlbumCoverLoader : public QObject { Q_OBJECT public: - explicit AlbumCoverLoader(QObject *parent = nullptr); + explicit AlbumCoverLoader(SharedPtr tagreader_client, QObject *parent = nullptr); void ExitAsync(); void Stop() { stop_requested_ = true; } @@ -125,6 +126,7 @@ class AlbumCoverLoader : public QObject { void LoadRemoteImageFinished(QNetworkReply *reply, AlbumCoverLoader::TaskPtr task, const AlbumCoverLoaderResult::Type result_type, const QUrl &cover_url); private: + SharedPtr tagreader_client_; SharedPtr network_; QTimer *timer_process_tasks_; bool stop_requested_; diff --git a/src/covermanager/albumcoverloaderoptions.cpp b/src/covermanager/albumcoverloaderoptions.cpp index 5a6c7f3ee1..155e458d21 100644 --- a/src/covermanager/albumcoverloaderoptions.cpp +++ b/src/covermanager/albumcoverloaderoptions.cpp @@ -22,7 +22,7 @@ #include #include "core/settings.h" -#include "settings/coverssettingspage.h" +#include "constants/coverssettings.h" using namespace Qt::Literals::StringLiterals; @@ -37,9 +37,9 @@ AlbumCoverLoaderOptions::Types AlbumCoverLoaderOptions::LoadTypes() { Types cover_types; Settings s; - s.beginGroup(CoversSettingsPage::kSettingsGroup); + s.beginGroup(CoversSettings::kSettingsGroup); const QStringList all_cover_types = QStringList() << u"art_unset"_s << u"art_embedded"_s << u"art_manual"_s << u"art_automatic"_s; - const QStringList cover_types_strlist = s.value(CoversSettingsPage::kTypes, all_cover_types).toStringList(); + const QStringList cover_types_strlist = s.value(CoversSettings::kTypes, all_cover_types).toStringList(); for (const QString &cover_type_str : cover_types_strlist) { if (cover_type_str == "art_unset"_L1) { cover_types << AlbumCoverLoaderOptions::Type::Unset; diff --git a/src/covermanager/albumcovermanager.cpp b/src/covermanager/albumcovermanager.cpp index 95193c5e57..d434a147ef 100644 --- a/src/covermanager/albumcovermanager.cpp +++ b/src/covermanager/albumcovermanager.cpp @@ -61,13 +61,14 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/application.h" #include "core/iconloader.h" -#include "core/database.h" #include "core/settings.h" +#include "core/database.h" +#include "core/networkaccessmanager.h" +#include "core/songmimedata.h" #include "utilities/strutils.h" #include "utilities/fileutils.h" #include "utilities/imageutils.h" @@ -78,8 +79,6 @@ #include "tagreader/tagreaderclient.h" #include "collection/collectionbackend.h" #include "collection/collectionquery.h" -#include "playlist/songmimedata.h" -#include "coverproviders.h" #include "albumcovermanager.h" #include "albumcoversearcher.h" #include "albumcoverchoicecontroller.h" @@ -88,6 +87,7 @@ #include "albumcoverfetcher.h" #include "albumcoverloader.h" #include "albumcoverloaderresult.h" +#include "coverproviders.h" #include "coversearchstatistics.h" #include "coversearchstatisticsdialog.h" #include "albumcoverimageresult.h" @@ -102,21 +102,31 @@ constexpr char kSettingsGroup[] = "CoverManager"; constexpr int kThumbnailSize = 120; } -AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtr collection_backend, QMainWindow *mainwindow, QWidget *parent) +AlbumCoverManager::AlbumCoverManager(SharedPtr network, + SharedPtr collection_backend, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr streaming_services, + QMainWindow *mainwindow, QWidget *parent) : QMainWindow(parent), ui_(new Ui_CoverManager), mainwindow_(mainwindow), - app_(app), + network_(network), collection_backend_(collection_backend), + tagreader_client_(tagreader_client), + albumcover_loader_(albumcover_loader), + cover_providers_(cover_providers), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), timer_album_cover_load_(new QTimer(this)), filter_all_(nullptr), filter_with_covers_(nullptr), filter_without_covers_(nullptr), - cover_fetcher_(new AlbumCoverFetcher(app_->cover_providers(), app_->network(), this)), + cover_fetcher_(new AlbumCoverFetcher(cover_providers, network, this)), cover_searcher_(nullptr), cover_export_(nullptr), - cover_exporter_(new AlbumCoverExporter(this)), + cover_exporter_(new AlbumCoverExporter(tagreader_client_, this)), artist_icon_(IconLoader::Load(u"folder-sound"_s)), all_artists_icon_(IconLoader::Load(u"library-music"_s)), image_nocover_thumbnail_(ImageUtils::GenerateNoCoverImage(QSize(120, 120), devicePixelRatio())), @@ -142,9 +152,9 @@ AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtraction_add_to_playlist->setIcon(IconLoader::Load(u"media-playback-start"_s)); ui_->action_load->setIcon(IconLoader::Load(u"media-playback-start"_s)); - album_cover_choice_controller_->Init(app_); + album_cover_choice_controller_->Init(network, tagreader_client, collection_backend, albumcover_loader, current_albumcover_loader, cover_providers, streaming_services); - cover_searcher_ = new AlbumCoverSearcher(icon_nocover_item_, app_, this); + cover_searcher_ = new AlbumCoverSearcher(icon_nocover_item_, albumcover_loader_, this); cover_export_ = new AlbumCoverExport(this); // Set up the status bar @@ -241,7 +251,7 @@ void AlbumCoverManager::Init() { s.endGroup(); - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverManager::AlbumCoverLoaded); + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverManager::AlbumCoverLoaded); cover_searcher_->Init(cover_fetcher_); @@ -320,7 +330,7 @@ void AlbumCoverManager::SaveSettings() { void AlbumCoverManager::CancelRequests() { - app_->album_cover_loader()->CancelTasks(QSet(cover_loading_tasks_.keyBegin(), cover_loading_tasks_.keyEnd())); + albumcover_loader_->CancelTasks(QSet(cover_loading_tasks_.keyBegin(), cover_loading_tasks_.keyEnd())); cover_loading_pending_.clear(); cover_loading_tasks_.clear(); cover_save_tasks_.clear(); @@ -363,7 +373,7 @@ void AlbumCoverManager::Reset() { } void AlbumCoverManager::EnableCoversButtons() { - ui_->button_fetch->setEnabled(app_->cover_providers()->HasAnyProviders()); + ui_->button_fetch->setEnabled(cover_providers_->HasAnyProviders()); ui_->export_covers->setEnabled(true); } @@ -466,7 +476,7 @@ void AlbumCoverManager::LoadAlbumCoverAsync(AlbumItem *album_item) { cover_options.types = cover_types_; cover_options.desired_scaled_size = QSize(kThumbnailSize, kThumbnailSize); cover_options.device_pixel_ratio = devicePixelRatioF(); - quint64 cover_load_id = app_->album_cover_loader()->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst()); + quint64 cover_load_id = albumcover_loader_->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst()); cover_loading_tasks_.insert(cover_load_id, album_item); } @@ -643,7 +653,7 @@ bool AlbumCoverManager::eventFilter(QObject *obj, QEvent *e) { album_cover_choice_controller_->cover_to_file_action()->setEnabled(some_with_covers); album_cover_choice_controller_->cover_from_file_action()->setEnabled(context_menu_items_.size() == 1); album_cover_choice_controller_->cover_from_url_action()->setEnabled(context_menu_items_.size() == 1); - album_cover_choice_controller_->search_for_cover_action()->setEnabled(app_->cover_providers()->HasAnyProviders()); + album_cover_choice_controller_->search_for_cover_action()->setEnabled(cover_providers_->HasAnyProviders()); album_cover_choice_controller_->unset_cover_action()->setEnabled(some_with_covers || some_clear); album_cover_choice_controller_->clear_cover_action()->setEnabled(some_with_covers || some_unset); album_cover_choice_controller_->delete_cover_action()->setEnabled(some_with_covers); @@ -757,7 +767,7 @@ void AlbumCoverManager::SaveCoverToFile() { return; case AlbumCoverLoaderOptions::Type::Embedded: if (song.art_embedded()) { - const TagReaderResult tagreaderclient_result = TagReaderClient::Instance()->LoadCoverDataBlocking(song.url().toLocalFile(), result.image_data); + const TagReaderResult tagreaderclient_result = tagreader_client_->LoadCoverDataBlocking(song.url().toLocalFile(), result.image_data); if (!tagreaderclient_result.success()) { qLog(Error) << "Could not load embedded art from" << song.url() << tagreaderclient_result.error_string(); } @@ -844,7 +854,7 @@ void AlbumCoverManager::SaveImageToAlbums(Song *song, const AlbumCoverImageResul case CoverOptions::CoverType::Embedded:{ for (const QUrl &url : std::as_const(album_item->urls)) { const bool art_embedded = !result.image_data.isEmpty(); - TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.image_data, result.mime_type)); + TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.image_data, result.mime_type)); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, album_item, url, art_embedded]() { SaveEmbeddedCoverFinished(reply, album_item, url, art_embedded); }); @@ -994,7 +1004,7 @@ void AlbumCoverManager::SaveAndSetCover(AlbumItem *album_item, const AlbumCoverI if (album_cover_choice_controller_->get_save_album_cover_type() == CoverOptions::CoverType::Embedded && Song::save_embedded_cover_supported(filetype) && !has_cue) { for (const QUrl &url : urls) { const bool art_embedded = !result.image_data.isEmpty(); - TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.cover_url.isValid() ? result.cover_url.toLocalFile() : QString(), result.image_data, result.mime_type)); + TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.cover_url.isValid() ? result.cover_url.toLocalFile() : QString(), result.image_data, result.mime_type)); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, album_item, url, art_embedded]() { SaveEmbeddedCoverFinished(reply, album_item, url, art_embedded); }); diff --git a/src/covermanager/albumcovermanager.h b/src/covermanager/albumcovermanager.h index a29a5b86a4..27e418e260 100644 --- a/src/covermanager/albumcovermanager.h +++ b/src/covermanager/albumcovermanager.h @@ -37,7 +37,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "tagreader/tagreaderclient.h" #include "albumcoverloaderoptions.h" @@ -55,8 +55,11 @@ class QEvent; class QCloseEvent; class QShowEvent; -class Application; +class NetworkAccessManager; class CollectionBackend; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; class SongMimeData; class AlbumCoverExport; class AlbumCoverExporter; @@ -78,7 +81,15 @@ class AlbumCoverManager : public QMainWindow { Q_OBJECT public: - explicit AlbumCoverManager(Application *app, SharedPtr collection_backend, QMainWindow *mainwindow, QWidget *parent = nullptr); + explicit AlbumCoverManager(SharedPtr network, + SharedPtr collection_backend, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr streaming_services, + QMainWindow *mainwindow, + QWidget *parent = nullptr); ~AlbumCoverManager() override; void Reset(); @@ -190,8 +201,11 @@ class AlbumCoverManager : public QMainWindow { private: Ui_CoverManager *ui_; QMainWindow *mainwindow_; - Application *app_; + SharedPtr network_; SharedPtr collection_backend_; + SharedPtr tagreader_client_; + SharedPtr albumcover_loader_; + SharedPtr cover_providers_; AlbumCoverChoiceController *album_cover_choice_controller_; QTimer *timer_album_cover_load_; diff --git a/src/covermanager/albumcovermanagerlist.cpp b/src/covermanager/albumcovermanagerlist.cpp index e5e3488be0..e590a047eb 100644 --- a/src/covermanager/albumcovermanagerlist.cpp +++ b/src/covermanager/albumcovermanagerlist.cpp @@ -33,10 +33,10 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" #include "core/song.h" +#include "core/songmimedata.h" #include "collection/collectionbackend.h" -#include "playlist/songmimedata.h" #include "albumcovermanager.h" #include "albumcovermanagerlist.h" diff --git a/src/covermanager/albumcoversearcher.cpp b/src/covermanager/albumcoversearcher.cpp index 4b643535b0..b357eb56bd 100644 --- a/src/covermanager/albumcoversearcher.cpp +++ b/src/covermanager/albumcoversearcher.cpp @@ -47,9 +47,7 @@ #include #include -#include "core/application.h" #include "utilities/strutils.h" -#include "utilities/timeutils.h" #include "utilities/mimeutils.h" #include "widgets/busyindicator.h" #include "widgets/forcescrollperpixel.h" @@ -114,10 +112,10 @@ void SizeOverlayDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o } -AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, Application *app, QWidget *parent) +AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, SharedPtr albumcover_loader, QWidget *parent) : QDialog(parent), ui_(new Ui_AlbumCoverSearcher), - app_(app), + albumcover_loader_(albumcover_loader), model_(new QStandardItemModel(this)), no_cover_icon_(no_cover_icon), fetcher_(nullptr), @@ -132,7 +130,7 @@ AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, Application * ui_->covers->setItemDelegate(new SizeOverlayDelegate(this)); ui_->covers->setModel(model_); - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverSearcher::AlbumCoverLoaded); + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverSearcher::AlbumCoverLoaded); QObject::connect(ui_->search, &QPushButton::clicked, this, &AlbumCoverSearcher::Search); QObject::connect(ui_->covers, &GroupedIconView::doubleClicked, this, &AlbumCoverSearcher::CoverDoubleClicked); @@ -220,7 +218,7 @@ void AlbumCoverSearcher::SearchFinished(const quint64 id, const CoverProviderSea AlbumCoverLoaderOptions cover_options(AlbumCoverLoaderOptions::Option::RawImageData | AlbumCoverLoaderOptions::Option::OriginalImage | AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage); cover_options.desired_scaled_size = ui_->covers->iconSize(), ui_->covers->iconSize(); - quint64 new_id = app_->album_cover_loader()->LoadImageAsync(cover_options, false, result.image_url, QUrl(), false); + quint64 new_id = albumcover_loader_->LoadImageAsync(cover_options, false, result.image_url, QUrl(), false); QStandardItem *item = new QStandardItem; item->setIcon(no_cover_icon_); diff --git a/src/covermanager/albumcoversearcher.h b/src/covermanager/albumcoversearcher.h index c6dec1beb9..8b2cd80717 100644 --- a/src/covermanager/albumcoversearcher.h +++ b/src/covermanager/albumcoversearcher.h @@ -48,7 +48,7 @@ class QPainter; class QModelIndex; class QKeyEvent; -class Application; +class AlbumCoverLoader; class Ui_AlbumCoverSearcher; class SizeOverlayDelegate : public QStyledItemDelegate { @@ -65,7 +65,7 @@ class AlbumCoverSearcher : public QDialog { Q_OBJECT public: - explicit AlbumCoverSearcher(const QIcon &no_cover_icon, Application *app, QWidget *parent); + explicit AlbumCoverSearcher(const QIcon &no_cover_icon, SharedPtr albumcover_loader, QWidget *parent); ~AlbumCoverSearcher() override; enum Role { @@ -95,7 +95,7 @@ class AlbumCoverSearcher : public QDialog { private: Ui_AlbumCoverSearcher *ui_; - Application *app_; + SharedPtr albumcover_loader_; QStandardItemModel *model_; QIcon no_cover_icon_; diff --git a/src/covermanager/coverexportrunnable.cpp b/src/covermanager/coverexportrunnable.cpp index 232c014843..7712039556 100644 --- a/src/covermanager/coverexportrunnable.cpp +++ b/src/covermanager/coverexportrunnable.cpp @@ -36,8 +36,9 @@ using namespace Qt::Literals::StringLiterals; -CoverExportRunnable::CoverExportRunnable(const AlbumCoverExport::DialogResult &dialog_result, const AlbumCoverLoaderOptions::Types &cover_types, const Song &song, QObject *parent) +CoverExportRunnable::CoverExportRunnable(SharedPtr tagreader_client, const AlbumCoverExport::DialogResult &dialog_result, const AlbumCoverLoaderOptions::Types &cover_types, const Song &song, QObject *parent) : QObject(parent), + tagreader_client_(tagreader_client), dialog_result_(dialog_result), cover_types_(cover_types), song_(song) {} @@ -78,7 +79,7 @@ void CoverExportRunnable::ProcessAndExportCover() { break; case AlbumCoverLoaderOptions::Type::Embedded: if (song_.art_embedded() && dialog_result_.export_embedded_) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(song_.url().toLocalFile(), image); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(song_.url().toLocalFile(), image); if (result.success() && !image.isNull()) { extension = "jpg"_L1; } @@ -170,7 +171,7 @@ void CoverExportRunnable::ExportCover() { break; case AlbumCoverLoaderOptions::Type::Embedded: if (song_.art_embedded() && dialog_result_.export_embedded_) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(song_.url().toLocalFile(), image); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(song_.url().toLocalFile(), image); if (result.success() && !image.isNull()) { embedded_cover = true; extension = "jpg"_L1; diff --git a/src/covermanager/coverexportrunnable.h b/src/covermanager/coverexportrunnable.h index b58e732162..6abd6f3db9 100644 --- a/src/covermanager/coverexportrunnable.h +++ b/src/covermanager/coverexportrunnable.h @@ -28,15 +28,22 @@ #include #include +#include "includes/shared_ptr.h" #include "core/song.h" #include "albumcoverloaderoptions.h" #include "albumcoverexport.h" +class TagReaderClient; + class CoverExportRunnable : public QObject, public QRunnable { Q_OBJECT public: - explicit CoverExportRunnable(const AlbumCoverExport::DialogResult &dialog_result, const AlbumCoverLoaderOptions::Types &cover_types, const Song &song, QObject *parent = nullptr); + explicit CoverExportRunnable(SharedPtr tagreader_client, + const AlbumCoverExport::DialogResult &dialog_result, + const AlbumCoverLoaderOptions::Types &cover_types, + const Song &song, + QObject *parent = nullptr); void run() override; @@ -51,6 +58,7 @@ class CoverExportRunnable : public QObject, public QRunnable { void ProcessAndExportCover(); void ExportCover(); + SharedPtr tagreader_client_; AlbumCoverExport::DialogResult dialog_result_; AlbumCoverLoaderOptions::Types cover_types_; Song song_; diff --git a/src/covermanager/coverfromurldialog.cpp b/src/covermanager/coverfromurldialog.cpp index 08605fdcac..f3c3b44ed2 100644 --- a/src/covermanager/coverfromurldialog.cpp +++ b/src/covermanager/coverfromurldialog.cpp @@ -31,7 +31,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/mimeutils.h" #include "widgets/busyindicator.h" diff --git a/src/covermanager/coverfromurldialog.h b/src/covermanager/coverfromurldialog.h index 61678d039e..f511a0e0d3 100644 --- a/src/covermanager/coverfromurldialog.h +++ b/src/covermanager/coverfromurldialog.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "albumcoverimageresult.h" class QWidget; diff --git a/src/covermanager/coverprovider.cpp b/src/covermanager/coverprovider.cpp index 955dba7074..f1e6dedc0e 100644 --- a/src/covermanager/coverprovider.cpp +++ b/src/covermanager/coverprovider.cpp @@ -24,8 +24,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.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 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 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) {} diff --git a/src/covermanager/coverprovider.h b/src/covermanager/coverprovider.h index 41ea4e6eb8..81b3106193 100644 --- a/src/covermanager/coverprovider.h +++ b/src/covermanager/coverprovider.h @@ -30,10 +30,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "albumcoverfetcher.h" -class Application; class NetworkAccessManager; // Each implementation of this interface downloads covers from one online service. @@ -42,7 +41,7 @@ class CoverProvider : public QObject { Q_OBJECT public: - explicit CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr 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 network, QObject *parent); // A name (very short description) of this provider, like "last.fm". QString name() const { return name_; } @@ -79,7 +78,6 @@ class CoverProvider : public QObject { using Param = QPair; using ParamList = QList; - Application *app_; SharedPtr network_; QString name_; bool enabled_; diff --git a/src/covermanager/coverproviders.cpp b/src/covermanager/coverproviders.cpp index f3980a401d..34887b9b39 100644 --- a/src/covermanager/coverproviders.cpp +++ b/src/covermanager/coverproviders.cpp @@ -36,7 +36,7 @@ #include "coverprovider.h" #include "coverproviders.h" -#include "settings/coverssettingspage.h" +#include "constants/coverssettings.h" int CoverProviders::NextOrderId = 0; @@ -60,8 +60,8 @@ void CoverProviders::ReloadSettings() { } Settings s; - s.beginGroup(CoversSettingsPage::kSettingsGroup); - const QStringList providers_enabled = s.value(CoversSettingsPage::kProviders, QStringList() << all_providers.values()).toStringList(); + s.beginGroup(CoversSettings::kSettingsGroup); + const QStringList providers_enabled = s.value(CoversSettings::kProviders, QStringList() << all_providers.values()).toStringList(); s.endGroup(); int i = 0; diff --git a/src/covermanager/currentalbumcoverloader.cpp b/src/covermanager/currentalbumcoverloader.cpp index 29f7ddebd4..d3c8d552e0 100644 --- a/src/covermanager/currentalbumcoverloader.cpp +++ b/src/covermanager/currentalbumcoverloader.cpp @@ -29,10 +29,9 @@ #include #include -#include "core/application.h" +#include "core/logging.h" #include "core/song.h" #include "core/temporaryfile.h" -#include "playlist/playlistmanager.h" #include "albumcoverloader.h" #include "albumcoverloaderresult.h" #include "currentalbumcoverloader.h" @@ -40,9 +39,9 @@ using std::make_unique; using namespace Qt::Literals::StringLiterals; -CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(Application *app, QObject *parent) +CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(SharedPtr albumcover_loader, QObject *parent) : QObject(parent), - app_(app), + albumcover_loader_(albumcover_loader), temp_file_pattern_(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + u"/strawberry-cover-XXXXXX.jpg"_s), id_(0) { @@ -52,8 +51,7 @@ CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(Application *app, QObject *pare options_.desired_scaled_size = QSize(120, 120); options_.default_cover = u":/pictures/cdcase.png"_s; - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &CurrentAlbumCoverLoader::LoadAlbumCover); - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CurrentAlbumCoverLoader::AlbumCoverReady); + QObject::connect(&*albumcover_loader, &AlbumCoverLoader::AlbumCoverLoaded, this, &CurrentAlbumCoverLoader::AlbumCoverReady); ReloadSettingsAsync(); @@ -76,7 +74,7 @@ void CurrentAlbumCoverLoader::ReloadSettings() { void CurrentAlbumCoverLoader::LoadAlbumCover(const Song &song) { last_song_ = song; - id_ = app_->album_cover_loader()->LoadImageAsync(options_, last_song_); + id_ = albumcover_loader_->LoadImageAsync(options_, last_song_); } diff --git a/src/covermanager/currentalbumcoverloader.h b/src/covermanager/currentalbumcoverloader.h index 008d622244..4289d0b529 100644 --- a/src/covermanager/currentalbumcoverloader.h +++ b/src/covermanager/currentalbumcoverloader.h @@ -29,19 +29,20 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/temporaryfile.h" #include "core/song.h" #include "albumcoverloaderoptions.h" #include "albumcoverloaderresult.h" -class Application; +class AlbumCoverLoader; class CurrentAlbumCoverLoader : public QObject { Q_OBJECT public: - explicit CurrentAlbumCoverLoader(Application *app, QObject *parent = nullptr); + explicit CurrentAlbumCoverLoader(SharedPtr albumcover_loader, QObject *parent = nullptr); ~CurrentAlbumCoverLoader() override; const AlbumCoverLoaderOptions &options() const { return options_; } @@ -61,7 +62,7 @@ class CurrentAlbumCoverLoader : public QObject { void AlbumCoverReady(const quint64 id, AlbumCoverLoaderResult result); private: - Application *app_; + SharedPtr albumcover_loader_; AlbumCoverLoaderOptions options_; QString temp_file_pattern_; diff --git a/src/covermanager/deezercoverprovider.cpp b/src/covermanager/deezercoverprovider.cpp index e16159e2a6..a5d90f362e 100644 --- a/src/covermanager/deezercoverprovider.cpp +++ b/src/covermanager/deezercoverprovider.cpp @@ -39,7 +39,6 @@ #include #include -#include "core/application.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/song.h" @@ -55,8 +54,8 @@ constexpr char kApiUrl[] = "https://api.deezer.com"; constexpr int kLimit = 10; } -DeezerCoverProvider::DeezerCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Deezer"_s, true, false, 2.0, true, true, app, network, parent) {} +DeezerCoverProvider::DeezerCoverProvider(SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Deezer"_s, true, false, 2.0, true, true, network, parent) {} DeezerCoverProvider::~DeezerCoverProvider() { diff --git a/src/covermanager/deezercoverprovider.h b/src/covermanager/deezercoverprovider.h index b84860896d..adcc50997f 100644 --- a/src/covermanager/deezercoverprovider.h +++ b/src/covermanager/deezercoverprovider.h @@ -34,13 +34,12 @@ class NetworkAccessManager; class QNetworkReply; -class Application; class DeezerCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit DeezerCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit DeezerCoverProvider(SharedPtr network, QObject *parent = nullptr); ~DeezerCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/discogscoverprovider.cpp b/src/covermanager/discogscoverprovider.cpp index d45d7fbee6..9912a6c95b 100644 --- a/src/covermanager/discogscoverprovider.cpp +++ b/src/covermanager/discogscoverprovider.cpp @@ -41,8 +41,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" #include "utilities/cryptutils.h" @@ -58,8 +57,8 @@ const char *DiscogsCoverProvider::kAccessKeyB64 = "dGh6ZnljUGJlZ1NEeXBuSFFxSVk=" const char *DiscogsCoverProvider::kSecretKeyB64 = "ZkFIcmlaSER4aHhRSlF2U3d0bm5ZVmdxeXFLWUl0UXI="; const int DiscogsCoverProvider::kRequestsDelay = 1000; -DiscogsCoverProvider::DiscogsCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Discogs"_s, false, false, 0.0, false, false, app, network, parent), +DiscogsCoverProvider::DiscogsCoverProvider(SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Discogs"_s, false, false, 0.0, false, false, network, parent), timer_flush_requests_(new QTimer(this)) { timer_flush_requests_->setInterval(kRequestsDelay); diff --git a/src/covermanager/discogscoverprovider.h b/src/covermanager/discogscoverprovider.h index 47f7667cff..7c33a4216d 100644 --- a/src/covermanager/discogscoverprovider.h +++ b/src/covermanager/discogscoverprovider.h @@ -35,20 +35,19 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "albumcoverfetcher.h" class NetworkAccessManager; class QNetworkReply; class QTimer; -class Application; class DiscogsCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit DiscogsCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit DiscogsCoverProvider(SharedPtr network, QObject *parent = nullptr); ~DiscogsCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/jsoncoverprovider.cpp b/src/covermanager/jsoncoverprovider.cpp index 531d8c6ee9..dd158c193d 100644 --- a/src/covermanager/jsoncoverprovider.cpp +++ b/src/covermanager/jsoncoverprovider.cpp @@ -25,16 +25,15 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "coverprovider.h" #include "jsoncoverprovider.h" using namespace Qt::Literals::StringLiterals; -JsonCoverProvider::JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr network, QObject *parent) - : CoverProvider(name, enabled, authentication_required, quality, batch, allow_missing_album, app, network, parent) {} +JsonCoverProvider::JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, SharedPtr network, QObject *parent) + : CoverProvider(name, enabled, authentication_required, quality, batch, allow_missing_album, network, parent) {} QJsonObject JsonCoverProvider::ExtractJsonObj(const QByteArray &data) { diff --git a/src/covermanager/jsoncoverprovider.h b/src/covermanager/jsoncoverprovider.h index e00a83908c..5a6a3b453f 100644 --- a/src/covermanager/jsoncoverprovider.h +++ b/src/covermanager/jsoncoverprovider.h @@ -27,17 +27,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "coverprovider.h" -class Application; class NetworkAccessManager; class JsonCoverProvider : public CoverProvider { Q_OBJECT public: - explicit JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr 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 network, QObject *parent); protected: QJsonObject ExtractJsonObj(const QByteArray &data); diff --git a/src/covermanager/lastfmcoverprovider.cpp b/src/covermanager/lastfmcoverprovider.cpp index 75eb29d15e..b9417199cc 100644 --- a/src/covermanager/lastfmcoverprovider.cpp +++ b/src/covermanager/lastfmcoverprovider.cpp @@ -38,8 +38,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" @@ -55,8 +54,8 @@ constexpr char kApiKey[] = "211990b4c96782c05d1536e7219eb56e"; constexpr char kSecret[] = "80fd738f49596e9709b1bf9319c444a8"; } // namespace -LastFmCoverProvider::LastFmCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Last.fm"_s, true, false, 1.0, true, false, app, network, parent) {} +LastFmCoverProvider::LastFmCoverProvider(SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Last.fm"_s, true, false, 1.0, true, false, network, parent) {} LastFmCoverProvider::~LastFmCoverProvider() { diff --git a/src/covermanager/lastfmcoverprovider.h b/src/covermanager/lastfmcoverprovider.h index 231fdb9eda..fea9e7cd6d 100644 --- a/src/covermanager/lastfmcoverprovider.h +++ b/src/covermanager/lastfmcoverprovider.h @@ -29,18 +29,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" class NetworkAccessManager; class QNetworkReply; -class Application; class LastFmCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit LastFmCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit LastFmCoverProvider(SharedPtr network, QObject *parent = nullptr); ~LastFmCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/musicbrainzcoverprovider.cpp b/src/covermanager/musicbrainzcoverprovider.cpp index 4a778438e4..b228234549 100644 --- a/src/covermanager/musicbrainzcoverprovider.cpp +++ b/src/covermanager/musicbrainzcoverprovider.cpp @@ -36,8 +36,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "albumcoverfetcher.h" @@ -53,8 +52,8 @@ constexpr int kLimit = 8; constexpr int kRequestsDelay = 1000; } // namespace -MusicbrainzCoverProvider::MusicbrainzCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"MusicBrainz"_s, true, false, 1.5, true, false, app, network, parent), +MusicbrainzCoverProvider::MusicbrainzCoverProvider(SharedPtr network, QObject *parent) + : JsonCoverProvider(u"MusicBrainz"_s, true, false, 1.5, true, false, network, parent), timer_flush_requests_(new QTimer(this)) { timer_flush_requests_->setInterval(kRequestsDelay); diff --git a/src/covermanager/musicbrainzcoverprovider.h b/src/covermanager/musicbrainzcoverprovider.h index 2ceacbf476..8f7a745346 100644 --- a/src/covermanager/musicbrainzcoverprovider.h +++ b/src/covermanager/musicbrainzcoverprovider.h @@ -30,19 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" class QNetworkReply; class QTimer; -class Application; class NetworkAccessManager; class MusicbrainzCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit MusicbrainzCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit MusicbrainzCoverProvider(SharedPtr network, QObject *parent = nullptr); ~MusicbrainzCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/musixmatchcoverprovider.cpp b/src/covermanager/musixmatchcoverprovider.cpp index f3bf5731fb..5611c4ef01 100644 --- a/src/covermanager/musixmatchcoverprovider.cpp +++ b/src/covermanager/musixmatchcoverprovider.cpp @@ -32,18 +32,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" -#include "providers/musixmatchprovider.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" #include "musixmatchcoverprovider.h" using namespace Qt::Literals::StringLiterals; -MusixmatchCoverProvider::MusixmatchCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Musixmatch"_s, true, false, 1.0, true, false, app, network, parent) {} +MusixmatchCoverProvider::MusixmatchCoverProvider(SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Musixmatch"_s, true, false, 1.0, true, false, network, parent) {} MusixmatchCoverProvider::~MusixmatchCoverProvider() { diff --git a/src/covermanager/musixmatchcoverprovider.h b/src/covermanager/musixmatchcoverprovider.h index 6ded62130b..d7ef882676 100644 --- a/src/covermanager/musixmatchcoverprovider.h +++ b/src/covermanager/musixmatchcoverprovider.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "providers/musixmatchprovider.h" @@ -39,7 +39,7 @@ class MusixmatchCoverProvider : public JsonCoverProvider, MusixmatchProvider { Q_OBJECT public: - explicit MusixmatchCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit MusixmatchCoverProvider(SharedPtr network, QObject *parent = nullptr); ~MusixmatchCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/opentidalcoverprovider.cpp b/src/covermanager/opentidalcoverprovider.cpp index 205f409510..c4ac4b6e7d 100644 --- a/src/covermanager/opentidalcoverprovider.cpp +++ b/src/covermanager/opentidalcoverprovider.cpp @@ -37,12 +37,12 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/settings.h" -#include "utilities/timeconstants.h" +#include "core/song.h" +#include "constants/timeconstants.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" #include "opentidalcoverprovider.h" @@ -61,8 +61,8 @@ constexpr const int kRequestsDelay = 1000; using std::make_shared; -OpenTidalCoverProvider::OpenTidalCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"OpenTidal"_s, true, false, 2.5, true, false, app, network, parent), +OpenTidalCoverProvider::OpenTidalCoverProvider(SharedPtr network, QObject *parent) + : JsonCoverProvider(u"OpenTidal"_s, true, false, 2.5, true, false, network, parent), login_timer_(new QTimer(this)), timer_flush_requests_(new QTimer(this)), login_in_progress_(false), diff --git a/src/covermanager/opentidalcoverprovider.h b/src/covermanager/opentidalcoverprovider.h index 396d16c78b..d7bf55c70e 100644 --- a/src/covermanager/opentidalcoverprovider.h +++ b/src/covermanager/opentidalcoverprovider.h @@ -32,11 +32,10 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" class QNetworkReply; -class Application; class NetworkAccessManager; class QTimer; @@ -44,7 +43,7 @@ class OpenTidalCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit OpenTidalCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit OpenTidalCoverProvider(SharedPtr network, QObject *parent = nullptr); ~OpenTidalCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/qobuzcoverprovider.cpp b/src/covermanager/qobuzcoverprovider.cpp index c4b0a09c75..cc146c61c7 100644 --- a/src/covermanager/qobuzcoverprovider.cpp +++ b/src/covermanager/qobuzcoverprovider.cpp @@ -36,12 +36,10 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/song.h" -#include "streaming/streamingservices.h" #include "qobuz/qobuzservice.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" @@ -53,9 +51,9 @@ namespace { constexpr int kLimit = 10; } -QobuzCoverProvider::QobuzCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Qobuz"_s, true, true, 2.0, true, true, app, network, parent), - service_(app->streaming_services()->Service()) {} +QobuzCoverProvider::QobuzCoverProvider(QobuzServicePtr service, SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Qobuz"_s, true, true, 2.0, true, true, network, parent), + service_(service) {} QobuzCoverProvider::~QobuzCoverProvider() { diff --git a/src/covermanager/qobuzcoverprovider.h b/src/covermanager/qobuzcoverprovider.h index 6368d24819..8cd6be2a05 100644 --- a/src/covermanager/qobuzcoverprovider.h +++ b/src/covermanager/qobuzcoverprovider.h @@ -30,19 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "qobuz/qobuzservice.h" class QNetworkReply; -class Application; class NetworkAccessManager; class QobuzCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit QobuzCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit QobuzCoverProvider(QobuzServicePtr service, SharedPtr network, QObject *parent = nullptr); ~QobuzCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/spotifycoverprovider.cpp b/src/covermanager/spotifycoverprovider.cpp index b33caacfe6..866f3e1df9 100644 --- a/src/covermanager/spotifycoverprovider.cpp +++ b/src/covermanager/spotifycoverprovider.cpp @@ -38,11 +38,9 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" -#include "streaming/streamingservices.h" #include "spotify/spotifyservice.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" @@ -55,9 +53,9 @@ constexpr char kApiUrl[] = "https://api.spotify.com/v1"; constexpr int kLimit = 10; } // namespace -SpotifyCoverProvider::SpotifyCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Spotify"_s, true, true, 2.5, true, true, app, network, parent), - service_(app->streaming_services()->Service()) {} +SpotifyCoverProvider::SpotifyCoverProvider(SpotifyServicePtr service, SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Spotify"_s, true, true, 2.5, true, true, network, parent), + service_(service) {} SpotifyCoverProvider::~SpotifyCoverProvider() { diff --git a/src/covermanager/spotifycoverprovider.h b/src/covermanager/spotifycoverprovider.h index 99df10f0ba..05efae1dfb 100644 --- a/src/covermanager/spotifycoverprovider.h +++ b/src/covermanager/spotifycoverprovider.h @@ -34,19 +34,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "spotify/spotifyservice.h" class QNetworkReply; -class Application; class NetworkAccessManager; class SpotifyCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit SpotifyCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit SpotifyCoverProvider(SpotifyServicePtr service, SharedPtr network, QObject *parent = nullptr); ~SpotifyCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/tidalcoverprovider.cpp b/src/covermanager/tidalcoverprovider.cpp index 0cefaaf4ad..4ed71d1c76 100644 --- a/src/covermanager/tidalcoverprovider.cpp +++ b/src/covermanager/tidalcoverprovider.cpp @@ -34,12 +34,10 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/song.h" -#include "streaming/streamingservices.h" #include "tidal/tidalservice.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" @@ -51,9 +49,9 @@ namespace { constexpr int kLimit = 10; } -TidalCoverProvider::TidalCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Tidal"_s, true, true, 2.5, true, true, app, network, parent), - service_(app->streaming_services()->Service()) {} +TidalCoverProvider::TidalCoverProvider(TidalServicePtr service, SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Tidal"_s, true, true, 2.5, true, true, network, parent), + service_(service) {} TidalCoverProvider::~TidalCoverProvider() { diff --git a/src/covermanager/tidalcoverprovider.h b/src/covermanager/tidalcoverprovider.h index 351d51eef5..717e245431 100644 --- a/src/covermanager/tidalcoverprovider.h +++ b/src/covermanager/tidalcoverprovider.h @@ -32,19 +32,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "tidal/tidalservice.h" class QNetworkReply; -class Application; class NetworkAccessManager; class TidalCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit TidalCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit TidalCoverProvider(TidalServicePtr service, SharedPtr network, QObject *parent = nullptr); ~TidalCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/device/cddadevice.cpp b/src/device/cddadevice.cpp index 7c4d4d0f24..9fcb2226ed 100644 --- a/src/device/cddadevice.cpp +++ b/src/device/cddadevice.cpp @@ -24,24 +24,33 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "collection/collectionmodel.h" #include "cddasongloader.h" #include "connecteddevice.h" #include "cddadevice.h" -class Application; class DeviceLister; class DeviceManager; -CddaDevice::CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, int database_id, bool first_time, QObject *parent) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), +CddaDevice::CddaDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) + : ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), cdda_song_loader_(url) { QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsLoaded, this, &CddaDevice::SongsLoaded); QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsDurationLoaded, this, &CddaDevice::SongsLoaded); QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsMetadataLoaded, this, &CddaDevice::SongsLoaded); - QObject::connect(this, &CddaDevice::SongsDiscovered, model_, &CollectionModel::AddReAddOrUpdate); + QObject::connect(this, &CddaDevice::SongsDiscovered, collection_model_, &CollectionModel::AddReAddOrUpdate); } @@ -64,7 +73,7 @@ void CddaDevice::Refresh() { void CddaDevice::SongsLoaded(const SongList &songs) { - model_->Reset(); + collection_model_->Reset(); Q_EMIT SongsDiscovered(songs); song_count_ = songs.size(); diff --git a/src/device/cddadevice.h b/src/device/cddadevice.h index 283b1e35d5..aa0a8c456c 100644 --- a/src/device/cddadevice.h +++ b/src/device/cddadevice.h @@ -24,30 +24,42 @@ #include "config.h" +#include +#include + #include #include #include #include -// These must come after Qt includes -#include -#include - -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" #include "cddasongloader.h" #include "connecteddevice.h" -class Application; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class CddaDevice : public ConnectedDevice { Q_OBJECT public: - Q_INVOKABLE explicit CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr 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, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); bool Init() override; void Refresh() override; diff --git a/src/device/cddasongloader.cpp b/src/device/cddasongloader.cpp index 9a7d16db46..16b726f011 100644 --- a/src/device/cddasongloader.cpp +++ b/src/device/cddasongloader.cpp @@ -40,10 +40,10 @@ #include #include "cddasongloader.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" using std::make_shared; diff --git a/src/device/cddasongloader.h b/src/device/cddasongloader.h index 10d16d159a..0b127d6d8a 100644 --- a/src/device/cddasongloader.h +++ b/src/device/cddasongloader.h @@ -35,7 +35,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #ifdef HAVE_MUSICBRAINZ # include "musicbrainz/musicbrainzclient.h" diff --git a/src/device/connecteddevice.cpp b/src/device/connecteddevice.cpp index d981a087c9..58976f15f6 100644 --- a/src/device/connecteddevice.cpp +++ b/src/device/connecteddevice.cpp @@ -26,9 +26,9 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" +#include "core/taskmanager.h" #include "core/database.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" @@ -41,47 +41,58 @@ using namespace Qt::Literals::StringLiterals; using std::make_shared; -ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) +ConnectedDevice::ConnectedDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) : QObject(parent), - app_(app), url_(url), first_time_(first_time), lister_(lister), unique_id_(unique_id), database_id_(database_id), - manager_(manager), - backend_(nullptr), - model_(nullptr), + device_manager_(device_manager), + collection_backend_(nullptr), + collection_model_(nullptr), song_count_(0) { + Q_UNUSED(tagreader_client) + qLog(Info) << "Connected" << url << unique_id << first_time; // Create the backend in the database thread. - backend_ = make_shared(); - backend_->moveToThread(app_->database()->thread()); - qLog(Debug) << &*backend_ << "for device" << unique_id_ << "moved to thread" << app_->database()->thread(); + collection_backend_ = make_shared(); + collection_backend_->moveToThread(database->thread()); + qLog(Debug) << &*collection_backend_ << "for device" << unique_id_ << "moved to thread" << database->thread(); if (url_.scheme() != "cdda"_L1) { - QObject::connect(&*backend_, &CollectionBackend::TotalSongCountUpdated, this, &ConnectedDevice::BackendTotalSongCountUpdated); + QObject::connect(&*collection_backend_, &CollectionBackend::TotalSongCountUpdated, this, &ConnectedDevice::BackendTotalSongCountUpdated); } - backend_->Init(app_->database(), - app_->task_manager(), - Song::Source::Device, - QStringLiteral("device_%1_songs").arg(database_id), - QStringLiteral("device_%1_directories").arg(database_id), - QStringLiteral("device_%1_subdirectories").arg(database_id)); + collection_backend_->Init(database, + task_manager, + Song::Source::Device, + QStringLiteral("device_%1_songs").arg(database_id), + QStringLiteral("device_%1_directories").arg(database_id), + QStringLiteral("device_%1_subdirectories").arg(database_id)); // Create the model - model_ = new CollectionModel(backend_, app_, this); + collection_model_ = new CollectionModel(collection_backend_, albumcover_loader, this); } void ConnectedDevice::InitBackendDirectory(const QString &mount_point, const bool first_time, const bool rewrite_path) { - QList directories = backend_->GetAllDirectories(); + QList directories = collection_backend_->GetAllDirectories(); if (first_time || directories.isEmpty()) { - backend_->AddDirectory(mount_point); + collection_backend_->AddDirectory(mount_point); } else { if (rewrite_path) { @@ -95,12 +106,12 @@ void ConnectedDevice::InitBackendDirectory(const QString &mount_point, const boo if (dir.path != mount_point) { // The directory is different, commence the munging. qLog(Info) << "Changing path from" << dir.path << "to" << mount_point; - backend_->ChangeDirPath(dir.id, dir.path, mount_point); + collection_backend_->ChangeDirPath(dir.id, dir.path, mount_point); } } // Load the directory properly now - backend_->LoadDirectoriesAsync(); + collection_backend_->LoadDirectoriesAsync(); } } @@ -109,8 +120,8 @@ void ConnectedDevice::ConnectAsync() { Q_EMIT DeviceConnectFinished(unique_id_, void ConnectedDevice::Close() { - QObject::connect(&*backend_, &CollectionBackend::ExitFinished, this, &ConnectedDevice::BackendCloseFinished); - backend_->ExitAsync(); + QObject::connect(&*collection_backend_, &CollectionBackend::ExitFinished, this, &ConnectedDevice::BackendCloseFinished); + collection_backend_->ExitAsync(); } @@ -122,13 +133,13 @@ void ConnectedDevice::BackendCloseFinished() { void ConnectedDevice::Eject() { - DeviceInfo *info = manager_->FindDeviceById(unique_id_); + DeviceInfo *info = device_manager_->FindDeviceById(unique_id_); if (!info) return; - QModelIndex idx = manager_->ItemToIndex(info); + QModelIndex idx = device_manager_->ItemToIndex(info); if (!idx.isValid()) return; - manager_->UnmountAsync(idx); + device_manager_->UnmountAsync(idx); } @@ -150,10 +161,10 @@ bool ConnectedDevice::FinishDelete(bool success, QString &error_text) { MusicStorage::TranscodeMode ConnectedDevice::GetTranscodeMode() const { - DeviceInfo *info = manager_->FindDeviceById(unique_id_); + DeviceInfo *info = device_manager_->FindDeviceById(unique_id_); if (!info) return MusicStorage::TranscodeMode(); - QModelIndex idx = manager_->ItemToIndex(info); + QModelIndex idx = device_manager_->ItemToIndex(info); if (!idx.isValid()) return MusicStorage::TranscodeMode(); return static_cast(idx.data(DeviceManager::Role_TranscodeMode).toInt()); @@ -162,10 +173,10 @@ MusicStorage::TranscodeMode ConnectedDevice::GetTranscodeMode() const { Song::FileType ConnectedDevice::GetTranscodeFormat() const { - DeviceInfo *info = manager_->FindDeviceById(unique_id_); + DeviceInfo *info = device_manager_->FindDeviceById(unique_id_); if (!info) return Song::FileType::Unknown; - QModelIndex idx = manager_->ItemToIndex(info); + QModelIndex idx = device_manager_->ItemToIndex(info); if (!idx.isValid()) return Song::FileType::Unknown; return static_cast(idx.data(DeviceManager::Role_TranscodeFormat).toInt()); diff --git a/src/device/connecteddevice.h b/src/device/connecteddevice.h index 724ade506c..f5b0c7e842 100644 --- a/src/device/connecteddevice.h +++ b/src/device/connecteddevice.h @@ -30,15 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/musicstorage.h" #include "core/song.h" -class Application; +class TaskManager; +class Database; class CollectionBackend; class CollectionModel; class DeviceLister; class DeviceManager; +class TagReaderClient; +class AlbumCoverLoader; using std::enable_shared_from_this; @@ -46,7 +49,17 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab Q_OBJECT public: - explicit ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr 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, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); Song::Source source() const override { return Song::Source::Device; } @@ -63,7 +76,7 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab DeviceLister *lister() const { return lister_; } QString unique_id() const { return unique_id_; } - CollectionModel *model() const { return model_; } + CollectionModel *collection_model() const { return collection_model_; } QUrl url() const { return url_; } qint64 song_count() const { return song_count_; } @@ -81,23 +94,20 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab void SongCountUpdated(const int count); void DeviceConnectFinished(const QString &id, const bool success); void DeviceCloseFinished(const QString &id); + void Error(const QString &error); protected: void InitBackendDirectory(const QString &mount_point, const bool first_time, const bool rewrite_path = true); protected: - Application *app_; - QUrl url_; bool first_time_; DeviceLister *lister_; QString unique_id_; int database_id_; - SharedPtr manager_; - - SharedPtr backend_; - CollectionModel *model_; - + DeviceManager *device_manager_; + SharedPtr collection_backend_; + CollectionModel *collection_model_; qint64 song_count_; private Q_SLOTS: diff --git a/src/device/devicedatabasebackend.cpp b/src/device/devicedatabasebackend.cpp index 1784de0253..86b0da5d13 100644 --- a/src/device/devicedatabasebackend.cpp +++ b/src/device/devicedatabasebackend.cpp @@ -32,7 +32,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/database.h" #include "core/sqlquery.h" #include "core/scopedtransaction.h" diff --git a/src/device/devicedatabasebackend.h b/src/device/devicedatabasebackend.h index 0b26c64001..4c1f11f93a 100644 --- a/src/device/devicedatabasebackend.h +++ b/src/device/devicedatabasebackend.h @@ -30,7 +30,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" diff --git a/src/device/devicemanager.cpp b/src/device/devicemanager.cpp index c19776be48..571dee134d 100644 --- a/src/device/devicemanager.cpp +++ b/src/device/devicemanager.cpp @@ -45,10 +45,9 @@ #include "devicemanager.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/database.h" #include "core/iconloader.h" #include "core/musicstorage.h" @@ -88,20 +87,27 @@ using std::make_unique; const int DeviceManager::kDeviceIconSize = 32; const int DeviceManager::kDeviceIconOverlaySize = 16; -DeviceManager::DeviceManager(Application *app, QObject *parent) +DeviceManager::DeviceManager(const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + QObject *parent) : SimpleTreeModel(new DeviceInfo(this), parent), - app_(app), + task_manager_(task_manager), + database_(database), + tagreader_client_(tagreader_client), + albumcover_loader_(albumcover_loader), not_connected_overlay_(IconLoader::Load(u"edit-delete"_s)) { setObjectName(QLatin1String(metaObject()->className())); thread_pool_.setMaxThreadCount(1); - QObject::connect(&*app_->task_manager(), &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged); + QObject::connect(&*task_manager, &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged); // Create the backend in the database thread backend_ = make_unique(); - backend_->moveToThread(app_->database()->thread()); - backend_->Init(app_->database()); + backend_->moveToThread(database->thread()); + backend_->Init(database); QObject::connect(this, &DeviceManager::DeviceCreatedFromDB, this, &DeviceManager::AddDeviceFromDB); @@ -225,6 +231,7 @@ void DeviceManager::DeviceDestroyed() { if (wait_for_exit_.isEmpty()) CloseListers(); } + void DeviceManager::LoadAllDevices() { Q_ASSERT(QThread::currentThread() != qApp->thread()); @@ -363,7 +370,7 @@ QVariant DeviceManager::data(const QModelIndex &idx, int role) const { QString ret = info->device_->url().path(); #ifdef Q_OS_WIN32 - if (ret.startsWith('/')) ret.remove(0, 1); + if (ret.startsWith(u'/')) ret.remove(0, 1); #endif return QDir::toNativeSeparators(ret); } @@ -627,7 +634,7 @@ SharedPtr DeviceManager::Connect(DeviceInfo *info) { url_strings << url.toString(); } - app_->AddError(tr("This type of device is not supported: %1").arg(url_strings.join(", "_L1))); + Q_EMIT DeviceError(tr("This type of device is not supported: %1").arg(url_strings.join(", "_L1))); return ret; } @@ -636,8 +643,11 @@ SharedPtr DeviceManager::Connect(DeviceInfo *info) { Q_ARG(QUrl, device_url), Q_ARG(DeviceLister*, info->BestBackend()->lister_), Q_ARG(QString, info->BestBackend()->unique_id_), - Q_ARG(SharedPtr, app_->device_manager()), - Q_ARG(Application*, app_), + Q_ARG(DeviceManager*, this), + Q_ARG(SharedPtr, task_manager_), + Q_ARG(SharedPtr, database_), + Q_ARG(SharedPtr, tagreader_client_), + Q_ARG(SharedPtr, albumcover_loader_), Q_ARG(int, info->database_id_), Q_ARG(bool, first_time)); @@ -664,7 +674,10 @@ SharedPtr DeviceManager::Connect(DeviceInfo *info) { QObject::connect(&*info->device_, &ConnectedDevice::SongCountUpdated, this, &DeviceManager::DeviceSongCountUpdated); QObject::connect(&*info->device_, &ConnectedDevice::DeviceConnectFinished, this, &DeviceManager::DeviceConnectFinished); QObject::connect(&*info->device_, &ConnectedDevice::DeviceCloseFinished, this, &DeviceManager::DeviceCloseFinished); + QObject::connect(&*info->device_, &ConnectedDevice::Error, this, &DeviceManager::DeviceError); + ret->ConnectAsync(); + return ret; } @@ -842,7 +855,7 @@ void DeviceManager::DeviceTaskStarted(const int id) { void DeviceManager::TasksChanged() { - const QList tasks = app_->task_manager()->GetTasks(); + const QList tasks = task_manager_->GetTasks(); QList finished_tasks = active_tasks_.values(); for (const TaskManager::Task &task : tasks) { diff --git a/src/device/devicemanager.h b/src/device/devicemanager.h index 8fd2a82a3b..68a3a46a6d 100644 --- a/src/device/devicemanager.h +++ b/src/device/devicemanager.h @@ -37,8 +37,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" #include "core/simpletreemodel.h" @@ -49,7 +49,10 @@ class QModelIndex; class QPersistentModelIndex; -class Application; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class ConnectedDevice; class DeviceLister; class DeviceStateFilterModel; @@ -58,7 +61,12 @@ class DeviceManager : public SimpleTreeModel { Q_OBJECT public: - explicit DeviceManager(Application *app, QObject *parent = nullptr); + explicit DeviceManager(const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + QObject *parent = nullptr); + ~DeviceManager() override; enum Role { @@ -123,6 +131,7 @@ class DeviceManager : public SimpleTreeModel { void DeviceConnected(const QModelIndex idx); void DeviceDisconnected(const QModelIndex idx); void DeviceCreatedFromDB(DeviceInfo *info); + void DeviceError(const QString &error); private Q_SLOTS: void PhysicalDeviceAdded(const QString &id); @@ -152,7 +161,11 @@ class DeviceManager : public SimpleTreeModel { void CloseBackend(); private: - Application *app_; + const SharedPtr task_manager_; + const SharedPtr database_; + const SharedPtr tagreader_client_; + const SharedPtr albumcover_loader_; + ScopedPtr backend_; DeviceStateFilterModel *connected_devices_model_; diff --git a/src/device/deviceproperties.cpp b/src/device/deviceproperties.cpp index 0e53f75397..ef5db1f9e8 100644 --- a/src/device/deviceproperties.cpp +++ b/src/device/deviceproperties.cpp @@ -46,7 +46,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/iconloader.h" #include "core/musicstorage.h" #include "widgets/freespacebar.h" @@ -62,7 +62,7 @@ using namespace Qt::Literals::StringLiterals; DeviceProperties::DeviceProperties(QWidget *parent) : QDialog(parent), ui_(new Ui_DeviceProperties), - manager_(nullptr), + device_manager_(nullptr), updating_formats_(false) { ui_->setupUi(this); @@ -76,12 +76,12 @@ DeviceProperties::DeviceProperties(QWidget *parent) DeviceProperties::~DeviceProperties() { delete ui_; } -void DeviceProperties::SetDeviceManager(SharedPtr manager) { +void DeviceProperties::Init(SharedPtr device_manager) { - manager_ = manager; - QObject::connect(&*manager_, &DeviceManager::dataChanged, this, &DeviceProperties::ModelChanged); - QObject::connect(&*manager_, &DeviceManager::rowsInserted, this, &DeviceProperties::ModelChanged); - QObject::connect(&*manager_, &DeviceManager::rowsRemoved, this, &DeviceProperties::ModelChanged); + device_manager_ = device_manager; + QObject::connect(&*device_manager_, &DeviceManager::dataChanged, this, &DeviceProperties::ModelChanged); + QObject::connect(&*device_manager_, &DeviceManager::rowsInserted, this, &DeviceProperties::ModelChanged); + QObject::connect(&*device_manager_, &DeviceManager::rowsRemoved, this, &DeviceProperties::ModelChanged); } @@ -155,7 +155,7 @@ void DeviceProperties::UpdateHardwareInfo() { // Hardware information QString id = index_.data(DeviceManager::Role_UniqueId).toString(); - if (DeviceLister *lister = manager_->GetLister(index_)) { + if (DeviceLister *lister = device_manager_->GetLister(index_)) { QVariantMap info = lister->DeviceHardwareInfo(id); // Remove empty items @@ -202,8 +202,8 @@ void DeviceProperties::UpdateHardwareInfo() { void DeviceProperties::UpdateFormats() { - DeviceLister *lister = manager_->GetLister(index_); - SharedPtr device = manager_->GetConnectedDevice(index_); + DeviceLister *lister = device_manager_->GetLister(index_); + SharedPtr device = device_manager_->GetConnectedDevice(index_); // Transcode mode MusicStorage::TranscodeMode mode = static_cast(index_.data(DeviceManager::Role_TranscodeMode).toInt()); @@ -274,11 +274,11 @@ void DeviceProperties::accept() { icon_name = ui_->icon->currentItem()->data(Qt::UserRole).toString(); } - manager_->SetDeviceOptions(index_, ui_->name->text(), icon_name, mode, format); + device_manager_->SetDeviceOptions(index_, ui_->name->text(), icon_name, mode, format); } -void DeviceProperties::OpenDevice() { manager_->Connect(index_); } +void DeviceProperties::OpenDevice() { device_manager_->Connect(index_); } void DeviceProperties::UpdateFormatsFinished() { diff --git a/src/device/deviceproperties.h b/src/device/deviceproperties.h index 74bf5286ea..23e13400ba 100644 --- a/src/device/deviceproperties.h +++ b/src/device/deviceproperties.h @@ -33,7 +33,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QWidget; @@ -48,7 +48,7 @@ class DeviceProperties : public QDialog { explicit DeviceProperties(QWidget *parent = nullptr); ~DeviceProperties() override; - void SetDeviceManager(SharedPtr manager); + void Init(SharedPtr device_manager); void ShowDevice(const QModelIndex &idx); public Q_SLOTS: @@ -67,7 +67,7 @@ class DeviceProperties : public QDialog { private: Ui_DeviceProperties *ui_; - SharedPtr manager_; + SharedPtr device_manager_; QPersistentModelIndex index_; bool updating_formats_; diff --git a/src/device/deviceview.cpp b/src/device/deviceview.cpp index d9b7ccdf7d..0aa94f59eb 100644 --- a/src/device/deviceview.cpp +++ b/src/device/deviceview.cpp @@ -48,9 +48,9 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/shared_ptr.h" +#include "includes/scoped_ptr.h" #include "core/iconloader.h" -#include "core/application.h" #include "core/deletefiles.h" #include "core/mergedproxymodel.h" #include "core/mimedata.h" @@ -61,8 +61,8 @@ #include "collection/collectiondirectorymodel.h" #include "collection/collectionmodel.h" #include "collection/collectionitemdelegate.h" -#include "connecteddevice.h" #include "devicelister.h" +#include "connecteddevice.h" #include "devicemanager.h" #include "deviceproperties.h" #include "deviceview.h" @@ -175,7 +175,6 @@ void DeviceItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op DeviceView::DeviceView(QWidget *parent) : AutoExpandingTreeView(parent), - app_(nullptr), merged_model_(nullptr), sort_model_(nullptr), properties_dialog_(new DeviceProperties), @@ -202,16 +201,20 @@ DeviceView::DeviceView(QWidget *parent) DeviceView::~DeviceView() = default; -void DeviceView::SetApplication(Application *app) { +void DeviceView::Init(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr device_manager, + CollectionDirectoryModel *collection_directory_model) { - Q_ASSERT(app_ == nullptr); - app_ = app; + task_manager_ = task_manager; + tagreader_client_ = tagreader_client; + device_manager_ = device_manager; - QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceConnected, this, &DeviceView::DeviceConnected); - QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceDisconnected, this, &DeviceView::DeviceDisconnected); + QObject::connect(&*device_manager_, &DeviceManager::DeviceConnected, this, &DeviceView::DeviceConnected); + QObject::connect(&*device_manager_, &DeviceManager::DeviceDisconnected, this, &DeviceView::DeviceDisconnected); sort_model_ = new QSortFilterProxyModel(this); - sort_model_->setSourceModel(&*app_->device_manager()); + sort_model_->setSourceModel(&*device_manager_); sort_model_->setDynamicSortFilter(true); sort_model_->setSortCaseSensitivity(Qt::CaseInsensitive); sort_model_->sort(0); @@ -222,10 +225,10 @@ void DeviceView::SetApplication(Application *app) { QObject::connect(merged_model_, &MergedProxyModel::SubModelReset, this, &AutoExpandingTreeView::RecursivelyExpandSlot); - properties_dialog_->SetDeviceManager(app_->device_manager()); + properties_dialog_->Init(device_manager_); - organize_dialog_ = make_unique(app_->task_manager(), nullptr, this); - organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model()); + organize_dialog_ = make_unique(task_manager, tagreader_client, nullptr, this); + organize_dialog_->SetDestinationModel(collection_directory_model); } @@ -257,8 +260,8 @@ void DeviceView::contextMenuEvent(QContextMenuEvent *e) { const QModelIndex collection_index = MapToCollection(menu_index_); if (device_index.isValid()) { - const bool is_plugged_in = app_->device_manager()->GetLister(device_index); - const bool is_remembered = app_->device_manager()->GetDatabaseId(device_index) != -1; + const bool is_plugged_in = device_manager_->GetLister(device_index); + const bool is_remembered = device_manager_->GetDatabaseId(device_index) != -1; forget_action_->setEnabled(is_remembered); eject_action_->setEnabled(is_plugged_in); @@ -270,7 +273,7 @@ void DeviceView::contextMenuEvent(QContextMenuEvent *e) { bool is_filesystem_device = false; if (parent_device_index.isValid()) { - SharedPtr device = app_->device_manager()->GetConnectedDevice(parent_device_index); + SharedPtr device = device_manager_->GetConnectedDevice(parent_device_index); if (device && !device->LocalPath().isEmpty()) is_filesystem_device = true; } @@ -309,21 +312,21 @@ QModelIndex DeviceView::MapToCollection(const QModelIndex &merged_model_index) c void DeviceView::Connect() { QModelIndex device_idx = MapToDevice(menu_index_); - app_->device_manager()->data(device_idx, MusicStorage::Role_StorageForceConnect); + device_manager_->data(device_idx, MusicStorage::Role_StorageForceConnect); } void DeviceView::DeviceConnected(const QModelIndex &idx) { if (!idx.isValid()) return; - SharedPtr device = app_->device_manager()->GetConnectedDevice(idx); + SharedPtr device = device_manager_->GetConnectedDevice(idx); if (!device) return; QModelIndex sort_idx = sort_model_->mapFromSource(idx); if (!sort_idx.isValid()) return; - QSortFilterProxyModel *sort_model = new QSortFilterProxyModel(device->model()); - sort_model->setSourceModel(device->model()); + QSortFilterProxyModel *sort_model = new QSortFilterProxyModel(device->collection_model()); + sort_model->setSourceModel(device->collection_model()); sort_model->setSortRole(CollectionModel::Role_SortText); sort_model->setDynamicSortFilter(true); sort_model->sort(0); @@ -341,8 +344,8 @@ void DeviceView::DeviceDisconnected(const QModelIndex &idx) { void DeviceView::Forget() { QModelIndex device_idx = MapToDevice(menu_index_); - QString unique_id = app_->device_manager()->data(device_idx, DeviceManager::Role_UniqueId).toString(); - if (app_->device_manager()->GetLister(device_idx) && app_->device_manager()->GetLister(device_idx)->AskForScan(unique_id)) { + QString unique_id = device_manager_->data(device_idx, DeviceManager::Role_UniqueId).toString(); + if (device_manager_->GetLister(device_idx) && device_manager_->GetLister(device_idx)->AskForScan(unique_id)) { ScopedPtr dialog(new QMessageBox( QMessageBox::Question, tr("Forget device"), tr("Forgetting a device will remove it from this list and Strawberry will have to rescan all the songs again next time you connect it."), @@ -353,7 +356,7 @@ void DeviceView::Forget() { if (dialog->clickedButton() != forget) return; } - app_->device_manager()->Forget(device_idx); + device_manager_->Forget(device_idx); } @@ -368,7 +371,7 @@ void DeviceView::mouseDoubleClickEvent(QMouseEvent *e) { QModelIndex merged_index = indexAt(e->pos()); QModelIndex device_index = MapToDevice(merged_index); if (device_index.isValid()) { - if (!app_->device_manager()->GetConnectedDevice(device_index)) { + if (!device_manager_->GetConnectedDevice(device_index)) { menu_index_ = merged_index; Connect(); } @@ -433,7 +436,7 @@ void DeviceView::Delete() { SharedPtr storage = device_index.data(MusicStorage::Role_Storage).value>(); - DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, false); + DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, false); QObject::connect(delete_files, &DeleteFiles::Finished, this, &DeviceView::DeleteFinished); delete_files->Start(GetSelectedSongs()); @@ -456,7 +459,7 @@ void DeviceView::Organize() { void DeviceView::Unmount() { QModelIndex device_idx = MapToDevice(menu_index_); - app_->device_manager()->Unmount(device_idx); + device_manager_->Unmount(device_idx); } void DeviceView::DeleteFinished(const SongList &songs_with_errors) { diff --git a/src/device/deviceview.h b/src/device/deviceview.h index d8cbcecedf..db75f26373 100644 --- a/src/device/deviceview.h +++ b/src/device/deviceview.h @@ -30,7 +30,8 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "collection/collectionitemdelegate.h" #include "widgets/autoexpandingtreeview.h" @@ -43,8 +44,11 @@ class QAction; class QMouseEvent; class QContextMenuEvent; -class Application; +class TaskManager; +class TagReaderClient; +class DeviceManager; class DeviceProperties; +class CollectionDirectoryModel; class MergedProxyModel; class OrganizeDialog; @@ -67,7 +71,10 @@ class DeviceView : public AutoExpandingTreeView { explicit DeviceView(QWidget *parent = nullptr); ~DeviceView() override; - void SetApplication(Application *app); + void Init(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr device_manager, + CollectionDirectoryModel *collection_directory_model); // AutoExpandingTreeView bool CanRecursivelyExpand(const QModelIndex &idx) const override; @@ -102,7 +109,9 @@ class DeviceView : public AutoExpandingTreeView { SongList GetSelectedSongs() const; private: - Application *app_; + SharedPtr task_manager_; + SharedPtr tagreader_client_; + SharedPtr device_manager_; MergedProxyModel *merged_model_; QSortFilterProxyModel *sort_model_; diff --git a/src/device/filesystemdevice.cpp b/src/device/filesystemdevice.cpp index f31970d76d..bb872a57cf 100644 --- a/src/device/filesystemdevice.cpp +++ b/src/device/filesystemdevice.cpp @@ -25,53 +25,67 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/song.h" +#include "core/taskmanager.h" +#include "core/database.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" #include "collection/collectionwatcher.h" + +#include "covermanager/albumcoverloader.h" + #include "connecteddevice.h" #include "devicemanager.h" #include "filesystemdevice.h" class DeviceLister; -FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) +FilesystemDevice::FilesystemDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) : FilesystemMusicStorage(Song::Source::Device, url.toLocalFile()), - ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), - watcher_(new CollectionWatcher(Song::Source::Device)), + ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), + collection_watcher_(new CollectionWatcher(Song::Source::Device, task_manager, tagreader_client, collection_backend_)), watcher_thread_(new QThread(this)) { - watcher_->moveToThread(watcher_thread_); + collection_watcher_->moveToThread(watcher_thread_); watcher_thread_->start(QThread::IdlePriority); - qLog(Debug) << watcher_ << "for device" << unique_id << "moved to thread" << watcher_thread_; - - watcher_->set_device_name(manager->DeviceNameByID(unique_id)); - watcher_->set_backend(backend_); - watcher_->set_task_manager(app_->task_manager()); - - QObject::connect(&*backend_, &CollectionBackend::DirectoryAdded, watcher_, &CollectionWatcher::AddDirectory); - QObject::connect(&*backend_, &CollectionBackend::DirectoryDeleted, watcher_, &CollectionWatcher::RemoveDirectory); - QObject::connect(watcher_, &CollectionWatcher::NewOrUpdatedSongs, &*backend_, &CollectionBackend::AddOrUpdateSongs); - QObject::connect(watcher_, &CollectionWatcher::SongsMTimeUpdated, &*backend_, &CollectionBackend::UpdateMTimesOnly); - QObject::connect(watcher_, &CollectionWatcher::SongsDeleted, &*backend_, &CollectionBackend::DeleteSongs); - QObject::connect(watcher_, &CollectionWatcher::SongsUnavailable, &*backend_, &CollectionBackend::MarkSongsUnavailable); - QObject::connect(watcher_, &CollectionWatcher::SongsReadded, &*backend_, &CollectionBackend::MarkSongsUnavailable); - QObject::connect(watcher_, &CollectionWatcher::SubdirsDiscovered, &*backend_, &CollectionBackend::AddOrUpdateSubdirs); - QObject::connect(watcher_, &CollectionWatcher::SubdirsMTimeUpdated, &*backend_, &CollectionBackend::AddOrUpdateSubdirs); - QObject::connect(watcher_, &CollectionWatcher::CompilationsNeedUpdating, &*backend_, &CollectionBackend::CompilationsNeedUpdating); - QObject::connect(watcher_, &CollectionWatcher::UpdateLastSeen, &*backend_, &CollectionBackend::UpdateLastSeen); - QObject::connect(watcher_, &CollectionWatcher::ScanStarted, this, &FilesystemDevice::TaskStarted); + qLog(Debug) << collection_watcher_ << "for device" << unique_id << "moved to thread" << watcher_thread_; + + collection_watcher_->set_device_name(device_manager->DeviceNameByID(unique_id)); + collection_watcher_->set_backend(collection_backend_); + collection_watcher_->set_task_manager(task_manager); + + QObject::connect(&*collection_backend_, &CollectionBackend::DirectoryAdded, collection_watcher_, &CollectionWatcher::AddDirectory); + QObject::connect(&*collection_backend_, &CollectionBackend::DirectoryDeleted, collection_watcher_, &CollectionWatcher::RemoveDirectory); + QObject::connect(collection_watcher_, &CollectionWatcher::NewOrUpdatedSongs, &*collection_backend_, &CollectionBackend::AddOrUpdateSongs); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsMTimeUpdated, &*collection_backend_, &CollectionBackend::UpdateMTimesOnly); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsDeleted, &*collection_backend_, &CollectionBackend::DeleteSongs); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsUnavailable, &*collection_backend_, &CollectionBackend::MarkSongsUnavailable); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsReadded, &*collection_backend_, &CollectionBackend::MarkSongsUnavailable); + QObject::connect(collection_watcher_, &CollectionWatcher::SubdirsDiscovered, &*collection_backend_, &CollectionBackend::AddOrUpdateSubdirs); + QObject::connect(collection_watcher_, &CollectionWatcher::SubdirsMTimeUpdated, &*collection_backend_, &CollectionBackend::AddOrUpdateSubdirs); + QObject::connect(collection_watcher_, &CollectionWatcher::CompilationsNeedUpdating, &*collection_backend_, &CollectionBackend::CompilationsNeedUpdating); + QObject::connect(collection_watcher_, &CollectionWatcher::UpdateLastSeen, &*collection_backend_, &CollectionBackend::UpdateLastSeen); + QObject::connect(collection_watcher_, &CollectionWatcher::ScanStarted, this, &FilesystemDevice::TaskStarted); } FilesystemDevice::~FilesystemDevice() { - watcher_->Abort(); - watcher_->deleteLater(); + collection_watcher_->Abort(); + collection_watcher_->deleteLater(); watcher_thread_->exit(); watcher_thread_->wait(); @@ -80,7 +94,7 @@ FilesystemDevice::~FilesystemDevice() { bool FilesystemDevice::Init() { InitBackendDirectory(url_.toLocalFile(), first_time_); - model_->Init(); + collection_model_->Init(); return true; } @@ -93,15 +107,15 @@ void FilesystemDevice::Close() { Q_ASSERT(QThread::currentThread() == thread()); - wait_for_exit_ << &*backend_ << watcher_; + wait_for_exit_ << &*collection_backend_ << collection_watcher_; - QObject::disconnect(&*backend_, nullptr, watcher_, nullptr); - QObject::disconnect(watcher_, nullptr, &*backend_, nullptr); + QObject::disconnect(&*collection_backend_, nullptr, collection_watcher_, nullptr); + QObject::disconnect(collection_watcher_, nullptr, &*collection_backend_, nullptr); - QObject::connect(&*backend_, &CollectionBackend::ExitFinished, this, &FilesystemDevice::ExitFinished); - QObject::connect(watcher_, &CollectionWatcher::ExitFinished, this, &FilesystemDevice::ExitFinished); - backend_->ExitAsync(); - watcher_->ExitAsync(); + QObject::connect(&*collection_backend_, &CollectionBackend::ExitFinished, this, &FilesystemDevice::ExitFinished); + QObject::connect(collection_watcher_, &CollectionWatcher::ExitFinished, this, &FilesystemDevice::ExitFinished); + collection_backend_->ExitAsync(); + collection_watcher_->ExitAsync(); } diff --git a/src/device/filesystemdevice.h b/src/device/filesystemdevice.h index b74baec747..bbeecf96ef 100644 --- a/src/device/filesystemdevice.h +++ b/src/device/filesystemdevice.h @@ -30,21 +30,35 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/filesystemmusicstorage.h" #include "connecteddevice.h" class QThread; -class Application; -class CollectionWatcher; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; +class CollectionWatcher; class FilesystemDevice : public ConnectedDevice, public virtual FilesystemMusicStorage { Q_OBJECT public: - Q_INVOKABLE FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr 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, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); + ~FilesystemDevice() override; Song::Source source() const final { return Song::Source::Device; } @@ -59,7 +73,7 @@ class FilesystemDevice : public ConnectedDevice, public virtual FilesystemMusicS void ExitFinished(); private: - CollectionWatcher *watcher_; + CollectionWatcher *collection_watcher_; QThread *watcher_thread_; QList wait_for_exit_; }; diff --git a/src/device/giolister.h b/src/device/giolister.h index d19c667042..4fa574e171 100644 --- a/src/device/giolister.h +++ b/src/device/giolister.h @@ -38,7 +38,7 @@ #include #include -#include "core/scopedgobject.h" +#include "includes/scopedgobject.h" #include "devicelister.h" class GioLister : public DeviceLister { diff --git a/src/device/gpoddevice.cpp b/src/device/gpoddevice.cpp index 3fc9633417..a257d7c13a 100644 --- a/src/device/gpoddevice.cpp +++ b/src/device/gpoddevice.cpp @@ -38,12 +38,14 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/temporaryfile.h" +#include "core/taskmanager.h" +#include "core/database.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" +#include "covermanager/albumcoverloader.h" #include "connecteddevice.h" #include "gpoddevice.h" #include "gpodloader.h" @@ -54,8 +56,19 @@ class DeviceManager; using std::make_shared; using namespace Qt::Literals::StringLiterals; -GPodDevice::GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), +GPodDevice::GPodDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) + : ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), + task_manager_(task_manager), loader_(nullptr), loader_thread_(nullptr), db_(nullptr), @@ -64,9 +77,9 @@ GPodDevice::GPodDevice(const QUrl &url, DeviceLister *lister, const QString &uni bool GPodDevice::Init() { InitBackendDirectory(url_.path(), first_time_); - model_->Init(); + collection_model_->Init(); - loader_ = new GPodLoader(url_.path(), app_->task_manager(), backend_, shared_from_this()); + loader_ = new GPodLoader(url_.path(), task_manager_, collection_backend_, shared_from_this()); loader_thread_ = new QThread(); loader_->moveToThread(loader_thread_); @@ -135,7 +148,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 Error(message); +} void GPodDevice::Start() { @@ -240,7 +255,7 @@ bool GPodDevice::CopyToStorage(const CopyJob &job, QString &error_text) { error_text = tr("Could not copy %1 to %2: %3").arg(job.metadata_.url().toLocalFile(), url_.path(), QString::fromUtf8(error->message)); g_error_free(error); qLog(Error) << error_text; - app_->AddError(error_text); + Q_EMIT Error(error_text); // Need to remove the track from the db again itdb_track_remove(track); @@ -286,7 +301,7 @@ bool GPodDevice::WriteDatabase(QString &error_text) { else { error_text = tr("Writing database failed."); } - app_->AddError(error_text); + Q_EMIT Error(error_text); } return success; @@ -297,12 +312,12 @@ void GPodDevice::Finish(const bool success) { // Update the collection model if (success) { - if (!songs_to_add_.isEmpty()) backend_->AddOrUpdateSongs(songs_to_add_); - if (!songs_to_remove_.isEmpty()) backend_->DeleteSongs(songs_to_remove_); + if (!songs_to_add_.isEmpty()) collection_backend_->AddOrUpdateSongs(songs_to_add_); + if (!songs_to_remove_.isEmpty()) collection_backend_->DeleteSongs(songs_to_remove_); } // This is done in the organize thread so close the unique DB connection. - backend_->Close(); + collection_backend_->Close(); songs_to_add_.clear(); songs_to_remove_.clear(); diff --git a/src/device/gpoddevice.h b/src/device/gpoddevice.h index d299e9564f..b590304ae1 100644 --- a/src/device/gpoddevice.h +++ b/src/device/gpoddevice.h @@ -34,7 +34,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" #include "core/temporaryfile.h" @@ -42,15 +42,29 @@ #include "gpodloader.h" class QThread; -class Application; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class GPodDevice : public ConnectedDevice, public virtual MusicStorage { Q_OBJECT public: - Q_INVOKABLE GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr 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, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); + ~GPodDevice() override; bool Init() override; @@ -86,6 +100,7 @@ class GPodDevice : public ConnectedDevice, public virtual MusicStorage { bool WriteDatabase(QString &error_text); protected: + SharedPtr task_manager_; GPodLoader *loader_; QThread *loader_thread_; diff --git a/src/device/gpodloader.cpp b/src/device/gpodloader.cpp index bd4ce910e2..90fea651c6 100644 --- a/src/device/gpodloader.cpp +++ b/src/device/gpodloader.cpp @@ -29,14 +29,18 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/song.h" #include "core/taskmanager.h" #include "collection/collectionbackend.h" #include "gpodloader.h" -GPodLoader::GPodLoader(const QString &mount_point, SharedPtr task_manager, SharedPtr backend, SharedPtr device, QObject *parent) +GPodLoader::GPodLoader(const QString &mount_point, + SharedPtr task_manager, + SharedPtr backend, + SharedPtr device, + QObject *parent) : QObject(parent), device_(device), mount_point_(mount_point), diff --git a/src/device/gpodloader.h b/src/device/gpodloader.h index 418c109684..bdb9a4fda0 100644 --- a/src/device/gpodloader.h +++ b/src/device/gpodloader.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QThread; @@ -41,7 +41,12 @@ class GPodLoader : public QObject { Q_OBJECT public: - explicit GPodLoader(const QString &mount_point, SharedPtr task_manager, SharedPtr backend, SharedPtr device, QObject *parent = nullptr); + explicit GPodLoader(const QString &mount_point, + SharedPtr task_manager, + SharedPtr backend, + SharedPtr device, + QObject *parent = nullptr); + ~GPodLoader() override; void set_music_path_prefix(const QString &prefix) { path_prefix_ = prefix; } diff --git a/src/device/macosdevicelister.mm b/src/device/macosdevicelister.mm index fcad47da2e..3020589e09 100644 --- a/src/device/macosdevicelister.mm +++ b/src/device/macosdevicelister.mm @@ -19,6 +19,8 @@ * */ +#include "config.h" + #include #include @@ -38,13 +40,12 @@ #include #include -#include "config.h" #include "macosdevicelister.h" #include "mtpconnection.h" +#include "includes/scoped_cftyperef.h" +#include "includes/scoped_nsobject.h" #include "core/logging.h" -#include "core/scoped_cftyperef.h" #include "core/scoped_nsautorelease_pool.h" -#include "core/scoped_nsobject.h" #import #import diff --git a/src/device/mtpdevice.cpp b/src/device/mtpdevice.cpp index 601a3cae16..3bc400857b 100644 --- a/src/device/mtpdevice.cpp +++ b/src/device/mtpdevice.cpp @@ -33,9 +33,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/musicstorage.h" #include "collection/collectionmodel.h" #include "collection/collectionbackend.h" @@ -46,13 +45,27 @@ using namespace Qt::Literals::StringLiterals; +class TaskManager; +class Database; +class AlbumCoverLoader; class DeviceLister; class DeviceManager; bool MtpDevice::sInitializedLibMTP = false; -MtpDevice::MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), +MtpDevice::MtpDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) + : ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), + task_manager_(task_manager), loader_(nullptr), loader_thread_(nullptr), closing_(false) { @@ -79,9 +92,9 @@ MtpDevice::~MtpDevice() { bool MtpDevice::Init() { InitBackendDirectory(u"/"_s, first_time_, false); - model_->Init(); + collection_model_->Init(); - loader_ = new MtpLoader(url_, app_->task_manager(), backend_); + loader_ = new MtpLoader(url_, task_manager_, collection_backend_); loader_thread_ = new QThread(); loader_->moveToThread(loader_thread_); @@ -132,7 +145,7 @@ void MtpDevice::LoadFinished(const bool success, MtpConnection *connection) { } void MtpDevice::LoaderError(const QString &message) { - app_->AddError(message); + Q_EMIT Error(message); } bool MtpDevice::StartCopy(QList *supported_types) { @@ -204,15 +217,15 @@ bool MtpDevice::CopyToStorage(const CopyJob &job, QString &error_text) { bool MtpDevice::FinishCopy(const bool success, QString &error_text) { if (success) { - if (!songs_to_add_.isEmpty()) backend_->AddOrUpdateSongs(songs_to_add_); - if (!songs_to_remove_.isEmpty()) backend_->DeleteSongs(songs_to_remove_); + if (!songs_to_add_.isEmpty()) collection_backend_->AddOrUpdateSongs(songs_to_add_); + if (!songs_to_remove_.isEmpty()) collection_backend_->DeleteSongs(songs_to_remove_); } songs_to_add_.clear(); songs_to_remove_.clear(); // This is done in the organize thread so close the unique DB connection. - backend_->Close(); + collection_backend_->Close(); db_busy_.unlock(); diff --git a/src/device/mtpdevice.h b/src/device/mtpdevice.h index b363d7b56d..8c0cfc4c2a 100644 --- a/src/device/mtpdevice.h +++ b/src/device/mtpdevice.h @@ -31,15 +31,18 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "connecteddevice.h" class QThread; -class Application; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class MtpLoader; class MtpConnection; struct LIBMTP_mtpdevice_struct; @@ -48,7 +51,18 @@ class MtpDevice : public ConnectedDevice { Q_OBJECT public: - Q_INVOKABLE MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr 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, + DeviceManager *device_manager, + SharedPtr task_manager, + SharedPtr database, + SharedPtr tagreader_client, + SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); + ~MtpDevice() override; static QStringList url_schemes() { return QStringList() << QStringLiteral("mtp"); } @@ -82,6 +96,8 @@ class MtpDevice : public ConnectedDevice { private: static bool sInitializedLibMTP; + SharedPtr task_manager_; + MtpLoader *loader_; QThread *loader_thread_; bool closing_; diff --git a/src/device/mtploader.cpp b/src/device/mtploader.cpp index e126bf8b62..41d26ca905 100644 --- a/src/device/mtploader.cpp +++ b/src/device/mtploader.cpp @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/taskmanager.h" #include "core/song.h" #include "collection/collectionbackend.h" diff --git a/src/device/mtploader.h b/src/device/mtploader.h index d7ba44de08..67399ba77e 100644 --- a/src/device/mtploader.h +++ b/src/device/mtploader.h @@ -28,8 +28,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QThread; class TaskManager; diff --git a/src/device/udisks2lister.cpp b/src/device/udisks2lister.cpp index 93f1b75397..6e851fa8f5 100644 --- a/src/device/udisks2lister.cpp +++ b/src/device/udisks2lister.cpp @@ -41,9 +41,9 @@ #include #include +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" #include "utilities/diskutils.h" #include "udisks2lister.h" diff --git a/src/device/udisks2lister.h b/src/device/udisks2lister.h index ee5c40bf63..83309fd25d 100644 --- a/src/device/udisks2lister.h +++ b/src/device/udisks2lister.h @@ -38,9 +38,9 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" -#include "core/dbus_metatypes.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" +#include "includes/dbus_metatypes.h" #include "devicelister.h" diff --git a/src/dialogs/console.cpp b/src/dialogs/console.cpp index a7903e3d8d..ef52892f4d 100644 --- a/src/dialogs/console.cpp +++ b/src/dialogs/console.cpp @@ -36,13 +36,14 @@ #include #include "console.h" + +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/application.h" #include "core/database.h" using namespace Qt::Literals::StringLiterals; -Console::Console(Application *app, QWidget *parent) : QDialog(parent), ui_{}, app_(app) { +Console::Console(SharedPtr database, QWidget *parent) : QDialog(parent), ui_{}, database_(database) { ui_.setupUi(this); @@ -60,7 +61,7 @@ Console::Console(Application *app, QWidget *parent) : QDialog(parent), ui_{}, ap void Console::RunQuery() { - QSqlDatabase db = app_->database()->Connect(); + QSqlDatabase db = database_->Connect(); QSqlQuery query(db); if (!query.prepare(ui_.query->text())) { qLog(Error) << query.lastError(); diff --git a/src/dialogs/console.h b/src/dialogs/console.h index d2ccfa28e2..c62f9b2310 100644 --- a/src/dialogs/console.h +++ b/src/dialogs/console.h @@ -31,20 +31,22 @@ #include "ui_console.h" -class Application; +#include "includes/shared_ptr.h" + +class Database; class Console : public QDialog { Q_OBJECT public: - explicit Console(Application *app, QWidget *parent = nullptr); + explicit Console(SharedPtr database, QWidget *parent = nullptr); private Q_SLOTS: void RunQuery(); private: Ui::Console ui_; - Application *app_; + SharedPtr database_; }; #endif // CONSOLE_H diff --git a/src/dialogs/edittagdialog.cpp b/src/dialogs/edittagdialog.cpp index 28d30df1da..b21a367b31 100644 --- a/src/dialogs/edittagdialog.cpp +++ b/src/dialogs/edittagdialog.cpp @@ -70,7 +70,6 @@ #include #include -#include "core/application.h" #include "core/iconloader.h" #include "core/logging.h" #include "core/settings.h" @@ -110,16 +109,28 @@ constexpr int kSmallImageSize = 128; const char EditTagDialog::kTagsDifferentHintText[] = QT_TR_NOOP("(different across multiple songs)"); const char EditTagDialog::kArtDifferentHintText[] = QT_TR_NOOP("Different art across multiple songs."); -EditTagDialog::EditTagDialog(Application *app, QWidget *parent) +EditTagDialog::EditTagDialog(SharedPtr network, + SharedPtr tagreader_client, + SharedPtr collection_backend, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr lyrics_providers, + SharedPtr streaming_services, + QWidget *parent) : QDialog(parent), ui_(new Ui_EditTagDialog), - app_(app), + tagreader_client_(tagreader_client), + collection_backend_(collection_backend), + albumcover_loader_(albumcover_loader), + current_albumcover_loader_(current_albumcover_loader), + cover_providers_(cover_providers), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), #ifdef HAVE_MUSICBRAINZ - tag_fetcher_(new TagFetcher(app->network(), this)), - results_dialog_(new TrackSelectionDialog(this)), + tag_fetcher_(new TagFetcher(network, this)), + results_dialog_(new TrackSelectionDialog(tagreader_client, this)), #endif - lyrics_fetcher_(new LyricsFetcher(app->lyrics_providers(), this)), + lyrics_fetcher_(new LyricsFetcher(lyrics_providers, this)), cover_menu_(new QMenu(this)), image_no_cover_thumbnail_(ImageUtils::GenerateNoCoverImage(QSize(128, 128), devicePixelRatioF())), loading_(false), @@ -130,7 +141,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) save_tag_pending_(0), lyrics_id_(-1) { - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &EditTagDialog::AlbumCoverLoaded); + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &EditTagDialog::AlbumCoverLoaded); #ifdef HAVE_MUSICBRAINZ QObject::connect(tag_fetcher_, &TagFetcher::ResultAvailable, results_dialog_, &TrackSelectionDialog::FetchTagFinished, Qt::QueuedConnection); @@ -140,7 +151,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) #endif QObject::connect(lyrics_fetcher_, &LyricsFetcher::LyricsFetched, this, &EditTagDialog::UpdateLyrics); - album_cover_choice_controller_->Init(app_); + album_cover_choice_controller_->Init(network, tagreader_client, collection_backend, albumcover_loader, current_albumcover_loader, cover_providers, streaming_services); ui_->setupUi(this); ui_->splitter->setSizes(QList() << 200 << width() - 200); @@ -259,13 +270,13 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) QKeySequence(QKeySequence::Forward).toString(QKeySequence::NativeText), QKeySequence(QKeySequence::MoveToNextPage).toString(QKeySequence::NativeText))); - new TagCompleter(app_->collection_backend(), Playlist::Column::Artist, ui_->artist); - new TagCompleter(app_->collection_backend(), Playlist::Column::Album, ui_->album); - new TagCompleter(app_->collection_backend(), Playlist::Column::AlbumArtist, ui_->albumartist); - new TagCompleter(app_->collection_backend(), Playlist::Column::Genre, ui_->genre); - new TagCompleter(app_->collection_backend(), Playlist::Column::Composer, ui_->composer); - new TagCompleter(app_->collection_backend(), Playlist::Column::Performer, ui_->performer); - new TagCompleter(app_->collection_backend(), Playlist::Column::Grouping, ui_->grouping); + new TagCompleter(collection_backend, Playlist::Column::Artist, ui_->artist); + new TagCompleter(collection_backend, Playlist::Column::Album, ui_->album); + new TagCompleter(collection_backend, Playlist::Column::AlbumArtist, ui_->albumartist); + new TagCompleter(collection_backend, Playlist::Column::Genre, ui_->genre); + new TagCompleter(collection_backend, Playlist::Column::Composer, ui_->composer); + new TagCompleter(collection_backend, Playlist::Column::Performer, ui_->performer); + new TagCompleter(collection_backend, Playlist::Column::Grouping, ui_->grouping); } @@ -393,7 +404,7 @@ bool EditTagDialog::SetLoading(const QString &message) { } -QList EditTagDialog::LoadData(const SongList &songs) { +QList EditTagDialog::LoadData(const SongList &songs) const { QList ret; @@ -401,7 +412,7 @@ QList EditTagDialog::LoadData(const SongList &songs) { if (song.IsEditable()) { // Try reloading the tags from file Song copy(song); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(copy.url().toLocalFile(), ©); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(copy.url().toLocalFile(), ©); if (result.success() && copy.is_valid()) { copy.MergeUserSetData(song, false, false); ret << Data(copy); @@ -424,7 +435,7 @@ void EditTagDialog::SetSongs(const SongList &s, const PlaylistItemPtrList &items collection_songs_.clear(); // Reload tags in the background - QFuture> future = QtConcurrent::run(&EditTagDialog::LoadData, s); + QFuture> future = QtConcurrent::run(&EditTagDialog::LoadData, this, s); QFutureWatcher> *watcher = new QFutureWatcher>(); QObject::connect(watcher, &QFutureWatcher>::finished, this, &EditTagDialog::SetSongsFinished); watcher->setFuture(future); @@ -725,7 +736,7 @@ void EditTagDialog::SelectionChanged() { album_cover_choice_controller_->cover_to_file_action()->setEnabled(first_song.has_valid_art() && !first_song.art_unset()); album_cover_choice_controller_->cover_from_file_action()->setEnabled(enable_change_art); album_cover_choice_controller_->cover_from_url_action()->setEnabled(enable_change_art); - album_cover_choice_controller_->search_for_cover_action()->setEnabled(app_->cover_providers()->HasAnyProviders() && enable_change_art); + album_cover_choice_controller_->search_for_cover_action()->setEnabled(cover_providers_->HasAnyProviders() && enable_change_art); album_cover_choice_controller_->unset_cover_action()->setEnabled(enable_change_art && !first_song.art_unset()); album_cover_choice_controller_->clear_cover_action()->setEnabled(enable_change_art && (!first_song.art_manual().isEmpty() || first_song.art_unset())); album_cover_choice_controller_->delete_cover_action()->setEnabled(enable_change_art && (first_song.art_embedded() || !first_song.art_automatic().isEmpty() || !first_song.art_manual().isEmpty())); @@ -734,10 +745,10 @@ void EditTagDialog::SelectionChanged() { cover_options.desired_scaled_size = QSize(kSmallImageSize, kSmallImageSize); cover_options.device_pixel_ratio = devicePixelRatioF(); if (data_.value(indexes.first().row()).cover_action_ == UpdateCoverAction::None) { - tags_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, first_song); + tags_cover_art_id_ = albumcover_loader_->LoadImageAsync(cover_options, first_song); } else { - tags_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, data_[indexes.first().row()].cover_result_); + tags_cover_art_id_ = albumcover_loader_->LoadImageAsync(cover_options, data_[indexes.first().row()].cover_result_); } } @@ -788,7 +799,7 @@ void EditTagDialog::UpdateSummaryTab(const Song &song) { cover_options.types = cover_types_; cover_options.desired_scaled_size = QSize(kSmallImageSize, kSmallImageSize); cover_options.device_pixel_ratio = devicePixelRatioF(); - summary_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, song); + summary_cover_art_id_ = albumcover_loader_->LoadImageAsync(cover_options, song); ui_->summary->setText(u"

"_s + song.PrettyTitleWithArtist().toHtmlEscaped() + u"

"_s); @@ -1299,7 +1310,7 @@ void EditTagDialog::SaveData() { if (save_embedded_cover) { save_tags_options |= TagReaderClient::SaveOption::Cover; } - TagReaderReplyPtr reply = TagReaderClient::Instance()->WriteFileAsync(ref.current_.url().toLocalFile(), ref.current_, save_tags_options, save_tag_cover_data); + TagReaderReplyPtr reply = tagreader_client_->WriteFileAsync(ref.current_.url().toLocalFile(), ref.current_, save_tags_options, save_tag_cover_data); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveTagsComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_); }, Qt::QueuedConnection); } // If the cover was changed, but no tags written, make sure to update the collection. @@ -1307,8 +1318,8 @@ void EditTagDialog::SaveData() { if (ref.current_.is_collection_song()) { collection_songs_.insert(ref.current_.id(), ref.current_); } - if (ref.current_ == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(ref.current_); + if (ref.current_ == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(ref.current_); } } @@ -1321,7 +1332,7 @@ void EditTagDialog::SaveData() { void EditTagDialog::SaveDataFinished() { if (!collection_songs_.isEmpty()) { - app_->collection_backend()->AddOrUpdateSongsAsync(collection_songs_.values()); + collection_backend_->AddOrUpdateSongsAsync(collection_songs_.values()); collection_songs_.clear(); } @@ -1483,8 +1494,8 @@ void EditTagDialog::SongSaveTagsComplete(TagReaderReplyPtr reply, const QString } collection_songs_.insert(song.id(), song); } - if (cover_action != UpdateCoverAction::None && song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(song); + if (cover_action != UpdateCoverAction::None && song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(song); } } else { diff --git a/src/dialogs/edittagdialog.h b/src/dialogs/edittagdialog.h index 9a3a9434e6..e25ffdd4db 100644 --- a/src/dialogs/edittagdialog.h +++ b/src/dialogs/edittagdialog.h @@ -51,7 +51,13 @@ class QEvent; class QShowEvent; class QHideEvent; -class Application; +class NetworkAccessManager; +class CollectionBackend; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; +class LyricsProviders; +class StreamingServices; class AlbumCoverChoiceController; class Ui_EditTagDialog; #ifdef HAVE_MUSICBRAINZ @@ -64,7 +70,16 @@ class EditTagDialog : public QDialog { Q_OBJECT public: - explicit EditTagDialog(Application *app, QWidget *parent = nullptr); + explicit EditTagDialog(SharedPtr network, + SharedPtr tagreader_client, + SharedPtr collection_backend, + SharedPtr albumcover_loader, + SharedPtr current_albumcover_loader, + SharedPtr cover_providers, + SharedPtr lyrics_providers, + SharedPtr streaming_services, + QWidget *parent = nullptr); + ~EditTagDialog() override; void SetSongs(const SongList &songs, const PlaylistItemPtrList &items = PlaylistItemPtrList()); @@ -168,7 +183,7 @@ class EditTagDialog : public QDialog { void SetSongListVisibility(bool visible); // Called by QtConcurrentRun - static QList LoadData(const SongList &songs); + QList LoadData(const SongList &songs) const; void SaveData(); static void SetText(QLabel *label, const int value, const QString &suffix, const QString &def = QString()); @@ -180,7 +195,12 @@ class EditTagDialog : public QDialog { Ui_EditTagDialog *ui_; - Application *app_; + SharedPtr tagreader_client_; + SharedPtr collection_backend_; + SharedPtr albumcover_loader_; + SharedPtr current_albumcover_loader_; + SharedPtr cover_providers_; + AlbumCoverChoiceController *album_cover_choice_controller_; #ifdef HAVE_MUSICBRAINZ TagFetcher *tag_fetcher_; diff --git a/src/dialogs/lastfmimportdialog.cpp b/src/dialogs/lastfmimportdialog.cpp index a30b64f987..cae401b76f 100644 --- a/src/dialogs/lastfmimportdialog.cpp +++ b/src/dialogs/lastfmimportdialog.cpp @@ -27,7 +27,7 @@ #include "lastfmimportdialog.h" #include "ui_lastfmimportdialog.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/iconloader.h" #include "scrobbler/lastfmimport.h" diff --git a/src/dialogs/lastfmimportdialog.h b/src/dialogs/lastfmimportdialog.h index 94560e6dc4..cc1a822c55 100644 --- a/src/dialogs/lastfmimportdialog.h +++ b/src/dialogs/lastfmimportdialog.h @@ -26,7 +26,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "ui_lastfmimportdialog.h" diff --git a/src/dialogs/saveplaylistsdialog.cpp b/src/dialogs/saveplaylistsdialog.cpp index 18699cdff2..3fc80d7929 100644 --- a/src/dialogs/saveplaylistsdialog.cpp +++ b/src/dialogs/saveplaylistsdialog.cpp @@ -30,16 +30,16 @@ #include "ui_saveplaylistsdialog.h" #include "core/settings.h" -#include "playlist/playlist.h" +#include "constants/playlistsettings.h" SavePlaylistsDialog::SavePlaylistsDialog(const QStringList &types, const QString &default_extension, QWidget *parent) : QDialog(parent), ui_(new Ui_SavePlaylistsDialog) { ui_->setupUi(this); Settings s; - s.beginGroup(Playlist::kSettingsGroup); - QString last_save_path = s.value("last_save_all_path", QDir::homePath()).toString(); - QString last_save_extension = s.value("last_save_all_extension", default_extension).toString(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + QString last_save_path = s.value(PlaylistSettings::kLastSaveAllPath, QDir::homePath()).toString(); + QString last_save_extension = s.value(PlaylistSettings::kLastSaveAllExtension, default_extension).toString(); s.endGroup(); ui_->lineedit_path->setText(last_save_path); @@ -81,9 +81,9 @@ void SavePlaylistsDialog::accept() { } Settings s; - s.beginGroup(Playlist::kSettingsGroup); - s.setValue("last_save_all_path", path); - s.setValue("last_save_all_extension", ui_->combobox_type->currentText()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + s.setValue(PlaylistSettings::kLastSaveAllPath, path); + s.setValue(PlaylistSettings::kLastSaveAllExtension, ui_->combobox_type->currentText()); s.endGroup(); QDialog::accept(); diff --git a/src/dialogs/snapdialog.cpp b/src/dialogs/snapdialog.cpp index ec180cd798..0502b9fb21 100644 --- a/src/dialogs/snapdialog.cpp +++ b/src/dialogs/snapdialog.cpp @@ -17,9 +17,9 @@ * */ +#include "constants/mainwindowsettings.h" #include "core/logging.h" #include "core/iconloader.h" -#include "core/mainwindow.h" #include "utilities/screenutils.h" #include "snapdialog.h" @@ -84,7 +84,7 @@ SnapDialog::SnapDialog(QWidget *parent) : MessageDialog(parent) { ui_->label_text->adjustSize(); adjustSize(); - settings_group_ = QLatin1String(MainWindow::kSettingsGroup); + settings_group_ = QLatin1String(MainWindowSettings::kSettingsGroup); do_not_show_message_again_ = "ignore_snap"_L1; if (parent) { diff --git a/src/dialogs/trackselectiondialog.cpp b/src/dialogs/trackselectiondialog.cpp index 2e29f0dac1..235efe8f71 100644 --- a/src/dialogs/trackselectiondialog.cpp +++ b/src/dialogs/trackselectiondialog.cpp @@ -53,9 +53,10 @@ #include "trackselectiondialog.h" #include "ui_trackselectiondialog.h" -TrackSelectionDialog::TrackSelectionDialog(QWidget *parent) +TrackSelectionDialog::TrackSelectionDialog(SharedPtr tagreader_client, QWidget *parent) : QDialog(parent), ui_(new Ui_TrackSelectionDialog), + tagreader_client_(tagreader_client), save_on_close_(false) { // Setup dialog window @@ -261,10 +262,10 @@ void TrackSelectionDialog::SetLoading(const QString &message) { } -void TrackSelectionDialog::SaveData(const QList &data) { +void TrackSelectionDialog::SaveData(const QList &_data) const { - for (int i = 0; i < data.count(); ++i) { - const Data &ref = data[i]; + for (int i = 0; i < _data.count(); ++i) { + const Data &ref = _data[i]; if (ref.pending_ || ref.results_.isEmpty() || ref.selected_result_ == -1) { continue; } @@ -278,7 +279,7 @@ void TrackSelectionDialog::SaveData(const QList &data) { copy.set_track(new_metadata.track()); copy.set_year(new_metadata.year()); - const TagReaderResult result = TagReaderClient::Instance()->WriteFileBlocking(copy.url().toLocalFile(), copy, TagReaderClient::SaveOption::Tags, SaveTagCoverData()); + const TagReaderResult result = tagreader_client_->WriteFileBlocking(copy.url().toLocalFile(), copy, TagReaderClient::SaveOption::Tags, SaveTagCoverData()); if (!result.success()) { qLog(Error) << "Failed to write new auto-tags to" << copy.url().toLocalFile() << result.error_string(); } @@ -292,7 +293,7 @@ void TrackSelectionDialog::accept() { SetLoading(tr("Saving tracks") + QStringLiteral("...")); // Save tags in the background - QFuture future = QtConcurrent::run(&TrackSelectionDialog::SaveData, data_); + QFuture future = QtConcurrent::run(&TrackSelectionDialog::SaveData, this, data_); QFutureWatcher *watcher = new QFutureWatcher(this); QObject::connect(watcher, &QFutureWatcher::finished, this, &TrackSelectionDialog::AcceptFinished); watcher->setFuture(future); diff --git a/src/dialogs/trackselectiondialog.h b/src/dialogs/trackselectiondialog.h index 54f40a7c73..78ff9a2957 100644 --- a/src/dialogs/trackselectiondialog.h +++ b/src/dialogs/trackselectiondialog.h @@ -22,24 +22,27 @@ #ifndef TRACKSELECTIONDIALOG_H #define TRACKSELECTIONDIALOG_H +#include "config.h" + #include #include #include #include -#include "config.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QWidget; class QTreeWidget; class QPushButton; class Ui_TrackSelectionDialog; +class TagReaderClient; class TrackSelectionDialog : public QDialog { Q_OBJECT public: - explicit TrackSelectionDialog(QWidget *parent = nullptr); + explicit TrackSelectionDialog(SharedPtr tagreader_client, QWidget *parent = nullptr); ~TrackSelectionDialog() override; void set_save_on_close(bool save_on_close) { save_on_close_ = save_on_close; } @@ -83,9 +86,11 @@ class TrackSelectionDialog : public QDialog { static void AddSong(const Song &song, int result_index, QTreeWidget *parent); void SetLoading(const QString &message); - static void SaveData(const QList &data); + void SaveData(const QList &data) const; private: + SharedPtr tagreader_client_; + QList data_; QPushButton *previous_button_; diff --git a/src/engine/enginebase.cpp b/src/engine/enginebase.cpp index 0481398f40..54bf185974 100644 --- a/src/engine/enginebase.cpp +++ b/src/engine/enginebase.cpp @@ -31,14 +31,15 @@ #include #include "utilities/envutils.h" -#include "utilities/timeconstants.h" -#include "core/networkproxyfactory.h" +#include "constants/timeconstants.h" +#include "core/logging.h" #include "core/settings.h" +#include "core/networkproxyfactory.h" #include "enginebase.h" -#include "settings/backendsettingspage.h" -#include "settings/networkproxysettingspage.h" +#include "constants/backendsettings.h" +#include "constants/networkproxysettings.h" #ifdef HAVE_SPOTIFY -# include "settings/spotifysettingspage.h" +# include "constants/spotifysettings.h" #endif using namespace Qt::Literals::StringLiterals; @@ -61,9 +62,9 @@ EngineBase::EngineBase(QObject *parent) rg_compression_(true), ebur128_loudness_normalization_(false), ebur128_target_level_lufs_(-23.0), - buffer_duration_nanosec_(BackendSettingsPage::kDefaultBufferDuration * kNsecPerMsec), - buffer_low_watermark_(BackendSettingsPage::kDefaultBufferLowWatermark), - buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark), + buffer_duration_nanosec_(BackendSettings::kDefaultBufferDuration * kNsecPerMsec), + buffer_low_watermark_(BackendSettings::kDefaultBufferLowWatermark), + buffer_high_watermark_(BackendSettings::kDefaultBufferHighWatermark), fadeout_enabled_(true), crossfade_enabled_(true), autocrossfade_enabled_(false), @@ -167,59 +168,59 @@ void EngineBase::ReloadSettings() { Settings s; - s.beginGroup(BackendSettingsPage::kSettingsGroup); + s.beginGroup(BackendSettings::kSettingsGroup); - output_ = s.value("output").toString(); - device_ = s.value("device"); + output_ = s.value(BackendSettings::kOutput).toString(); + device_ = s.value(BackendSettings::kDevice); - exclusive_mode_ = s.value("exclusive_mode", false).toBool(); + exclusive_mode_ = s.value(BackendSettings::kExclusiveMode, false).toBool(); - volume_control_ = s.value("volume_control", true).toBool(); + volume_control_ = s.value(BackendSettings::kVolumeControl, true).toBool(); - channels_enabled_ = s.value("channels_enabled", false).toBool(); - channels_ = s.value("channels", 0).toInt(); + channels_enabled_ = s.value(BackendSettings::kChannelsEnabled, false).toBool(); + channels_ = s.value(BackendSettings::kChannels, 0).toInt(); - buffer_duration_nanosec_ = s.value("bufferduration", BackendSettingsPage::kDefaultBufferDuration).toLongLong() * kNsecPerMsec; - buffer_low_watermark_ = s.value("bufferlowwatermark", BackendSettingsPage::kDefaultBufferLowWatermark).toDouble(); - buffer_high_watermark_ = s.value("bufferhighwatermark", BackendSettingsPage::kDefaultBufferHighWatermark).toDouble(); + buffer_duration_nanosec_ = s.value(BackendSettings::kBufferDuration, BackendSettings::kDefaultBufferDuration).toLongLong() * kNsecPerMsec; + buffer_low_watermark_ = s.value(BackendSettings::kBufferLowWatermark, BackendSettings::kDefaultBufferLowWatermark).toDouble(); + buffer_high_watermark_ = s.value(BackendSettings::kBufferHighWatermark, BackendSettings::kDefaultBufferHighWatermark).toDouble(); - rg_enabled_ = s.value("rgenabled", false).toBool(); - rg_mode_ = s.value("rgmode", 0).toInt(); - rg_preamp_ = s.value("rgpreamp", 0.0).toDouble(); - rg_fallbackgain_ = s.value("rgfallbackgain", 0.0).toDouble(); - rg_compression_ = s.value("rgcompression", true).toBool(); + rg_enabled_ = s.value(BackendSettings::kRgEnabled, false).toBool(); + rg_mode_ = s.value(BackendSettings::kRgMode, 0).toInt(); + rg_preamp_ = s.value(BackendSettings::kRgPreamp, 0.0).toDouble(); + rg_fallbackgain_ = s.value(BackendSettings::kRgFallbackGain, 0.0).toDouble(); + rg_compression_ = s.value(BackendSettings::kRgCompression, true).toBool(); - ebur128_loudness_normalization_ = s.value("ebur128_loudness_normalization", false).toBool(); - ebur128_target_level_lufs_ = s.value("ebur128_target_level_lufs", -23.0).toDouble(); + ebur128_loudness_normalization_ = s.value(BackendSettings::kEBUR128LoudnessNormalization, false).toBool(); + ebur128_target_level_lufs_ = s.value(BackendSettings::kEBUR128TargetLevelLUFS, -23.0).toDouble(); - fadeout_enabled_ = s.value("FadeoutEnabled", false).toBool(); - crossfade_enabled_ = s.value("CrossfadeEnabled", false).toBool(); - autocrossfade_enabled_ = s.value("AutoCrossfadeEnabled", false).toBool(); - crossfade_same_album_ = !s.value("NoCrossfadeSameAlbum", true).toBool(); - fadeout_pause_enabled_ = s.value("FadeoutPauseEnabled", false).toBool(); - fadeout_duration_ = s.value("FadeoutDuration", 2000).toLongLong(); + fadeout_enabled_ = s.value(BackendSettings::kFadeoutEnabled, false).toBool(); + crossfade_enabled_ = s.value(BackendSettings::kCrossfadeEnabled, false).toBool(); + autocrossfade_enabled_ = s.value(BackendSettings::kAutoCrossfadeEnabled, false).toBool(); + crossfade_same_album_ = !s.value(BackendSettings::kNoCrossfadeSameAlbum, true).toBool(); + fadeout_pause_enabled_ = s.value(BackendSettings::kFadeoutPauseEnabled, false).toBool(); + fadeout_duration_ = s.value(BackendSettings::kFadeoutDuration, 2000).toLongLong(); fadeout_duration_nanosec_ = (fadeout_duration_ * kNsecPerMsec); - fadeout_pause_duration_ = s.value("FadeoutPauseDuration", 250).toLongLong(); + fadeout_pause_duration_ = s.value(BackendSettings::kFadeoutPauseDuration, 250).toLongLong(); fadeout_pause_duration_nanosec_ = (fadeout_pause_duration_ * kNsecPerMsec); - bs2b_enabled_ = s.value("bs2b", false).toBool(); + bs2b_enabled_ = s.value(BackendSettings::kBS2B, false).toBool(); - bool http2_enabled = s.value("http2", false).toBool(); + bool http2_enabled = s.value(BackendSettings::kHTTP2, false).toBool(); if (http2_enabled != http2_enabled_) { http2_enabled_ = http2_enabled; Utilities::SetEnv("SOUP_FORCE_HTTP1", http2_enabled_ ? ""_L1 : u"1"_s); qLog(Debug) << "SOUP_FORCE_HTTP1:" << (http2_enabled_ ? "OFF" : "ON"); } - strict_ssl_enabled_ = s.value("strict_ssl", false).toBool(); + strict_ssl_enabled_ = s.value(BackendSettings::kStrictSSL, false).toBool(); s.endGroup(); - s.beginGroup(NetworkProxySettingsPage::kSettingsGroup); + s.beginGroup(NetworkProxySettings::kSettingsGroup); const NetworkProxyFactory::Mode proxy_mode = static_cast(s.value("mode", static_cast(NetworkProxyFactory::Mode::System)).toInt()); - if (proxy_mode == NetworkProxyFactory::Mode::Manual && s.contains("engine") && s.value("engine").toBool()) { - QString proxy_host = s.value("hostname").toString(); - int proxy_port = s.value("port").toInt(); + if (proxy_mode == NetworkProxyFactory::Mode::Manual && s.contains(NetworkProxySettings::kEngine) && s.value(NetworkProxySettings::kEngine).toBool()) { + QString proxy_host = s.value(NetworkProxySettings::kHostname).toString(); + int proxy_port = s.value(NetworkProxySettings::kPort).toInt(); if (proxy_host.isEmpty() || proxy_port <= 0) { proxy_address_.clear(); proxy_authentication_ = false; @@ -228,9 +229,9 @@ void EngineBase::ReloadSettings() { } else { proxy_address_ = QStringLiteral("%1:%2").arg(proxy_host).arg(proxy_port); - proxy_authentication_ = s.value("use_authentication").toBool(); - proxy_user_ = s.value("username").toString(); - proxy_pass_ = s.value("password").toString(); + proxy_authentication_ = s.value(NetworkProxySettings::kUseAuthentication).toBool(); + proxy_user_ = s.value(NetworkProxySettings::kUsername).toString(); + proxy_pass_ = s.value(NetworkProxySettings::kPassword).toString(); } } else { @@ -243,8 +244,8 @@ void EngineBase::ReloadSettings() { s.endGroup(); #ifdef HAVE_SPOTIFY - s.beginGroup(SpotifySettingsPage::kSettingsGroup); - spotify_access_token_ = s.value("access_token").toString(); + s.beginGroup(SpotifySettings::kSettingsGroup); + spotify_access_token_ = s.value(SpotifySettings::kAccessToken).toString(); s.endGroup(); #endif diff --git a/src/engine/enginebase.h b/src/engine/enginebase.h index 2940c99f2e..796a1fd60a 100644 --- a/src/engine/enginebase.h +++ b/src/engine/enginebase.h @@ -39,7 +39,7 @@ #include #include "devicefinders.h" -#include "enginemetadata.h" +#include "core/enginemetadata.h" #include "core/song.h" class EngineBase : public QObject { diff --git a/src/engine/gstengine.cpp b/src/engine/gstengine.cpp index dcff4a76a8..a1c3353d5c 100644 --- a/src/engine/gstengine.cpp +++ b/src/engine/gstengine.cpp @@ -50,16 +50,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/taskmanager.h" #include "core/signalchecker.h" -#include "utilities/timeconstants.h" +#include "core/enginemetadata.h" +#include "constants/timeconstants.h" #include "enginebase.h" #include "gstengine.h" #include "gstenginepipeline.h" #include "gstbufferconsumer.h" -#include "enginemetadata.h" using namespace Qt::Literals::StringLiterals; using std::make_shared; diff --git a/src/engine/gstengine.h b/src/engine/gstengine.h index 22291d32ee..da20037737 100644 --- a/src/engine/gstengine.h +++ b/src/engine/gstengine.h @@ -39,7 +39,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "enginebase.h" #include "gststartup.h" #include "gstenginepipeline.h" diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index d4e74977b9..ebc27f2c40 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -61,8 +61,8 @@ #include "core/logging.h" #include "core/signalchecker.h" -#include "utilities/timeconstants.h" -#include "settings/backendsettingspage.h" +#include "constants/timeconstants.h" +#include "constants/backendsettings.h" #include "gstengine.h" #include "gstenginepipeline.h" #include "gstbufferconsumer.h" @@ -103,9 +103,9 @@ GstEnginePipeline::GstEnginePipeline(QObject *parent) volume_enabled_(true), fading_enabled_(false), strict_ssl_enabled_(false), - buffer_duration_nanosec_(BackendSettingsPage::kDefaultBufferDuration * kNsecPerMsec), - buffer_low_watermark_(BackendSettingsPage::kDefaultBufferLowWatermark), - buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark), + buffer_duration_nanosec_(BackendSettings::kDefaultBufferDuration * kNsecPerMsec), + buffer_low_watermark_(BackendSettings::kDefaultBufferLowWatermark), + buffer_high_watermark_(BackendSettings::kDefaultBufferHighWatermark), proxy_authentication_(false), channels_enabled_(false), channels_(0), diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index 9792e526ae..fa11b58055 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -43,9 +43,9 @@ #include #include -#include "core/shared_ptr.h" -#include "core/mutex_protected.h" -#include "enginemetadata.h" +#include "includes/shared_ptr.h" +#include "includes/mutex_protected.h" +#include "core/enginemetadata.h" class QTimer; class QTimerEvent; diff --git a/src/moodbar/gstfastspectrum.cpp b/src/engine/gstfastspectrum.cpp similarity index 100% rename from src/moodbar/gstfastspectrum.cpp rename to src/engine/gstfastspectrum.cpp diff --git a/src/moodbar/gstfastspectrum.h b/src/engine/gstfastspectrum.h similarity index 100% rename from src/moodbar/gstfastspectrum.h rename to src/engine/gstfastspectrum.h diff --git a/src/moodbar/gstfastspectrumplugin.cpp b/src/engine/gstfastspectrumplugin.cpp similarity index 100% rename from src/moodbar/gstfastspectrumplugin.cpp rename to src/engine/gstfastspectrumplugin.cpp diff --git a/src/moodbar/gstfastspectrumplugin.h b/src/engine/gstfastspectrumplugin.h similarity index 100% rename from src/moodbar/gstfastspectrumplugin.h rename to src/engine/gstfastspectrumplugin.h diff --git a/src/engine/gststartup.cpp b/src/engine/gststartup.cpp index 45a8aa59a5..c56702840c 100644 --- a/src/engine/gststartup.cpp +++ b/src/engine/gststartup.cpp @@ -39,7 +39,7 @@ #include "utilities/envutils.h" #ifdef HAVE_MOODBAR -# include "moodbar/gstfastspectrumplugin.h" +# include "gstfastspectrumplugin.h" #endif #include "gststartup.h" diff --git a/src/engine/macosdevicefinder.cpp b/src/engine/macosdevicefinder.cpp index aa6ee0fb4e..a76bdb9dad 100644 --- a/src/engine/macosdevicefinder.cpp +++ b/src/engine/macosdevicefinder.cpp @@ -27,8 +27,8 @@ #include +#include "includes/scoped_cftyperef.h" #include "core/logging.h" -#include "core/scoped_cftyperef.h" #include "macosdevicefinder.h" #include "enginedevice.h" diff --git a/src/widgets/fileview.cpp b/src/fileview/fileview.cpp similarity index 93% rename from src/widgets/fileview.cpp rename to src/fileview/fileview.cpp index 2cfa1e1fed..2de5663173 100644 --- a/src/widgets/fileview.cpp +++ b/src/fileview/fileview.cpp @@ -36,31 +36,23 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/deletefiles.h" #include "core/filesystemmusicstorage.h" #include "core/iconloader.h" -#include "core/mimedata.h" #include "core/settings.h" +#include "core/mimedata.h" #include "dialogs/deleteconfirmationdialog.h" #include "fileview.h" #include "fileviewlist.h" #include "ui_fileview.h" #include "organize/organizeerrordialog.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" +#include "constants/filefilterconstants.h" using std::make_unique; using namespace Qt::Literals::StringLiterals; -const char *FileView::kFileFilter = - "*.wav *.flac *.wv *.ogg *.oga *.opus *.spx *.ape *.mpc " - "*.mp2 *.mp3 *.m4a *.mp4 *.aac *.asf *.asx *.wma " - "*.aif *.aiff *.mka *.tta *.dsf *.dsd " - "*.cue *.m3u *.m3u8 *.pls *.xspf *.asxini " - "*.ac3 *.dts " - "*.mod *.s3m *.xm *.it" - "*.spc *.vgm"; - FileView::FileView(QWidget *parent) : QWidget(parent), ui_(new Ui_FileView), @@ -95,7 +87,7 @@ FileView::FileView(QWidget *parent) QObject::connect(ui_->list, &FileViewList::Delete, this, &FileView::Delete); QObject::connect(ui_->list, &FileViewList::EditTags, this, &FileView::EditTags); - QString filter = QLatin1String(FileView::kFileFilter); + QString filter = QLatin1String(kFileFilter); filter_list_ << filter.split(u' '); ReloadSettings(); @@ -109,8 +101,8 @@ FileView::~FileView() { void FileView::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeLeftPanelButtons, 22).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeLeftPanelButtons, 22).toInt(); s.endGroup(); ui_->back->setIconSize(QSize(iconsize, iconsize)); diff --git a/src/widgets/fileview.h b/src/fileview/fileview.h similarity index 96% rename from src/widgets/fileview.h rename to src/fileview/fileview.h index d9b6c5c404..645286b559 100644 --- a/src/widgets/fileview.h +++ b/src/fileview/fileview.h @@ -30,8 +30,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QMimeData; @@ -52,8 +52,6 @@ class FileView : public QWidget { explicit FileView(QWidget *parent = nullptr); ~FileView() override; - static const char *kFileFilter; - void ReloadSettings(); void SetPath(const QString &path); diff --git a/src/widgets/fileview.ui b/src/fileview/fileview.ui similarity index 98% rename from src/widgets/fileview.ui rename to src/fileview/fileview.ui index 3be6f3ab65..62dfc3c71b 100644 --- a/src/widgets/fileview.ui +++ b/src/fileview/fileview.ui @@ -125,7 +125,7 @@ FileViewList QListView -
widgets/fileviewlist.h
+
fileview/fileviewlist.h
diff --git a/src/widgets/fileviewlist.cpp b/src/fileview/fileviewlist.cpp similarity index 100% rename from src/widgets/fileviewlist.cpp rename to src/fileview/fileviewlist.cpp diff --git a/src/widgets/fileviewlist.h b/src/fileview/fileviewlist.h similarity index 100% rename from src/widgets/fileviewlist.h rename to src/fileview/fileviewlist.h diff --git a/src/filterparser/filterparser.cpp b/src/filterparser/filterparser.cpp index 93d890f760..a61608d139 100644 --- a/src/filterparser/filterparser.cpp +++ b/src/filterparser/filterparser.cpp @@ -20,12 +20,15 @@ * */ -#include "config.h" - #include #include "filterparser.h" -#include "filtertree.h" +#include "filtertreenop.h" +#include "filtertreeand.h" +#include "filtertreeor.h" +#include "filtertreenot.h" +#include "filtertreeterm.h" +#include "filtertreecolumnterm.h" #include "filterparsersearchcomparators.h" using namespace Qt::Literals::StringLiterals; @@ -52,9 +55,9 @@ void FilterParser::advance() { FilterTree *FilterParser::parseOrGroup() { advance(); - if (iter_ == end_) return new NopFilter; + if (iter_ == end_) return new FilterTreeNop; - OrFilter *group = new OrFilter; + FilterTreeOr *group = new FilterTreeOr; group->add(parseAndGroup()); advance(); while (checkOr()) { @@ -69,9 +72,9 @@ FilterTree *FilterParser::parseOrGroup() { FilterTree *FilterParser::parseAndGroup() { advance(); - if (iter_ == end_) return new NopFilter; + if (iter_ == end_) return new FilterTreeNop; - AndFilter *group = new AndFilter(); + FilterTreeAnd *group = new FilterTreeAnd(); do { group->add(parseSearchExpression()); advance(); @@ -150,7 +153,7 @@ bool FilterParser::checkOr(const bool step_over) { FilterTree *FilterParser::parseSearchExpression() { advance(); - if (iter_ == end_) return new NopFilter; + if (iter_ == end_) return new FilterTreeNop; if (*iter_ == u'(') { ++iter_; advance(); @@ -166,7 +169,7 @@ FilterTree *FilterParser::parseSearchExpression() { else if (*iter_ == u'-') { ++iter_; FilterTree *tree = parseSearchExpression(); - if (tree->type() != FilterTree::FilterType::Nop) return new NotFilter(tree); + if (tree->type() != FilterTree::FilterType::Nop) return new FilterTreeNot(tree); return tree; } else { @@ -232,7 +235,7 @@ FilterTree *FilterParser::parseSearchTerm() { FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const QString &prefix, const QString &value) const { if (value.isEmpty() && prefix != u'=') { - return new NopFilter; + return new FilterTreeNop; } FilterParserSearchTermComparator *cmp = nullptr; @@ -360,10 +363,10 @@ FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const } if (cmp) { - return new FilterColumnTerm(column, cmp); + return new FilterTreeColumnTerm(column, cmp); } - return new FilterTerm(new FilterParserTextContainsComparator(value)); + return new FilterTreeTerm(new FilterParserTextContainsComparator(value)); } diff --git a/src/filterparser/filterparser.h b/src/filterparser/filterparser.h index 55f0e6b3f1..8b54820b51 100644 --- a/src/filterparser/filterparser.h +++ b/src/filterparser/filterparser.h @@ -23,8 +23,6 @@ #ifndef FILTERPARSER_H #define FILTERPARSER_H -#include "config.h" - #include class FilterTree; diff --git a/src/filterparser/filterparserfloateqcomparator.cpp b/src/filterparser/filterparserfloateqcomparator.cpp new file mode 100644 index 0000000000..690cbeb0bd --- /dev/null +++ b/src/filterparser/filterparserfloateqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserfloateqcomparator.h" + +FilterParserFloatEqComparator::FilterParserFloatEqComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatEqComparator::Matches(const QVariant &value) const { + return value.toFloat() == search_term_; +} diff --git a/src/filterparser/filterparserfloateqcomparator.h b/src/filterparser/filterparserfloateqcomparator.h new file mode 100644 index 0000000000..166264c820 --- /dev/null +++ b/src/filterparser/filterparserfloateqcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERFLOATEQCOMPARATOR_H +#define FILTERPARSERFLOATEQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatEqComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatEqComparator) +}; + +#endif // FILTERPARSERFLOATEQCOMPARATOR_H diff --git a/src/filterparser/filterparserfloatgecomparator.cpp b/src/filterparser/filterparserfloatgecomparator.cpp new file mode 100644 index 0000000000..a14f6878c4 --- /dev/null +++ b/src/filterparser/filterparserfloatgecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserfloatgecomparator.h" + +FilterParserFloatGeComparator::FilterParserFloatGeComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatGeComparator::Matches(const QVariant &value) const { + return value.toFloat() >= search_term_; +} diff --git a/src/filterparser/filterparserfloatgecomparator.h b/src/filterparser/filterparserfloatgecomparator.h new file mode 100644 index 0000000000..8f12116ee6 --- /dev/null +++ b/src/filterparser/filterparserfloatgecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERFLOATGECOMPARATOR_H +#define FILTERPARSERFLOATGECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatGeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatGeComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatGeComparator) +}; + +#endif // FILTERPARSERFLOATGECOMPARATOR_H diff --git a/src/filterparser/filterparserfloatgtcomparator.cpp b/src/filterparser/filterparserfloatgtcomparator.cpp new file mode 100644 index 0000000000..1da2f6f906 --- /dev/null +++ b/src/filterparser/filterparserfloatgtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserfloatgtcomparator.h" + +FilterParserFloatGtComparator::FilterParserFloatGtComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatGtComparator::Matches(const QVariant &value) const { + return value.toFloat() > search_term_; +} diff --git a/src/filterparser/filterparserfloatgtcomparator.h b/src/filterparser/filterparserfloatgtcomparator.h new file mode 100644 index 0000000000..7d28924446 --- /dev/null +++ b/src/filterparser/filterparserfloatgtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERFLOATGTCOMPARATOR_H +#define FILTERPARSERFLOATGTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatGtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatGtComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatGtComparator) +}; + +#endif // FILTERPARSERFLOATGTCOMPARATOR_H diff --git a/src/filterparser/filterparserfloatlecomparator.cpp b/src/filterparser/filterparserfloatlecomparator.cpp new file mode 100644 index 0000000000..be2556fec3 --- /dev/null +++ b/src/filterparser/filterparserfloatlecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserfloatlecomparator.h" + +FilterParserFloatLeComparator::FilterParserFloatLeComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatLeComparator::Matches(const QVariant &value) const { + return value.toFloat() <= search_term_; +} diff --git a/src/filterparser/filterparserfloatlecomparator.h b/src/filterparser/filterparserfloatlecomparator.h new file mode 100644 index 0000000000..f8fe59d4e3 --- /dev/null +++ b/src/filterparser/filterparserfloatlecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERFLOATLECOMPARATOR_H +#define FILTERPARSERFLOATLECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatLeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatLeComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatLeComparator) +}; + +#endif // FILTERPARSERFLOATLECOMPARATOR_H diff --git a/src/filterparser/filterparserfloatltcomparator.cpp b/src/filterparser/filterparserfloatltcomparator.cpp new file mode 100644 index 0000000000..bb41378f9a --- /dev/null +++ b/src/filterparser/filterparserfloatltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserfloatltcomparator.h" + +FilterParserFloatLtComparator::FilterParserFloatLtComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatLtComparator::Matches(const QVariant &value) const { + return value.toFloat() < search_term_; +} diff --git a/src/filterparser/filterparserfloatltcomparator.h b/src/filterparser/filterparserfloatltcomparator.h new file mode 100644 index 0000000000..c612773723 --- /dev/null +++ b/src/filterparser/filterparserfloatltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERFLOATLTCOMPARATOR_H +#define FILTERPARSERFLOATLTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatLtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatLtComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatLtComparator) +}; + +#endif // FILTERPARSERFLOATLTCOMPARATOR_H diff --git a/src/filterparser/filterparserfloatnecomparator.cpp b/src/filterparser/filterparserfloatnecomparator.cpp new file mode 100644 index 0000000000..8dad959bfe --- /dev/null +++ b/src/filterparser/filterparserfloatnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserfloatnecomparator.h" + +FilterParserFloatNeComparator::FilterParserFloatNeComparator(const float value) : search_term_(value) {} + +bool FilterParserFloatNeComparator::Matches(const QVariant &value) const { + return value.toFloat() != search_term_; +} diff --git a/src/filterparser/filterparserfloatnecomparator.h b/src/filterparser/filterparserfloatnecomparator.h new file mode 100644 index 0000000000..efa55641b2 --- /dev/null +++ b/src/filterparser/filterparserfloatnecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERFLOATNECOMPARATOR_H +#define FILTERPARSERFLOATNECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatNeComparator(const float value); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatNeComparator) +}; + +#endif // FILTERPARSERFLOATNECOMPARATOR_H diff --git a/src/filterparser/filterparserint64eqcomparator.cpp b/src/filterparser/filterparserint64eqcomparator.cpp new file mode 100644 index 0000000000..4a74f240c5 --- /dev/null +++ b/src/filterparser/filterparserint64eqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserint64eqcomparator.h" + +FilterParserInt64EqComparator::FilterParserInt64EqComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64EqComparator::Matches(const QVariant &value) const { + return value.toLongLong() == search_term_; +} diff --git a/src/filterparser/filterparserint64eqcomparator.h b/src/filterparser/filterparserint64eqcomparator.h new file mode 100644 index 0000000000..fc8ca593cf --- /dev/null +++ b/src/filterparser/filterparserint64eqcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINT64EQCOMPARATOR_H +#define FILTERPARSERINT64EQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64EqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64EqComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64EqComparator) +}; + +#endif // FILTERPARSERINT64EQCOMPARATOR_H diff --git a/src/filterparser/filterparserint64gecomparator.cpp b/src/filterparser/filterparserint64gecomparator.cpp new file mode 100644 index 0000000000..bdcd2b30a7 --- /dev/null +++ b/src/filterparser/filterparserint64gecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserint64gecomparator.h" + +FilterParserInt64GeComparator::FilterParserInt64GeComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64GeComparator::Matches(const QVariant &value) const { + return value.toLongLong() >= search_term_; +} diff --git a/src/filterparser/filterparserint64gecomparator.h b/src/filterparser/filterparserint64gecomparator.h new file mode 100644 index 0000000000..27869becd6 --- /dev/null +++ b/src/filterparser/filterparserint64gecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINT64GECOMPARATOR_H +#define FILTERPARSERINT64GECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64GeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64GeComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64GeComparator) +}; + +#endif // FILTERPARSERINT64GECOMPARATOR_H diff --git a/src/filterparser/filterparserint64gtcomparator.cpp b/src/filterparser/filterparserint64gtcomparator.cpp new file mode 100644 index 0000000000..a6d3f6edbd --- /dev/null +++ b/src/filterparser/filterparserint64gtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserint64gtcomparator.h" + +FilterParserInt64GtComparator::FilterParserInt64GtComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64GtComparator::Matches(const QVariant &value) const { + return value.toLongLong() > search_term_; +} diff --git a/src/filterparser/filterparserint64gtcomparator.h b/src/filterparser/filterparserint64gtcomparator.h new file mode 100644 index 0000000000..8aeaac0994 --- /dev/null +++ b/src/filterparser/filterparserint64gtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINT64GTCOMPARATOR_H +#define FILTERPARSERINT64GTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64GtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64GtComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64GtComparator) +}; + +#endif // FILTERPARSERINT64GTCOMPARATOR_H diff --git a/src/filterparser/filterparserint64lecomparator.cpp b/src/filterparser/filterparserint64lecomparator.cpp new file mode 100644 index 0000000000..136e5c2480 --- /dev/null +++ b/src/filterparser/filterparserint64lecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserint64lecomparator.h" + +FilterParserInt64LeComparator::FilterParserInt64LeComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64LeComparator::Matches(const QVariant &value) const { + return value.toLongLong() <= search_term_; +} diff --git a/src/filterparser/filterparserint64lecomparator.h b/src/filterparser/filterparserint64lecomparator.h new file mode 100644 index 0000000000..22792d7a03 --- /dev/null +++ b/src/filterparser/filterparserint64lecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINT64LECOMPARATOR_H +#define FILTERPARSERINT64LECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64LeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64LeComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64LeComparator) +}; + +#endif // FILTERPARSERINT64LECOMPARATOR_H diff --git a/src/filterparser/filterparserint64ltcomparator.cpp b/src/filterparser/filterparserint64ltcomparator.cpp new file mode 100644 index 0000000000..0e47c4fe78 --- /dev/null +++ b/src/filterparser/filterparserint64ltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserint64ltcomparator.h" + +FilterParserInt64LtComparator::FilterParserInt64LtComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64LtComparator::Matches(const QVariant &value) const { + return value.toLongLong() < search_term_; +} diff --git a/src/filterparser/filterparserint64ltcomparator.h b/src/filterparser/filterparserint64ltcomparator.h new file mode 100644 index 0000000000..0fe8c16f4b --- /dev/null +++ b/src/filterparser/filterparserint64ltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINT64LTCOMPARATOR_H +#define FILTERPARSERINT64LTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64LtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64LtComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64LtComparator) +}; + +#endif // FILTERPARSERINT64LTCOMPARATOR_H diff --git a/src/filterparser/filterparserint64necomparator.cpp b/src/filterparser/filterparserint64necomparator.cpp new file mode 100644 index 0000000000..dcefca5bb7 --- /dev/null +++ b/src/filterparser/filterparserint64necomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserint64necomparator.h" + +FilterParserInt64NeComparator::FilterParserInt64NeComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64NeComparator::Matches(const QVariant &value) const { + return value.toLongLong() != search_term_; +} diff --git a/src/filterparser/filterparserint64necomparator.h b/src/filterparser/filterparserint64necomparator.h new file mode 100644 index 0000000000..3f9d6bebcd --- /dev/null +++ b/src/filterparser/filterparserint64necomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINT64NECOMPARATOR_H +#define FILTERPARSERINT64NECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64NeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64NeComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64NeComparator) +}; + +#endif // FILTERPARSERINT64NECOMPARATOR_H diff --git a/src/filterparser/filterparserinteqcomparator.cpp b/src/filterparser/filterparserinteqcomparator.cpp new file mode 100644 index 0000000000..99d1620cb7 --- /dev/null +++ b/src/filterparser/filterparserinteqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserinteqcomparator.h" + +FilterParserIntEqComparator::FilterParserIntEqComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntEqComparator::Matches(const QVariant &value) const { + return value.toInt() == search_term_; +} diff --git a/src/filterparser/filterparserinteqcomparator.h b/src/filterparser/filterparserinteqcomparator.h new file mode 100644 index 0000000000..4b6494d96c --- /dev/null +++ b/src/filterparser/filterparserinteqcomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINTEQCOMPARATOR_H +#define FILTERPARSERINTEQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntEqComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntEqComparator) +}; + +#endif // FILTERPARSERINTEQCOMPARATOR_H + diff --git a/src/filterparser/filterparserintgecomparator.cpp b/src/filterparser/filterparserintgecomparator.cpp new file mode 100644 index 0000000000..1c254262ff --- /dev/null +++ b/src/filterparser/filterparserintgecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserintgecomparator.h" + +FilterParserIntGeComparator::FilterParserIntGeComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntGeComparator::Matches(const QVariant &value) const { + return value.toInt() >= search_term_; +} diff --git a/src/filterparser/filterparserintgecomparator.h b/src/filterparser/filterparserintgecomparator.h new file mode 100644 index 0000000000..6e6bc56574 --- /dev/null +++ b/src/filterparser/filterparserintgecomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINTGECOMPARATOR_H +#define FILTERPARSERINTGECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntGeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntGeComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntGeComparator) +}; + +#endif // FILTERPARSERINTGECOMPARATOR_H + diff --git a/src/filterparser/filterparserintgtcomparator.cpp b/src/filterparser/filterparserintgtcomparator.cpp new file mode 100644 index 0000000000..e2e350ac20 --- /dev/null +++ b/src/filterparser/filterparserintgtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserintgtcomparator.h" + +FilterParserIntGtComparator::FilterParserIntGtComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntGtComparator::Matches(const QVariant &value) const { + return value.toInt() > search_term_; +} diff --git a/src/filterparser/filterparserintgtcomparator.h b/src/filterparser/filterparserintgtcomparator.h new file mode 100644 index 0000000000..9e993136bc --- /dev/null +++ b/src/filterparser/filterparserintgtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINTGTCOMPARATOR_H +#define FILTERPARSERINTGTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntGtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntGtComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntGtComparator) +}; + +#endif // FILTERPARSERINTGTCOMPARATOR_H diff --git a/src/filterparser/filterparserintlecomparator.cpp b/src/filterparser/filterparserintlecomparator.cpp new file mode 100644 index 0000000000..b127a63f81 --- /dev/null +++ b/src/filterparser/filterparserintlecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserintlecomparator.h" + +FilterParserIntLeComparator::FilterParserIntLeComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntLeComparator::Matches(const QVariant &value) const { + return value.toInt() <= search_term_; +} diff --git a/src/filterparser/filterparserintlecomparator.h b/src/filterparser/filterparserintlecomparator.h new file mode 100644 index 0000000000..d39b1f2abd --- /dev/null +++ b/src/filterparser/filterparserintlecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINTLECOMPARATOR_H +#define FILTERPARSERINTLECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntLeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntLeComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntLeComparator) +}; + +#endif // FILTERPARSERINTLECOMPARATOR_H diff --git a/src/filterparser/filterparserintltcomparator.cpp b/src/filterparser/filterparserintltcomparator.cpp new file mode 100644 index 0000000000..05934d9c0e --- /dev/null +++ b/src/filterparser/filterparserintltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserintltcomparator.h" + +FilterParserIntLtComparator::FilterParserIntLtComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntLtComparator::Matches(const QVariant &value) const { + return value.toInt() < search_term_; +} diff --git a/src/filterparser/filterparserintltcomparator.h b/src/filterparser/filterparserintltcomparator.h new file mode 100644 index 0000000000..f972046e86 --- /dev/null +++ b/src/filterparser/filterparserintltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINTLTCOMPARATOR_H +#define FILTERPARSERINTLTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntLtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntLtComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntLtComparator) +}; + +#endif // FILTERPARSERINTLTCOMPARATOR_H diff --git a/src/filterparser/filterparserintnecomparator.cpp b/src/filterparser/filterparserintnecomparator.cpp new file mode 100644 index 0000000000..d7be5b7b34 --- /dev/null +++ b/src/filterparser/filterparserintnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparserintnecomparator.h" + +FilterParserIntNeComparator::FilterParserIntNeComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntNeComparator::Matches(const QVariant &value) const { + return value.toInt() != search_term_; +} diff --git a/src/filterparser/filterparserintnecomparator.h b/src/filterparser/filterparserintnecomparator.h new file mode 100644 index 0000000000..9e78002103 --- /dev/null +++ b/src/filterparser/filterparserintnecomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERINTNECOMPARATOR_H +#define FILTERPARSERINTNECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntNeComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntNeComparator) +}; + +#endif // FILTERPARSERINTNECOMPARATOR_H + diff --git a/src/filterparser/filterparsersearchcomparators.h b/src/filterparser/filterparsersearchcomparators.h index 3f09f1d2eb..7e4dff511d 100644 --- a/src/filterparser/filterparsersearchcomparators.h +++ b/src/filterparser/filterparsersearchcomparators.h @@ -1,314 +1,28 @@ -/* - * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2012, David Sansome - * Copyright 2018-2024, Jonas Kvinge - * - * 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 . - * - */ - -#ifndef FILTERPARSERSEARCHCOMPARATORS_H -#define FILTERPARSERSEARCHCOMPARATORS_H - -#include "config.h" - -#include -#include -#include - -class FilterParserSearchTermComparator { - public: - FilterParserSearchTermComparator() = default; - virtual ~FilterParserSearchTermComparator() = default; - virtual bool Matches(const QVariant &value) const = 0; - private: - Q_DISABLE_COPY(FilterParserSearchTermComparator) -}; - -// "compares" by checking if the field contains the search term -class FilterParserTextContainsComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserTextContainsComparator(const QString &search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.metaType().id() == QMetaType::QString && value.toString().contains(search_term_, Qt::CaseInsensitive); - } - private: - QString search_term_; - - Q_DISABLE_COPY(FilterParserTextContainsComparator) -}; - -class FilterParserTextEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserTextEqComparator(const QString &search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return search_term_.compare(value.toString(), Qt::CaseInsensitive) == 0; - } - private: - QString search_term_; -}; - -class FilterParserTextNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserTextNeComparator(const QString &search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return search_term_.compare(value.toString(), Qt::CaseInsensitive) != 0; - } - private: - QString search_term_; -}; - -class FilterParserIntEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntEqComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() == search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntNeComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() != search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntGtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntGtComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() > search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntGeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntGeComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() >= search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntLtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntLtComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() < search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntLeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntLeComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() <= search_term_; - } - private: - int search_term_; -}; - -class FilterParserUIntEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntEqComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() == search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntNeComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() != search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntGtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntGtComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() > search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntGeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntGeComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() >= search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntLtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntLtComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() < search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntLeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntLeComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() <= search_term_; - } - private: - uint search_term_; -}; - -class FilterParserInt64EqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64EqComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() == search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64NeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64NeComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() != search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64GtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64GtComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() > search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64GeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64GeComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() >= search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64LtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64LtComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() < search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64LeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64LeComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() <= search_term_; - } - private: - qint64 search_term_; -}; - -// Float Comparators are for the rating -class FilterParserFloatEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatEqComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() == search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatNeComparator(const float value) : search_term_(value) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() != search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatGtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatGtComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() > search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatGeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatGeComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() >= search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatLtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatLtComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() < search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatLeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatLeComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() <= search_term_; - } - private: - float search_term_; -}; - -#endif // FILTERPARSERSEARCHCOMPARATORS_H +#include "filterparserfloateqcomparator.h" +#include "filterparserfloatgecomparator.h" +#include "filterparserfloatgtcomparator.h" +#include "filterparserfloatlecomparator.h" +#include "filterparserfloatltcomparator.h" +#include "filterparserfloatnecomparator.h" +#include "filterparserint64eqcomparator.h" +#include "filterparserint64gecomparator.h" +#include "filterparserint64gtcomparator.h" +#include "filterparserint64lecomparator.h" +#include "filterparserint64ltcomparator.h" +#include "filterparserint64necomparator.h" +#include "filterparserinteqcomparator.h" +#include "filterparserintgecomparator.h" +#include "filterparserintgtcomparator.h" +#include "filterparserintlecomparator.h" +#include "filterparserintltcomparator.h" +#include "filterparserintnecomparator.h" +#include "filterparsersearchtermcomparator.h" +#include "filterparsertextcontainscomparator.h" +#include "filterparsertexteqcomparator.h" +#include "filterparsertextnecomparator.h" +#include "filterparseruinteqcomparator.h" +#include "filterparseruintgecomparator.h" +#include "filterparseruintgtcomparator.h" +#include "filterparseruintlecomparator.h" +#include "filterparseruintltcomparator.h" +#include "filterparseruintnecomparator.h" diff --git a/src/filterparser/filterparsersearchtermcomparator.cpp b/src/filterparser/filterparsersearchtermcomparator.cpp new file mode 100644 index 0000000000..c7d52ca2c5 --- /dev/null +++ b/src/filterparser/filterparsersearchtermcomparator.cpp @@ -0,0 +1,24 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparsersearchtermcomparator.h" + +FilterParserSearchTermComparator::FilterParserSearchTermComparator() = default; + +FilterParserSearchTermComparator::~FilterParserSearchTermComparator() = default; diff --git a/src/filterparser/filterparsersearchtermcomparator.h b/src/filterparser/filterparsersearchtermcomparator.h new file mode 100644 index 0000000000..72bbf9e4fd --- /dev/null +++ b/src/filterparser/filterparsersearchtermcomparator.h @@ -0,0 +1,34 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERSEARCHTERMCOMPARATOR_H +#define FILTERPARSERSEARCHTERMCOMPARATOR_H + +#include + +class FilterParserSearchTermComparator { + public: + explicit FilterParserSearchTermComparator(); + virtual ~FilterParserSearchTermComparator(); + virtual bool Matches(const QVariant &value) const = 0; + private: + Q_DISABLE_COPY(FilterParserSearchTermComparator) +}; + +#endif // FILTERPARSERSEARCHTERMCOMPARATOR_H diff --git a/src/filterparser/filterparsertextcontainscomparator.cpp b/src/filterparser/filterparsertextcontainscomparator.cpp new file mode 100644 index 0000000000..55822b36a3 --- /dev/null +++ b/src/filterparser/filterparsertextcontainscomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparsertextcontainscomparator.h" + +FilterParserTextContainsComparator::FilterParserTextContainsComparator(const QString &search_term) : search_term_(search_term) {} + +bool FilterParserTextContainsComparator::Matches(const QVariant &value) const { + return value.metaType().id() == QMetaType::QString && value.toString().contains(search_term_, Qt::CaseInsensitive); +} diff --git a/src/filterparser/filterparsertextcontainscomparator.h b/src/filterparser/filterparsertextcontainscomparator.h new file mode 100644 index 0000000000..1a18709f72 --- /dev/null +++ b/src/filterparser/filterparsertextcontainscomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERTEXTCONTAINSCOMPARATOR_H +#define FILTERPARSERTEXTCONTAINSCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserTextContainsComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserTextContainsComparator(const QString &search_term); + bool Matches(const QVariant &value) const override; + private: + QString search_term_; + Q_DISABLE_COPY(FilterParserTextContainsComparator) +}; + +#endif // FILTERPARSERTEXTCONTAINSCOMPARATOR_H diff --git a/src/filterparser/filterparsertexteqcomparator.cpp b/src/filterparser/filterparsertexteqcomparator.cpp new file mode 100644 index 0000000000..16dd3edf6d --- /dev/null +++ b/src/filterparser/filterparsertexteqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparsertexteqcomparator.h" + +FilterParserTextEqComparator::FilterParserTextEqComparator(const QString &search_term) : search_term_(search_term) {} + +bool FilterParserTextEqComparator::Matches(const QVariant &value) const { + return search_term_.compare(value.toString(), Qt::CaseInsensitive) == 0; +} diff --git a/src/filterparser/filterparsertexteqcomparator.h b/src/filterparser/filterparsertexteqcomparator.h new file mode 100644 index 0000000000..07f9eabae7 --- /dev/null +++ b/src/filterparser/filterparsertexteqcomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERTEXTEQCOMPARATOR_H +#define FILTERPARSERTEXTEQCOMPARATOR_H + +#include +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserTextEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserTextEqComparator(const QString &search_term); + bool Matches(const QVariant &value) const override; + private: + QString search_term_; + Q_DISABLE_COPY(FilterParserTextEqComparator) +}; + +#endif // FILTERPARSERTEXTEQCOMPARATOR_H diff --git a/src/filterparser/filterparsertextnecomparator.cpp b/src/filterparser/filterparsertextnecomparator.cpp new file mode 100644 index 0000000000..e7b5e3825d --- /dev/null +++ b/src/filterparser/filterparsertextnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparsertextnecomparator.h" + +FilterParserTextNeComparator::FilterParserTextNeComparator(const QString &search_term) : search_term_(search_term) {} + +bool FilterParserTextNeComparator::Matches(const QVariant &value) const { + return search_term_.compare(value.toString(), Qt::CaseInsensitive) != 0; +} diff --git a/src/filterparser/filterparsertextnecomparator.h b/src/filterparser/filterparsertextnecomparator.h new file mode 100644 index 0000000000..db286c7579 --- /dev/null +++ b/src/filterparser/filterparsertextnecomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERTEXTNECOMPARATOR_H +#define FILTERPARSERTEXTNECOMPARATOR_H + +#include +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserTextNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserTextNeComparator(const QString &search_term); + bool Matches(const QVariant &value) const override; + private: + QString search_term_; + Q_DISABLE_COPY(FilterParserTextNeComparator) +}; + +#endif // FILTERPARSERTEXTNECOMPARATOR_H diff --git a/src/filterparser/filterparseruinteqcomparator.cpp b/src/filterparser/filterparseruinteqcomparator.cpp new file mode 100644 index 0000000000..8151cf7b28 --- /dev/null +++ b/src/filterparser/filterparseruinteqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparseruinteqcomparator.h" + +FilterParserUIntEqComparator::FilterParserUIntEqComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntEqComparator::Matches(const QVariant &value) const { + return value.toUInt() == search_term_; +} diff --git a/src/filterparser/filterparseruinteqcomparator.h b/src/filterparser/filterparseruinteqcomparator.h new file mode 100644 index 0000000000..30a6187016 --- /dev/null +++ b/src/filterparser/filterparseruinteqcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERUINTEQCOMPARATOR_H +#define FILTERPARSERUINTEQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntEqComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntEqComparator) +}; + +#endif // FILTERPARSERUINTEQCOMPARATOR_H diff --git a/src/filterparser/filterparseruintgecomparator.cpp b/src/filterparser/filterparseruintgecomparator.cpp new file mode 100644 index 0000000000..dc20c70081 --- /dev/null +++ b/src/filterparser/filterparseruintgecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparseruintgecomparator.h" + +FilterParserUIntGeComparator::FilterParserUIntGeComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntGeComparator::Matches(const QVariant &value) const { + return value.toUInt() >= search_term_; +} diff --git a/src/filterparser/filterparseruintgecomparator.h b/src/filterparser/filterparseruintgecomparator.h new file mode 100644 index 0000000000..02543b508c --- /dev/null +++ b/src/filterparser/filterparseruintgecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERUINTGECOMPARATOR_H +#define FILTERPARSERUINTGECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntGeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntGeComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntGeComparator) +}; + +#endif // FILTERPARSERUINTGECOMPARATOR_H diff --git a/src/filterparser/filterparseruintgtcomparator.cpp b/src/filterparser/filterparseruintgtcomparator.cpp new file mode 100644 index 0000000000..9b644a27cb --- /dev/null +++ b/src/filterparser/filterparseruintgtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparseruintgtcomparator.h" + +FilterParserUIntGtComparator::FilterParserUIntGtComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntGtComparator::Matches(const QVariant &value) const { + return value.toUInt() > search_term_; +} diff --git a/src/filterparser/filterparseruintgtcomparator.h b/src/filterparser/filterparseruintgtcomparator.h new file mode 100644 index 0000000000..fe8441d479 --- /dev/null +++ b/src/filterparser/filterparseruintgtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERUINTGTCOMPARATOR_H +#define FILTERPARSERUINTGTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntGtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntGtComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntGtComparator) +}; + +#endif // FILTERPARSERUINTGTCOMPARATOR_H diff --git a/src/filterparser/filterparseruintlecomparator.cpp b/src/filterparser/filterparseruintlecomparator.cpp new file mode 100644 index 0000000000..9943985b97 --- /dev/null +++ b/src/filterparser/filterparseruintlecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparseruintlecomparator.h" + +FilterParserUIntLeComparator::FilterParserUIntLeComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntLeComparator::Matches(const QVariant &value) const { + return value.toUInt() <= search_term_; +} diff --git a/src/filterparser/filterparseruintlecomparator.h b/src/filterparser/filterparseruintlecomparator.h new file mode 100644 index 0000000000..b6390a5473 --- /dev/null +++ b/src/filterparser/filterparseruintlecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERUINTLECOMPARATOR_H +#define FILTERPARSERUINTLECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntLeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntLeComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntLeComparator) +}; + +#endif // FILTERPARSERUINTLECOMPARATOR_H diff --git a/src/filterparser/filterparseruintltcomparator.cpp b/src/filterparser/filterparseruintltcomparator.cpp new file mode 100644 index 0000000000..57f7866874 --- /dev/null +++ b/src/filterparser/filterparseruintltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparseruintltcomparator.h" + +FilterParserUIntLtComparator::FilterParserUIntLtComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntLtComparator::Matches(const QVariant &value) const { + return value.toUInt() < search_term_; +} diff --git a/src/filterparser/filterparseruintltcomparator.h b/src/filterparser/filterparseruintltcomparator.h new file mode 100644 index 0000000000..f31c53632e --- /dev/null +++ b/src/filterparser/filterparseruintltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERUINTLTCOMPARATOR_H +#define FILTERPARSERUINTLTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntLtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntLtComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntLtComparator) +}; + +#endif // FILTERPARSERUINTLTCOMPARATOR_H diff --git a/src/filterparser/filterparseruintnecomparator.cpp b/src/filterparser/filterparseruintnecomparator.cpp new file mode 100644 index 0000000000..81c1165048 --- /dev/null +++ b/src/filterparser/filterparseruintnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filterparseruintnecomparator.h" + +FilterParserUIntNeComparator::FilterParserUIntNeComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntNeComparator::Matches(const QVariant &value) const { + return value.toUInt() != search_term_; +} diff --git a/src/filterparser/filterparseruintnecomparator.h b/src/filterparser/filterparseruintnecomparator.h new file mode 100644 index 0000000000..a000d040d8 --- /dev/null +++ b/src/filterparser/filterparseruintnecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERPARSERUINTNECOMPARATOR_H +#define FILTERPARSERUINTNECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntNeComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntNeComparator) +}; + +#endif // FILTERPARSERUINTNECOMPARATOR_H diff --git a/src/filterparser/filtertree.cpp b/src/filterparser/filtertree.cpp index a8bbb81c91..50f1bf1c5c 100644 --- a/src/filterparser/filtertree.cpp +++ b/src/filterparser/filtertree.cpp @@ -23,6 +23,8 @@ #include "filtertree.h" +#include "core/song.h" + using namespace Qt::Literals::StringLiterals; FilterTree::FilterTree() = default; diff --git a/src/filterparser/filtertree.h b/src/filterparser/filtertree.h index 7098f1ca20..5e49c78b83 100644 --- a/src/filterparser/filtertree.h +++ b/src/filterparser/filtertree.h @@ -22,15 +22,9 @@ #ifndef FILTERTREE_H #define FILTERTREE_H -#include "config.h" - -#include #include -#include -#include #include "core/song.h" -#include "filterparsersearchcomparators.h" class FilterTree { public: @@ -57,99 +51,4 @@ class FilterTree { Q_DISABLE_COPY(FilterTree) }; -// Trivial filter that accepts *anything* -class NopFilter : public FilterTree { - public: - FilterType type() const override { return FilterType::Nop; } - bool accept(const Song &song) const override { Q_UNUSED(song); return true; } -}; - -// Filter that applies a SearchTermComparator to all fields -class FilterTerm : public FilterTree { - public: - explicit FilterTerm(FilterParserSearchTermComparator *comparator) : cmp_(comparator) {} - - FilterType type() const override { return FilterType::Term; } - - bool accept(const Song &song) const override { - - if (cmp_->Matches(song.PrettyTitle())) return true; - if (cmp_->Matches(song.album())) return true; - if (cmp_->Matches(song.artist())) return true; - if (cmp_->Matches(song.albumartist())) return true; - if (cmp_->Matches(song.composer())) return true; - if (cmp_->Matches(song.performer())) return true; - if (cmp_->Matches(song.grouping())) return true; - if (cmp_->Matches(song.genre())) return true; - if (cmp_->Matches(song.comment())) return true; - - return false; - - } - - private: - QScopedPointer cmp_; -}; - -class FilterColumnTerm : public FilterTree { - public: - explicit FilterColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator) : column_(column), cmp_(comparator) {} - - FilterType type() const override { return FilterType::Column; } - - bool accept(const Song &song) const override { - return cmp_->Matches(DataFromColumn(column_, song)); - } - - private: - const QString column_; - QScopedPointer cmp_; -}; - -class NotFilter : public FilterTree { - public: - explicit NotFilter(const FilterTree *inv) : child_(inv) {} - - FilterType type() const override { return FilterType::Not; } - - bool accept(const Song &song) const override { - return !child_->accept(song); - } - - private: - QScopedPointer child_; -}; - -class OrFilter : public FilterTree { - public: - ~OrFilter() override { qDeleteAll(children_); } - - FilterType type() const override { return FilterType::Or; } - - virtual void add(FilterTree *child) { children_.append(child); } - - bool accept(const Song &song) const override { - return std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return child->accept(song); }); - } - - private: - QList children_; -}; - -class AndFilter : public FilterTree { - public: - ~AndFilter() override { qDeleteAll(children_); } - - FilterType type() const override { return FilterType::And; } - - virtual void add(FilterTree *child) { children_.append(child); } - - bool accept(const Song &song) const override { - return !std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return !child->accept(song); }); - } - - private: - QList children_; -}; - #endif // FILTERTREE_H diff --git a/src/filterparser/filtertreeand.cpp b/src/filterparser/filtertreeand.cpp new file mode 100644 index 0000000000..0672a4abf0 --- /dev/null +++ b/src/filterparser/filtertreeand.cpp @@ -0,0 +1,34 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filtertreeand.h" + +FilterTreeAnd::FilterTreeAnd() = default; + +FilterTreeAnd::~FilterTreeAnd() { + qDeleteAll(children_); +} + +void FilterTreeAnd::add(FilterTree *child) { children_.append(child); } + +bool FilterTreeAnd::accept(const Song &song) const { + return !std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return !child->accept(song); }); +} diff --git a/src/filterparser/filtertreeand.h b/src/filterparser/filtertreeand.h new file mode 100644 index 0000000000..442d8fe841 --- /dev/null +++ b/src/filterparser/filtertreeand.h @@ -0,0 +1,46 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERTREEAND_H +#define FILTERTREEAND_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterTreeAnd : public FilterTree { + public: + explicit FilterTreeAnd(); + ~FilterTreeAnd() override; + + FilterType type() const override { return FilterType::And; } + virtual void add(FilterTree *child); + bool accept(const Song &song) const override; + + private: + QList children_; + + Q_DISABLE_COPY(FilterTreeAnd) +}; + +#endif // FILTERTREEAND_H diff --git a/src/filterparser/filtertreecolumnterm.cpp b/src/filterparser/filtertreecolumnterm.cpp new file mode 100644 index 0000000000..9c1d8f572d --- /dev/null +++ b/src/filterparser/filtertreecolumnterm.cpp @@ -0,0 +1,31 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "filtertreecolumnterm.h" +#include "filterparsersearchtermcomparator.h" + +FilterTreeColumnTerm::FilterTreeColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator) : column_(column), cmp_(comparator) {} + +bool FilterTreeColumnTerm::accept(const Song &song) const { + return cmp_->Matches(DataFromColumn(column_, song)); +} diff --git a/src/filterparser/filtertreecolumnterm.h b/src/filterparser/filtertreecolumnterm.h new file mode 100644 index 0000000000..ffaa403763 --- /dev/null +++ b/src/filterparser/filtertreecolumnterm.h @@ -0,0 +1,48 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERTREECOLUMNTERM_H +#define FILTERTREECOLUMNTERM_H + +#include +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterParserSearchTermComparator; + +class FilterTreeColumnTerm : public FilterTree { + public: + explicit FilterTreeColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator); + + FilterType type() const override { return FilterType::Column; } + bool accept(const Song &song) const override; + + private: + const QString column_; + QScopedPointer cmp_; + + Q_DISABLE_COPY(FilterTreeColumnTerm) +}; + +#endif // FILTERTREECOLUMNTERM_H diff --git a/src/filterparser/filtertreenop.cpp b/src/filterparser/filtertreenop.cpp new file mode 100644 index 0000000000..df153ce95b --- /dev/null +++ b/src/filterparser/filtertreenop.cpp @@ -0,0 +1,29 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filtertreenop.h" + +FilterTreeNop::FilterTreeNop() = default; + +bool FilterTreeNop::accept(const Song &song) const { + Q_UNUSED(song); + return true; +} diff --git a/src/filterparser/filtertreenop.h b/src/filterparser/filtertreenop.h new file mode 100644 index 0000000000..b7d6a5ce50 --- /dev/null +++ b/src/filterparser/filtertreenop.h @@ -0,0 +1,38 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERTREENOP_H +#define FILTERTREENOP_H + +#include "filtertree.h" + +#include "core/song.h" + +// Trivial filter that accepts *anything* +class FilterTreeNop : public FilterTree { + public: + explicit FilterTreeNop(); + FilterType type() const override { return FilterType::Nop; } + bool accept(const Song &song) const override; + Q_DISABLE_COPY(FilterTreeNop) +}; + +#endif // FILTERTREENOP_H diff --git a/src/filterparser/filtertreenot.cpp b/src/filterparser/filtertreenot.cpp new file mode 100644 index 0000000000..0289068721 --- /dev/null +++ b/src/filterparser/filtertreenot.cpp @@ -0,0 +1,30 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "filtertreenot.h" + +FilterTreeNot::FilterTreeNot(const FilterTree *inv) : child_(inv) {} + +bool FilterTreeNot::accept(const Song &song) const { + return !child_->accept(song); +} diff --git a/src/filterparser/filtertreenot.h b/src/filterparser/filtertreenot.h new file mode 100644 index 0000000000..ede71b6a94 --- /dev/null +++ b/src/filterparser/filtertreenot.h @@ -0,0 +1,44 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERTREENOT_H +#define FILTERTREENOT_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterTreeNot : public FilterTree { + public: + explicit FilterTreeNot(const FilterTree *inv); + + FilterType type() const override { return FilterType::Not; } + bool accept(const Song &song) const override; + + private: + QScopedPointer child_; + + Q_DISABLE_COPY(FilterTreeNot) +}; + +#endif // FILTERTREENOT_H diff --git a/src/filterparser/filtertreeor.cpp b/src/filterparser/filtertreeor.cpp new file mode 100644 index 0000000000..109646dc8b --- /dev/null +++ b/src/filterparser/filtertreeor.cpp @@ -0,0 +1,38 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "filtertreeor.h" + +FilterTreeOr::FilterTreeOr() = default; + +FilterTreeOr::~FilterTreeOr() { + qDeleteAll(children_); +} + +void FilterTreeOr::add(FilterTree *child) { + children_.append(child); +} + +bool FilterTreeOr::accept(const Song &song) const { + return std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return child->accept(song); }); +} diff --git a/src/filterparser/filtertreeor.h b/src/filterparser/filtertreeor.h new file mode 100644 index 0000000000..bd570d31af --- /dev/null +++ b/src/filterparser/filtertreeor.h @@ -0,0 +1,46 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERTREEOR_H +#define FILTERTREEOR_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterTreeOr : public FilterTree { + public: + explicit FilterTreeOr(); + ~FilterTreeOr() override; + + FilterType type() const override { return FilterType::Or; } + virtual void add(FilterTree *child); + bool accept(const Song &song) const override; + + private: + QList children_; + + Q_DISABLE_COPY(FilterTreeOr) +}; + +#endif // FILTERTREEOR_H diff --git a/src/filterparser/filtertreeterm.cpp b/src/filterparser/filtertreeterm.cpp new file mode 100644 index 0000000000..5b212cde05 --- /dev/null +++ b/src/filterparser/filtertreeterm.cpp @@ -0,0 +1,41 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "filtertreeterm.h" +#include "filterparsersearchtermcomparator.h" + +FilterTreeTerm::FilterTreeTerm(FilterParserSearchTermComparator *comparator) : cmp_(comparator) {} + +bool FilterTreeTerm::accept(const Song &song) const { + + if (cmp_->Matches(song.PrettyTitle())) return true; + if (cmp_->Matches(song.album())) return true; + if (cmp_->Matches(song.artist())) return true; + if (cmp_->Matches(song.albumartist())) return true; + if (cmp_->Matches(song.composer())) return true; + if (cmp_->Matches(song.performer())) return true; + if (cmp_->Matches(song.grouping())) return true; + if (cmp_->Matches(song.genre())) return true; + if (cmp_->Matches(song.comment())) return true; + + return false; + +} diff --git a/src/filterparser/filtertreeterm.h b/src/filterparser/filtertreeterm.h new file mode 100644 index 0000000000..1cf68da24a --- /dev/null +++ b/src/filterparser/filtertreeterm.h @@ -0,0 +1,47 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef FILTERTREETERM_H +#define FILTERTREETERM_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterParserSearchTermComparator; + +// Filter that applies a SearchTermComparator to all fields +class FilterTreeTerm : public FilterTree { + public: + explicit FilterTreeTerm(FilterParserSearchTermComparator *comparator); + + FilterType type() const override { return FilterType::Term; } + bool accept(const Song &song) const override; + + private: + QScopedPointer cmp_; + + Q_DISABLE_COPY(FilterTreeTerm) +}; + +#endif // FILTERTREETERM_H diff --git a/src/globalshortcuts/globalshortcutsbackend-macos.h b/src/globalshortcuts/globalshortcutsbackend-macos.h index 4abd125127..209ddfbdab 100644 --- a/src/globalshortcuts/globalshortcutsbackend-macos.h +++ b/src/globalshortcuts/globalshortcutsbackend-macos.h @@ -31,7 +31,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class GlobalShortcutsBackendMacOSPrivate; diff --git a/src/globalshortcuts/globalshortcutsbackend-macos.mm b/src/globalshortcuts/globalshortcutsbackend-macos.mm index 99234509d3..1f3de83cc2 100644 --- a/src/globalshortcuts/globalshortcutsbackend-macos.mm +++ b/src/globalshortcuts/globalshortcutsbackend-macos.mm @@ -36,12 +36,11 @@ #include #include -#include "config.h" #include "globalshortcutsmanager.h" #include "core/logging.h" #include "core/mac_startup.h" -#import "core/SBSystemPreferences.h" +#import "includes/SBSystemPreferences.h" class GlobalShortcutsBackendMacOSPrivate { public: diff --git a/src/globalshortcuts/globalshortcutsmanager.cpp b/src/globalshortcuts/globalshortcutsmanager.cpp index b16022d2fe..545c7819b1 100644 --- a/src/globalshortcuts/globalshortcutsmanager.cpp +++ b/src/globalshortcuts/globalshortcutsmanager.cpp @@ -31,6 +31,8 @@ #include #include +#include "core/logging.h" + #include "globalshortcutsmanager.h" #include "globalshortcutsbackend.h" @@ -58,13 +60,13 @@ # include "globalshortcutsbackend-macos.h" #endif -#include "settings/globalshortcutssettingspage.h" +#include "constants/globalshortcutssettings.h" using namespace Qt::Literals::StringLiterals; GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) : QWidget(parent) { - settings_.beginGroup(GlobalShortcutsSettingsPage::kSettingsGroup); + settings_.beginGroup(GlobalShortcutsSettings::kSettingsGroup); // Create actions AddShortcut(u"play"_s, tr("Play"), std::bind(&GlobalShortcutsManager::Play, this)); @@ -131,25 +133,25 @@ void GlobalShortcutsManager::ReloadSettings() { #endif #ifdef HAVE_KDE_GLOBALSHORTCUTS - if (settings_.value("use_kde", true).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseKDE, true).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::KDE; } #endif #ifdef HAVE_GNOME_GLOBALSHORTCUTS - if (settings_.value("use_gnome", true).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseGnome, true).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::Gnome; } #endif #ifdef HAVE_MATE_GLOBALSHORTCUTS - if (settings_.value("use_mate", true).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseMate, true).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::Mate; } #endif #ifdef HAVE_X11_GLOBALSHORTCUTS - if (settings_.value("use_x11", false).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseX11, false).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::X11; } #endif diff --git a/src/core/SBSystemPreferences.h b/src/includes/SBSystemPreferences.h similarity index 100% rename from src/core/SBSystemPreferences.h rename to src/includes/SBSystemPreferences.h diff --git a/src/core/arraysize.h b/src/includes/arraysize.h similarity index 100% rename from src/core/arraysize.h rename to src/includes/arraysize.h diff --git a/src/core/dbus_metatypes.h b/src/includes/dbus_metatypes.h similarity index 100% rename from src/core/dbus_metatypes.h rename to src/includes/dbus_metatypes.h diff --git a/src/core/iconmapper.h b/src/includes/iconmapper.h similarity index 100% rename from src/core/iconmapper.h rename to src/includes/iconmapper.h diff --git a/src/core/lazy.h b/src/includes/lazy.h similarity index 100% rename from src/core/lazy.h rename to src/includes/lazy.h diff --git a/src/core/mac_delegate.h b/src/includes/mac_delegate.h similarity index 100% rename from src/core/mac_delegate.h rename to src/includes/mac_delegate.h diff --git a/src/core/mutex_protected.h b/src/includes/mutex_protected.h similarity index 100% rename from src/core/mutex_protected.h rename to src/includes/mutex_protected.h diff --git a/src/core/qt_blurimage.h b/src/includes/qt_blurimage.h similarity index 100% rename from src/core/qt_blurimage.h rename to src/includes/qt_blurimage.h diff --git a/src/core/scoped_cftyperef.h b/src/includes/scoped_cftyperef.h similarity index 100% rename from src/core/scoped_cftyperef.h rename to src/includes/scoped_cftyperef.h diff --git a/src/core/scoped_nsobject.h b/src/includes/scoped_nsobject.h similarity index 100% rename from src/core/scoped_nsobject.h rename to src/includes/scoped_nsobject.h diff --git a/src/core/scoped_ptr.h b/src/includes/scoped_ptr.h similarity index 100% rename from src/core/scoped_ptr.h rename to src/includes/scoped_ptr.h diff --git a/src/core/scopedgobject.h b/src/includes/scopedgobject.h similarity index 100% rename from src/core/scopedgobject.h rename to src/includes/scopedgobject.h diff --git a/src/core/shared_ptr.h b/src/includes/shared_ptr.h similarity index 100% rename from src/core/shared_ptr.h rename to src/includes/shared_ptr.h diff --git a/src/lyrics/azlyricscomlyricsprovider.cpp b/src/lyrics/azlyricscomlyricsprovider.cpp index 3046725805..f45a7c1fa4 100644 --- a/src/lyrics/azlyricscomlyricsprovider.cpp +++ b/src/lyrics/azlyricscomlyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/transliterate.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/azlyricscomlyricsprovider.h b/src/lyrics/azlyricscomlyricsprovider.h index 88a41bb42b..74fb084a5a 100644 --- a/src/lyrics/azlyricscomlyricsprovider.h +++ b/src/lyrics/azlyricscomlyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/chartlyricsprovider.cpp b/src/lyrics/chartlyricsprovider.cpp index 9b48e9bf09..c74f8e459f 100644 --- a/src/lyrics/chartlyricsprovider.cpp +++ b/src/lyrics/chartlyricsprovider.cpp @@ -30,8 +30,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/chartlyricsprovider.h b/src/lyrics/chartlyricsprovider.h index 1df3564b01..571faa408f 100644 --- a/src/lyrics/chartlyricsprovider.h +++ b/src/lyrics/chartlyricsprovider.h @@ -27,7 +27,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsprovider.h" #include "lyricsfetcher.h" diff --git a/src/lyrics/elyricsnetlyricsprovider.cpp b/src/lyrics/elyricsnetlyricsprovider.cpp index 473064b400..e370084b74 100644 --- a/src/lyrics/elyricsnetlyricsprovider.cpp +++ b/src/lyrics/elyricsnetlyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/transliterate.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/elyricsnetlyricsprovider.h b/src/lyrics/elyricsnetlyricsprovider.h index f1341f2ce7..7fde500e66 100644 --- a/src/lyrics/elyricsnetlyricsprovider.h +++ b/src/lyrics/elyricsnetlyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/geniuslyricsprovider.cpp b/src/lyrics/geniuslyricsprovider.cpp index 371497cfa3..9d179772e1 100644 --- a/src/lyrics/geniuslyricsprovider.cpp +++ b/src/lyrics/geniuslyricsprovider.cpp @@ -45,8 +45,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/settings.h" #include "core/localredirectserver.h" diff --git a/src/lyrics/geniuslyricsprovider.h b/src/lyrics/geniuslyricsprovider.h index 56dcf9f925..ab045d0a80 100644 --- a/src/lyrics/geniuslyricsprovider.h +++ b/src/lyrics/geniuslyricsprovider.h @@ -34,7 +34,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsonlyricsprovider.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" diff --git a/src/lyrics/htmllyricsprovider.cpp b/src/lyrics/htmllyricsprovider.cpp index 71edb3d915..3c7645a18a 100644 --- a/src/lyrics/htmllyricsprovider.cpp +++ b/src/lyrics/htmllyricsprovider.cpp @@ -29,8 +29,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "htmllyricsprovider.h" diff --git a/src/lyrics/htmllyricsprovider.h b/src/lyrics/htmllyricsprovider.h index 4f77df6bc0..2e822d9f38 100644 --- a/src/lyrics/htmllyricsprovider.h +++ b/src/lyrics/htmllyricsprovider.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "lyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/jsonlyricsprovider.cpp b/src/lyrics/jsonlyricsprovider.cpp index afd7f81ae6..e5a2d7d3e5 100644 --- a/src/lyrics/jsonlyricsprovider.cpp +++ b/src/lyrics/jsonlyricsprovider.cpp @@ -26,7 +26,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "jsonlyricsprovider.h" diff --git a/src/lyrics/jsonlyricsprovider.h b/src/lyrics/jsonlyricsprovider.h index 58135424e5..8cd97e3a8e 100644 --- a/src/lyrics/jsonlyricsprovider.h +++ b/src/lyrics/jsonlyricsprovider.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsprovider.h" class NetworkAccessManager; diff --git a/src/lyrics/letraslyricsprovider.cpp b/src/lyrics/letraslyricsprovider.cpp index f62bd497c6..2939d8c795 100644 --- a/src/lyrics/letraslyricsprovider.cpp +++ b/src/lyrics/letraslyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "utilities/transliterate.h" diff --git a/src/lyrics/letraslyricsprovider.h b/src/lyrics/letraslyricsprovider.h index 0f57a30072..d1f5cecd31 100644 --- a/src/lyrics/letraslyricsprovider.h +++ b/src/lyrics/letraslyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/lololyricsprovider.cpp b/src/lyrics/lololyricsprovider.cpp index 01ac5b499c..978ff3ea18 100644 --- a/src/lyrics/lololyricsprovider.cpp +++ b/src/lyrics/lololyricsprovider.cpp @@ -30,8 +30,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/lololyricsprovider.h b/src/lyrics/lololyricsprovider.h index fdbcd825f4..8ddfd736a3 100644 --- a/src/lyrics/lololyricsprovider.h +++ b/src/lyrics/lololyricsprovider.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/lyricsfetcher.cpp b/src/lyrics/lyricsfetcher.cpp index 7158700cac..547727277b 100644 --- a/src/lyrics/lyricsfetcher.cpp +++ b/src/lyrics/lyricsfetcher.cpp @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "lyricsfetcher.h" #include "lyricsfetchersearch.h" diff --git a/src/lyrics/lyricsfetcher.h b/src/lyrics/lyricsfetcher.h index 95ed452981..b96f7fc260 100644 --- a/src/lyrics/lyricsfetcher.h +++ b/src/lyrics/lyricsfetcher.h @@ -32,7 +32,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" diff --git a/src/lyrics/lyricsfetchersearch.cpp b/src/lyrics/lyricsfetchersearch.cpp index 670ff9e8cc..7b3a168e0c 100644 --- a/src/lyrics/lyricsfetchersearch.cpp +++ b/src/lyrics/lyricsfetchersearch.cpp @@ -26,7 +26,7 @@ #include #include "core/logging.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsfetchersearch.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" diff --git a/src/lyrics/lyricsfetchersearch.h b/src/lyrics/lyricsfetchersearch.h index 221f200a0d..3b75cff9f9 100644 --- a/src/lyrics/lyricsfetchersearch.h +++ b/src/lyrics/lyricsfetchersearch.h @@ -27,7 +27,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" diff --git a/src/lyrics/lyricsprovider.cpp b/src/lyrics/lyricsprovider.cpp index 5403464d37..b5c036ed98 100644 --- a/src/lyrics/lyricsprovider.cpp +++ b/src/lyrics/lyricsprovider.cpp @@ -21,7 +21,7 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "lyricsprovider.h" diff --git a/src/lyrics/lyricsprovider.h b/src/lyrics/lyricsprovider.h index 74e169508c..02b841f6f5 100644 --- a/src/lyrics/lyricsprovider.h +++ b/src/lyrics/lyricsprovider.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" diff --git a/src/lyrics/lyricsproviders.cpp b/src/lyrics/lyricsproviders.cpp index ac30f1c94c..6b4afb3345 100644 --- a/src/lyrics/lyricsproviders.cpp +++ b/src/lyrics/lyricsproviders.cpp @@ -36,7 +36,7 @@ #include "lyricsprovider.h" #include "lyricsproviders.h" -#include "settings/lyricssettingspage.h" +#include "constants/lyricssettings.h" int LyricsProviders::NextOrderId = 0; @@ -72,8 +72,8 @@ void LyricsProviders::ReloadSettings() { } Settings s; - s.beginGroup(LyricsSettingsPage::kSettingsGroup); - const QStringList providers_enabled = s.value("providers", QStringList() << all_providers.values()).toStringList(); + s.beginGroup(LyricsSettings::kSettingsGroup); + const QStringList providers_enabled = s.value(LyricsSettings::kProviders, QStringList() << all_providers.values()).toStringList(); s.endGroup(); int i = 0; diff --git a/src/lyrics/lyricsproviders.h b/src/lyrics/lyricsproviders.h index 27906523e8..f2cba01108 100644 --- a/src/lyrics/lyricsproviders.h +++ b/src/lyrics/lyricsproviders.h @@ -31,7 +31,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class NetworkAccessManager; class LyricsProvider; diff --git a/src/lyrics/musixmatchlyricsprovider.cpp b/src/lyrics/musixmatchlyricsprovider.cpp index 44e9496ddf..35d55c817e 100644 --- a/src/lyrics/musixmatchlyricsprovider.cpp +++ b/src/lyrics/musixmatchlyricsprovider.cpp @@ -35,8 +35,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "jsonlyricsprovider.h" diff --git a/src/lyrics/musixmatchlyricsprovider.h b/src/lyrics/musixmatchlyricsprovider.h index f3c03711ee..488e8cde4a 100644 --- a/src/lyrics/musixmatchlyricsprovider.h +++ b/src/lyrics/musixmatchlyricsprovider.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsonlyricsprovider.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" diff --git a/src/lyrics/ovhlyricsprovider.cpp b/src/lyrics/ovhlyricsprovider.cpp index baeac5c047..bbea1a5f44 100644 --- a/src/lyrics/ovhlyricsprovider.cpp +++ b/src/lyrics/ovhlyricsprovider.cpp @@ -28,8 +28,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/ovhlyricsprovider.h b/src/lyrics/ovhlyricsprovider.h index 6dea61cbcf..ab667fb1f5 100644 --- a/src/lyrics/ovhlyricsprovider.h +++ b/src/lyrics/ovhlyricsprovider.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsonlyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/lyrics/songlyricscomlyricsprovider.cpp b/src/lyrics/songlyricscomlyricsprovider.cpp index d76ba1929c..9b6bbd40fb 100644 --- a/src/lyrics/songlyricscomlyricsprovider.cpp +++ b/src/lyrics/songlyricscomlyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "lyricssearchrequest.h" #include "songlyricscomlyricsprovider.h" diff --git a/src/lyrics/songlyricscomlyricsprovider.h b/src/lyrics/songlyricscomlyricsprovider.h index 93aa3ce611..961a2d725a 100644 --- a/src/lyrics/songlyricscomlyricsprovider.h +++ b/src/lyrics/songlyricscomlyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" diff --git a/src/main.cpp b/src/main.cpp index f817c69174..709748d3e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,10 +65,10 @@ #include "main.h" -#include "core/logging.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "core/logging.h" #include "core/settings.h" #include "utilities/envutils.h" @@ -87,22 +87,27 @@ #ifdef HAVE_MPRIS2 # include "mpris2/mpris2.h" #endif -#include "core/metatypes.h" + #include "core/iconloader.h" -#include "core/mainwindow.h" #include "core/commandlineoptions.h" -#include "core/application.h" #include "core/networkproxyfactory.h" + +#include "core/application.h" +#include "core/metatypes.h" +#include "core/mainwindow.h" + #ifdef Q_OS_MACOS -# include "core/macsystemtrayicon.h" +# include "systemtrayicon/macsystemtrayicon.h" #else -# include "core/qtsystemtrayicon.h" +# include "systemtrayicon/qtsystemtrayicon.h" #endif + #ifdef HAVE_TRANSLATIONS # include "core/translations.h" #endif -#include "settings/behavioursettingspage.h" -#include "settings/appearancesettingspage.h" + +#include "constants/behavioursettings.h" +#include "constants/appearancesettings.h" #if defined(Q_OS_MACOS) # include "osd/osdmac.h" @@ -210,11 +215,11 @@ int main(int argc, char *argv[]) { { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - QString style = s.value(AppearanceSettingsPage::kStyle).toString(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + QString style = s.value(AppearanceSettings::kStyle).toString(); if (style.isEmpty()) { style = "default"_L1; - s.setValue(AppearanceSettingsPage::kStyle, style); + s.setValue(AppearanceSettings::kStyle, style); } s.endGroup(); if (style != "default"_L1) { @@ -252,8 +257,8 @@ int main(int argc, char *argv[]) { QString language = options.language(); if (language.isEmpty()) { Settings s; - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - language = s.value("language").toString(); + s.beginGroup(BehaviourSettings::kSettingsGroup); + language = s.value(BehaviourSettings::kLanguage).toString(); s.endGroup(); } @@ -307,7 +312,7 @@ int main(int argc, char *argv[]) { #endif #ifdef HAVE_MPRIS2 - mpris::Mpris2 mpris2(&app); + mpris::Mpris2 mpris2(app.player(), app.playlist_manager(), app.current_albumcover_loader()); #endif // Window diff --git a/src/moodbar/moodbarbuilder.cpp b/src/moodbar/moodbarbuilder.cpp index 5535172555..9dc5e7c68e 100644 --- a/src/moodbar/moodbarbuilder.cpp +++ b/src/moodbar/moodbarbuilder.cpp @@ -27,7 +27,7 @@ #include "moodbarbuilder.h" #include "core/logging.h" -#include "core/arraysize.h" +#include "includes/arraysize.h" namespace { diff --git a/src/moodbar/moodbarcontroller.cpp b/src/moodbar/moodbarcontroller.cpp index 403599f719..e38d910a39 100644 --- a/src/moodbar/moodbarcontroller.cpp +++ b/src/moodbar/moodbarcontroller.cpp @@ -23,26 +23,22 @@ #include #include -#include "core/application.h" -#include "core/player.h" #include "core/song.h" #include "core/settings.h" +#include "core/player.h" #include "engine/enginebase.h" -#include "settings/moodbarsettingspage.h" -#include "playlist/playlistmanager.h" +#include "constants/moodbarsettings.h" #include "moodbarcontroller.h" #include "moodbarloader.h" #include "moodbarpipeline.h" -MoodbarController::MoodbarController(Application *app, QObject *parent) +MoodbarController::MoodbarController(SharedPtr player, SharedPtr moodbar_loader, QObject *parent) : QObject(parent), - app_(app), + player_(player), + moodbar_loader_(moodbar_loader), enabled_(false) { - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &MoodbarController::CurrentSongChanged); - QObject::connect(&*app_->player(), &Player::Stopped, this, &MoodbarController::PlaybackStopped); - ReloadSettings(); } @@ -50,8 +46,8 @@ MoodbarController::MoodbarController(Application *app, QObject *parent) void MoodbarController::ReloadSettings() { Settings s; - s.beginGroup(MoodbarSettingsPage::kSettingsGroup); - enabled_ = s.value("enabled", false).toBool(); + s.beginGroup(MoodbarSettings::kSettingsGroup); + enabled_ = s.value(MoodbarSettings::kEnabled, false).toBool(); s.endGroup(); } @@ -62,7 +58,7 @@ void MoodbarController::CurrentSongChanged(const Song &song) { QByteArray data; MoodbarPipeline *pipeline = nullptr; - const MoodbarLoader::Result result = app_->moodbar_loader()->Load(song.url(), song.has_cue(), &data, &pipeline); + const MoodbarLoader::Result result = moodbar_loader_->Load(song.url(), song.has_cue(), &data, &pipeline); switch (result) { case MoodbarLoader::Result::CannotLoad: @@ -95,12 +91,12 @@ void MoodbarController::PlaybackStopped() { void MoodbarController::AsyncLoadComplete(MoodbarPipeline *pipeline, const QUrl &url) { // Is this song still playing? - PlaylistItemPtr current_item = app_->player()->GetCurrentItem(); + PlaylistItemPtr current_item = player_->GetCurrentItem(); if (current_item && current_item->Url() != url) { return; } // Did we stop the song? - switch (app_->player()->GetState()) { + switch (player_->GetState()) { case EngineBase::State::Error: case EngineBase::State::Empty: case EngineBase::State::Idle: diff --git a/src/moodbar/moodbarcontroller.h b/src/moodbar/moodbarcontroller.h index 7d5e6b8f7e..5be08fa23b 100644 --- a/src/moodbar/moodbarcontroller.h +++ b/src/moodbar/moodbarcontroller.h @@ -27,28 +27,35 @@ #include #include -class Application; +#include "includes/shared_ptr.h" + +class MoodbarLoader; class MoodbarPipeline; class Song; +class Player; class MoodbarController : public QObject { Q_OBJECT public: - explicit MoodbarController(Application *app, QObject *parent = nullptr); + explicit MoodbarController(SharedPtr player, SharedPtr moodbar_loader, QObject *parent = nullptr); void ReloadSettings(); Q_SIGNALS: void CurrentMoodbarDataChanged(const QByteArray &data); + void StyleChanged(); - private Q_SLOTS: + public Q_SLOTS: void CurrentSongChanged(const Song &song); void PlaybackStopped(); + + private Q_SLOTS: void AsyncLoadComplete(MoodbarPipeline *pipeline, const QUrl &url); private: - Application *app_; + SharedPtr player_; + SharedPtr moodbar_loader_; bool enabled_; }; diff --git a/src/moodbar/moodbaritemdelegate.cpp b/src/moodbar/moodbaritemdelegate.cpp index 16820907f2..e9ab0d5101 100644 --- a/src/moodbar/moodbaritemdelegate.cpp +++ b/src/moodbar/moodbaritemdelegate.cpp @@ -36,7 +36,6 @@ #include #include -#include "core/application.h" #include "core/settings.h" #include "playlist/playlist.h" #include "playlist/playlistview.h" @@ -47,18 +46,20 @@ #include "moodbarpipeline.h" #include "moodbarrenderer.h" -#include "settings/moodbarsettingspage.h" +#include "constants/moodbarsettings.h" MoodbarItemDelegate::Data::Data() : state_(State::None) {} -MoodbarItemDelegate::MoodbarItemDelegate(Application *app, PlaylistView *view, QObject *parent) +MoodbarItemDelegate::MoodbarItemDelegate(SharedPtr moodbar_loader, PlaylistView *playlist_view, QObject *parent) : QItemDelegate(parent), - app_(app), - view_(view), + moodbar_loader_(moodbar_loader), + playlist_view_(playlist_view), enabled_(false), - style_(MoodbarRenderer::MoodbarStyle::Normal) { + style_(MoodbarSettings::Style::Normal) { + + QObject::connect(&*moodbar_loader, &MoodbarLoader::SettingsReloaded, this, &MoodbarItemDelegate::ReloadSettings); + QObject::connect(&*moodbar_loader, &MoodbarLoader::StyleChanged, this, &MoodbarItemDelegate::ReloadSettings); - QObject::connect(app_, &Application::SettingsChanged, this, &MoodbarItemDelegate::ReloadSettings); ReloadSettings(); } @@ -66,9 +67,9 @@ MoodbarItemDelegate::MoodbarItemDelegate(Application *app, PlaylistView *view, Q void MoodbarItemDelegate::ReloadSettings() { Settings s; - s.beginGroup(MoodbarSettingsPage::kSettingsGroup); - enabled_ = s.value("enabled", false).toBool(); - const MoodbarRenderer::MoodbarStyle new_style = static_cast(s.value("style", static_cast(MoodbarRenderer::MoodbarStyle::Normal)).toInt()); + s.beginGroup(MoodbarSettings::kSettingsGroup); + enabled_ = s.value(MoodbarSettings::kEnabled, false).toBool(); + const MoodbarSettings::Style new_style = static_cast(s.value(MoodbarSettings::kStyle, static_cast(MoodbarSettings::Style::Normal)).toInt()); s.endGroup(); if (!enabled_) { @@ -151,7 +152,7 @@ void MoodbarItemDelegate::StartLoadingData(const QUrl &url, const bool has_cue, // Load a mood file for this song and generate some colors from it QByteArray bytes; MoodbarPipeline *pipeline = nullptr; - switch (app_->moodbar_loader()->Load(url, has_cue, &bytes, &pipeline)) { + switch (moodbar_loader_->Load(url, has_cue, &bytes, &pipeline)) { case MoodbarLoader::Result::CannotLoad: data->state_ = Data::State::CannotLoad; break; @@ -278,7 +279,7 @@ void MoodbarItemDelegate::ImageLoaded(const QUrl &url, const QImage &image) { data->pixmap_ = QPixmap::fromImage(image); data->state_ = Data::State::Loaded; - Playlist *playlist = view_->playlist(); + Playlist *playlist = playlist_view_->playlist(); const PlaylistFilter *filter = playlist->filter(); // Update all the indices with the new pixmap. diff --git a/src/moodbar/moodbaritemdelegate.h b/src/moodbar/moodbaritemdelegate.h index 16ec915ea7..cc1808cee7 100644 --- a/src/moodbar/moodbaritemdelegate.h +++ b/src/moodbar/moodbaritemdelegate.h @@ -36,10 +36,11 @@ #include #include +#include "includes/shared_ptr.h" +#include "constants/moodbarsettings.h" + class QPainter; -class QModelIndex; -class QPersistentModelIndex; -class Application; +class MoodbarLoader; class MoodbarPipeline; class PlaylistView; @@ -47,7 +48,7 @@ class MoodbarItemDelegate : public QItemDelegate { Q_OBJECT public: - explicit MoodbarItemDelegate(Application *app, PlaylistView *view, QObject *parent = nullptr); + explicit MoodbarItemDelegate(SharedPtr moodbar_loader, PlaylistView *view, QObject *parent = nullptr); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const override; @@ -58,6 +59,9 @@ class MoodbarItemDelegate : public QItemDelegate { void ColorsLoaded(const QUrl &url, const ColorVector &colors); void ImageLoaded(const QUrl &url, const QImage &image); + Q_SIGNALS: + void StyleChanged(); + private: struct Data { Data(); @@ -90,12 +94,12 @@ class MoodbarItemDelegate : public QItemDelegate { void ReloadAllColors(); private: - Application *app_; - PlaylistView *view_; + SharedPtr moodbar_loader_; + PlaylistView *playlist_view_; QCache data_; bool enabled_; - MoodbarRenderer::MoodbarStyle style_; + MoodbarSettings::Style style_; }; #endif // MOODBARITEMDELEGATE_H diff --git a/src/moodbar/moodbarloader.cpp b/src/moodbar/moodbarloader.cpp index e32dbf199a..cd05b7e133 100644 --- a/src/moodbar/moodbarloader.cpp +++ b/src/moodbar/moodbarloader.cpp @@ -41,14 +41,13 @@ #include #include +#include "includes/scoped_ptr.h" #include "core/logging.h" -#include "core/scoped_ptr.h" -#include "core/application.h" #include "core/settings.h" #include "moodbarpipeline.h" -#include "settings/moodbarsettingspage.h" +#include "constants/moodbarsettings.h" using namespace std::chrono_literals; using namespace Qt::Literals::StringLiterals; @@ -57,7 +56,7 @@ using namespace Qt::Literals::StringLiterals; # include #endif -MoodbarLoader::MoodbarLoader(Application *app, QObject *parent) +MoodbarLoader::MoodbarLoader(QObject *parent) : QObject(parent), cache_(new QNetworkDiskCache(this)), thread_(new QThread(this)), @@ -67,7 +66,6 @@ MoodbarLoader::MoodbarLoader(Application *app, QObject *parent) cache_->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u"/moodbar"_s); cache_->setMaximumCacheSize(60LL * 1024LL * 1024LL); // 60MB - enough for 20,000 moodbars - QObject::connect(app, &Application::SettingsChanged, this, &MoodbarLoader::ReloadSettings); ReloadSettings(); } @@ -80,12 +78,14 @@ MoodbarLoader::~MoodbarLoader() { void MoodbarLoader::ReloadSettings() { Settings s; - s.beginGroup(MoodbarSettingsPage::kSettingsGroup); - save_ = s.value("save", false).toBool(); + s.beginGroup(MoodbarSettings::kSettingsGroup); + save_ = s.value(MoodbarSettings::kSave, false).toBool(); s.endGroup(); MaybeTakeNextRequest(); + Q_EMIT SettingsReloaded(); + } QStringList MoodbarLoader::MoodFilenames(const QString &song_filename) { diff --git a/src/moodbar/moodbarloader.h b/src/moodbar/moodbarloader.h index 0ca01b47be..a07ff6b0da 100644 --- a/src/moodbar/moodbarloader.h +++ b/src/moodbar/moodbarloader.h @@ -33,14 +33,13 @@ class QThread; class QByteArray; class QNetworkDiskCache; -class Application; class MoodbarPipeline; class MoodbarLoader : public QObject { Q_OBJECT public: - explicit MoodbarLoader(Application *app, QObject *parent = nullptr); + explicit MoodbarLoader(QObject *parent = nullptr); ~MoodbarLoader() override; enum class Result { @@ -56,11 +55,11 @@ class MoodbarLoader : public QObject { WillLoadAsync }; + void ReloadSettings(); + Result Load(const QUrl &url, const bool has_cue, QByteArray *data, MoodbarPipeline **async_pipeline); private Q_SLOTS: - void ReloadSettings(); - void RequestFinished(MoodbarPipeline *request, const QUrl &url); void MaybeTakeNextRequest(); @@ -68,6 +67,11 @@ class MoodbarLoader : public QObject { static QStringList MoodFilenames(const QString &song_filename); static QUrl CacheUrlEntry(const QString &filename); + Q_SIGNALS: + void MoodbarEnabled(const bool enabled); + void StyleChanged(); + void SettingsReloaded(); + private: QNetworkDiskCache *cache_; QThread *thread_; diff --git a/src/moodbar/moodbarpipeline.cpp b/src/moodbar/moodbarpipeline.cpp index 79f8b94355..cfe80c5ea5 100644 --- a/src/moodbar/moodbarpipeline.cpp +++ b/src/moodbar/moodbarpipeline.cpp @@ -39,8 +39,7 @@ #include "core/signalchecker.h" #include "utilities/threadutils.h" #include "moodbar/moodbarbuilder.h" - -#include "gstfastspectrum.h" +#include "engine/gstfastspectrum.h" using namespace Qt::Literals::StringLiterals; using std::make_unique; diff --git a/src/moodbar/moodbarpipeline.h b/src/moodbar/moodbarpipeline.h index bac39cfc64..604bc5db25 100644 --- a/src/moodbar/moodbarpipeline.h +++ b/src/moodbar/moodbarpipeline.h @@ -31,7 +31,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class MoodbarBuilder; diff --git a/src/moodbar/moodbarproxystyle.cpp b/src/moodbar/moodbarproxystyle.cpp index 4524ee7053..716489db01 100644 --- a/src/moodbar/moodbarproxystyle.cpp +++ b/src/moodbar/moodbarproxystyle.cpp @@ -40,12 +40,11 @@ #include #include -#include "core/application.h" #include "core/settings.h" #include "moodbarproxystyle.h" #include "moodbarrenderer.h" -#include "settings/moodbarsettingspage.h" +#include "constants/moodbarsettings.h" namespace { constexpr int kMarginSize = 3; @@ -54,12 +53,11 @@ constexpr int kArrowWidth = 17; constexpr int kArrowHeight = 13; } // namespace -MoodbarProxyStyle::MoodbarProxyStyle(Application *app, QSlider *slider, QObject *parent) +MoodbarProxyStyle::MoodbarProxyStyle(QSlider *slider, QObject *parent) : QProxyStyle(nullptr), - app_(app), slider_(slider), - enabled_(true), - moodbar_style_(MoodbarRenderer::MoodbarStyle::Normal), + show_(true), + moodbar_style_(MoodbarSettings::Style::Normal), state_(State::MoodbarOff), fade_timeline_(new QTimeLine(1000, this)), moodbar_colors_dirty_(true), @@ -75,8 +73,6 @@ MoodbarProxyStyle::MoodbarProxyStyle(Application *app, QSlider *slider, QObject QObject::connect(fade_timeline_, &QTimeLine::valueChanged, this, &MoodbarProxyStyle::FaderValueChanged); - QObject::connect(app, &Application::SettingsChanged, this, &MoodbarProxyStyle::ReloadSettings); - ReloadSettings(); } @@ -84,14 +80,13 @@ MoodbarProxyStyle::MoodbarProxyStyle(Application *app, QSlider *slider, QObject void MoodbarProxyStyle::ReloadSettings() { Settings s; - s.beginGroup(MoodbarSettingsPage::kSettingsGroup); - // Get the enabled/disabled setting, and start the timelines if there's a change. - enabled_ = s.value("show", false).toBool(); + s.beginGroup(MoodbarSettings::kSettingsGroup); + show_ = s.value(MoodbarSettings::kEnabled, false).toBool() && s.value(MoodbarSettings::kShow, false).toBool(); NextState(); // Get the style, and redraw if there's a change. - const MoodbarRenderer::MoodbarStyle new_style = static_cast(s.value("style", static_cast(MoodbarRenderer::MoodbarStyle::Normal)).toInt()); + const MoodbarSettings::Style new_style = static_cast(s.value(MoodbarSettings::kStyle, static_cast(MoodbarSettings::Style::Normal)).toInt()); s.endGroup(); @@ -111,23 +106,25 @@ void MoodbarProxyStyle::SetMoodbarData(const QByteArray &data) { } -void MoodbarProxyStyle::SetMoodbarEnabled(const bool enabled) { +void MoodbarProxyStyle::SetShowMoodbar(const bool show) { - enabled_ = enabled; + if (show != show_) { - // Save the enabled setting. - Settings s; - s.beginGroup(MoodbarSettingsPage::kSettingsGroup); - s.setValue("show", enabled); - s.endGroup(); + show_ = show; - app_->ReloadSettings(); + Settings s; + s.beginGroup(MoodbarSettings::kSettingsGroup); + s.setValue(MoodbarSettings::kShow, show); + s.endGroup(); + + ReloadSettings(); + } } void MoodbarProxyStyle::NextState() { - const bool visible = enabled_ && !data_.isEmpty(); + const bool visible = show_ && !data_.isEmpty(); // While the regular slider should stay at the standard size (Fixed), // moodbars should use all available space (MinimumExpanding). @@ -135,7 +132,7 @@ void MoodbarProxyStyle::NextState() { slider_->updateGeometry(); if (show_moodbar_action_) { - show_moodbar_action_->setChecked(enabled_); + show_moodbar_action_->setChecked(show_); } if ((visible && (state_ == State::MoodbarOn || state_ == State::FadingToOn)) || (!visible && (state_ == State::MoodbarOff || state_ == State::FadingToOff))) { @@ -376,16 +373,16 @@ void MoodbarProxyStyle::ShowContextMenu(const QPoint pos) { if (!context_menu_) { context_menu_ = new QMenu(slider_); - show_moodbar_action_ = context_menu_->addAction(tr("Show moodbar"), this, &MoodbarProxyStyle::SetMoodbarEnabled); + show_moodbar_action_ = context_menu_->addAction(tr("Show moodbar"), this, &MoodbarProxyStyle::SetShowMoodbar); show_moodbar_action_->setCheckable(true); - show_moodbar_action_->setChecked(enabled_); + show_moodbar_action_->setChecked(show_); QMenu *styles_menu = context_menu_->addMenu(tr("Moodbar style")); style_action_group_ = new QActionGroup(styles_menu); - for (int i = 0; i < static_cast(MoodbarRenderer::MoodbarStyle::StyleCount); ++i) { - const MoodbarRenderer::MoodbarStyle style = static_cast(i); + for (int i = 0; i < static_cast(MoodbarSettings::Style::StyleCount); ++i) { + const MoodbarSettings::Style style = static_cast(i); QAction *action = style_action_group_->addAction(MoodbarRenderer::StyleName(style)); action->setCheckable(true); @@ -394,13 +391,13 @@ void MoodbarProxyStyle::ShowContextMenu(const QPoint pos) { styles_menu->addActions(style_action_group_->actions()); - QObject::connect(styles_menu, &QMenu::triggered, this, &MoodbarProxyStyle::ChangeStyle); + QObject::connect(styles_menu, &QMenu::triggered, this, &MoodbarProxyStyle::SetStyle); } // Update the currently selected style const QList actions = style_action_group_->actions(); for (QAction *action : actions) { - if (static_cast(action->data().toInt()) == moodbar_style_) { + if (static_cast(action->data().toInt()) == moodbar_style_) { action->setChecked(true); break; } @@ -410,13 +407,15 @@ void MoodbarProxyStyle::ShowContextMenu(const QPoint pos) { } -void MoodbarProxyStyle::ChangeStyle(QAction *action) { +void MoodbarProxyStyle::SetStyle(QAction *action) { Settings s; - s.beginGroup(MoodbarSettingsPage::kSettingsGroup); - s.setValue("style", action->data().toInt()); + s.beginGroup(MoodbarSettings::kSettingsGroup); + s.setValue(MoodbarSettings::kStyle, action->data().toInt()); s.endGroup(); - app_->ReloadSettings(); + ReloadSettings(); + + Q_EMIT StyleChanged(); } diff --git a/src/moodbar/moodbarproxystyle.h b/src/moodbar/moodbarproxystyle.h index 42011cb9c3..52547631d6 100644 --- a/src/moodbar/moodbarproxystyle.h +++ b/src/moodbar/moodbarproxystyle.h @@ -33,6 +33,7 @@ #include #include +#include "constants/moodbarsettings.h" #include "moodbarrenderer.h" class QAction; @@ -46,13 +47,13 @@ class QTimeLine; class QWidget; class QEvent; -class Application; - class MoodbarProxyStyle : public QProxyStyle { Q_OBJECT public: - explicit MoodbarProxyStyle(Application *app, QSlider *slider, QObject *parent = nullptr); + explicit MoodbarProxyStyle(QSlider *slider, QObject *parent = nullptr); + + void ReloadSettings(); // QProxyStyle void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const override; @@ -66,7 +67,11 @@ class MoodbarProxyStyle : public QProxyStyle { void SetMoodbarData(const QByteArray &data); // If the moodbar is disabled then a normal slider will always be shown. - void SetMoodbarEnabled(const bool enabled); + void SetShowMoodbar(const bool enabled); + + Q_SIGNALS: + void MoodbarShow(const bool enabled); + void StyleChanged(); private: enum class State { @@ -87,17 +92,18 @@ class MoodbarProxyStyle : public QProxyStyle { static QPixmap MoodbarPixmap(const ColorVector &colors, const QSize size, const QPalette &palette, const QStyleOptionSlider *opt); private Q_SLOTS: - void ReloadSettings(); void FaderValueChanged(qreal value); - void ChangeStyle(QAction *action); + void SetStyle(QAction *action); + + Q_SIGNALS: + void SettingsChanged(); private: - Application *app_; QSlider *slider_; - bool enabled_; + bool show_; QByteArray data_; - MoodbarRenderer::MoodbarStyle moodbar_style_; + MoodbarSettings::Style moodbar_style_; State state_; QTimeLine *fade_timeline_; diff --git a/src/moodbar/moodbarrenderer.cpp b/src/moodbar/moodbarrenderer.cpp index 77b36b89e7..c475164dd0 100644 --- a/src/moodbar/moodbarrenderer.cpp +++ b/src/moodbar/moodbarrenderer.cpp @@ -32,27 +32,28 @@ #include #include "moodbarrenderer.h" +#include "constants/moodbarsettings.h" -ColorVector MoodbarRenderer::Colors(const QByteArray &data, const MoodbarStyle style, const QPalette &palette) { +ColorVector MoodbarRenderer::Colors(const QByteArray &data, const MoodbarSettings::Style style, const QPalette &palette) { const int samples = static_cast(data.size() / 3); // Set some parameters based on the moodbar style StyleProperties properties; switch (style) { - case MoodbarStyle::Angry: + case MoodbarSettings::Style::Angry: properties = StyleProperties(samples / 360 * 9, 45, -45, 200, 100); break; - case MoodbarStyle::Frozen: + case MoodbarSettings::Style::Frozen: properties = StyleProperties(samples / 360 * 1, 140, 160, 50, 100); break; - case MoodbarStyle::Happy: + case MoodbarSettings::Style::Happy: properties = StyleProperties(samples / 360 * 2, 0, 359, 150, 250); break; - case MoodbarStyle::Normal: + case MoodbarSettings::Style::Normal: properties = StyleProperties(samples / 360 * 3, 0, 359, 100, 100); break; - case MoodbarStyle::SystemPalette: + case MoodbarSettings::Style::SystemPalette: default:{ const QColor highlight_color(palette.color(QPalette::Active, QPalette::Highlight)); @@ -162,18 +163,18 @@ QImage MoodbarRenderer::RenderToImage(const ColorVector &colors, const QSize siz } -QString MoodbarRenderer::StyleName(const MoodbarStyle style) { +QString MoodbarRenderer::StyleName(const MoodbarSettings::Style style) { switch (style) { - case MoodbarStyle::Normal: + case MoodbarSettings::Style::Normal: return QObject::tr("Normal"); - case MoodbarStyle::Angry: + case MoodbarSettings::Style::Angry: return QObject::tr("Angry"); - case MoodbarStyle::Frozen: + case MoodbarSettings::Style::Frozen: return QObject::tr("Frozen"); - case MoodbarStyle::Happy: + case MoodbarSettings::Style::Happy: return QObject::tr("Happy"); - case MoodbarStyle::SystemPalette: + case MoodbarSettings::Style::SystemPalette: return QObject::tr("System colors"); default: diff --git a/src/moodbar/moodbarrenderer.h b/src/moodbar/moodbarrenderer.h index 4f170e5b7f..6e838af1df 100644 --- a/src/moodbar/moodbarrenderer.h +++ b/src/moodbar/moodbarrenderer.h @@ -32,25 +32,17 @@ #include #include +#include "constants/moodbarsettings.h" + class QPainter; using ColorVector = QList; class MoodbarRenderer { public: - // These values are persisted. Remember to change moodbarsettingspage.ui when changing them. - enum class MoodbarStyle { - Normal = 0, - Angry, - Frozen, - Happy, - SystemPalette, - StyleCount - }; - - static QString StyleName(const MoodbarStyle style); + static QString StyleName(const MoodbarSettings::Style style); - static ColorVector Colors(const QByteArray &data, const MoodbarStyle style, const QPalette &palette); + static ColorVector Colors(const QByteArray &data, const MoodbarSettings::Style style, const QPalette &palette); static void Render(const ColorVector &colors, QPainter *p, const QRect rect); static QImage RenderToImage(const ColorVector &colors, const QSize size); diff --git a/src/mpris2/mpris2.cpp b/src/mpris2/mpris2.cpp index b97ec9a53d..d72b888a60 100644 --- a/src/mpris2/mpris2.cpp +++ b/src/mpris2/mpris2.cpp @@ -46,10 +46,9 @@ #include "mpris_common.h" #include "mpris2.h" +#include "constants/timeconstants.h" #include "core/song.h" -#include "core/application.h" #include "core/player.h" -#include "utilities/timeconstants.h" #include "engine/enginebase.h" #include "playlist/playlist.h" #include "playlist/playlistitem.h" @@ -100,9 +99,11 @@ constexpr char kMprisObjectPath[] = "/org/mpris/MediaPlayer2"; constexpr char kServiceName[] = "org.mpris.MediaPlayer2.strawberry"; constexpr char kFreedesktopPath[] = "org.freedesktop.DBus.Properties"; -Mpris2::Mpris2(Application *app, QObject *parent) +Mpris2::Mpris2(SharedPtr player, SharedPtr playlist_manager, SharedPtr current_albumcover_loader, QObject *parent) : QObject(parent), - app_(app), + player_(player), + playlist_manager_(playlist_manager), + current_albumcover_loader_(current_albumcover_loader), app_name_(QCoreApplication::applicationName()) { new Mpris2Root(this); @@ -120,16 +121,16 @@ Mpris2::Mpris2(Application *app, QObject *parent) return; } - QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &Mpris2::AlbumCoverLoaded); + QObject::connect(&*current_albumcover_loader_, &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &Mpris2::AlbumCoverLoaded); - QObject::connect(&*app_->player()->engine(), &EngineBase::StateChanged, this, &Mpris2::EngineStateChanged); - QObject::connect(&*app_->player(), &Player::VolumeChanged, this, &Mpris2::VolumeChanged); - QObject::connect(&*app_->player(), &Player::Seeked, this, &Mpris2::Seeked); + QObject::connect(&*player_->engine(), &EngineBase::StateChanged, this, &Mpris2::EngineStateChanged); + QObject::connect(&*player_, &Player::VolumeChanged, this, &Mpris2::VolumeChanged); + QObject::connect(&*player_, &Player::Seeked, this, &Mpris2::Seeked); - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::PlaylistManagerInitialized, this, &Mpris2::PlaylistManagerInitialized); - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &Mpris2::CurrentSongChanged); - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::PlaylistChanged, this, &Mpris2::PlaylistChangedSlot); - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentChanged, this, &Mpris2::PlaylistCollectionChanged); + QObject::connect(&*playlist_manager_, &PlaylistManager::PlaylistManagerInitialized, this, &Mpris2::PlaylistManagerInitialized); + QObject::connect(&*playlist_manager_, &PlaylistManager::CurrentSongChanged, this, &Mpris2::CurrentSongChanged); + QObject::connect(&*playlist_manager_, &PlaylistManager::PlaylistChanged, this, &Mpris2::PlaylistChangedSlot); + QObject::connect(&*playlist_manager_, &PlaylistManager::CurrentChanged, this, &Mpris2::PlaylistCollectionChanged); app_name_[0] = app_name_[0].toUpper(); @@ -159,8 +160,8 @@ Mpris2::Mpris2(Application *app, QObject *parent) // when PlaylistManager gets it ready, we connect PlaylistSequence with this void Mpris2::PlaylistManagerInitialized() { - QObject::connect(app_->playlist_manager()->sequence(), &PlaylistSequence::ShuffleModeChanged, this, &Mpris2::ShuffleModeChanged); - QObject::connect(app_->playlist_manager()->sequence(), &PlaylistSequence::RepeatModeChanged, this, &Mpris2::RepeatModeChanged); + QObject::connect(playlist_manager_->sequence(), &PlaylistSequence::ShuffleModeChanged, this, &Mpris2::ShuffleModeChanged); + QObject::connect(playlist_manager_->sequence(), &PlaylistSequence::RepeatModeChanged, this, &Mpris2::RepeatModeChanged); } void Mpris2::EngineStateChanged(EngineBase::State newState) { @@ -295,7 +296,7 @@ void Mpris2::Raise() { Q_EMIT RaiseMainWindow(); } void Mpris2::Quit() { QCoreApplication::quit(); } QString Mpris2::PlaybackStatus() const { - return PlaybackStatus(app_->player()->GetState()); + return PlaybackStatus(player_->GetState()); } QString Mpris2::PlaybackStatus(EngineBase::State state) const { @@ -310,11 +311,11 @@ QString Mpris2::PlaybackStatus(EngineBase::State state) const { QString Mpris2::LoopStatus() const { - if (!app_->playlist_manager()->sequence()) { + if (!playlist_manager_->sequence()) { return u"None"_s; } - switch (app_->playlist_manager()->active() ? app_->playlist_manager()->active()->RepeatMode() : app_->playlist_manager()->sequence()->repeat_mode()) { + switch (playlist_manager_->active() ? playlist_manager_->active()->RepeatMode() : playlist_manager_->sequence()->repeat_mode()) { case PlaylistSequence::RepeatMode::Album: case PlaylistSequence::RepeatMode::Playlist: return u"Playlist"_s; case PlaylistSequence::RepeatMode::Track: return u"Track"_s; @@ -337,7 +338,7 @@ void Mpris2::SetLoopStatus(const QString &value) { mode = PlaylistSequence::RepeatMode::Playlist; } - app_->playlist_manager()->active()->sequence()->SetRepeatMode(mode); + playlist_manager_->active()->sequence()->SetRepeatMode(mode); } @@ -346,26 +347,26 @@ double Mpris2::Rate() const { return 1.0; } void Mpris2::SetRate(double rate) { if (rate == 0) { - app_->player()->Pause(); + player_->Pause(); } } bool Mpris2::Shuffle() const { - const PlaylistSequence::ShuffleMode shuffle_mode = app_->playlist_manager()->active() ? app_->playlist_manager()->active()->ShuffleMode() : app_->playlist_manager()->sequence()->shuffle_mode(); + const PlaylistSequence::ShuffleMode shuffle_mode = playlist_manager_->active() ? playlist_manager_->active()->ShuffleMode() : playlist_manager_->sequence()->shuffle_mode(); return shuffle_mode != PlaylistSequence::ShuffleMode::Off; } void Mpris2::SetShuffle(bool enable) { - app_->playlist_manager()->active()->sequence()->SetShuffleMode(enable ? PlaylistSequence::ShuffleMode::All : PlaylistSequence::ShuffleMode::Off); + playlist_manager_->active()->sequence()->SetShuffleMode(enable ? PlaylistSequence::ShuffleMode::All : PlaylistSequence::ShuffleMode::Off); } QVariantMap Mpris2::Metadata() const { return last_metadata_; } double Mpris2::Rating() const { - float rating = app_->playlist_manager()->active()->current_item_metadata().rating(); + float rating = playlist_manager_->active()->current_item_metadata().rating(); return (rating <= 0) ? 0 : rating; } @@ -378,12 +379,12 @@ void Mpris2::SetRating(double rating) { rating = -1.0; } - app_->playlist_manager()->RateCurrentSong(static_cast(rating)); + playlist_manager_->RateCurrentSong(static_cast(rating)); } QDBusObjectPath Mpris2::current_track_id() const { - return QDBusObjectPath(QStringLiteral("/org/strawberrymusicplayer/strawberry/Track/%1").arg(QString::number(app_->playlist_manager()->active()->current_row()))); + return QDBusObjectPath(QStringLiteral("/org/strawberrymusicplayer/strawberry/Track/%1").arg(QString::number(playlist_manager_->active()->current_row()))); } // We send Metadata change notification as soon as the process of changing song starts... @@ -433,15 +434,15 @@ void Mpris2::AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResult &re } double Mpris2::Volume() const { - return app_->player()->GetVolume() / 100.0; + return player_->GetVolume() / 100.0; } void Mpris2::SetVolume(const double volume) { - app_->player()->SetVolume(static_cast(qBound(0L, lround(volume * 100.0), 100L))); + player_->SetVolume(static_cast(qBound(0L, lround(volume * 100.0), 100L))); } qint64 Mpris2::Position() const { - return app_->player()->engine()->position_nanosec() / kNsecPerUsec; + return player_->engine()->position_nanosec() / kNsecPerUsec; } double Mpris2::MaximumRate() const { return 1.0; } @@ -449,66 +450,66 @@ double Mpris2::MaximumRate() const { return 1.0; } double Mpris2::MinimumRate() const { return 1.0; } bool Mpris2::CanGoNext() const { - return app_->playlist_manager()->active() && app_->playlist_manager()->active()->next_row() != -1; + return playlist_manager_->active() && playlist_manager_->active()->next_row() != -1; } bool Mpris2::CanGoPrevious() const { - return app_->playlist_manager()->active() && (app_->playlist_manager()->active()->previous_row() != -1 || app_->player()->PreviousWouldRestartTrack()); + return playlist_manager_->active() && (playlist_manager_->active()->previous_row() != -1 || player_->PreviousWouldRestartTrack()); } bool Mpris2::CanPlay() const { - return app_->playlist_manager()->active() && app_->playlist_manager()->active()->rowCount() != 0; + return playlist_manager_->active() && playlist_manager_->active()->rowCount() != 0; } // This one's a bit different than MPRIS 1 - we want this to be true even when the song is already paused or stopped. bool Mpris2::CanPause() const { - return (app_->player()->GetCurrentItem() && app_->player()->GetState() == EngineBase::State::Playing && !(app_->player()->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused"_L1 || PlaybackStatus() == "Stopped"_L1; + return (player_->GetCurrentItem() && player_->GetState() == EngineBase::State::Playing && !(player_->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused"_L1 || PlaybackStatus() == "Stopped"_L1; } -bool Mpris2::CanSeek() const { return CanSeek(app_->player()->GetState()); } +bool Mpris2::CanSeek() const { return CanSeek(player_->GetState()); } bool Mpris2::CanSeek(EngineBase::State state) const { - return app_->player()->GetCurrentItem() && state != EngineBase::State::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream(); + return player_->GetCurrentItem() && state != EngineBase::State::Empty && !player_->GetCurrentItem()->Metadata().is_stream(); } bool Mpris2::CanControl() const { return true; } void Mpris2::Next() { if (CanGoNext()) { - app_->player()->Next(); + player_->Next(); } } void Mpris2::Previous() { if (CanGoPrevious()) { - app_->player()->Previous(); + player_->Previous(); } } void Mpris2::Pause() { - if (CanPause() && app_->player()->GetState() != EngineBase::State::Paused) { - app_->player()->Pause(); + if (CanPause() && player_->GetState() != EngineBase::State::Paused) { + player_->Pause(); } } void Mpris2::PlayPause() { if (CanPause()) { - app_->player()->PlayPause(); + player_->PlayPause(); } } -void Mpris2::Stop() { app_->player()->Stop(); } +void Mpris2::Stop() { player_->Stop(); } void Mpris2::Play() { if (CanPlay()) { - app_->player()->Play(); + player_->Play(); } } void Mpris2::Seek(qint64 offset) { if (CanSeek()) { - app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + offset / kUsecPerSec); + player_->SeekTo(player_->engine()->position_nanosec() / kNsecPerSec + offset / kUsecPerSec); } } @@ -518,15 +519,15 @@ void Mpris2::SetPosition(const QDBusObjectPath &trackId, qint64 offset) { if (CanSeek() && trackId == current_track_id() && offset >= 0) { offset *= kNsecPerUsec; - if (offset < app_->player()->GetCurrentItem()->Metadata().length_nanosec()) { - app_->player()->SeekTo(offset / kNsecPerSec); + if (offset < player_->GetCurrentItem()->Metadata().length_nanosec()) { + player_->SeekTo(offset / kNsecPerSec); } } } void Mpris2::OpenUri(const QString &uri) { - app_->playlist_manager()->active()->InsertUrls(QList() << QUrl(uri), -1, true); + playlist_manager_->active()->InsertUrls(QList() << QUrl(uri), -1, true); } Track_Ids Mpris2::Tracks() const { @@ -566,7 +567,7 @@ void Mpris2::GoTo(const QDBusObjectPath &trackId) { } quint32 Mpris2::PlaylistCount() const { - return app_->playlist_manager()->GetAllPlaylists().size(); + return playlist_manager_->GetAllPlaylists().size(); } QStringList Mpris2::Orderings() const { return QStringList() << u"User"_s; } @@ -582,14 +583,14 @@ QDBusObjectPath MakePlaylistPath(int id) { MaybePlaylist Mpris2::ActivePlaylist() const { MaybePlaylist maybe_playlist; - Playlist *current_playlist = app_->playlist_manager()->current(); + Playlist *current_playlist = playlist_manager_->current(); maybe_playlist.valid = current_playlist; if (!current_playlist) { return maybe_playlist; } maybe_playlist.playlist.id = MakePlaylistPath(current_playlist->id()); - maybe_playlist.playlist.name = app_->playlist_manager()->GetPlaylistName(current_playlist->id()); + maybe_playlist.playlist.name = playlist_manager_->GetPlaylistName(current_playlist->id()); return maybe_playlist; } @@ -606,12 +607,12 @@ void Mpris2::ActivatePlaylist(const QDBusObjectPath &playlist_id) { if (!ok) { return; } - if (!app_->playlist_manager()->IsPlaylistOpen(p)) { + if (!playlist_manager_->IsPlaylistOpen(p)) { qLog(Error) << "Playlist isn't opened!"; return; } - app_->playlist_manager()->SetActivePlaylist(p); - app_->player()->Next(); + playlist_manager_->SetActivePlaylist(p); + player_->Next(); } @@ -620,13 +621,13 @@ MprisPlaylistList Mpris2::GetPlaylists(quint32 index, quint32 max_count, const Q Q_UNUSED(order); - const QList playlists = app_->playlist_manager()->GetAllPlaylists(); + const QList playlists = playlist_manager_->GetAllPlaylists(); MprisPlaylistList ret; ret.reserve(playlists.count()); for (Playlist *p : playlists) { MprisPlaylist mpris_playlist; mpris_playlist.id = MakePlaylistPath(p->id()); - mpris_playlist.name = app_->playlist_manager()->GetPlaylistName(p->id()); + mpris_playlist.name = playlist_manager_->GetPlaylistName(p->id()); ret << mpris_playlist; } @@ -642,7 +643,7 @@ void Mpris2::PlaylistChangedSlot(Playlist *playlist) { MprisPlaylist mpris_playlist; mpris_playlist.id = MakePlaylistPath(playlist->id()); - mpris_playlist.name = app_->playlist_manager()->GetPlaylistName(playlist->id()); + mpris_playlist.name = playlist_manager_->GetPlaylistName(playlist->id()); Q_EMIT PlaylistChanged(mpris_playlist); diff --git a/src/mpris2/mpris2.h b/src/mpris2/mpris2.h index ddd2113202..167c7f159b 100644 --- a/src/mpris2/mpris2.h +++ b/src/mpris2/mpris2.h @@ -37,10 +37,13 @@ #include #include +#include "includes/shared_ptr.h" #include "engine/enginebase.h" #include "covermanager/albumcoverloaderresult.h" -class Application; +class Player; +class PlaylistManager; +class CurrentAlbumCoverLoader; class Song; class Playlist; @@ -75,7 +78,7 @@ class Mpris2 : public QObject { Q_OBJECT public: - explicit Mpris2(Application *app, QObject *parent = nullptr); + explicit Mpris2(SharedPtr player, SharedPtr playlist_manager, SharedPtr current_albumcover_loader, QObject *parent = nullptr); // org.mpris.MediaPlayer2 MPRIS 2.0 Root interface Q_PROPERTY(bool CanQuit READ CanQuit) @@ -231,7 +234,9 @@ class Mpris2 : public QObject { QString DesktopEntryAbsolutePath() const; private: - Application *app_; + SharedPtr player_; + SharedPtr playlist_manager_; + SharedPtr current_albumcover_loader_; QString app_name_; QString desktopfilepath_; diff --git a/src/musicbrainz/acoustidclient.cpp b/src/musicbrainz/acoustidclient.cpp index b25c025749..c332aab801 100644 --- a/src/musicbrainz/acoustidclient.cpp +++ b/src/musicbrainz/acoustidclient.cpp @@ -41,11 +41,11 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/networktimeouts.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "acoustidclient.h" diff --git a/src/musicbrainz/acoustidclient.h b/src/musicbrainz/acoustidclient.h index 48e4e1b8a5..babdd17e4f 100644 --- a/src/musicbrainz/acoustidclient.h +++ b/src/musicbrainz/acoustidclient.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class QNetworkReply; class NetworkAccessManager; diff --git a/src/musicbrainz/musicbrainzclient.cpp b/src/musicbrainz/musicbrainzclient.cpp index bf3e30161b..c9ebc3b1d1 100644 --- a/src/musicbrainz/musicbrainzclient.cpp +++ b/src/musicbrainz/musicbrainzclient.cpp @@ -43,8 +43,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/networktimeouts.h" #include "utilities/xmlutils.h" diff --git a/src/musicbrainz/musicbrainzclient.h b/src/musicbrainz/musicbrainzclient.h index 1bb5eab97a..9a73513d83 100644 --- a/src/musicbrainz/musicbrainzclient.h +++ b/src/musicbrainz/musicbrainzclient.h @@ -33,7 +33,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class QNetworkReply; class QTimer; diff --git a/src/musicbrainz/tagfetcher.cpp b/src/musicbrainz/tagfetcher.cpp index fab3bd421b..82273a36aa 100644 --- a/src/musicbrainz/tagfetcher.cpp +++ b/src/musicbrainz/tagfetcher.cpp @@ -30,9 +30,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "engine/chromaprinter.h" #include "acoustidclient.h" #include "musicbrainzclient.h" diff --git a/src/musicbrainz/tagfetcher.h b/src/musicbrainz/tagfetcher.h index cd17f17995..332e72cd1f 100644 --- a/src/musicbrainz/tagfetcher.h +++ b/src/musicbrainz/tagfetcher.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "musicbrainzclient.h" diff --git a/src/organize/organize.cpp b/src/organize/organize.cpp index d5ef60bda3..8fec493ebc 100644 --- a/src/organize/organize.cpp +++ b/src/organize/organize.cpp @@ -35,8 +35,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/taskmanager.h" #include "core/musicstorage.h" #include "core/song.h" @@ -54,10 +54,22 @@ constexpr int kBatchSize = 10; constexpr int kTranscodeProgressInterval = 500; } // namespace -Organize::Organize(SharedPtr task_manager, SharedPtr destination, const OrganizeFormat &format, const bool copy, const bool overwrite, const bool albumcover, const NewSongInfoList &songs_info, const bool eject_after, const QString &playlist, QObject *parent) +Organize::Organize(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr destination, + const OrganizeFormat &format, + const bool copy, + const bool overwrite, + const bool albumcover, + const NewSongInfoList &songs_info, + const bool eject_after, + const QString &playlist, + QObject *parent) + : QObject(parent), thread_(nullptr), task_manager_(task_manager), + tagreader_client_(tagreader_client), transcoder_(new Transcoder(this)), process_files_timer_(new QTimer(this)), destination_(destination), @@ -236,7 +248,7 @@ void Organize::ProcessSomeFiles() { } } else if (destination_->source() == Song::Source::Device) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(task.song_info_.song_.url().toLocalFile(), job.cover_image_); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(task.song_info_.song_.url().toLocalFile(), job.cover_image_); if (!result.success()) { qLog(Error) << "Could not load embedded art from" << task.song_info_.song_.url() << result.error_string(); } diff --git a/src/organize/organize.h b/src/organize/organize.h index 473f3d0d5c..2d546a7d89 100644 --- a/src/organize/organize.h +++ b/src/organize/organize.h @@ -35,7 +35,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "organizeformat.h" @@ -43,8 +43,9 @@ class QThread; class QTimer; class QTimerEvent; -class MusicStorage; class TaskManager; +class TagReaderClient; +class MusicStorage; class Transcoder; class Organize : public QObject { @@ -60,7 +61,18 @@ class Organize : public QObject { }; using NewSongInfoList = QList; - explicit Organize(SharedPtr task_manager, SharedPtr destination, const OrganizeFormat &format, const bool copy, const bool overwrite, const bool albumcover, const NewSongInfoList &songs, const bool eject_after, const QString &playlist = QString(), QObject *parent = nullptr); + explicit Organize(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr destination, + const OrganizeFormat &format, + const bool copy, + const bool overwrite, + const bool albumcover, + const NewSongInfoList &songs, + const bool eject_after, + const QString &playlist = QString(), + QObject *parent = nullptr); + ~Organize() override; void Start(); @@ -98,7 +110,8 @@ class Organize : public QObject { QThread *thread_; QThread *original_thread_; - SharedPtr task_manager_; + const SharedPtr task_manager_; + const SharedPtr tagreader_client_; Transcoder *transcoder_; QTimer *process_files_timer_; SharedPtr destination_; diff --git a/src/organize/organizedialog.cpp b/src/organize/organizedialog.cpp index b7ed03a598..6792febd2e 100644 --- a/src/organize/organizedialog.cpp +++ b/src/organize/organizedialog.cpp @@ -55,8 +55,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/iconloader.h" #include "core/musicstorage.h" #include "core/settings.h" @@ -82,11 +82,16 @@ constexpr char kSettingsGroup[] = "OrganizeDialog"; constexpr char kDefaultFormat[] = "%albumartist/%album{ (Disc %disc)}/{%track - }{%albumartist - }%album{ (Disc %disc)} - %title.%extension"; } -OrganizeDialog::OrganizeDialog(SharedPtr task_manager, SharedPtr collection_backend, QWidget *parentwindow, QWidget *parent) +OrganizeDialog::OrganizeDialog(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr collection_backend, + QWidget *parentwindow, + QWidget *parent) : QDialog(parent), parentwindow_(parentwindow), ui_(new Ui_OrganizeDialog), task_manager_(task_manager), + tagreader_client_(tagreader_client), collection_backend_(collection_backend), total_size_(0), devices_(false) { @@ -195,7 +200,7 @@ void OrganizeDialog::accept() { // It deletes itself when it's finished. const bool copy = ui_->aftercopying->currentIndex() == 0; - Organize *organize = new Organize(task_manager_, storage, format_, copy, ui_->overwrite->isChecked(), ui_->albumcover->isChecked(), new_songs_info_, ui_->eject_after->isChecked(), playlist_); + Organize *organize = new Organize(task_manager_, tagreader_client_, storage, format_, copy, ui_->overwrite->isChecked(), ui_->albumcover->isChecked(), new_songs_info_, ui_->eject_after->isChecked(), playlist_); QObject::connect(organize, &Organize::Finished, this, &OrganizeDialog::OrganizeFinished); QObject::connect(organize, &Organize::FileCopied, this, &OrganizeDialog::FileCopied); if (collection_backend_) { @@ -377,7 +382,7 @@ bool OrganizeDialog::SetUrls(const QList &urls) { bool OrganizeDialog::SetFilenames(const QStringList &filenames) { - songs_future_ = QtConcurrent::run(&OrganizeDialog::LoadSongsBlocking, filenames); + songs_future_ = QtConcurrent::run(&OrganizeDialog::LoadSongsBlocking, this, filenames); QFutureWatcher *watcher = new QFutureWatcher(); QObject::connect(watcher, &QFutureWatcher::finished, this, [this, watcher]() { SetSongs(watcher->result()); @@ -403,7 +408,7 @@ void OrganizeDialog::SetLoadingSongs(const bool loading) { } -SongList OrganizeDialog::LoadSongsBlocking(const QStringList &filenames) { +SongList OrganizeDialog::LoadSongsBlocking(const QStringList &filenames) const { SongList songs; Song song; @@ -422,7 +427,7 @@ SongList OrganizeDialog::LoadSongsBlocking(const QStringList &filenames) { continue; } - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(filename, &song); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(filename, &song); if (result.success() && song.is_valid()) { songs << song; } diff --git a/src/organize/organizedialog.h b/src/organize/organizedialog.h index 3f78a72b13..faaeb1aefd 100644 --- a/src/organize/organizedialog.h +++ b/src/organize/organizedialog.h @@ -35,8 +35,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "organize.h" #include "organizeformat.h" @@ -56,7 +56,12 @@ class OrganizeDialog : public QDialog { Q_OBJECT public: - explicit OrganizeDialog(SharedPtr task_manager, SharedPtr collection_backend = nullptr, QWidget *parentwindow = nullptr, QWidget *parent = nullptr); + explicit OrganizeDialog(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr collection_backend = nullptr, + QWidget *parentwindow = nullptr, + QWidget *parent = nullptr); + ~OrganizeDialog() override; void SetDestinationModel(QAbstractItemModel *model, const bool devices = false); @@ -83,7 +88,7 @@ class OrganizeDialog : public QDialog { void LoadSettings(); void AdjustSize(); - static SongList LoadSongsBlocking(const QStringList &filenames); + SongList LoadSongsBlocking(const QStringList &filenames) const; void SetLoadingSongs(const bool loading); Q_SIGNALS: @@ -107,8 +112,9 @@ class OrganizeDialog : public QDialog { private: QWidget *parentwindow_; Ui_OrganizeDialog *ui_; - SharedPtr task_manager_; - SharedPtr collection_backend_; + const SharedPtr task_manager_; + const SharedPtr tagreader_client_; + const SharedPtr collection_backend_; OrganizeFormat format_; diff --git a/src/organize/organizeformat.cpp b/src/organize/organizeformat.cpp index 154a282855..7d66ed935f 100644 --- a/src/organize/organizeformat.cpp +++ b/src/organize/organizeformat.cpp @@ -28,8 +28,8 @@ #include #include -#include "utilities/filenameconstants.h" -#include "utilities/timeconstants.h" +#include "constants/filenameconstants.h" +#include "constants/timeconstants.h" #include "utilities/transliterate.h" #include "core/song.h" diff --git a/src/osd/osdbase.cpp b/src/osd/osdbase.cpp index 263df8491b..e518c41305 100644 --- a/src/osd/osdbase.cpp +++ b/src/osd/osdbase.cpp @@ -31,30 +31,26 @@ #include "osdbase.h" #include "osdpretty.h" -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/settings.h" #ifdef Q_OS_MACOS -# include "core/macsystemtrayicon.h" +# include "systemtrayicon/macsystemtrayicon.h" #else -# include "core/qtsystemtrayicon.h" +# include "systemtrayicon/qtsystemtrayicon.h" #endif #include "utilities/strutils.h" -#include "covermanager/currentalbumcoverloader.h" +#include "constants/notificationssettings.h" using namespace Qt::Literals::StringLiterals; -const char *OSDBase::kSettingsGroup = "OSD"; - -OSDBase::OSDBase(SharedPtr tray_icon, Application *app, QObject *parent) +OSDBase::OSDBase(SharedPtr tray_icon, QObject *parent) : QObject(parent), - app_(app), tray_icon_(tray_icon), pretty_popup_(new OSDPretty(OSDPretty::Mode::Popup)), app_name_(QCoreApplication::applicationName()), timeout_msec_(5000), - behaviour_(Behaviour::Native), + type_(OSDSettings::Type::Native), show_on_volume_change_(false), show_art_(true), show_on_play_mode_change_(true), @@ -65,8 +61,6 @@ OSDBase::OSDBase(SharedPtr tray_icon, Application *app, QObject ignore_next_stopped_(false), playing_(false) { - QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::ThumbnailLoaded, this, &OSDBase::AlbumCoverLoaded); - app_name_[0] = app_name_[0].toUpper(); } @@ -78,9 +72,9 @@ OSDBase::~OSDBase() { void OSDBase::ReloadSettings() { Settings s; - s.beginGroup(kSettingsGroup); - behaviour_ = static_cast(s.value("Behaviour", static_cast(Behaviour::Native)).toInt()); - timeout_msec_ = s.value("Timeout", 5000).toInt(); + s.beginGroup(OSDSettings::kSettingsGroup); + type_ = static_cast(s.value(OSDSettings::kType, static_cast(OSDSettings::Type::Native)).toInt()); + timeout_msec_ = s.value(OSDSettings::kTimeout, 5000).toInt(); show_on_volume_change_ = s.value("ShowOnVolumeChange", false).toBool(); show_art_ = s.value("ShowArt", true).toBool(); show_on_play_mode_change_ = s.value("ShowOnPlayModeChange", true).toBool(); @@ -92,15 +86,15 @@ void OSDBase::ReloadSettings() { s.endGroup(); #ifdef Q_OS_WIN32 - if (!SupportsNativeNotifications() && !SupportsTrayPopups() && behaviour_ == Behaviour::Native) { + if (!SupportsNativeNotifications() && !SupportsTrayPopups() && type_ == OSDSettings::Type::Native) { #else - if (!SupportsNativeNotifications() && behaviour_ == Behaviour::Native) { + if (!SupportsNativeNotifications() && type_ == OSDSettings::Type::Native) { #endif - behaviour_ = Behaviour::Pretty; + type_ = OSDSettings::Type::Pretty; } - if (!SupportsTrayPopups() && behaviour_ == Behaviour::TrayPopup) { - behaviour_ = Behaviour::Disabled; + if (!SupportsTrayPopups() && type_ == OSDSettings::Type::TrayPopup) { + type_ = OSDSettings::Type::Disabled; } ReloadPrettyOSDSettings(); @@ -160,12 +154,12 @@ void OSDBase::ShowPlaying(const Song &song, const QUrl &cover_url, const QImage if (song.track() > 0) { message_parts << tr("track %1").arg(song.track()); } - if (behaviour_ == Behaviour::Pretty) { + if (type_ == OSDSettings::Type::Pretty) { summary = summary.toHtmlEscaped(); html_escaped = true; } #if defined(HAVE_DBUS) && !defined(Q_OS_MACOS) - else if (behaviour_ == Behaviour::Native) { + else if (type_ == OSDSettings::Type::Native) { html_escaped = true; } #endif @@ -206,7 +200,7 @@ void OSDBase::Paused() { summary.prepend(" - "_L1); summary.prepend(last_song_.artist()); } - if (behaviour_ == Behaviour::Pretty) { + if (type_ == OSDSettings::Type::Pretty) { summary = summary.toHtmlEscaped(); } } @@ -251,7 +245,7 @@ void OSDBase::Stopped() { summary.prepend(" - "_L1); summary.prepend(last_song_.artist()); } - if (behaviour_ == Behaviour::Pretty) { + if (type_ == OSDSettings::Type::Pretty) { summary = summary.toHtmlEscaped(); } } @@ -287,11 +281,11 @@ void OSDBase::VolumeChanged(const uint value) { if (!show_on_volume_change_) return; QString message = tr("Volume %1%").arg(value); - if (behaviour_ == Behaviour::Pretty) { + if (type_ == OSDSettings::Type::Pretty) { message = message.toHtmlEscaped(); } #if defined(HAVE_DBUS) && !defined(Q_OS_MACOS) - else if (behaviour_ == Behaviour::Native) { + else if (type_ == OSDSettings::Type::Native) { message = message.toHtmlEscaped(); } #endif @@ -306,8 +300,8 @@ void OSDBase::ShowMessage(const QString &summary, const QString &message, const pretty_popup_->ShowMessage(summary, message, image); } else { - switch (behaviour_) { - case Behaviour::Native: + switch (type_) { + case OSDSettings::Type::Native: #ifdef Q_OS_WIN32 Q_UNUSED(icon) [[fallthrough]]; @@ -320,18 +314,18 @@ void OSDBase::ShowMessage(const QString &summary, const QString &message, const } break; #endif - case Behaviour::TrayPopup: + case OSDSettings::Type::TrayPopup: #ifdef Q_OS_MACOS [[fallthrough]]; #else if (tray_icon_) tray_icon_->ShowPopup(summary, message, timeout_msec_); break; #endif - case Behaviour::Disabled: + case OSDSettings::Type::Disabled: if (!force_show_next_) break; force_show_next_ = false; [[fallthrough]]; - case Behaviour::Pretty: + case OSDSettings::Type::Pretty: pretty_popup_->ShowMessage(summary, message, image); break; @@ -384,8 +378,8 @@ QString OSDBase::ReplaceMessage(const MessageType type, const QString &message, QString newline = ""_L1; // We need different strings depending on notification type - switch (behaviour_) { - case Behaviour::Native: + switch (type_) { + case OSDSettings::Type::Native: #if defined(Q_OS_MACOS) html_escaped = false; newline = QLatin1String("\n"); @@ -411,13 +405,13 @@ QString OSDBase::ReplaceMessage(const MessageType type, const QString &message, qLog(Debug) << "Native notifications are not supported on this OS."; break; #endif - case Behaviour::TrayPopup: + case OSDSettings::Type::TrayPopup: qLog(Debug) << "New line not supported by this notification type."; html_escaped = false; newline = ""_L1; break; - case Behaviour::Disabled: // When notifications are disabled, we force the PrettyOSD - case Behaviour::Pretty: + case OSDSettings::Type::Disabled: // When notifications are disabled, we force the PrettyOSD + case OSDSettings::Type::Pretty: html_escaped = true; newline = "
"_L1; break; @@ -427,9 +421,9 @@ QString OSDBase::ReplaceMessage(const MessageType type, const QString &message, } -void OSDBase::ShowPreview(const Behaviour type, const QString &line1, const QString &line2, const Song &song) { +void OSDBase::ShowPreview(const OSDSettings::Type type, const QString &line1, const QString &line2, const Song &song) { - behaviour_ = type; + type_ = type; custom_text1_ = line1; custom_text2_ = line2; if (!use_custom_text_) use_custom_text_ = true; diff --git a/src/osd/osdbase.h b/src/osd/osdbase.h index 9d8c2f7bfa..42335fc3ee 100644 --- a/src/osd/osdbase.h +++ b/src/osd/osdbase.h @@ -31,11 +31,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "playlist/playlistsequence.h" +#include "constants/notificationssettings.h" -class Application; class OSDPretty; class SystemTrayIcon; @@ -43,18 +43,9 @@ class OSDBase : public QObject { Q_OBJECT public: - explicit OSDBase(SharedPtr tray_icon, Application *app, QObject *parent = nullptr); + explicit OSDBase(SharedPtr tray_icon, QObject *parent = nullptr); ~OSDBase() override; - static const char *kSettingsGroup; - - enum class Behaviour { - Disabled = 0, - Native, - TrayPopup, - Pretty - }; - int timeout_msec() const { return timeout_msec_; } void ReloadPrettyOSDSettings(); void SetPrettyOSDToggleMode(bool toggle); @@ -79,7 +70,9 @@ class OSDBase : public QObject { void ReshowCurrentSong(); - void ShowPreview(const OSDBase::Behaviour type, const QString &line1, const QString &line2, const Song &song); + void ShowPreview(const OSDSettings::Type type, const QString &line1, const QString &line2, const Song &song); + + void AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image); private: enum class MessageType { @@ -91,17 +84,13 @@ class OSDBase : public QObject { QString ReplaceMessage(const MessageType type, const QString &message, const Song &song); virtual void ShowMessageNative(const QString &summary, const QString &message, const QString &icon = QString(), const QImage &image = QImage()); - private Q_SLOTS: - void AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image); - private: - Application *app_; SharedPtr tray_icon_; OSDPretty *pretty_popup_; QString app_name_; int timeout_msec_; - Behaviour behaviour_; + OSDSettings::Type type_; bool show_on_volume_change_; bool show_art_; bool show_on_play_mode_change_; diff --git a/src/osd/osddbus.cpp b/src/osd/osddbus.cpp index 056cae4496..68718c2124 100644 --- a/src/osd/osddbus.cpp +++ b/src/osd/osddbus.cpp @@ -40,8 +40,8 @@ #include #include +#include "includes/scoped_ptr.h" #include "core/logging.h" -#include "core/scoped_ptr.h" #include "osddbus.h" #include "notification.h" @@ -105,8 +105,8 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QImage &image) { } -OSDDBus::OSDDBus(SharedPtr tray_icon, Application *app, QObject *parent) - : OSDBase(tray_icon, app, parent), +OSDDBus::OSDDBus(SharedPtr tray_icon, QObject *parent) + : OSDBase(tray_icon, parent), version_(1, 1), notification_id_(0) { diff --git a/src/osd/osddbus.h b/src/osd/osddbus.h index 138bd55202..cf8f22af38 100644 --- a/src/osd/osddbus.h +++ b/src/osd/osddbus.h @@ -33,20 +33,19 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" #include "osdbase.h" class OrgFreedesktopNotificationsInterface; class QDBusPendingCallWatcher; -class Application; class SystemTrayIcon; class OSDDBus : public OSDBase { Q_OBJECT public: - explicit OSDDBus(SharedPtr tray_icon, Application *app, QObject *parent = nullptr); + explicit OSDDBus(SharedPtr tray_icon, QObject *parent = nullptr); ~OSDDBus() override; static const char *kSettingsGroup; diff --git a/src/osd/osdmac.h b/src/osd/osdmac.h index a3b270d813..6c4ae61b29 100644 --- a/src/osd/osdmac.h +++ b/src/osd/osdmac.h @@ -37,7 +37,7 @@ class OSDMac : public OSDBase { Q_OBJECT public: - explicit OSDMac(SharedPtr tray_icon, Application *app, QObject *parent = nullptr); + explicit OSDMac(SharedPtr tray_icon, QObject *parent = nullptr); ~OSDMac() override; bool SupportsNativeNotifications() override; diff --git a/src/osd/osdmac.mm b/src/osd/osdmac.mm index 2e95bca2fa..df864c97bd 100644 --- a/src/osd/osdmac.mm +++ b/src/osd/osdmac.mm @@ -27,7 +27,7 @@ #include #include -#include "core/scoped_nsobject.h" +#include "includes/scoped_nsobject.h" #include "osdmac.h" @@ -53,7 +53,7 @@ void SendNotificationCenterMessage(NSString *title, NSString *subtitle) { } // namespace -OSDMac::OSDMac(SharedPtr tray_icon, Application *app, QObject *parent) : OSDBase(tray_icon, app, parent) {} +OSDMac::OSDMac(SharedPtr tray_icon, QObject *parent) : OSDBase(tray_icon, parent) {} OSDMac::~OSDMac() = default; diff --git a/src/osd/osdpretty.cpp b/src/osd/osdpretty.cpp index 020c6788d3..7fed1a1305 100644 --- a/src/osd/osdpretty.cpp +++ b/src/osd/osdpretty.cpp @@ -56,6 +56,7 @@ #endif #include "core/settings.h" +#include "constants/notificationssettings.h" #include "osdpretty.h" #include "ui_osdpretty.h" @@ -71,22 +72,20 @@ using namespace std::chrono_literals; using namespace Qt::Literals::StringLiterals; -const char *OSDPretty::kSettingsGroup = "OSDPretty"; +namespace { -const int OSDPretty::kDropShadowSize = 13; -const int OSDPretty::kBorderRadius = 10; -const int OSDPretty::kMaxIconSize = 100; +constexpr int kDropShadowSize = 13; +constexpr int kBorderRadius = 10; +constexpr int kMaxIconSize = 100; +constexpr int kSnapProximity = 20; -const int OSDPretty::kSnapProximity = 20; - -const QRgb OSDPretty::kPresetBlue = qRgb(102, 150, 227); -const QRgb OSDPretty::kPresetRed = qRgb(202, 22, 16); +} // namespace OSDPretty::OSDPretty(Mode mode, QWidget *parent) : QWidget(parent), ui_(new Ui_OSDPretty), mode_(mode), - background_color_(kPresetBlue), + background_color_(OSDPrettySettings::kPresetBlue), background_opacity_(0.85), popup_screen_(nullptr), disable_duration_(false), @@ -232,20 +231,20 @@ bool OSDPretty::IsTransparencyAvailable() { void OSDPretty::Load() { Settings s; - s.beginGroup(kSettingsGroup); - foreground_color_ = QColor(s.value("foreground_color", 0).toInt()); - background_color_ = QColor(s.value("background_color", kPresetBlue).toInt()); - background_opacity_ = s.value("background_opacity", 0.85).toFloat(); - font_.fromString(s.value("font", u"Verdana,9,-1,5,50,0,0,0,0,0"_s).toString()); - disable_duration_ = s.value("disable_duration", false).toBool(); + s.beginGroup(OSDPrettySettings::kSettingsGroup); + foreground_color_ = QColor(s.value(OSDPrettySettings::kForegroundColor, 0).toInt()); + background_color_ = QColor(s.value(OSDPrettySettings::kBackgroundColor, OSDPrettySettings::kPresetBlue).toInt()); + background_opacity_ = s.value(OSDPrettySettings::kBackgroundOpacity, 0.85).toFloat(); + font_.fromString(s.value(OSDPrettySettings::kFont, u"Verdana,9,-1,5,50,0,0,0,0,0"_s).toString()); + disable_duration_ = s.value(OSDPrettySettings::kDisableDuration, false).toBool(); #ifdef Q_OS_WIN - fading_enabled_ = s.value("fading", true).toBool(); + fading_enabled_ = s.value(OSDPrettySettings::kFading, true).toBool(); #else - fading_enabled_ = s.value("fading", false).toBool(); + fading_enabled_ = s.value(OSDPrettySettings::kFading, false).toBool(); #endif - if (s.contains("popup_screen"_L1)) { - popup_screen_name_ = s.value("popup_screen").toString(); + if (s.contains(OSDPrettySettings::kPopupScreen)) { + popup_screen_name_ = s.value(OSDPrettySettings::kPopupScreen).toString(); if (screens_.contains(popup_screen_name_)) { popup_screen_ = screens_.value(popup_screen_name_); } @@ -260,8 +259,8 @@ void OSDPretty::Load() { if (current_screen()) popup_screen_name_ = current_screen()->name(); } - if (s.contains("popup_pos"_L1)) { - popup_pos_ = s.value("popup_pos").toPoint(); + if (s.contains(OSDPrettySettings::kPopupPos)) { + popup_pos_ = s.value(OSDPrettySettings::kPopupPos).toPoint(); } else { if (popup_screen_) { diff --git a/src/osd/osdpretty.h b/src/osd/osdpretty.h index a7f661552c..2a87e42d5b 100644 --- a/src/osd/osdpretty.h +++ b/src/osd/osdpretty.h @@ -60,17 +60,6 @@ class OSDPretty : public QWidget { explicit OSDPretty(Mode mode, QWidget *parent = nullptr); ~OSDPretty() override; - static const char *kSettingsGroup; - - static const int kDropShadowSize; - static const int kBorderRadius; - static const int kMaxIconSize; - - static const int kSnapProximity; - - static const QRgb kPresetBlue; - static const QRgb kPresetRed; - bool IsTransparencyAvailable(); void SetMessage(const QString &summary, const QString &message, const QImage &image); diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 01b6b321b6..e09cbc8e8c 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -58,15 +58,16 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/mimedata.h" #include "core/song.h" #include "core/settings.h" -#include "utilities/timeconstants.h" +#include "core/songmimedata.h" +#include "constants/timeconstants.h" +#include "constants/playlistsettings.h" #include "tagreader/tagreaderclient.h" -#include "collection/collection.h" +#include "collection/collectionlibrary.h" #include "collection/collectionbackend.h" #include "collection/collectionplaylistitem.h" #include "covermanager/albumcoverloaderresult.h" @@ -78,10 +79,14 @@ #include "playlistbackend.h" #include "playlistfilter.h" #include "playlistitemmimedata.h" -#include "playlistundocommands.h" #include "songloaderinserter.h" -#include "songmimedata.h" #include "songplaylistitem.h" +#include "playlistundocommandinsertitems.h" +#include "playlistundocommandremoveitems.h" +#include "playlistundocommandmoveitems.h" +#include "playlistundocommandreorderitems.h" +#include "playlistundocommandsortitems.h" +#include "playlistundocommandshuffleitems.h" #include "smartplaylists/playlistgenerator.h" #include "smartplaylists/playlistgeneratorinserter.h" @@ -98,7 +103,6 @@ using std::make_shared; using namespace std::chrono_literals; using namespace Qt::Literals::StringLiterals; -const char *Playlist::kSettingsGroup = "Playlist"; const char *Playlist::kCddaMimeType = "x-content/audio-cdda"; const char *Playlist::kRowsMimetype = "application/x-strawberry-playlist-rows"; const char *Playlist::kPlayNowMimetype = "application/x-strawberry-play-now"; @@ -120,15 +124,25 @@ constexpr int kMaxPlayedIndexes = 100; } // namespace -Playlist::Playlist(SharedPtr backend, SharedPtr task_manager, SharedPtr collection_backend, const int id, const QString &special_type, const bool favorite, QObject *parent) +Playlist::Playlist(const SharedPtr task_manager, + const SharedPtr url_handlers, + const SharedPtr playlist_backend, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + const int id, + const QString &special_type, + const bool favorite, + QObject *parent) : QAbstractListModel(parent), is_loading_(false), filter_(new PlaylistFilter(this)), queue_(new Queue(this, this)), timer_save_(new QTimer(this)), - backend_(backend), task_manager_(task_manager), + url_handlers_(url_handlers), + playlist_backend_(playlist_backend), collection_backend_(collection_backend), + tagreader_client_(tagreader_client), id_(id), favorite_(favorite), current_is_paused_(false), @@ -418,7 +432,7 @@ bool Playlist::setData(const QModelIndex &idx, const QVariant &value, const int if (!set_column_value(song, static_cast(idx.column()), value)) return false; if (song.url().isLocalFile()) { - TagReaderReplyPtr reply = TagReaderClient::Instance()->WriteFileAsync(song.url().toLocalFile(), song); + TagReaderReplyPtr reply = tagreader_client_->WriteFileAsync(song.url().toLocalFile(), song); QPersistentModelIndex persistent_index = QPersistentModelIndex(idx); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, persistent_index, item]() { SongSaveComplete(reply, persistent_index, item->OriginalMetadata()); }, Qt::QueuedConnection); } @@ -813,7 +827,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const if (const SongMimeData *song_data = qobject_cast(data)) { // Dragged from a collection // We want to check if these songs are from the actual local file backend, if they are we treat them differently. - if (song_data->backend && song_data->backend->songs_table() == QLatin1String(SCollection::kSongsTable)) { + if (song_data->backend && song_data->backend->songs_table() == QLatin1String(CollectionLibrary::kSongsTable)) { InsertSongItems(song_data->songs, row, play_now, enqueue_now, enqueue_next_now); } else { @@ -856,7 +870,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const if (source_playlist == this) { // Dragged from this playlist - rearrange the items - undo_stack_->push(new PlaylistUndoCommands::MoveItems(this, source_rows, row)); + undo_stack_->push(new PlaylistUndoCommandMoveItems(this, source_rows, row)); } else if (pid == own_pid) { // Drag from a different playlist @@ -870,19 +884,19 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const undo_stack_->clear(); } else { - undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, row)); + undo_stack_->push(new PlaylistUndoCommandInsertItems(this, items, row)); } // Remove the items from the source playlist if it was a move event if (action == Qt::MoveAction) { for (const int i : std::as_const(source_rows)) { - source_playlist->undo_stack()->push(new PlaylistUndoCommands::RemoveItems(source_playlist, i, 1)); + source_playlist->undo_stack()->push(new PlaylistUndoCommandRemoveItems(source_playlist, i, 1)); } } } } else if (data->hasFormat(QLatin1String(kCddaMimeType))) { - SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_backend_, backend_->app()->player()); + SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, tagreader_client_, url_handlers_, collection_backend_); QObject::connect(inserter, &SongLoaderInserter::Error, this, &Playlist::Error); inserter->LoadAudioCD(this, row, play_now, enqueue_now, enqueue_next_now); } @@ -897,7 +911,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const void Playlist::InsertUrls(const QList &urls, const int pos, const bool play_now, const bool enqueue, const bool enqueue_next) { - SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_backend_, backend_->app()->player()); + SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, tagreader_client_, url_handlers_, collection_backend_); QObject::connect(inserter, &SongLoaderInserter::Error, this, &Playlist::Error); inserter->Load(this, pos, play_now, enqueue, enqueue_next, urls); @@ -1095,7 +1109,7 @@ void Playlist::InsertItems(const PlaylistItemPtrList &itemsIn, const int pos, co undo_stack_->clear(); } else { - undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue, enqueue_next)); + undo_stack_->push(new PlaylistUndoCommandInsertItems(this, items, pos, enqueue, enqueue_next)); } if (play_now) Q_EMIT PlayRequested(index(start, 0), AutoScroll::Maybe); @@ -1254,7 +1268,7 @@ void Playlist::UpdateItems(SongList songs) { // Also update undo actions for (int y = 0; y < undo_stack_->count(); y++) { QUndoCommand *undo_action = const_cast(undo_stack_->command(i)); - PlaylistUndoCommands::InsertItems *undo_action_insert = dynamic_cast(undo_action); + PlaylistUndoCommandInsertItems *undo_action_insert = dynamic_cast(undo_action); if (undo_action_insert) { bool found_and_updated = undo_action_insert->UpdateItem(new_item); if (found_and_updated) break; @@ -1464,7 +1478,7 @@ void Playlist::sort(const int column_number, const Qt::SortOrder order) { std::stable_sort(begin, new_items.end(), std::bind(&Playlist::CompareItems, column, order, std::placeholders::_1, std::placeholders::_2)); } - undo_stack_->push(new PlaylistUndoCommands::SortItems(this, column, order, new_items)); + undo_stack_->push(new PlaylistUndoCommandSortItems(this, column, order, new_items)); } @@ -1541,7 +1555,7 @@ void Playlist::ScheduleSaveAsync() { void Playlist::ScheduleSave() { - if (!backend_ || is_loading_) return; + if (!playlist_backend_ || is_loading_) return; timer_save_->start(); @@ -1549,22 +1563,22 @@ void Playlist::ScheduleSave() { void Playlist::Save() { - if (!backend_ || is_loading_) return; + if (!playlist_backend_ || is_loading_) return; - backend_->SavePlaylistAsync(id_, items_, last_played_row(), dynamic_playlist_); + playlist_backend_->SavePlaylistAsync(id_, items_, last_played_row(), dynamic_playlist_); } void Playlist::Restore() { - if (!backend_) return; + if (!playlist_backend_) return; items_.clear(); virtual_items_.clear(); collection_items_by_id_.clear(); cancel_restore_ = false; - QFuture future = QtConcurrent::run(&PlaylistBackend::GetPlaylistItems, backend_, id_); + QFuture future = QtConcurrent::run(&PlaylistBackend::GetPlaylistItems, playlist_backend_, id_); QFutureWatcher *watcher = new QFutureWatcher(); QObject::connect(watcher, &QFutureWatcher::finished, this, &Playlist::ItemsLoaded); watcher->setFuture(future); @@ -1593,7 +1607,7 @@ void Playlist::ItemsLoaded() { InsertItems(items, 0); is_loading_ = false; - PlaylistBackend::Playlist p = backend_->GetPlaylist(id_); + PlaylistBackend::Playlist p = playlist_backend_->GetPlaylist(id_); // The newly loaded list of items might be shorter than it was before so look out for a bad last_played index last_played_item_index_ = p.last_played == -1 || p.last_played >= rowCount() ? QModelIndex() : index(p.last_played); @@ -1617,8 +1631,8 @@ void Playlist::ItemsLoaded() { Q_EMIT RestoreFinished(); Settings s; - s.beginGroup(kSettingsGroup); - bool greyout = s.value("greyout_songs_startup", true).toBool(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + bool greyout = s.value(PlaylistSettings::kGreyoutSongsStartup, true).toBool(); s.endGroup(); // Should we gray out deleted songs asynchronously on startup? @@ -1667,7 +1681,7 @@ bool Playlist::removeRows(const int row, const int count, const QModelIndex &par undo_stack_->clear(); } else { - undo_stack_->push(new PlaylistUndoCommands::RemoveItems(this, row, count)); + undo_stack_->push(new PlaylistUndoCommandRemoveItems(this, row, count)); } return true; @@ -1839,7 +1853,7 @@ void Playlist::Clear() { undo_stack_->clear(); } else { - undo_stack_->push(new PlaylistUndoCommands::RemoveItems(this, 0, count)); + undo_stack_->push(new PlaylistUndoCommandRemoveItems(this, 0, count)); } TurnOffDynamicPlaylist(); @@ -1942,7 +1956,7 @@ void Playlist::Shuffle() { std::swap(new_items[i], new_items[new_pos]); } - undo_stack_->push(new PlaylistUndoCommands::ShuffleItems(this, new_items)); + undo_stack_->push(new PlaylistUndoCommandShuffleItems(this, new_items)); } diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index 17161fc2ea..f4ac6cc52e 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -41,7 +41,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "tagreader/tagreaderclient.h" #include "covermanager/albumcoverloaderresult.h" @@ -54,11 +54,12 @@ class QMimeData; class QUndoStack; class QTimer; +class TaskManager; +class UrlHandlers; class CollectionBackend; class PlaylistBackend; class PlaylistFilter; class Queue; -class TaskManager; class RadioService; namespace PlaylistUndoCommands { @@ -77,13 +78,22 @@ Q_DECLARE_METATYPE(ColumnAlignmentMap) class Playlist : public QAbstractListModel { Q_OBJECT - friend class PlaylistUndoCommands::InsertItems; - friend class PlaylistUndoCommands::RemoveItems; - friend class PlaylistUndoCommands::MoveItems; - friend class PlaylistUndoCommands::ReOrderItems; + friend class PlaylistUndoCommandInsertItems; + friend class PlaylistUndoCommandRemoveItems; + friend class PlaylistUndoCommandMoveItems; + friend class PlaylistUndoCommandReOrderItems; public: - explicit Playlist(SharedPtr playlist_backend, SharedPtr task_manager, SharedPtr collection_backend, const int id, const QString &special_type = QString(), const bool favorite = false, QObject *parent = nullptr); + explicit Playlist(const SharedPtr task_manager, + const SharedPtr url_handlers, + const SharedPtr playlist_backend, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + const int id, + const QString &special_type = QString(), + const bool favorite = false, + QObject *parent = nullptr); + ~Playlist() override; void SkipTracks(const QModelIndexList &source_indexes); @@ -141,7 +151,6 @@ class Playlist : public QAbstractListModel { Always }; - static const char *kSettingsGroup; static const char *kCddaMimeType; static const char *kRowsMimetype; static const char *kPlayNowMimetype; @@ -364,9 +373,12 @@ class Playlist : public QAbstractListModel { QList temp_dequeue_change_indexes_; - SharedPtr backend_; - SharedPtr task_manager_; - SharedPtr collection_backend_; + const SharedPtr task_manager_; + const SharedPtr url_handlers_; + const SharedPtr playlist_backend_; + const SharedPtr collection_backend_; + const SharedPtr tagreader_client_; + int id_; QString ui_path_; bool favorite_; diff --git a/src/playlist/playlistbackend.cpp b/src/playlist/playlistbackend.cpp index d46d8ac0b6..28525f9e96 100644 --- a/src/playlist/playlistbackend.cpp +++ b/src/playlist/playlistbackend.cpp @@ -38,8 +38,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/database.h" #include "core/logging.h" #include "core/scopedtransaction.h" @@ -60,10 +59,11 @@ namespace { constexpr int kSongTableJoins = 2; } -PlaylistBackend::PlaylistBackend(Application *app, QObject *parent) +PlaylistBackend::PlaylistBackend(SharedPtr database, SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) : QObject(parent), - app_(app), - db_(app_->database()), + database_(database), + tagreader_client_(tagreader_client), + collection_backend_(collection_backend), original_thread_(nullptr) { setObjectName(QLatin1String(metaObject()->className())); @@ -74,9 +74,9 @@ PlaylistBackend::PlaylistBackend(Application *app, QObject *parent) void PlaylistBackend::Close() { - if (db_) { - QMutexLocker l(db_->Mutex()); - db_->Close(); + if (database_) { + QMutexLocker l(database_->Mutex()); + database_->Close(); } } @@ -108,8 +108,8 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetAllFavoritePlaylists() { PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFlags flags) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); PlaylistList ret; @@ -128,7 +128,7 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFl SqlQuery q(db); q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend FROM playlists "_s + condition + u" ORDER BY ui_order"_s); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return ret; } @@ -152,15 +152,15 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFl PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(const int id) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); SqlQuery q(db); q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend FROM playlists WHERE ROWID=:id"_s); q.BindValue(u":id"_s, id); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return Playlist(); } @@ -187,8 +187,8 @@ PlaylistItemPtrList PlaylistBackend::GetPlaylistItems(const int playlist) { { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(QStringLiteral("songs")), Song::JoinSpec(QStringLiteral("p"))); @@ -198,7 +198,7 @@ PlaylistItemPtrList PlaylistBackend::GetPlaylistItems(const int playlist) { q.prepare(query); q.BindValue(u":playlist"_s, playlist); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return PlaylistItemPtrList(); } @@ -223,8 +223,8 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) { SongList songs; { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(u"songs"_s), Song::JoinSpec(u"p"_s)); @@ -234,7 +234,7 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) { q.prepare(query); q.BindValue(u":playlist"_s, playlist); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return SongList(); } @@ -282,7 +282,7 @@ PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, SharedPtr< // We need collection to run a CueParser; also, this method applies only to file-type PlaylistItems if (item->source() != Song::Source::LocalFile) return item; - CueParser cue_parser(app_->collection_backend()); + CueParser cue_parser(tagreader_client_, collection_backend_); Song song = item->Metadata(); // We're only interested in .cue songs here @@ -334,8 +334,8 @@ void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemPtrList void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &items, int last_played, PlaylistGeneratorPtr dynamic) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); qLog(Debug) << "Saving playlist" << playlist; @@ -347,7 +347,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item q.prepare(u"DELETE FROM playlist_items WHERE playlist = :playlist"_s); q.BindValue(u":playlist"_s, playlist); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } } @@ -360,7 +360,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item item->BindToQuery(&q); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } } @@ -382,7 +382,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item } q.BindValue(u":playlist"_s, playlist); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } } @@ -393,15 +393,15 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item int PlaylistBackend::CreatePlaylist(const QString &name, const QString &special_type) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); SqlQuery q(db); q.prepare(u"INSERT INTO playlists (name, special_type) VALUES (:name, :special_type)"_s); q.BindValue(u":name"_s, name); q.BindValue(u":special_type"_s, special_type); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return -1; } @@ -411,8 +411,8 @@ int PlaylistBackend::CreatePlaylist(const QString &name, const QString &special_ void PlaylistBackend::RemovePlaylist(int id) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); ScopedTransaction transaction(&db); @@ -421,7 +421,7 @@ void PlaylistBackend::RemovePlaylist(int id) { q.prepare(u"DELETE FROM playlists WHERE ROWID=:id"_s); q.BindValue(u":id"_s, id); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } } @@ -431,7 +431,7 @@ void PlaylistBackend::RemovePlaylist(int id) { q.prepare(u"DELETE FROM playlist_items WHERE playlist=:id"_s); q.BindValue(u":id"_s, id); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } } @@ -442,44 +442,44 @@ void PlaylistBackend::RemovePlaylist(int id) { void PlaylistBackend::RenamePlaylist(const int id, const QString &new_name) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); SqlQuery q(db); q.prepare(u"UPDATE playlists SET name=:name WHERE ROWID=:id"_s); q.BindValue(u":name"_s, new_name); q.BindValue(u":id"_s, id); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); } } void PlaylistBackend::FavoritePlaylist(const int id, const bool is_favorite) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); SqlQuery q(db); q.prepare(u"UPDATE playlists SET is_favorite=:is_favorite WHERE ROWID=:id"_s); q.BindValue(u":is_favorite"_s, is_favorite ? 1 : 0); q.BindValue(u":id"_s, id); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); } } void PlaylistBackend::SetPlaylistOrder(const QList &ids) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); ScopedTransaction transaction(&db); SqlQuery q(db); q.prepare(u"UPDATE playlists SET ui_order=-1"_s); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } @@ -488,7 +488,7 @@ void PlaylistBackend::SetPlaylistOrder(const QList &ids) { q.BindValue(u":index"_s, i); q.BindValue(u":id"_s, ids[i]); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } } @@ -499,8 +499,8 @@ void PlaylistBackend::SetPlaylistOrder(const QList &ids) { void PlaylistBackend::SetPlaylistUiPath(const int id, const QString &path) { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); + QMutexLocker l(database_->Mutex()); + QSqlDatabase db(database_->Connect()); SqlQuery q(db); q.prepare(u"UPDATE playlists SET ui_path=:path WHERE ROWID=:id"_s); @@ -509,7 +509,7 @@ void PlaylistBackend::SetPlaylistUiPath(const int id, const QString &path) { q.BindValue(u":path"_s, path); q.BindValue(u":id"_s, id); if (!q.Exec()) { - db_->ReportErrors(q); + database_->ReportErrors(q); return; } diff --git a/src/playlist/playlistbackend.h b/src/playlist/playlistbackend.h index b9a3564031..f113baafdf 100644 --- a/src/playlist/playlistbackend.h +++ b/src/playlist/playlistbackend.h @@ -30,24 +30,25 @@ #include #include #include -#include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" -#include "core/sqlquery.h" #include "core/sqlrow.h" #include "playlistitem.h" #include "smartplaylists/playlistgenerator.h" class QThread; -class Application; class Database; +class TagReaderClient; class PlaylistBackend : public QObject { Q_OBJECT public: - Q_INVOKABLE explicit PlaylistBackend(Application *app, QObject *parent = nullptr); + Q_INVOKABLE explicit PlaylistBackend(SharedPtr database, + SharedPtr tagreader_client, + SharedPtr collection_backend, + QObject *parent = nullptr); struct Playlist { Playlist() : id(-1), favorite(false), last_played(0) {} @@ -84,8 +85,6 @@ class PlaylistBackend : public QObject { void FavoritePlaylist(const int id, bool is_favorite); void RemovePlaylist(const int id); - Application *app() const { return app_; } - public Q_SLOTS: void Exit(); void SavePlaylist(const int playlist, const PlaylistItemPtrList &items, const int last_played, PlaylistGeneratorPtr dynamic); @@ -110,8 +109,9 @@ class PlaylistBackend : public QObject { }; PlaylistList GetPlaylists(const GetPlaylistsFlags flags); - Application *app_; - SharedPtr db_; + SharedPtr database_; + SharedPtr tagreader_client_; + SharedPtr collection_backend_; QThread *original_thread_; }; diff --git a/src/playlist/playlistcontainer.cpp b/src/playlist/playlistcontainer.cpp index 86ff9c8f8b..0ca9139f8f 100644 --- a/src/playlist/playlistcontainer.cpp +++ b/src/playlist/playlistcontainer.cpp @@ -46,7 +46,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/iconloader.h" #include "core/settings.h" #include "filterparser/filterparser.h" @@ -59,7 +59,7 @@ #include "playlistparsers/playlistparser.h" #include "ui_playlistcontainer.h" #include "widgets/searchfield.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" using namespace Qt::Literals::StringLiterals; @@ -245,8 +245,8 @@ void PlaylistContainer::SetViewModel(Playlist *playlist, const int scroll_positi void PlaylistContainer::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizePlaylistButtons, 20).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizePlaylistButtons, 20).toInt(); s.endGroup(); ui_->create_new->setIconSize(QSize(iconsize, iconsize)); diff --git a/src/playlist/playlistcontainer.h b/src/playlist/playlistcontainer.h index b875ea095a..9842a0670f 100644 --- a/src/playlist/playlistcontainer.h +++ b/src/playlist/playlistcontainer.h @@ -44,7 +44,7 @@ class PlaylistView; class Ui_PlaylistContainer; -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/settings.h" class PlaylistContainer : public QWidget { diff --git a/src/playlist/playlistfilter.cpp b/src/playlist/playlistfilter.cpp index 7bbba9f7a1..0b579aa0d7 100644 --- a/src/playlist/playlistfilter.cpp +++ b/src/playlist/playlistfilter.cpp @@ -27,12 +27,12 @@ #include "playlist/playlist.h" #include "playlist/playlistitem.h" #include "filterparser/filterparser.h" -#include "filterparser/filtertree.h" +#include "filterparser/filtertreenop.h" #include "playlistfilter.h" PlaylistFilter::PlaylistFilter(QObject *parent) : QSortFilterProxyModel(parent), - filter_tree_(new NopFilter), + filter_tree_(new FilterTreeNop), query_hash_(0) { setDynamicSortFilter(true); diff --git a/src/playlist/playlistheader.cpp b/src/playlist/playlistheader.cpp index 82dac43e03..ca0a79c7f4 100644 --- a/src/playlist/playlistheader.cpp +++ b/src/playlist/playlistheader.cpp @@ -39,7 +39,7 @@ #include "core/settings.h" #include "widgets/stretchheaderview.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" PlaylistHeader::PlaylistHeader(Qt::Orientation orientation, PlaylistView *view, QWidget *parent) : StretchHeaderView(orientation, parent), @@ -83,8 +83,8 @@ PlaylistHeader::PlaylistHeader(Qt::Orientation orientation, PlaylistView *view, QObject::connect(this, &PlaylistHeader::StretchEnabledChanged, action_stretch_, &QAction::setChecked); Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - action_rating_lock_->setChecked(s.value("rating_locked", false).toBool()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + action_rating_lock_->setChecked(s.value(PlaylistSettings::kRatingLocked, false).toBool()); s.endGroup(); } diff --git a/src/playlist/playlistitem.h b/src/playlist/playlistitem.h index 7bf3ba0948..677cd577f7 100644 --- a/src/playlist/playlistitem.h +++ b/src/playlist/playlistitem.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QAction; diff --git a/src/playlist/playlistlistcontainer.cpp b/src/playlist/playlistlistcontainer.cpp index 05a20d7277..33b8690d7b 100644 --- a/src/playlist/playlistlistcontainer.cpp +++ b/src/playlist/playlistlistcontainer.cpp @@ -46,10 +46,9 @@ #include #include -#include "core/application.h" #include "core/iconloader.h" -#include "core/player.h" #include "core/settings.h" +#include "core/player.h" #include "playlist.h" #include "playlistbackend.h" #include "playlistlistview.h" @@ -59,7 +58,7 @@ #include "playlistmanager.h" #include "ui_playlistlistcontainer.h" #include "organize/organizedialog.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" #ifndef Q_OS_WIN # include "device/devicemanager.h" # include "device/devicestatefiltermodel.h" @@ -70,7 +69,6 @@ using namespace Qt::Literals::StringLiterals; PlaylistListContainer::PlaylistListContainer(QWidget *parent) : QWidget(parent), - app_(nullptr), ui_(new Ui_PlaylistListContainer), menu_(nullptr), action_new_folder_(new QAction(this)), @@ -123,26 +121,28 @@ PlaylistListContainer::PlaylistListContainer(QWidget *parent) PlaylistListContainer::~PlaylistListContainer() { delete ui_; } -void PlaylistListContainer::SetApplication(Application *app) { +void PlaylistListContainer::Init(SharedPtr task_manager, SharedPtr tagreader_client, SharedPtr player, SharedPtr playlist_manager, SharedPtr playlist_backend, SharedPtr device_manager) { - app_ = app; - PlaylistManager *manager = &*app_->playlist_manager(); - Player *player = &*app_->player(); + task_manager_ = task_manager; + tagreader_client_ = tagreader_client; + playlist_manager_ = playlist_manager; + playlist_backend_ = playlist_backend; + device_manager_ = device_manager; - QObject::connect(manager, &PlaylistManager::PlaylistAdded, this, &PlaylistListContainer::AddPlaylist); - QObject::connect(manager, &PlaylistManager::PlaylistFavorited, this, &PlaylistListContainer::PlaylistFavoriteStateChanged); - QObject::connect(manager, &PlaylistManager::PlaylistRenamed, this, &PlaylistListContainer::PlaylistRenamed); - QObject::connect(manager, &PlaylistManager::CurrentChanged, this, &PlaylistListContainer::CurrentChanged); - QObject::connect(manager, &PlaylistManager::ActiveChanged, this, &PlaylistListContainer::ActiveChanged); + QObject::connect(&*playlist_manager, &PlaylistManager::PlaylistAdded, this, &PlaylistListContainer::AddPlaylist); + QObject::connect(&*playlist_manager, &PlaylistManager::PlaylistFavorited, this, &PlaylistListContainer::PlaylistFavoriteStateChanged); + QObject::connect(&*playlist_manager, &PlaylistManager::PlaylistRenamed, this, &PlaylistListContainer::PlaylistRenamed); + QObject::connect(&*playlist_manager, &PlaylistManager::CurrentChanged, this, &PlaylistListContainer::CurrentChanged); + QObject::connect(&*playlist_manager, &PlaylistManager::ActiveChanged, this, &PlaylistListContainer::ActiveChanged); - QObject::connect(model_, &PlaylistListModel::PlaylistRenamed, manager, &PlaylistManager::Rename); + QObject::connect(model_, &PlaylistListModel::PlaylistRenamed, &*playlist_manager, &PlaylistManager::Rename); - QObject::connect(player, &Player::Paused, this, &PlaylistListContainer::ActivePaused); - QObject::connect(player, &Player::Playing, this, &PlaylistListContainer::ActivePlaying); - QObject::connect(player, &Player::Stopped, this, &PlaylistListContainer::ActiveStopped); + QObject::connect(&*player, &Player::Paused, this, &PlaylistListContainer::ActivePaused); + QObject::connect(&*player, &Player::Playing, this, &PlaylistListContainer::ActivePlaying); + QObject::connect(&*player, &Player::Stopped, this, &PlaylistListContainer::ActiveStopped); // Get all playlists, even ones that are hidden in the UI. - const QList playlists = app->playlist_backend()->GetAllFavoritePlaylists(); + const QList playlists = playlist_backend->GetAllFavoritePlaylists(); for (const PlaylistBackend::Playlist &p : playlists) { QStandardItem *playlist_item = model_->NewPlaylist(p.name, p.id); QStandardItem *parent_folder = model_->FolderByPath(p.ui_path); @@ -154,8 +154,8 @@ void PlaylistListContainer::SetApplication(Application *app) { void PlaylistListContainer::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeLeftPanelButtons, 22).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeLeftPanelButtons, 22).toInt(); s.endGroup(); ui_->new_folder->setIconSize(QSize(iconsize, iconsize)); @@ -236,7 +236,7 @@ void PlaylistListContainer::AddPlaylist(const int id, const QString &name, const return; } - const QString &ui_path = app_->playlist_manager()->playlist(id)->ui_path(); + const QString &ui_path = playlist_manager_->playlist(id)->ui_path(); QStandardItem *playlist_item = model_->NewPlaylist(name, id); QStandardItem *parent_folder = model_->FolderByPath(ui_path); @@ -280,7 +280,7 @@ void PlaylistListContainer::SavePlaylist() { const int playlist_id = idx.data(PlaylistListModel::Role_PlaylistId).toInt(); QStandardItem *item = model_->PlaylistById(playlist_id); QString playlist_name = item ? item->text() : tr("Playlist"); - app_->playlist_manager()->SaveWithUI(playlist_id, playlist_name); + playlist_manager_->SaveWithUI(playlist_id, playlist_name); } } @@ -288,7 +288,7 @@ void PlaylistListContainer::SavePlaylist() { void PlaylistListContainer::PlaylistFavoriteStateChanged(const int id, const bool favorite) { if (favorite) { - const QString &name = app_->playlist_manager()->GetPlaylistName(id); + const QString &name = playlist_manager_->GetPlaylistName(id); AddPlaylist(id, name, favorite); } else { @@ -330,8 +330,8 @@ void PlaylistListContainer::CurrentChanged(Playlist *new_playlist) { void PlaylistListContainer::PlaylistPathChanged(const int id, const QString &new_path) { // Update the path in the database - app_->playlist_backend()->SetPlaylistUiPath(id, new_path); - Playlist *playlist = app_->playlist_manager()->playlist(id); + playlist_backend_->SetPlaylistUiPath(id, new_path); + Playlist *playlist = playlist_manager_->playlist(id); // Check the playlist exists (if it's not opened it's not in the manager) if (playlist) { playlist->set_ui_path(new_path); @@ -351,7 +351,7 @@ void PlaylistListContainer::ItemDoubleClicked(const QModelIndex &proxy_idx) { // Is it a playlist? if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist) { - app_->playlist_manager()->SetCurrentOrOpen(idx.data(PlaylistListModel::Role_PlaylistId).toInt()); + playlist_manager_->SetCurrentOrOpen(idx.data(PlaylistListModel::Role_PlaylistId).toInt()); } } @@ -363,8 +363,8 @@ void PlaylistListContainer::ItemMimeDataDropped(const QModelIndex &proxy_idx, co // Drop playlist rows if type is playlist and it's not active, to prevent selfcopy int playlis_id = idx.data(PlaylistListModel::Role_PlaylistId).toInt(); - if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist && playlis_id != app_->playlist_manager()->active_id()) { - app_->playlist_manager()->playlist(playlis_id)->dropMimeData(q_mimedata, Qt::CopyAction, -1, 0, QModelIndex()); + if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist && playlis_id != playlist_manager_->active_id()) { + playlist_manager_->playlist(playlis_id)->dropMimeData(q_mimedata, Qt::CopyAction, -1, 0, QModelIndex()); } } @@ -382,7 +382,7 @@ void PlaylistListContainer::CopyToDevice() { if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist) { const int playlist_id = idx.data(PlaylistListModel::Role_PlaylistId).toInt(); - Playlist *playlist = app_->playlist_manager()->playlist(playlist_id); + Playlist *playlist = playlist_manager_->playlist(playlist_id); if (!playlist) { QMessageBox::critical(this, tr("Copy to device"), tr("Playlist must be open first.")); return; @@ -393,9 +393,9 @@ void PlaylistListContainer::CopyToDevice() { // Reuse the organize dialog, but set the detail about the playlist name if (!organize_dialog_) { - organize_dialog_ = make_unique(app_->task_manager(), nullptr, this); + organize_dialog_ = make_unique(task_manager_, tagreader_client_, 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_->SetPlaylist(playlist_name); organize_dialog_->SetSongs(playlist->GetAllSongs()); @@ -444,7 +444,7 @@ void PlaylistListContainer::Delete() { // Unfavorite the playlists for (const int id : std::as_const(ids)) { - app_->playlist_manager()->Favorite(id, false); + playlist_manager_->Favorite(id, false); } // Delete the top-level folders. diff --git a/src/playlist/playlistlistcontainer.h b/src/playlist/playlistlistcontainer.h index cc79e5d2a2..21bf602563 100644 --- a/src/playlist/playlistlistcontainer.h +++ b/src/playlist/playlistlistcontainer.h @@ -30,7 +30,8 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QStandardItem; class QSortFilterProxyModel; @@ -39,7 +40,12 @@ class QAction; class QContextMenuEvent; class QShowEvent; -class Application; +class TaskManager; +class TagReaderClient; +class Player; +class DeviceManager; +class PlaylistManager; +class PlaylistBackend; class Playlist; class PlaylistListModel; class Ui_PlaylistListContainer; @@ -52,7 +58,13 @@ class PlaylistListContainer : public QWidget { explicit PlaylistListContainer(QWidget *parent = nullptr); ~PlaylistListContainer() override; - void SetApplication(Application *app); + void Init(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr player, + SharedPtr playlist_manager, + SharedPtr playlist_backend, + SharedPtr device_manager); + void ReloadSettings(); protected: @@ -97,7 +109,12 @@ class PlaylistListContainer : public QWidget { void UpdateActiveIcon(int id, const QIcon &icon); - Application *app_; + SharedPtr task_manager_; + SharedPtr tagreader_client_; + SharedPtr playlist_manager_; + SharedPtr playlist_backend_; + SharedPtr device_manager_; + Ui_PlaylistListContainer *ui_; QMenu *menu_; diff --git a/src/playlist/playlistmanager.cpp b/src/playlist/playlistmanager.cpp index 4f03fd38fb..184a617cfe 100644 --- a/src/playlist/playlistmanager.cpp +++ b/src/playlist/playlistmanager.cpp @@ -42,15 +42,13 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" -#include "core/player.h" +#include "includes/shared_ptr.h" #include "core/settings.h" -#include "utilities/filenameconstants.h" +#include "constants/filenameconstants.h" #include "utilities/timeutils.h" #include "collection/collectionbackend.h" #include "covermanager/currentalbumcoverloader.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "playlist.h" #include "playlistbackend.h" #include "playlistcontainer.h" @@ -65,11 +63,20 @@ using namespace Qt::Literals::StringLiterals; class ParserBase; -PlaylistManager::PlaylistManager(Application *app, QObject *parent) - : PlaylistManagerInterface(app, parent), - app_(app), - playlist_backend_(nullptr), - collection_backend_(nullptr), +PlaylistManager::PlaylistManager(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr url_handlers, + SharedPtr playlist_backend, + SharedPtr collection_backend, + SharedPtr current_albumcover_loader, + QObject *parent) + : PlaylistManagerInterface(parent), + task_manager_(task_manager), + tagreader_client_(tagreader_client), + url_handlers_(url_handlers), + playlist_backend_(playlist_backend), + collection_backend_(collection_backend), + current_albumcover_loader_(current_albumcover_loader), sequence_(nullptr), parser_(nullptr), playlist_container_(nullptr), @@ -79,10 +86,6 @@ PlaylistManager::PlaylistManager(Application *app, QObject *parent) setObjectName(QLatin1String(metaObject()->className())); - QObject::connect(&*app_->player(), &Player::Paused, this, &PlaylistManager::SetActivePaused); - QObject::connect(&*app_->player(), &Player::Playing, this, &PlaylistManager::SetActivePlaying); - QObject::connect(&*app_->player(), &Player::Stopped, this, &PlaylistManager::SetActiveStopped); - } PlaylistManager::~PlaylistManager() { @@ -92,21 +95,20 @@ PlaylistManager::~PlaylistManager() { } -void PlaylistManager::Init(SharedPtr collection_backend, SharedPtr playlist_backend, PlaylistSequence *sequence, PlaylistContainer *playlist_container) { +void PlaylistManager::Init(PlaylistSequence *sequence, PlaylistContainer *playlist_container) { - collection_backend_ = collection_backend; - playlist_backend_ = playlist_backend; sequence_ = sequence; - parser_ = new PlaylistParser(collection_backend, this); playlist_container_ = playlist_container; + parser_ = new PlaylistParser(tagreader_client_, collection_backend_, this); + QObject::connect(&*collection_backend_, &CollectionBackend::SongsChanged, this, &PlaylistManager::UpdateCollectionSongs); QObject::connect(&*collection_backend_, &CollectionBackend::SongsStatisticsChanged, this, &PlaylistManager::UpdateCollectionSongs); QObject::connect(&*collection_backend_, &CollectionBackend::SongsRatingChanged, this, &PlaylistManager::UpdateCollectionSongs); QObject::connect(parser_, &PlaylistParser::Error, this, &PlaylistManager::Error); - const PlaylistBackend::PlaylistList playlists = playlist_backend->GetAllOpenPlaylists(); + const PlaylistBackend::PlaylistList playlists = playlist_backend_->GetAllOpenPlaylists(); for (const PlaylistBackend::Playlist &p : playlists) { ++playlists_loading_; Playlist *ret = AddPlaylist(p.id, p.name, p.special_type, p.ui_path, p.favorite); @@ -153,7 +155,7 @@ QItemSelection PlaylistManager::selection(const int id) const { Playlist *PlaylistManager::AddPlaylist(const int id, const QString &name, const QString &special_type, const QString &ui_path, const bool favorite) { - Playlist *ret = new Playlist(playlist_backend_, app_->task_manager(), collection_backend_, id, special_type, favorite); + Playlist *ret = new Playlist(task_manager_, url_handlers_, playlist_backend_, collection_backend_, tagreader_client_, id, special_type, favorite); ret->set_sequence(sequence_); ret->set_ui_path(ui_path); @@ -165,7 +167,7 @@ Playlist *PlaylistManager::AddPlaylist(const int id, const QString &name, const QObject::connect(ret, &Playlist::Error, this, &PlaylistManager::Error); QObject::connect(ret, &Playlist::PlayRequested, this, &PlaylistManager::PlayRequested); QObject::connect(playlist_container_->view(), &PlaylistView::ColumnAlignmentChanged, ret, &Playlist::SetColumnAlignment); - QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, ret, &Playlist::AlbumCoverLoaded); + QObject::connect(&*current_albumcover_loader_, &CurrentAlbumCoverLoader::AlbumCoverLoaded, ret, &Playlist::AlbumCoverLoaded); playlists_[id] = Data(ret, name); @@ -219,7 +221,7 @@ void PlaylistManager::Load(const QString &filename) { } -void PlaylistManager::Save(const int id, const QString &filename, const PlaylistSettingsPage::PathType path_type) { +void PlaylistManager::Save(const int id, const QString &filename, const PlaylistSettings::PathType path_type) { if (playlists_.contains(id)) { parser_->Save(playlist(id)->GetAllSongs(), filename, path_type); @@ -237,7 +239,7 @@ void PlaylistManager::Save(const int id, const QString &filename, const Playlist } -void PlaylistManager::ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettingsPage::PathType path_type) { +void PlaylistManager::ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettings::PathType path_type) { parser_->Save(songs, filename, path_type); @@ -246,10 +248,10 @@ void PlaylistManager::ItemsLoadedForSavePlaylist(const SongList &songs, const QS void PlaylistManager::SaveWithUI(const int id, const QString &playlist_name) { Settings s; - s.beginGroup(Playlist::kSettingsGroup); - QString last_save_filter = s.value("last_save_filter", parser()->default_filter()).toString(); - QString last_save_path = s.value("last_save_path", QDir::homePath()).toString(); - QString last_save_extension = s.value("last_save_extension", parser()->default_extension()).toString(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + QString last_save_filter = s.value(PlaylistSettings::kLastSaveFilter, parser()->default_filter()).toString(); + QString last_save_path = s.value(PlaylistSettings::kLastSavePath, QDir::homePath()).toString(); + QString last_save_extension = s.value(PlaylistSettings::kLastSaveExtension, parser()->default_extension()).toString(); s.endGroup(); QString suggested_filename = playlist_name; @@ -265,20 +267,20 @@ void PlaylistManager::SaveWithUI(const int id, const QString &playlist_name) { QMessageBox::warning(nullptr, tr("Unknown playlist extension"), tr("Unknown file extension for playlist.")); } - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - PlaylistSettingsPage::PathType path_type = static_cast(s.value("path_type", static_cast(PlaylistSettingsPage::PathType::Automatic)).toInt()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + PlaylistSettings::PathType path_type = static_cast(s.value(PlaylistSettings::kPathType, static_cast(PlaylistSettings::PathType::Automatic)).toInt()); s.endGroup(); - if (path_type == PlaylistSettingsPage::PathType::Ask_User) { + if (path_type == PlaylistSettings::PathType::Ask_User) { PlaylistSaveOptionsDialog optionsdialog; optionsdialog.setModal(true); if (optionsdialog.exec() != QDialog::Accepted) return; path_type = optionsdialog.path_type(); } - s.beginGroup(Playlist::kSettingsGroup); - s.setValue("last_save_filter", last_save_filter); - s.setValue("last_save_path", fileinfo.path()); - s.setValue("last_save_extension", fileinfo.suffix()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + s.setValue(PlaylistSettings::kLastSaveFilter, last_save_filter); + s.setValue(PlaylistSettings::kLastSavePath, fileinfo.path()); + s.setValue(PlaylistSettings::kLastSaveExtension, fileinfo.suffix()); s.endGroup(); Save(id == -1 ? current_id() : id, filename, path_type); @@ -541,45 +543,6 @@ void PlaylistManager::RemoveDeletedSongs() { } -QString PlaylistManager::GetNameForNewPlaylist(const SongList &songs) { - - if (songs.isEmpty()) { - return tr("Playlist"); - } - - QSet artists; - QSet albums; - artists.reserve(songs.count()); - albums.reserve(songs.count()); - for (const Song &song : songs) { - artists << (song.effective_albumartist().isEmpty() ? tr("Unknown") : song.effective_albumartist()); - albums << (song.album().isEmpty() ? tr("Unknown") : song.album()); - - if (artists.size() > 1) { - break; - } - } - - bool various_artists = artists.size() > 1; - - QString result; - if (various_artists) { - result = tr("Various artists"); - } - else { - QStringList artist_names = artists.values(); - result = artist_names.first(); - } - - if (!various_artists && albums.size() == 1) { - QStringList album_names = albums.values(); - result += " - "_L1 + album_names.first(); - } - - return result; - -} - void PlaylistManager::Open(const int id) { if (playlists_.contains(id)) { @@ -642,10 +605,10 @@ void PlaylistManager::SaveAllPlaylists() { if (extension.isEmpty()) extension = parser()->default_extension(); Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - PlaylistSettingsPage::PathType path_type = static_cast(s.value("path_type", static_cast(PlaylistSettingsPage::PathType::Automatic)).toInt()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + PlaylistSettings::PathType path_type = static_cast(s.value(PlaylistSettings::kPathType, static_cast(PlaylistSettings::PathType::Automatic)).toInt()); s.endGroup(); - if (path_type == PlaylistSettingsPage::PathType::Ask_User) { + if (path_type == PlaylistSettings::PathType::Ask_User) { PlaylistSaveOptionsDialog optionsdialog; optionsdialog.setModal(true); if (optionsdialog.exec() != QDialog::Accepted) return; diff --git a/src/playlist/playlistmanager.h b/src/playlist/playlistmanager.h index 9a3dce2b12..e88bb23e7e 100644 --- a/src/playlist/playlistmanager.h +++ b/src/playlist/playlistmanager.h @@ -27,125 +27,40 @@ #include #include #include -#include #include #include #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" +#include "playlistmanagerinterface.h" #include "playlist.h" #include "smartplaylists/playlistgenerator.h" -class QModelIndex; - -class Application; +class TaskManager; +class TagReaderClient; +class UrlHandlers; class CollectionBackend; +class CurrentAlbumCoverLoader; class PlaylistBackend; class PlaylistContainer; class PlaylistParser; class PlaylistSequence; -class PlaylistManagerInterface : public QObject { - Q_OBJECT - - public: - explicit PlaylistManagerInterface(Application *app, QObject *parent) : QObject(parent) { Q_UNUSED(app); } - - virtual int current_id() const = 0; - virtual int active_id() const = 0; - - virtual QList playlist_ids() const = 0; - virtual QString playlist_name(const int id) const = 0; - virtual Playlist *playlist(const int id) const = 0; - virtual Playlist *current() const = 0; - virtual Playlist *active() const = 0; - - // Returns the collection of playlists managed by this PlaylistManager. - virtual QList GetAllPlaylists() const = 0; - // Grays out and reloads all deleted songs in all playlists. - virtual void InvalidateDeletedSongs() = 0; - // Removes all deleted songs from all playlists. - virtual void RemoveDeletedSongs() = 0; - - virtual QItemSelection selection(const int id) const = 0; - virtual QItemSelection current_selection() const = 0; - virtual QItemSelection active_selection() const = 0; - - virtual QString GetPlaylistName(const int index) const = 0; - - virtual SharedPtr collection_backend() const = 0; - virtual SharedPtr playlist_backend() const = 0; - virtual PlaylistSequence *sequence() const = 0; - virtual PlaylistParser *parser() const = 0; - virtual PlaylistContainer *playlist_container() const = 0; - - virtual void PlaySmartPlaylist(PlaylistGeneratorPtr generator, const bool as_new, const bool clear) = 0; - - public Q_SLOTS: - virtual void New(const QString &name, const SongList &songs = SongList(), const QString &special_type = QString()) = 0; - virtual void Load(const QString &filename) = 0; - virtual void Save(const int id, const QString &filename, const PlaylistSettingsPage::PathType path_type) = 0; - virtual void Rename(const int id, const QString &new_name) = 0; - virtual void Delete(const int id) = 0; - virtual bool Close(const int id) = 0; - virtual void Open(const int id) = 0; - virtual void ChangePlaylistOrder(const QList &ids) = 0; - - virtual void SongChangeRequestProcessed(const QUrl &url, const bool valid) = 0; - - virtual void SetCurrentPlaylist(const int id) = 0; - virtual void SetActivePlaylist(const int id) = 0; - virtual void SetActiveToCurrent() = 0; - - virtual void SelectionChanged(const QItemSelection &selection) = 0; - - // Convenience slots that defer to either current() or active() - virtual void ClearCurrent() = 0; - virtual void ShuffleCurrent() = 0; - virtual void RemoveDuplicatesCurrent() = 0; - virtual void RemoveUnavailableCurrent() = 0; - virtual void SetActivePlaying() = 0; - virtual void SetActivePaused() = 0; - virtual void SetActiveStopped() = 0; - - // Rate current song using 0.0 - 1.0 scale. - virtual void RateCurrentSong(const float rating) = 0; - // Rate current song using 0 - 5 scale. - virtual void RateCurrentSong2(const int rating) = 0; - - Q_SIGNALS: - void PlaylistManagerInitialized(); - void AllPlaylistsLoaded(); - - void PlaylistAdded(const int id, const QString &name, const bool favorite); - void PlaylistDeleted(const int id); - void PlaylistClosed(const int id); - void PlaylistRenamed(const int id, const QString &new_name); - void PlaylistFavorited(const int id, const bool favorite); - void CurrentChanged(Playlist *new_playlist, const int scroll_position = 0); - void ActiveChanged(Playlist *new_playlist); - - void Error(const QString &message); - void SummaryTextChanged(const QString &summary); - - // Forwarded from individual playlists - void CurrentSongChanged(const Song &song); - void CurrentSongMetadataChanged(const Song &song); - - // Signals that one of manager's playlists has changed (new items, new ordering etc.) - the argument shows which. - void PlaylistChanged(Playlist *playlist); - void EditingFinished(const int playlist_id, const QModelIndex idx); - void PlayRequested(const QModelIndex idx, const Playlist::AutoScroll autoscroll); -}; - class PlaylistManager : public PlaylistManagerInterface { Q_OBJECT public: - explicit PlaylistManager(Application *app, QObject *parent = nullptr); + explicit PlaylistManager(SharedPtr task_manager, + SharedPtr tagreader_client, + SharedPtr url_handlers, + SharedPtr playlist_backend, + SharedPtr collection_backend, + SharedPtr current_albumcover_loader, + QObject *parent = nullptr); + ~PlaylistManager() override; int current_id() const override { return current_; } @@ -166,9 +81,6 @@ class PlaylistManager : public PlaylistManagerInterface { // Returns true if the playlist is open bool IsPlaylistOpen(const int id); - // Returns a pretty automatic name for playlist created from the given list of songs. - static QString GetNameForNewPlaylist(const SongList &songs); - QItemSelection selection(const int id) const override; QItemSelection current_selection() const override { return selection(current_id()); } QItemSelection active_selection() const override { return selection(active_id()); } @@ -176,7 +88,7 @@ class PlaylistManager : public PlaylistManagerInterface { QString GetPlaylistName(const int index) const override { return playlists_[index].name; } bool IsPlaylistFavorite(const int index) const { return playlists_[index].p->is_favorite(); } - void Init(SharedPtr collection_backend, SharedPtr playlist_backend, PlaylistSequence *sequence, PlaylistContainer *playlist_container); + void Init(PlaylistSequence *sequence, PlaylistContainer *playlist_container); SharedPtr collection_backend() const override { return collection_backend_; } SharedPtr playlist_backend() const override { return playlist_backend_; } @@ -187,7 +99,7 @@ class PlaylistManager : public PlaylistManagerInterface { public Q_SLOTS: void New(const QString &name, const SongList &songs = SongList(), const QString &special_type = QString()) override; void Load(const QString &filename) override; - void Save(const int id, const QString &filename, const PlaylistSettingsPage::PathType path_type) override; + void Save(const int id, const QString &filename, const PlaylistSettings::PathType path_type) override; // Display a file dialog to let user choose a file before saving the file void SaveWithUI(const int id, const QString &playlist_name); void Rename(const int id, const QString &new_name) override; @@ -230,15 +142,15 @@ class PlaylistManager : public PlaylistManagerInterface { void SaveAllPlaylists(); - private Q_SLOTS: void SetActivePlaying() override; void SetActivePaused() override; void SetActiveStopped() override; + private Q_SLOTS: void OneOfPlaylistsChanged(); void UpdateSummaryText(); void UpdateCollectionSongs(const SongList &songs); - void ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettingsPage::PathType path_type); + void ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettings::PathType path_type); void PlaylistLoaded(); private: @@ -253,9 +165,12 @@ class PlaylistManager : public PlaylistManagerInterface { int scroll_position; }; - Application *app_; + SharedPtr task_manager_; + SharedPtr tagreader_client_; + SharedPtr url_handlers_; SharedPtr playlist_backend_; SharedPtr collection_backend_; + SharedPtr current_albumcover_loader_; PlaylistSequence *sequence_; PlaylistParser *parser_; PlaylistContainer *playlist_container_; diff --git a/src/playlist/playlistmanagerinterface.cpp b/src/playlist/playlistmanagerinterface.cpp new file mode 100644 index 0000000000..eab1014b10 --- /dev/null +++ b/src/playlist/playlistmanagerinterface.cpp @@ -0,0 +1,24 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2010, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "playlistmanagerinterface.h" + +PlaylistManagerInterface::PlaylistManagerInterface(QObject *parent) : QObject(parent) {} diff --git a/src/playlist/playlistmanagerinterface.h b/src/playlist/playlistmanagerinterface.h new file mode 100644 index 0000000000..92badfbe3e --- /dev/null +++ b/src/playlist/playlistmanagerinterface.h @@ -0,0 +1,138 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2010, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTMANAGERINTERFACE_H +#define PLAYLISTMANAGERINTERFACE_H + +#include +#include +#include +#include +#include +#include + +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" +#include "playlist.h" +#include "smartplaylists/playlistgenerator.h" + +class QModelIndex; +class CollectionBackend; +class CurrentAlbumCoverLoader; +class PlaylistBackend; +class PlaylistContainer; +class PlaylistParser; +class PlaylistSequence; + +class PlaylistManagerInterface : public QObject { + Q_OBJECT + + public: + explicit PlaylistManagerInterface(QObject *parent); + + virtual int current_id() const = 0; + virtual int active_id() const = 0; + + virtual QList playlist_ids() const = 0; + virtual QString playlist_name(const int id) const = 0; + virtual Playlist *playlist(const int id) const = 0; + virtual Playlist *current() const = 0; + virtual Playlist *active() const = 0; + + // Returns the collection of playlists managed by this PlaylistManager. + virtual QList GetAllPlaylists() const = 0; + // Grays out and reloads all deleted songs in all playlists. + virtual void InvalidateDeletedSongs() = 0; + // Removes all deleted songs from all playlists. + virtual void RemoveDeletedSongs() = 0; + + virtual QItemSelection selection(const int id) const = 0; + virtual QItemSelection current_selection() const = 0; + virtual QItemSelection active_selection() const = 0; + + virtual QString GetPlaylistName(const int index) const = 0; + + virtual SharedPtr collection_backend() const = 0; + virtual SharedPtr playlist_backend() const = 0; + virtual PlaylistSequence *sequence() const = 0; + virtual PlaylistParser *parser() const = 0; + virtual PlaylistContainer *playlist_container() const = 0; + + virtual void PlaySmartPlaylist(PlaylistGeneratorPtr generator, const bool as_new, const bool clear) = 0; + + public Q_SLOTS: + virtual void New(const QString &name, const SongList &songs = SongList(), const QString &special_type = QString()) = 0; + virtual void Load(const QString &filename) = 0; + virtual void Save(const int id, const QString &filename, const PlaylistSettings::PathType path_type) = 0; + virtual void Rename(const int id, const QString &new_name) = 0; + virtual void Delete(const int id) = 0; + virtual bool Close(const int id) = 0; + virtual void Open(const int id) = 0; + virtual void ChangePlaylistOrder(const QList &ids) = 0; + + virtual void SongChangeRequestProcessed(const QUrl &url, const bool valid) = 0; + + virtual void SetCurrentPlaylist(const int id) = 0; + virtual void SetActivePlaylist(const int id) = 0; + virtual void SetActiveToCurrent() = 0; + + virtual void SelectionChanged(const QItemSelection &selection) = 0; + + // Convenience slots that defer to either current() or active() + virtual void ClearCurrent() = 0; + virtual void ShuffleCurrent() = 0; + virtual void RemoveDuplicatesCurrent() = 0; + virtual void RemoveUnavailableCurrent() = 0; + virtual void SetActivePlaying() = 0; + virtual void SetActivePaused() = 0; + virtual void SetActiveStopped() = 0; + + // Rate current song using 0.0 - 1.0 scale. + virtual void RateCurrentSong(const float rating) = 0; + // Rate current song using 0 - 5 scale. + virtual void RateCurrentSong2(const int rating) = 0; + + Q_SIGNALS: + void PlaylistManagerInitialized(); + void AllPlaylistsLoaded(); + + void PlaylistAdded(const int id, const QString &name, const bool favorite); + void PlaylistDeleted(const int id); + void PlaylistClosed(const int id); + void PlaylistRenamed(const int id, const QString &new_name); + void PlaylistFavorited(const int id, const bool favorite); + void CurrentChanged(Playlist *new_playlist, const int scroll_position = 0); + void ActiveChanged(Playlist *new_playlist); + + void Error(const QString &message); + void SummaryTextChanged(const QString &summary); + + // Forwarded from individual playlists + void CurrentSongChanged(const Song &song); + void CurrentSongMetadataChanged(const Song &song); + + // Signals that one of manager's playlists has changed (new items, new ordering etc.) - the argument shows which. + void PlaylistChanged(Playlist *playlist); + void EditingFinished(const int playlist_id, const QModelIndex idx); + void PlayRequested(const QModelIndex idx, const Playlist::AutoScroll autoscroll); +}; + +#endif // PLAYLISTMANAGERINTERFACE_H diff --git a/src/playlist/playlistproxystyle.h b/src/playlist/playlistproxystyle.h index 4bc512286a..703df9c3ab 100644 --- a/src/playlist/playlistproxystyle.h +++ b/src/playlist/playlistproxystyle.h @@ -28,7 +28,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class QPainter; diff --git a/src/playlist/playlistsaveoptionsdialog.cpp b/src/playlist/playlistsaveoptionsdialog.cpp index c38774b018..167436d2cd 100644 --- a/src/playlist/playlistsaveoptionsdialog.cpp +++ b/src/playlist/playlistsaveoptionsdialog.cpp @@ -28,7 +28,7 @@ #include #include "core/settings.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "playlistsaveoptionsdialog.h" #include "ui_playlistsaveoptionsdialog.h" @@ -38,9 +38,9 @@ PlaylistSaveOptionsDialog::PlaylistSaveOptionsDialog(QWidget *parent) : QDialog( ui->setupUi(this); - ui->filePaths->addItem(tr("Automatic"), QVariant::fromValue(PlaylistSettingsPage::PathType::Automatic)); - ui->filePaths->addItem(tr("Relative"), QVariant::fromValue(PlaylistSettingsPage::PathType::Relative)); - ui->filePaths->addItem(tr("Absolute"), QVariant::fromValue(PlaylistSettingsPage::PathType::Absolute)); + ui->filePaths->addItem(tr("Automatic"), QVariant::fromValue(PlaylistSettings::PathType::Automatic)); + ui->filePaths->addItem(tr("Relative"), QVariant::fromValue(PlaylistSettings::PathType::Relative)); + ui->filePaths->addItem(tr("Absolute"), QVariant::fromValue(PlaylistSettings::PathType::Absolute)); } @@ -50,8 +50,8 @@ void PlaylistSaveOptionsDialog::accept() { if (ui->remember_user_choice->isChecked()) { Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - s.setValue("path_type", ui->filePaths->itemData(ui->filePaths->currentIndex()).toInt()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + s.setValue(PlaylistSettings::kPathType, ui->filePaths->itemData(ui->filePaths->currentIndex()).toInt()); s.endGroup(); } @@ -59,6 +59,6 @@ void PlaylistSaveOptionsDialog::accept() { } -PlaylistSettingsPage::PathType PlaylistSaveOptionsDialog::path_type() const { - return ui->filePaths->itemData(ui->filePaths->currentIndex()).value(); +PlaylistSettings::PathType PlaylistSaveOptionsDialog::path_type() const { + return ui->filePaths->itemData(ui->filePaths->currentIndex()).value(); } diff --git a/src/playlist/playlistsaveoptionsdialog.h b/src/playlist/playlistsaveoptionsdialog.h index 825ee0e2e4..737d9ccf8a 100644 --- a/src/playlist/playlistsaveoptionsdialog.h +++ b/src/playlist/playlistsaveoptionsdialog.h @@ -27,7 +27,7 @@ #include #include -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" class QWidget; @@ -43,7 +43,7 @@ class PlaylistSaveOptionsDialog : public QDialog { ~PlaylistSaveOptionsDialog() override; void accept() override; - PlaylistSettingsPage::PathType path_type() const; + PlaylistSettings::PathType path_type() const; private: static const char *kSettingsGroup; diff --git a/src/playlist/playlistsequence.h b/src/playlist/playlistsequence.h index f0f9c05067..91464a9222 100644 --- a/src/playlist/playlistsequence.h +++ b/src/playlist/playlistsequence.h @@ -30,7 +30,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class QMenu; class QAction; diff --git a/src/playlist/playlisttabbar.cpp b/src/playlist/playlisttabbar.cpp index 9b22a392b3..2625731ec8 100644 --- a/src/playlist/playlisttabbar.cpp +++ b/src/playlist/playlisttabbar.cpp @@ -43,8 +43,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/iconloader.h" #include "core/mimedata.h" #include "core/settings.h" diff --git a/src/playlist/playlisttabbar.h b/src/playlist/playlisttabbar.h index aaebe36059..1a34c708c6 100644 --- a/src/playlist/playlisttabbar.h +++ b/src/playlist/playlisttabbar.h @@ -46,7 +46,7 @@ class QTimerEvent; class PlaylistManager; class RenameTabLineEdit; -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class PlaylistTabBar : public QTabBar { Q_OBJECT diff --git a/src/playlist/playlistundocommandbase.cpp b/src/playlist/playlistundocommandbase.cpp new file mode 100644 index 0000000000..0f4c17a785 --- /dev/null +++ b/src/playlist/playlistundocommandbase.cpp @@ -0,0 +1,25 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "playlist.h" +#include "playlistundocommandbase.h" + +PlaylistUndoCommandBase::PlaylistUndoCommandBase(Playlist *playlist) : QUndoCommand(nullptr), playlist_(playlist) {} diff --git a/src/playlist/playlistundocommandbase.h b/src/playlist/playlistundocommandbase.h new file mode 100644 index 0000000000..f053cfc930 --- /dev/null +++ b/src/playlist/playlistundocommandbase.h @@ -0,0 +1,39 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDBASE_H +#define PLAYLISTUNDOCOMMANDBASE_H + +#include + +class Playlist; + +class PlaylistUndoCommandBase : public QUndoCommand { + public: + explicit PlaylistUndoCommandBase(Playlist *playlist); + + enum class Type { + RemoveItems = 0, + }; + + protected: + Playlist *playlist_; +}; + +#endif // PLAYLISTUNDOCOMMANDBASE_H diff --git a/src/playlist/playlistundocommandinsertitems.cpp b/src/playlist/playlistundocommandinsertitems.cpp new file mode 100644 index 0000000000..df7d755348 --- /dev/null +++ b/src/playlist/playlistundocommandinsertitems.cpp @@ -0,0 +1,58 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "playlistundocommandinsertitems.h" +#include "playlist.h" + +PlaylistUndoCommandInsertItems::PlaylistUndoCommandInsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue, const bool enqueue_next) + : PlaylistUndoCommandBase(playlist), + items_(items), + pos_(pos), + enqueue_(enqueue), + enqueue_next_(enqueue_next) { + + setText(QObject::tr("add %n songs", "", static_cast(items_.count()))); + +} + +void PlaylistUndoCommandInsertItems::redo() { + playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_); +} + +void PlaylistUndoCommandInsertItems::undo() { + + const int start = pos_ == -1 ? static_cast(playlist_->rowCount() - items_.count()) : pos_; + playlist_->RemoveItemsWithoutUndo(start, static_cast(items_.count())); + +} + +bool PlaylistUndoCommandInsertItems::UpdateItem(const PlaylistItemPtr &updated_item) { + + for (int i = 0; i < items_.size(); i++) { + PlaylistItemPtr item = items_.value(i); + if (item->Metadata().url() == updated_item->Metadata().url()) { + items_[i] = updated_item; + return true; + } + } + return false; + +} diff --git a/src/playlist/playlistundocommandinsertitems.h b/src/playlist/playlistundocommandinsertitems.h new file mode 100644 index 0000000000..d09a88d81a --- /dev/null +++ b/src/playlist/playlistundocommandinsertitems.h @@ -0,0 +1,44 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDINSERTITEMS_H +#define PLAYLISTUNDOCOMMANDINSERTITEMS_H + +#include "playlistundocommandbase.h" +#include "playlistitem.h" + +class PlaylistUndoCommandInsertItems : public PlaylistUndoCommandBase { + public: + explicit PlaylistUndoCommandInsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue = false, const bool enqueue_next = false); + + void undo() override; + void redo() override; + // When load is async, items have already been pushed, so we need to update them. + // This function try to find the equivalent item, and replace it with the new (completely loaded) one. + // Return true if the was found (and updated), false otherwise + bool UpdateItem(const PlaylistItemPtr &updated_item); + + private: + PlaylistItemPtrList items_; + int pos_; + bool enqueue_; + bool enqueue_next_; +}; + +#endif // PLAYLISTUNDOCOMMANDINSERTITEMS_H diff --git a/src/playlist/playlistundocommandmoveitems.cpp b/src/playlist/playlistundocommandmoveitems.cpp new file mode 100644 index 0000000000..76802c8f1e --- /dev/null +++ b/src/playlist/playlistundocommandmoveitems.cpp @@ -0,0 +1,40 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "playlist.h" +#include "playlistundocommandmoveitems.h" + +PlaylistUndoCommandMoveItems::PlaylistUndoCommandMoveItems(Playlist *playlist, const QList &source_rows, const int pos) + : PlaylistUndoCommandBase(playlist), + source_rows_(source_rows), + pos_(pos) { + + setText(QObject::tr("move %n songs", "", static_cast(source_rows.count()))); + +} + +void PlaylistUndoCommandMoveItems::redo() { + playlist_->MoveItemsWithoutUndo(source_rows_, pos_); +} + +void PlaylistUndoCommandMoveItems::undo() { + playlist_->MoveItemsWithoutUndo(pos_, source_rows_); +} diff --git a/src/playlist/playlistundocommandmoveitems.h b/src/playlist/playlistundocommandmoveitems.h new file mode 100644 index 0000000000..e5013bc6d8 --- /dev/null +++ b/src/playlist/playlistundocommandmoveitems.h @@ -0,0 +1,41 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDMOVEITEMS_H +#define PLAYLISTUNDOCOMMANDMOVEITEMS_H + +#include + +#include "playlistundocommandbase.h" + +class Playlist; + +class PlaylistUndoCommandMoveItems : public PlaylistUndoCommandBase { + public: + explicit PlaylistUndoCommandMoveItems(Playlist *playlist, const QList &source_rows, const int pos); + + void undo() override; + void redo() override; + + private: + QList source_rows_; + int pos_; +}; + +#endif // PLAYLISTUNDOCOMMANDMOVEITEMS_H diff --git a/src/playlist/playlistundocommandremoveitems.cpp b/src/playlist/playlistundocommandremoveitems.cpp new file mode 100644 index 0000000000..f725c6cedb --- /dev/null +++ b/src/playlist/playlistundocommandremoveitems.cpp @@ -0,0 +1,58 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "playlist.h" +#include "playlistundocommandremoveitems.h" + +PlaylistUndoCommandRemoveItems::PlaylistUndoCommandRemoveItems(Playlist *playlist, const int pos, const int count) : PlaylistUndoCommandBase(playlist) { + setText(QObject::tr("remove %n songs", "", count)); + + ranges_ << Range(pos, count); +} + +void PlaylistUndoCommandRemoveItems::redo() { + + for (int i = 0; i < ranges_.count(); ++i) { + ranges_[i].items_ = playlist_->RemoveItemsWithoutUndo(ranges_[i].pos_, ranges_[i].count_); + } + +} + +void PlaylistUndoCommandRemoveItems::undo() { + + for (int i = static_cast(ranges_.count() - 1); i >= 0; --i) { + playlist_->InsertItemsWithoutUndo(ranges_[i].items_, ranges_[i].pos_); + } + +} + +bool PlaylistUndoCommandRemoveItems::mergeWith(const QUndoCommand *other) { + + const PlaylistUndoCommandRemoveItems *remove_command = static_cast(other); + ranges_.append(remove_command->ranges_); + + int sum = 0; + for (const Range &range : std::as_const(ranges_)) sum += range.count_; + setText(QObject::tr("remove %n songs", "", sum)); + + return true; + +} diff --git a/src/playlist/playlistundocommandremoveitems.h b/src/playlist/playlistundocommandremoveitems.h new file mode 100644 index 0000000000..662f0684d3 --- /dev/null +++ b/src/playlist/playlistundocommandremoveitems.h @@ -0,0 +1,49 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDREMOVEITEMS_H +#define PLAYLISTUNDOCOMMANDREMOVEITEMS_H + +#include + +#include "playlistundocommandbase.h" +#include "playlistitem.h" + +class PlaylistUndoCommandRemoveItems : public PlaylistUndoCommandBase { + public: + explicit PlaylistUndoCommandRemoveItems(Playlist *playlist, const int pos, const int count); + + int id() const override { return static_cast(PlaylistUndoCommandBase::Type::RemoveItems); } + + void undo() override; + void redo() override; + bool mergeWith(const QUndoCommand *other) override; + + private: + struct Range { + Range(const int pos, const int count) : pos_(pos), count_(count) {} + int pos_; + int count_; + PlaylistItemPtrList items_; + }; + + QList ranges_; +}; + +#endif // PLAYLISTUNDOCOMMANDREMOVEITEMS_H diff --git a/src/playlist/playlistundocommandreorderitems.cpp b/src/playlist/playlistundocommandreorderitems.cpp new file mode 100644 index 0000000000..ea04da52ac --- /dev/null +++ b/src/playlist/playlistundocommandreorderitems.cpp @@ -0,0 +1,28 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include "playlist.h" +#include "playlistundocommandreorderitems.h" + +PlaylistUndoCommandReOrderItems::PlaylistUndoCommandReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items) + : PlaylistUndoCommandBase(playlist), old_items_(playlist->items_), new_items_(new_items) {} + +void PlaylistUndoCommandReOrderItems::undo() { playlist_->ReOrderWithoutUndo(old_items_); } + +void PlaylistUndoCommandReOrderItems::redo() { playlist_->ReOrderWithoutUndo(new_items_); } diff --git a/src/playlist/playlistundocommandreorderitems.h b/src/playlist/playlistundocommandreorderitems.h new file mode 100644 index 0000000000..46eba84f2d --- /dev/null +++ b/src/playlist/playlistundocommandreorderitems.h @@ -0,0 +1,40 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDREORDERITEMS_H +#define PLAYLISTUNDOCOMMANDREORDERITEMS_H + +#include "playlistundocommandbase.h" +#include "playlistitem.h" + +class Playlist; + +class PlaylistUndoCommandReOrderItems : public PlaylistUndoCommandBase { + public: + explicit PlaylistUndoCommandReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items); + + void undo() override; + void redo() override; + + private: + PlaylistItemPtrList old_items_; + PlaylistItemPtrList new_items_; +}; + +#endif // PLAYLISTUNDOCOMMANDREORDERITEMS_H diff --git a/src/playlist/playlistundocommands.cpp b/src/playlist/playlistundocommands.cpp deleted file mode 100644 index a217c2d1e8..0000000000 --- a/src/playlist/playlistundocommands.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * - * 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 . - * - */ - -#include "config.h" - -#include - -#include -#include -#include - -#include "playlist.h" -#include "playlistitem.h" -#include "playlistundocommands.h" - -namespace PlaylistUndoCommands { - -Base::Base(Playlist *playlist) : QUndoCommand(nullptr), playlist_(playlist) {} - -InsertItems::InsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue, const bool enqueue_next) - : Base(playlist), - items_(items), - pos_(pos), - enqueue_(enqueue), - enqueue_next_(enqueue_next) { - - setText(tr("add %n songs", "", static_cast(items_.count()))); - -} - -void InsertItems::redo() { - playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_); -} - -void InsertItems::undo() { - const int start = pos_ == -1 ? static_cast(playlist_->rowCount() - items_.count()) : pos_; - playlist_->RemoveItemsWithoutUndo(start, static_cast(items_.count())); -} - -bool InsertItems::UpdateItem(const PlaylistItemPtr &updated_item) { - - for (int i = 0; i < items_.size(); i++) { - PlaylistItemPtr item = items_.value(i); - if (item->Metadata().url() == updated_item->Metadata().url()) { - items_[i] = updated_item; - return true; - } - } - return false; - -} - - -RemoveItems::RemoveItems(Playlist *playlist, const int pos, const int count) : Base(playlist) { - setText(tr("remove %n songs", "", count)); - - ranges_ << Range(pos, count); -} - -void RemoveItems::redo() { - - for (int i = 0; i < ranges_.count(); ++i) { - ranges_[i].items_ = playlist_->RemoveItemsWithoutUndo(ranges_[i].pos_, ranges_[i].count_); - } - -} - -void RemoveItems::undo() { - - for (int i = static_cast(ranges_.count() - 1); i >= 0; --i) { - playlist_->InsertItemsWithoutUndo(ranges_[i].items_, ranges_[i].pos_); - } - -} - -bool RemoveItems::mergeWith(const QUndoCommand *other) { - - const RemoveItems *remove_command = static_cast(other); - ranges_.append(remove_command->ranges_); - - int sum = 0; - for (const Range &range : std::as_const(ranges_)) sum += range.count_; - setText(tr("remove %n songs", "", sum)); - - return true; - -} - - -MoveItems::MoveItems(Playlist *playlist, const QList &source_rows, const int pos) - : Base(playlist), - source_rows_(source_rows), - pos_(pos) { - - setText(tr("move %n songs", "", static_cast(source_rows.count()))); - -} - -void MoveItems::redo() { - playlist_->MoveItemsWithoutUndo(source_rows_, pos_); -} - -void MoveItems::undo() { - playlist_->MoveItemsWithoutUndo(pos_, source_rows_); -} - -ReOrderItems::ReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items) - : Base(playlist), old_items_(playlist->items_), new_items_(new_items) {} - -void ReOrderItems::undo() { playlist_->ReOrderWithoutUndo(old_items_); } - -void ReOrderItems::redo() { playlist_->ReOrderWithoutUndo(new_items_); } - -SortItems::SortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items) - : ReOrderItems(playlist, new_items) { - - Q_UNUSED(column); - Q_UNUSED(order); - - setText(tr("sort songs")); - -} - - -ShuffleItems::ShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items) - : ReOrderItems(playlist, new_items) { - - setText(tr("shuffle songs")); - -} - -} // namespace PlaylistUndoCommands diff --git a/src/playlist/playlistundocommands.h b/src/playlist/playlistundocommands.h deleted file mode 100644 index d2b4957ce1..0000000000 --- a/src/playlist/playlistundocommands.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * - * 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 . - * - */ - -#ifndef PLAYLISTUNDOCOMMANDS_H -#define PLAYLISTUNDOCOMMANDS_H - -#include "config.h" - -#include -#include -#include - -#include "playlist.h" -#include "playlistitem.h" - -namespace PlaylistUndoCommands { - - enum Types { - Type_RemoveItems = 0, - }; - - class Base : public QUndoCommand { - Q_DECLARE_TR_FUNCTIONS(PlaylistUndoCommands) - - public: - explicit Base(Playlist *playlist); - - protected: - Playlist *playlist_; - }; - - class InsertItems : public Base { - public: - explicit InsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue = false, const bool enqueue_next = false); - - void undo() override; - void redo() override; - // When load is async, items have already been pushed, so we need to update them. - // This function try to find the equivalent item, and replace it with the new (completely loaded) one. - // Return true if the was found (and updated), false otherwise - bool UpdateItem(const PlaylistItemPtr &updated_item); - - private: - PlaylistItemPtrList items_; - int pos_; - bool enqueue_; - bool enqueue_next_; - }; - - class RemoveItems : public Base { - public: - explicit RemoveItems(Playlist *playlist, const int pos, const int count); - - int id() const override { return Type_RemoveItems; } - - void undo() override; - void redo() override; - bool mergeWith(const QUndoCommand *other) override; - - private: - struct Range { - Range(const int pos, const int count) : pos_(pos), count_(count) {} - int pos_; - int count_; - PlaylistItemPtrList items_; - }; - - QList ranges_; - }; - - class MoveItems : public Base { - public: - explicit MoveItems(Playlist *playlist, const QList &source_rows, const int pos); - - void undo() override; - void redo() override; - - private: - QList source_rows_; - int pos_; - }; - - class ReOrderItems : public Base { - public: - explicit ReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items); - - void undo() override; - void redo() override; - - private: - PlaylistItemPtrList old_items_; - PlaylistItemPtrList new_items_; - }; - - class SortItems : public ReOrderItems { - public: - explicit SortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items); - - }; - - class ShuffleItems : public ReOrderItems { - public: - explicit ShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items); - }; - -} // namespace - -#endif // PLAYLISTUNDOCOMMANDS_H diff --git a/src/playlist/playlistundocommandshuffleitems.cpp b/src/playlist/playlistundocommandshuffleitems.cpp new file mode 100644 index 0000000000..f52d268a83 --- /dev/null +++ b/src/playlist/playlistundocommandshuffleitems.cpp @@ -0,0 +1,30 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "playlist.h" +#include "playlistundocommandshuffleitems.h" + +PlaylistUndoCommandShuffleItems::PlaylistUndoCommandShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items) + : PlaylistUndoCommandReOrderItems(playlist, new_items) { + + setText(QObject::tr("shuffle songs")); + +} diff --git a/src/playlist/playlistundocommandshuffleitems.h b/src/playlist/playlistundocommandshuffleitems.h new file mode 100644 index 0000000000..7ef0e61f83 --- /dev/null +++ b/src/playlist/playlistundocommandshuffleitems.h @@ -0,0 +1,33 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDSHUFFLEITEMS_H +#define PLAYLISTUNDOCOMMANDSHUFFLEITEMS_H + +#include "playlistundocommandreorderitems.h" +#include "playlistitem.h" + +class Playlist; + +class PlaylistUndoCommandShuffleItems : public PlaylistUndoCommandReOrderItems { + public: + explicit PlaylistUndoCommandShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items); +}; + +#endif // PLAYLISTUNDOCOMMANDSHUFFLEITEMS_H diff --git a/src/playlist/playlistundocommandsortitems.cpp b/src/playlist/playlistundocommandsortitems.cpp new file mode 100644 index 0000000000..49bee637d5 --- /dev/null +++ b/src/playlist/playlistundocommandsortitems.cpp @@ -0,0 +1,33 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#include + +#include "playlist.h" +#include "playlistundocommandsortitems.h" + +PlaylistUndoCommandSortItems::PlaylistUndoCommandSortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items) + : PlaylistUndoCommandReOrderItems(playlist, new_items) { + + Q_UNUSED(column); + Q_UNUSED(order); + + setText(QObject::tr("sort songs")); + +} diff --git a/src/playlist/playlistundocommandsortitems.h b/src/playlist/playlistundocommandsortitems.h new file mode 100644 index 0000000000..13e7168fe2 --- /dev/null +++ b/src/playlist/playlistundocommandsortitems.h @@ -0,0 +1,32 @@ +/* + * Strawberry Music Player + * Copyright 2020-2024, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef PLAYLISTUNDOCOMMANDSORTITEMS_H +#define PLAYLISTUNDOCOMMANDSORTITEMS_H + +#include "playlistundocommandreorderitems.h" +#include "playlist.h" +#include "playlistitem.h" + +class PlaylistUndoCommandSortItems : public PlaylistUndoCommandReOrderItems { + public: + explicit PlaylistUndoCommandSortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items); +}; + +#endif // PLAYLISTUNDOCOMMANDSORTITEMS_H diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index 23a606c3db..f6cd01c610 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -59,11 +59,10 @@ #include #include -#include "core/application.h" -#include "core/player.h" -#include "core/qt_blurimage.h" +#include "includes/qt_blurimage.h" #include "core/song.h" #include "core/settings.h" +#include "core/player.h" #include "playlistmanager.h" #include "playlist.h" #include "playlistdelegates.h" @@ -73,8 +72,8 @@ #include "playlistproxystyle.h" #include "covermanager/currentalbumcoverloader.h" #include "covermanager/albumcoverloaderresult.h" -#include "settings/appearancesettingspage.h" -#include "settings/playlistsettingspage.h" +#include "constants/appearancesettings.h" +#include "constants/playlistsettings.h" #include "dynamicplaylistcontrols.h" #ifdef HAVE_MOODBAR @@ -92,18 +91,17 @@ constexpr int kDropIndicatorGradientWidth = 5; PlaylistView::PlaylistView(QWidget *parent) : QTreeView(parent), - app_(nullptr), style_(new PlaylistProxyStyle(QApplication::style()->name())), playlist_(nullptr), header_(new PlaylistHeader(Qt::Horizontal, this, this)), - background_image_type_(AppearanceSettingsPage::BackgroundImageType::Default), - background_image_position_(AppearanceSettingsPage::BackgroundImagePosition::BottomRight), + background_image_type_(AppearanceSettings::BackgroundImageType::Default), + background_image_position_(AppearanceSettings::BackgroundImagePosition::BottomRight), background_image_maxsize_(0), background_image_stretch_(false), background_image_do_not_cut_(true), background_image_keep_aspect_ratio_(true), - blur_radius_(AppearanceSettingsPage::kDefaultBlurRadius), - opacity_level_(AppearanceSettingsPage::kDefaultOpacityLevel), + blur_radius_(AppearanceSettings::kDefaultBlurRadius), + opacity_level_(AppearanceSettings::kDefaultOpacityLevel), background_initialized_(false), set_initial_header_layout_(false), header_state_loaded_(false), @@ -187,18 +185,27 @@ PlaylistView::~PlaylistView() { style_->deleteLater(); } -void PlaylistView::Init(Application *app) { +void PlaylistView::Init(const SharedPtr player, + const SharedPtr playlist_manager, + const SharedPtr collection_backend, +#ifdef HAVE_MOODBAR + const SharedPtr moodbar_loader, +#endif + const SharedPtr current_albumcover_loader) { - Q_ASSERT(app); - app_ = app; + player_ = player; + playlist_manager_ = playlist_manager; + collection_backend_ = collection_backend; + current_albumcover_loader_ = current_albumcover_loader; + moodbar_loader_ = moodbar_loader; SetItemDelegates(); - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &PlaylistView::SongChanged); - QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &PlaylistView::AlbumCoverLoaded); - QObject::connect(&*app_->player(), &Player::Playing, this, &PlaylistView::StartGlowing); - QObject::connect(&*app_->player(), &Player::Paused, this, &PlaylistView::StopGlowing); - QObject::connect(&*app_->player(), &Player::Stopped, this, &PlaylistView::Stopped); + QObject::connect(&*playlist_manager, &PlaylistManager::CurrentSongChanged, this, &PlaylistView::SongChanged); + QObject::connect(&*current_albumcover_loader_, &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &PlaylistView::AlbumCoverLoaded); + QObject::connect(&*player, &Player::Playing, this, &PlaylistView::StartGlowing); + QObject::connect(&*player, &Player::Paused, this, &PlaylistView::StopGlowing); + QObject::connect(&*player, &Player::Stopped, this, &PlaylistView::Stopped); } @@ -207,13 +214,13 @@ void PlaylistView::SetItemDelegates() { setItemDelegate(new PlaylistDelegateBase(this)); setItemDelegateForColumn(static_cast(Playlist::Column::Title), new TextItemDelegate(this)); - setItemDelegateForColumn(static_cast(Playlist::Column::Album), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Album)); - setItemDelegateForColumn(static_cast(Playlist::Column::Artist), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Artist)); - setItemDelegateForColumn(static_cast(Playlist::Column::AlbumArtist), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::AlbumArtist)); - setItemDelegateForColumn(static_cast(Playlist::Column::Genre), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Genre)); - setItemDelegateForColumn(static_cast(Playlist::Column::Composer), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Composer)); - setItemDelegateForColumn(static_cast(Playlist::Column::Performer), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Performer)); - setItemDelegateForColumn(static_cast(Playlist::Column::Grouping), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Grouping)); + setItemDelegateForColumn(static_cast(Playlist::Column::Album), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Album)); + setItemDelegateForColumn(static_cast(Playlist::Column::Artist), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Artist)); + setItemDelegateForColumn(static_cast(Playlist::Column::AlbumArtist), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::AlbumArtist)); + setItemDelegateForColumn(static_cast(Playlist::Column::Genre), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Genre)); + setItemDelegateForColumn(static_cast(Playlist::Column::Composer), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Composer)); + setItemDelegateForColumn(static_cast(Playlist::Column::Performer), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Performer)); + setItemDelegateForColumn(static_cast(Playlist::Column::Grouping), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Grouping)); setItemDelegateForColumn(static_cast(Playlist::Column::Length), new LengthItemDelegate(this)); setItemDelegateForColumn(static_cast(Playlist::Column::Filesize), new SizeItemDelegate(this)); setItemDelegateForColumn(static_cast(Playlist::Column::Filetype), new FileTypeItemDelegate(this)); @@ -230,7 +237,7 @@ void PlaylistView::SetItemDelegates() { setItemDelegateForColumn(static_cast(Playlist::Column::Source), new SongSourceDelegate(this)); #ifdef HAVE_MOODBAR - setItemDelegateForColumn(static_cast(Playlist::Column::Mood), new MoodbarItemDelegate(app_, this, this)); + setItemDelegateForColumn(static_cast(Playlist::Column::Mood), new MoodbarItemDelegate(moodbar_loader_, this, this)); #endif rating_delegate_ = new RatingItemDelegate(this); @@ -293,12 +300,12 @@ void PlaylistView::SetPlaylist(Playlist *playlist) { void PlaylistView::LoadHeaderState() { Settings s; - s.beginGroup(Playlist::kSettingsGroup); - if (s.contains("state")) { - header_state_version_ = s.value("state_version", 0).toInt(); - header_state_ = s.value("state").toByteArray(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + if (s.contains(PlaylistSettings::kState)) { + header_state_version_ = s.value(PlaylistSettings::kStateVersion, 0).toInt(); + header_state_ = s.value(PlaylistSettings::kState).toByteArray(); } - if (s.contains("column_alignments")) column_alignment_ = s.value("column_alignments").value(); + if (s.contains(PlaylistSettings::kColumnAlignments)) column_alignment_ = s.value(PlaylistSettings::kColumnAlignments).value(); s.endGroup(); if (column_alignment_.isEmpty()) { @@ -851,10 +858,10 @@ void PlaylistView::mousePressEvent(QMouseEvent *event) { if (idx.isValid()) { switch (event->button()) { case Qt::XButton1: - app_->player()->Previous(); + player_->Previous(); break; case Qt::XButton2: - app_->player()->Next(); + player_->Next(); break; case Qt::LeftButton:{ if (idx.data(Playlist::Role_CanSetRating).toBool() && !rating_locked_) { @@ -972,7 +979,7 @@ void PlaylistView::paintEvent(QPaintEvent *event) { // The cached pixmap gets invalidated in dragLeaveEvent, dropEvent and scrollContentsBy. // Draw background - if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Custom || background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Album) { + if (background_image_type_ == AppearanceSettings::BackgroundImageType::Custom || background_image_type_ == AppearanceSettings::BackgroundImageType::Album) { if (!background_image_.isNull() || !previous_background_image_.isNull()) { QPainter background_painter(viewport()); @@ -1023,23 +1030,23 @@ void PlaylistView::paintEvent(QPaintEvent *event) { background_painter.setOpacity(1.0 - previous_background_image_opacity_); } switch (background_image_position_) { - case AppearanceSettingsPage::BackgroundImagePosition::UpperLeft: + case AppearanceSettings::BackgroundImagePosition::UpperLeft: current_background_image_x_ = 0; current_background_image_y_ = 0; break; - case AppearanceSettingsPage::BackgroundImagePosition::UpperRight: + case AppearanceSettings::BackgroundImagePosition::UpperRight: current_background_image_x_ = (pb_width - cached_scaled_background_image_.width()); current_background_image_y_ = 0; break; - case AppearanceSettingsPage::BackgroundImagePosition::Middle: + case AppearanceSettings::BackgroundImagePosition::Middle: current_background_image_x_ = ((pb_width - cached_scaled_background_image_.width()) / 2); current_background_image_y_ = ((pb_height - cached_scaled_background_image_.height()) / 2); break; - case AppearanceSettingsPage::BackgroundImagePosition::BottomLeft: + case AppearanceSettings::BackgroundImagePosition::BottomLeft: current_background_image_x_ = 0; current_background_image_y_ = (pb_height - cached_scaled_background_image_.height()); break; - case AppearanceSettingsPage::BackgroundImagePosition::BottomRight: + case AppearanceSettings::BackgroundImagePosition::BottomRight: default: current_background_image_x_ = (pb_width - cached_scaled_background_image_.width()); current_background_image_y_ = (pb_height - cached_scaled_background_image_.height()); @@ -1169,32 +1176,32 @@ void PlaylistView::ReloadSettings() { Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - bars_enabled_ = s.value("show_bars", true).toBool(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + bars_enabled_ = s.value(PlaylistSettings::kShowBars, true).toBool(); #ifdef Q_OS_MACOS bool glow_effect = false; #else bool glow_effect = true; #endif - glow_enabled_ = bars_enabled_ && s.value("glow_effect", glow_effect).toBool(); - bool editmetadatainline = s.value("editmetadatainline", false).toBool(); - select_track_ = s.value("select_track", false).toBool(); - auto_sort_ = s.value("auto_sort", false).toBool(); - setAlternatingRowColors(s.value("alternating_row_colors", true).toBool()); + glow_enabled_ = bars_enabled_ && s.value(PlaylistSettings::kGlowEffect, glow_effect).toBool(); + bool editmetadatainline = s.value(PlaylistSettings::kEditMetadataInline, false).toBool(); + select_track_ = s.value(PlaylistSettings::kSelectTrack, false).toBool(); + auto_sort_ = s.value(PlaylistSettings::kAutoSort, false).toBool(); + setAlternatingRowColors(s.value(PlaylistSettings::kAlternatingRowColors, true).toBool()); s.endGroup(); - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - QVariant background_image_type_var = s.value(AppearanceSettingsPage::kBackgroundImageType); - QVariant background_image_position_var = s.value(AppearanceSettingsPage::kBackgroundImagePosition); - int background_image_maxsize = s.value(AppearanceSettingsPage::kBackgroundImageMaxSize).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + QVariant background_image_type_var = s.value(AppearanceSettings::kBackgroundImageType); + QVariant background_image_position_var = s.value(AppearanceSettings::kBackgroundImagePosition); + int background_image_maxsize = s.value(AppearanceSettings::kBackgroundImageMaxSize).toInt(); if (background_image_maxsize <= 10) background_image_maxsize = 9000; - QString background_image_filename = s.value(AppearanceSettingsPage::kBackgroundImageFilename).toString(); - bool background_image_stretch = s.value(AppearanceSettingsPage::kBackgroundImageStretch, false).toBool(); - bool background_image_do_not_cut = s.value(AppearanceSettingsPage::kBackgroundImageDoNotCut, true).toBool(); - bool background_image_keep_aspect_ratio = s.value(AppearanceSettingsPage::kBackgroundImageKeepAspectRatio, true).toBool(); - int blur_radius = s.value(AppearanceSettingsPage::kBlurRadius, AppearanceSettingsPage::kDefaultBlurRadius).toInt(); - int opacity_level = s.value(AppearanceSettingsPage::kOpacityLevel, AppearanceSettingsPage::kDefaultOpacityLevel).toInt(); - QColor playlist_playing_song_color = s.value(AppearanceSettingsPage::kPlaylistPlayingSongColor).value(); + QString background_image_filename = s.value(AppearanceSettings::kBackgroundImageFilename).toString(); + bool background_image_stretch = s.value(AppearanceSettings::kBackgroundImageStretch, false).toBool(); + bool background_image_do_not_cut = s.value(AppearanceSettings::kBackgroundImageDoNotCut, true).toBool(); + bool background_image_keep_aspect_ratio = s.value(AppearanceSettings::kBackgroundImageKeepAspectRatio, true).toBool(); + int blur_radius = s.value(AppearanceSettings::kBlurRadius, AppearanceSettings::kDefaultBlurRadius).toInt(); + int opacity_level = s.value(AppearanceSettings::kOpacityLevel, AppearanceSettings::kDefaultOpacityLevel).toInt(); + QColor playlist_playing_song_color = s.value(AppearanceSettings::kPlaylistPlayingSongColor).value(); if (playlist_playing_song_color != playlist_playing_song_color_) { row_height_ = -1; } @@ -1205,20 +1212,20 @@ void PlaylistView::ReloadSettings() { if (!glow_enabled_) StopGlowing(); // Background: - AppearanceSettingsPage::BackgroundImageType background_image_type(AppearanceSettingsPage::BackgroundImageType::Default); + AppearanceSettings::BackgroundImageType background_image_type(AppearanceSettings::BackgroundImageType::Default); if (background_image_type_var.isValid()) { - background_image_type = static_cast(background_image_type_var.toInt()); + background_image_type = static_cast(background_image_type_var.toInt()); } else { - background_image_type = AppearanceSettingsPage::BackgroundImageType::Default; + background_image_type = AppearanceSettings::BackgroundImageType::Default; } - AppearanceSettingsPage::BackgroundImagePosition background_image_position(AppearanceSettingsPage::BackgroundImagePosition::BottomRight); + AppearanceSettings::BackgroundImagePosition background_image_position(AppearanceSettings::BackgroundImagePosition::BottomRight); if (background_image_position_var.isValid()) { - background_image_position = static_cast(background_image_position_var.toInt()); + background_image_position = static_cast(background_image_position_var.toInt()); } else { - background_image_position = AppearanceSettingsPage::BackgroundImagePosition::BottomRight; + background_image_position = AppearanceSettings::BackgroundImagePosition::BottomRight; } // Check if background properties have changed. @@ -1250,10 +1257,10 @@ void PlaylistView::ReloadSettings() { blur_radius_ = blur_radius; opacity_level_ = opacity_level; - if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Custom) { + if (background_image_type_ == AppearanceSettings::BackgroundImageType::Custom) { set_background_image(QImage(background_image_filename)); } - else if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Album) { + else if (background_image_type_ == AppearanceSettings::BackgroundImageType::Album) { set_background_image(current_song_cover_art_); } else { @@ -1263,8 +1270,8 @@ void PlaylistView::ReloadSettings() { cached_scaled_background_image_ = QPixmap(); previous_background_image_ = QPixmap(); } - setProperty("default_background_enabled", background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Default); - setProperty("strawbs_background_enabled", background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Strawbs); + setProperty("default_background_enabled", background_image_type_ == AppearanceSettings::BackgroundImageType::Default); + setProperty("strawbs_background_enabled", background_image_type_ == AppearanceSettings::BackgroundImageType::Strawbs); Q_EMIT BackgroundPropertyChanged(); force_background_redraw_ = true; } @@ -1283,11 +1290,11 @@ void PlaylistView::SaveSettings() { if (!header_state_loaded_ || read_only_settings_) return; Settings s; - s.beginGroup(Playlist::kSettingsGroup); + s.beginGroup(PlaylistSettings::kSettingsGroup); s.setValue("state_version", header_state_version_); s.setValue("state", header_->SaveState()); s.setValue("column_alignments", QVariant::fromValue(column_alignment_)); - s.setValue("rating_locked", rating_locked_); + s.setValue(PlaylistSettings::kRatingLocked, rating_locked_); s.endGroup(); } @@ -1424,7 +1431,7 @@ void PlaylistView::AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResu current_song_cover_art_ = result.album_cover.image; - if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Album) { + if (background_image_type_ == AppearanceSettings::BackgroundImageType::Album) { set_background_image(result.success && result.type != AlbumCoverLoaderResult::Type::None && result.type != AlbumCoverLoaderResult::Type::Unset ? current_song_cover_art_ : QImage()); force_background_redraw_ = true; update(); diff --git a/src/playlist/playlistview.h b/src/playlist/playlistview.h index 4256fb35fe..38dcba9bbd 100644 --- a/src/playlist/playlistview.h +++ b/src/playlist/playlistview.h @@ -45,7 +45,7 @@ #include "core/song.h" #include "covermanager/albumcoverloaderresult.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" #include "playlist.h" class QWidget; @@ -66,13 +66,19 @@ class QMouseEvent; class QPaintEvent; class QTimerEvent; -class Application; +class Player; class CollectionBackend; +class PlaylistManager; +class CurrentAlbumCoverLoader; class PlaylistHeader; class PlaylistProxyStyle; class DynamicPlaylistControls; class RatingItemDelegate; +#ifdef HAVE_MOODBAR +class MoodbarLoader; +#endif + class PlaylistView : public QTreeView { Q_OBJECT @@ -82,7 +88,14 @@ class PlaylistView : public QTreeView { static ColumnAlignmentMap DefaultColumnAlignment(); - void Init(Application *app); + void Init(const SharedPtr player, + const SharedPtr playlist_manager, + const SharedPtr collection_backend, +#ifdef HAVE_MOODBAR + const SharedPtr moodbar_loader, +#endif + const SharedPtr current_albumcover_loader); + void SetItemDelegates(); void SetPlaylist(Playlist *playlist); void RemoveSelected(); @@ -90,7 +103,7 @@ class PlaylistView : public QTreeView { void SetReadOnlySettings(const bool read_only) { read_only_settings_ = read_only; } Playlist *playlist() const { return playlist_; } - AppearanceSettingsPage::BackgroundImageType background_image_type() const { return background_image_type_; } + AppearanceSettings::BackgroundImageType background_image_type() const { return background_image_type_; } Qt::Alignment column_alignment(int section) const; void ResetHeaderState(); @@ -175,7 +188,7 @@ class PlaylistView : public QTreeView { void LoadTinyPlayPausePixmaps(const int desired_size); void UpdateCachedCurrentRowPixmap(QStyleOptionViewItem option, const QModelIndex &idx); - void set_background_image_type(AppearanceSettingsPage::BackgroundImageType bg) { + void set_background_image_type(AppearanceSettings::BackgroundImageType bg) { background_image_type_ = bg; Q_EMIT BackgroundPropertyChanged(); // clazy:exclude=incorrect-emit } @@ -192,15 +205,22 @@ class PlaylistView : public QTreeView { void RepositionDynamicControls(); - Application *app_; + SharedPtr player_; + SharedPtr playlist_manager_; + SharedPtr collection_backend_; + SharedPtr current_albumcover_loader_; +#ifdef HAVE_MOODBAR + SharedPtr moodbar_loader_; +#endif + PlaylistProxyStyle *style_; Playlist *playlist_; PlaylistHeader *header_; qreal device_pixel_ratio_; - AppearanceSettingsPage::BackgroundImageType background_image_type_; + AppearanceSettings::BackgroundImageType background_image_type_; QString background_image_filename_; - AppearanceSettingsPage::BackgroundImagePosition background_image_position_; + AppearanceSettings::BackgroundImagePosition background_image_position_; int background_image_maxsize_; bool background_image_stretch_; bool background_image_do_not_cut_; diff --git a/src/playlist/songloaderinserter.cpp b/src/playlist/songloaderinserter.cpp index 92a7ed8c0f..005944f6f2 100644 --- a/src/playlist/songloaderinserter.cpp +++ b/src/playlist/songloaderinserter.cpp @@ -28,23 +28,29 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/songloader.h" +#include "core/urlhandlers.h" #include "core/taskmanager.h" +#include "core/songloader.h" #include "playlist.h" #include "songloaderinserter.h" -SongLoaderInserter::SongLoaderInserter(SharedPtr task_manager, SharedPtr collection_backend, const SharedPtr player, QObject *parent) +SongLoaderInserter::SongLoaderInserter(const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr url_handlers, + const SharedPtr collection_backend, + QObject *parent) : QObject(parent), task_manager_(task_manager), + tagreader_client_(tagreader_client), + url_handlers_(url_handlers), + collection_backend_(collection_backend), destination_(nullptr), row_(-1), play_now_(true), enqueue_(false), - enqueue_next_(false), - collection_backend_(collection_backend), - player_(player) {} + enqueue_next_(false) {} SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); } @@ -61,7 +67,7 @@ void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now, boo QObject::connect(this, &SongLoaderInserter::EffectiveLoadFinished, destination, &Playlist::UpdateItems); for (const QUrl &url : urls) { - SongLoader *loader = new SongLoader(collection_backend_, player_, this); + SongLoader *loader = new SongLoader(url_handlers_, collection_backend_, tagreader_client_, this); SongLoader::Result ret = loader->Load(url); @@ -103,7 +109,7 @@ void SongLoaderInserter::LoadAudioCD(Playlist *destination, int row, bool play_n enqueue_ = enqueue; enqueue_next_ = enqueue_next; - SongLoader *loader = new SongLoader(collection_backend_, player_, this); + SongLoader *loader = new SongLoader(url_handlers_, collection_backend_, tagreader_client_, this); QObject::connect(loader, &SongLoader::AudioCDTracksLoadFinished, this, [this, loader]() { AudioCDTracksLoadFinished(loader); }); QObject::connect(loader, &SongLoader::LoadAudioCDFinished, this, &SongLoaderInserter::AudioCDTagsLoaded); qLog(Info) << "Loading audio CD..."; diff --git a/src/playlist/songloaderinserter.h b/src/playlist/songloaderinserter.h index 531180f6d6..e94dc488ee 100644 --- a/src/playlist/songloaderinserter.h +++ b/src/playlist/songloaderinserter.h @@ -29,12 +29,14 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" +class TaskManager; +class UrlHandlers; class Player; +class TagReaderClient; class SongLoader; -class TaskManager; class CollectionBackendInterface; class Playlist; @@ -42,7 +44,12 @@ class SongLoaderInserter : public QObject { Q_OBJECT public: - explicit SongLoaderInserter(SharedPtr task_manager, SharedPtr collection_backend, const SharedPtr player, QObject *parent = nullptr); + explicit SongLoaderInserter(const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr url_handlers, + const SharedPtr collection_backend, + QObject *parent = nullptr); + ~SongLoaderInserter() override; void Load(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next, const QList &urls); @@ -63,7 +70,10 @@ class SongLoaderInserter : public QObject { void AsyncLoad(); private: - SharedPtr task_manager_; + const SharedPtr task_manager_; + const SharedPtr tagreader_client_; + const SharedPtr url_handlers_; + const SharedPtr collection_backend_; Playlist *destination_; int row_; @@ -74,8 +84,6 @@ class SongLoaderInserter : public QObject { SongList songs_; QList pending_; - SharedPtr collection_backend_; - const SharedPtr player_; }; #endif // SONGLOADERINSERTER_H diff --git a/src/playlistparsers/asxiniparser.cpp b/src/playlistparsers/asxiniparser.cpp index eee51b0c77..9d8116fe73 100644 --- a/src/playlistparsers/asxiniparser.cpp +++ b/src/playlistparsers/asxiniparser.cpp @@ -26,8 +26,8 @@ #include #include -#include "core/shared_ptr.h" -#include "settings/playlistsettingspage.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "parserbase.h" #include "asxiniparser.h" @@ -35,8 +35,8 @@ using namespace Qt::Literals::StringLiterals; class CollectionBackendInterface; -AsxIniParser::AsxIniParser(SharedPtr collection_backend, QObject *parent) - : ParserBase(collection_backend, parent) {} +AsxIniParser::AsxIniParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : ParserBase(tagreader_client, collection_backend, parent) {} bool AsxIniParser::TryMagic(const QByteArray &data) const { return data.toLower().contains("[reference]"); @@ -66,7 +66,7 @@ SongList AsxIniParser::Load(QIODevice *device, const QString &playlist_path, con } -void AsxIniParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void AsxIniParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { QTextStream s(device); s << "[Reference]" << Qt::endl; diff --git a/src/playlistparsers/asxiniparser.h b/src/playlistparsers/asxiniparser.h index 25886e49b9..12ca4e5d22 100644 --- a/src/playlistparsers/asxiniparser.h +++ b/src/playlistparsers/asxiniparser.h @@ -29,19 +29,20 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "parserbase.h" class QIODevice; +class TagReaderClient; class CollectionBackendInterface; class AsxIniParser : public ParserBase { Q_OBJECT public: - explicit AsxIniParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit AsxIniParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("ASX/INI"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("asxini"); } @@ -51,7 +52,7 @@ class AsxIniParser : public ParserBase { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; }; #endif // ASXINIPARSER_H diff --git a/src/playlistparsers/asxparser.cpp b/src/playlistparsers/asxparser.cpp index 6ae590dfda..bf64a723fa 100644 --- a/src/playlistparsers/asxparser.cpp +++ b/src/playlistparsers/asxparser.cpp @@ -29,9 +29,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "utilities/xmlutils.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "xmlparser.h" #include "asxparser.h" @@ -39,8 +39,8 @@ using namespace Qt::Literals::StringLiterals; class CollectionBackendInterface; -ASXParser::ASXParser(SharedPtr collection_backend, QObject *parent) - : XMLParser(collection_backend, parent) {} +ASXParser::ASXParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : XMLParser(tagreader_client, collection_backend, parent) {} SongList ASXParser::Load(QIODevice *device, const QString &playlist_path, const QDir &dir, const bool collection_lookup) const { @@ -133,7 +133,7 @@ Song ASXParser::ParseTrack(QXmlStreamReader *reader, const QDir &dir, const bool } -void ASXParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void ASXParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { Q_UNUSED(dir) Q_UNUSED(path_type) diff --git a/src/playlistparsers/asxparser.h b/src/playlistparsers/asxparser.h index 095ab83577..e437dc2bc0 100644 --- a/src/playlistparsers/asxparser.h +++ b/src/playlistparsers/asxparser.h @@ -29,21 +29,22 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "xmlparser.h" class QIODevice; class QXmlStreamReader; +class TagReaderClient; class CollectionBackendInterface; class ASXParser : public XMLParser { Q_OBJECT public: - explicit ASXParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit ASXParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("ASX"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("asx"); } @@ -53,7 +54,7 @@ class ASXParser : public XMLParser { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; private: Song ParseTrack(QXmlStreamReader *reader, const QDir &dir, const bool collection_lookup) const; diff --git a/src/playlistparsers/cueparser.cpp b/src/playlistparsers/cueparser.cpp index d3b0e3128b..7aeaf78b19 100644 --- a/src/playlistparsers/cueparser.cpp +++ b/src/playlistparsers/cueparser.cpp @@ -32,11 +32,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/timeconstants.h" #include "core/logging.h" -#include "utilities/timeconstants.h" #include "utilities/textencodingutils.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "parserbase.h" #include "cueparser.h" @@ -63,8 +63,8 @@ constexpr char kDate[] = "date"; constexpr char kDisc[] = "discnumber"; } // namespace -CueParser::CueParser(SharedPtr collection_backend, QObject *parent) - : ParserBase(collection_backend, parent) {} +CueParser::CueParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : ParserBase(tagreader_client, collection_backend, parent) {} SongList CueParser::Load(QIODevice *device, const QString &playlist_path, const QDir &dir, const bool collection_lookup) const { @@ -378,7 +378,7 @@ qint64 CueParser::IndexToMarker(const QString &index) { } -void CueParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void CueParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { Q_UNUSED(songs); Q_UNUSED(device); diff --git a/src/playlistparsers/cueparser.h b/src/playlistparsers/cueparser.h index 35c30ed710..9af943ebef 100644 --- a/src/playlistparsers/cueparser.h +++ b/src/playlistparsers/cueparser.h @@ -31,12 +31,13 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "parserbase.h" class QIODevice; +class TagReaderClient; class CollectionBackendInterface; // This parser will try to detect the real encoding of a .cue file @@ -45,7 +46,7 @@ class CueParser : public ParserBase { Q_OBJECT public: - explicit CueParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit CueParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("CUE"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("cue"); } @@ -56,7 +57,7 @@ class CueParser : public ParserBase { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; static QString FindCueFilename(const QString &filename); diff --git a/src/playlistparsers/m3uparser.cpp b/src/playlistparsers/m3uparser.cpp index 8c5ef93ede..67fd731f1a 100644 --- a/src/playlistparsers/m3uparser.cpp +++ b/src/playlistparsers/m3uparser.cpp @@ -27,11 +27,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/settings.h" -#include "utilities/timeconstants.h" -#include "settings/playlistsettingspage.h" +#include "constants/timeconstants.h" +#include "constants/playlistsettings.h" #include "parserbase.h" #include "m3uparser.h" @@ -39,8 +39,8 @@ using namespace Qt::Literals::StringLiterals; class CollectionBackendInterface; -M3UParser::M3UParser(SharedPtr collection_backend, QObject *parent) - : ParserBase(collection_backend, parent) {} +M3UParser::M3UParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : ParserBase(tagreader_client, collection_backend, parent) {} SongList M3UParser::Load(QIODevice *device, const QString &playlist_path, const QDir &dir, const bool collection_lookup) const { @@ -125,13 +125,13 @@ bool M3UParser::ParseMetadata(const QString &line, M3UParser::Metadata *metadata } -void M3UParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void M3UParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { device->write("#EXTM3U\n"); Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - bool write_metadata = s.value("write_metadata", true).toBool(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + bool write_metadata = s.value(PlaylistSettings::kWriteMetadata, true).toBool(); s.endGroup(); for (const Song &song : songs) { diff --git a/src/playlistparsers/m3uparser.h b/src/playlistparsers/m3uparser.h index c270d7136d..ecf1ca5c01 100644 --- a/src/playlistparsers/m3uparser.h +++ b/src/playlistparsers/m3uparser.h @@ -30,19 +30,20 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "parserbase.h" class QIODevice; +class TagReaderClient; class CollectionBackendInterface; class M3UParser : public ParserBase { Q_OBJECT public: - explicit M3UParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit M3UParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("M3U"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("m3u") << QStringLiteral("m3u8"); } @@ -53,7 +54,7 @@ class M3UParser : public ParserBase { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; private: enum class M3UType { diff --git a/src/playlistparsers/parserbase.cpp b/src/playlistparsers/parserbase.cpp index 51b7d15a1c..3bcf0abe60 100644 --- a/src/playlistparsers/parserbase.cpp +++ b/src/playlistparsers/parserbase.cpp @@ -27,17 +27,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "tagreader/tagreaderclient.h" #include "collection/collectionbackend.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "parserbase.h" using namespace Qt::Literals::StringLiterals; -ParserBase::ParserBase(SharedPtr collection_backend, QObject *parent) - : QObject(parent), collection_backend_(collection_backend) {} +ParserBase::ParserBase(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : QObject(parent), tagreader_client_(tagreader_client), collection_backend_(collection_backend) {} void ParserBase::LoadSong(const QString &filename_or_url, const qint64 beginning, const int track, const QDir &dir, Song *song, const bool collection_lookup) const { @@ -105,9 +105,11 @@ void ParserBase::LoadSong(const QString &filename_or_url, const qint64 beginning } } - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(filename, song); - if (!result.success()) { - qLog(Error) << "Could not read file" << filename << result.error_string(); + if (tagreader_client_) { + const TagReaderResult result = tagreader_client_->ReadFileBlocking(filename, song); + if (!result.success()) { + qLog(Error) << "Could not read file" << filename << result.error_string(); + } } } @@ -121,16 +123,16 @@ Song ParserBase::LoadSong(const QString &filename_or_url, const qint64 beginning } -QString ParserBase::URLOrFilename(const QUrl &url, const QDir &dir, const PlaylistSettingsPage::PathType path_type) { +QString ParserBase::URLOrFilename(const QUrl &url, const QDir &dir, const PlaylistSettings::PathType path_type) { if (!url.isLocalFile()) return url.toString(); const QString filename = url.toLocalFile(); - if (path_type != PlaylistSettingsPage::PathType::Absolute && QDir::isAbsolutePath(filename)) { + if (path_type != PlaylistSettings::PathType::Absolute && QDir::isAbsolutePath(filename)) { const QString relative = dir.relativeFilePath(filename); - if (!relative.startsWith("../"_L1) || path_type == PlaylistSettingsPage::PathType::Relative) { + if (!relative.startsWith("../"_L1) || path_type == PlaylistSettings::PathType::Relative) { return relative; } } diff --git a/src/playlistparsers/parserbase.h b/src/playlistparsers/parserbase.h index a0cd2d97fb..727cbc89dc 100644 --- a/src/playlistparsers/parserbase.h +++ b/src/playlistparsers/parserbase.h @@ -32,18 +32,19 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" class QIODevice; class CollectionBackendInterface; +class TagReaderClient; class ParserBase : public QObject { Q_OBJECT public: - explicit ParserBase(SharedPtr collection_backend, QObject *parent = nullptr); + explicit ParserBase(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); virtual QString name() const = 0; virtual QStringList file_extensions() const = 0; @@ -59,7 +60,7 @@ class ParserBase : public QObject { // Any playlist parser may decide to leave out some entries if it finds them incomplete or invalid. // This means that the final resulting SongList should be considered valid (at least from the parser's point of view). virtual SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const = 0; - virtual void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const = 0; + virtual void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const = 0; Q_SIGNALS: void Error(const QString &error) const; @@ -73,10 +74,11 @@ class ParserBase : public QObject { // If the URL is a file:// URL then returns its path, absolute or relative to the directory depending on the path_type option. // Otherwise, returns the URL as is. This function should always be used when saving a playlist. - static QString URLOrFilename(const QUrl &url, const QDir &dir, const PlaylistSettingsPage::PathType path_type); + static QString URLOrFilename(const QUrl &url, const QDir &dir, const PlaylistSettings::PathType path_type); private: - SharedPtr collection_backend_; + const SharedPtr tagreader_client_; + const SharedPtr collection_backend_; }; #endif // PARSERBASE_H diff --git a/src/playlistparsers/playlistparser.cpp b/src/playlistparsers/playlistparser.cpp index a87e0a6f19..62b3decf87 100644 --- a/src/playlistparsers/playlistparser.cpp +++ b/src/playlistparsers/playlistparser.cpp @@ -29,9 +29,9 @@ #include #include +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "settings/playlistsettingspage.h" #include "playlistparser.h" #include "parserbase.h" #include "asxiniparser.h" @@ -46,15 +46,15 @@ using namespace Qt::Literals::StringLiterals; const int PlaylistParser::kMagicSize = 512; -PlaylistParser::PlaylistParser(SharedPtr collection_backend, QObject *parent) : QObject(parent), default_parser_(nullptr) { +PlaylistParser::PlaylistParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) : QObject(parent), default_parser_(nullptr) { - AddParser(new XSPFParser(collection_backend, this)); - AddParser(new M3UParser(collection_backend, this)); - AddParser(new PLSParser(collection_backend, this)); - AddParser(new ASXParser(collection_backend, this)); - AddParser(new AsxIniParser(collection_backend, this)); - AddParser(new CueParser(collection_backend, this)); - AddParser(new WplParser(collection_backend, this)); + AddParser(new XSPFParser(tagreader_client, collection_backend, this)); + AddParser(new M3UParser(tagreader_client, collection_backend, this)); + AddParser(new PLSParser(tagreader_client, collection_backend, this)); + AddParser(new ASXParser(tagreader_client, collection_backend, this)); + AddParser(new AsxIniParser(tagreader_client, collection_backend, this)); + AddParser(new CueParser(tagreader_client, collection_backend, this)); + AddParser(new WplParser(tagreader_client, collection_backend, this)); } @@ -214,7 +214,7 @@ SongList PlaylistParser::LoadFromDevice(QIODevice *device, const QString &path_h } -void PlaylistParser::Save(const SongList &songs, const QString &filename, const PlaylistSettingsPage::PathType path_type) const { +void PlaylistParser::Save(const SongList &songs, const QString &filename, const PlaylistSettings::PathType path_type) const { QFileInfo fileinfo(filename); QDir dir(fileinfo.path()); @@ -233,10 +233,10 @@ void PlaylistParser::Save(const SongList &songs, const QString &filename, const return; } - if (path_type == PlaylistSettingsPage::PathType::Absolute && dir.path() != dir.absolutePath()) { + if (path_type == PlaylistSettings::PathType::Absolute && dir.path() != dir.absolutePath()) { dir.setPath(dir.absolutePath()); } - else if (path_type != PlaylistSettingsPage::PathType::Absolute && !dir.canonicalPath().isEmpty() && dir.path() != dir.canonicalPath()) { + else if (path_type != PlaylistSettings::PathType::Absolute && !dir.canonicalPath().isEmpty() && dir.path() != dir.canonicalPath()) { dir.setPath(dir.canonicalPath()); } diff --git a/src/playlistparsers/playlistparser.h b/src/playlistparsers/playlistparser.h index c6842274d9..215324f510 100644 --- a/src/playlistparsers/playlistparser.h +++ b/src/playlistparsers/playlistparser.h @@ -30,11 +30,12 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" class QIODevice; +class TagReaderClient; class CollectionBackendInterface; class ParserBase; @@ -42,7 +43,7 @@ class PlaylistParser : public QObject { Q_OBJECT public: - explicit PlaylistParser(SharedPtr collection_backend = nullptr, QObject *parent = nullptr); + explicit PlaylistParser(SharedPtr tagreader_client, SharedPtr collection_backend = nullptr, QObject *parent = nullptr); enum class Type { Load, @@ -65,7 +66,7 @@ class PlaylistParser : public QObject { SongList LoadFromFile(const QString &filename) const; SongList LoadFromDevice(QIODevice *device, const QString &path_hint = QString(), const QDir &dir_hint = QDir()) const; - void Save(const SongList &songs, const QString &filename, const PlaylistSettingsPage::PathType) const; + void Save(const SongList &songs, const QString &filename, const PlaylistSettings::PathType) const; Q_SIGNALS: void Error(const QString &error) const; diff --git a/src/playlistparsers/plsparser.cpp b/src/playlistparsers/plsparser.cpp index 46b2cc4838..be608b3293 100644 --- a/src/playlistparsers/plsparser.cpp +++ b/src/playlistparsers/plsparser.cpp @@ -28,9 +28,9 @@ #include #include -#include "core/shared_ptr.h" -#include "utilities/timeconstants.h" -#include "settings/playlistsettingspage.h" +#include "includes/shared_ptr.h" +#include "constants/timeconstants.h" +#include "constants/playlistsettings.h" #include "parserbase.h" #include "plsparser.h" @@ -38,8 +38,8 @@ using namespace Qt::Literals::StringLiterals; class CollectionBackendInterface; -PLSParser::PLSParser(SharedPtr collection_backend, QObject *parent) - : ParserBase(collection_backend, parent) {} +PLSParser::PLSParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : ParserBase(tagreader_client, collection_backend, parent) {} SongList PLSParser::Load(QIODevice *device, const QString &playlist_path, const QDir &dir, const bool collection_lookup) const { @@ -83,7 +83,7 @@ SongList PLSParser::Load(QIODevice *device, const QString &playlist_path, const } -void PLSParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void PLSParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { QTextStream s(device); s << "[playlist]" << Qt::endl; diff --git a/src/playlistparsers/plsparser.h b/src/playlistparsers/plsparser.h index efca350333..65e8598073 100644 --- a/src/playlistparsers/plsparser.h +++ b/src/playlistparsers/plsparser.h @@ -29,19 +29,20 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "parserbase.h" class QIODevice; +class TagReaderClient; class CollectionBackendInterface; class PLSParser : public ParserBase { Q_OBJECT public: - explicit PLSParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit PLSParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("PLS"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("pls"); } @@ -52,7 +53,7 @@ class PLSParser : public ParserBase { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; }; #endif // PLSPARSER_H diff --git a/src/playlistparsers/wplparser.cpp b/src/playlistparsers/wplparser.cpp index 0b6a873050..b5184d6b91 100644 --- a/src/playlistparsers/wplparser.cpp +++ b/src/playlistparsers/wplparser.cpp @@ -29,9 +29,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "utilities/xmlutils.h" -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "xmlparser.h" #include "wplparser.h" @@ -39,8 +39,8 @@ using namespace Qt::Literals::StringLiterals; class CollectionBackendInterface; -WplParser::WplParser(SharedPtr collection_backend, QObject *parent) - : XMLParser(collection_backend, parent) {} +WplParser::WplParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : XMLParser(tagreader_client, collection_backend, parent) {} bool WplParser::TryMagic(const QByteArray &data) const { return data.contains(""); @@ -98,7 +98,7 @@ void WplParser::ParseSeq(const QDir &dir, QXmlStreamReader *reader, SongList *so } -void WplParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void WplParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { QXmlStreamWriter writer(device); writer.setAutoFormatting(true); diff --git a/src/playlistparsers/wplparser.h b/src/playlistparsers/wplparser.h index 6561e4c171..41e483b03c 100644 --- a/src/playlistparsers/wplparser.h +++ b/src/playlistparsers/wplparser.h @@ -29,22 +29,23 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "xmlparser.h" class QIODevice; class QXmlStreamReader; class QXmlStreamWriter; +class TagReaderClient; class CollectionBackendInterface; class WplParser : public XMLParser { Q_OBJECT public: - explicit WplParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit WplParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("WPL"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("wpl"); } @@ -55,7 +56,7 @@ class WplParser : public XMLParser { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path, const QDir &dir, const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; private: void ParseSeq(const QDir &dir, QXmlStreamReader *reader, SongList *songs, const bool collection_lookup) const; diff --git a/src/playlistparsers/xmlparser.cpp b/src/playlistparsers/xmlparser.cpp index 90c188e6c3..d9df7b5055 100644 --- a/src/playlistparsers/xmlparser.cpp +++ b/src/playlistparsers/xmlparser.cpp @@ -20,11 +20,11 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "parserbase.h" #include "xmlparser.h" class CollectionBackendInterface; -XMLParser::XMLParser(SharedPtr collection_backend, QObject *parent) - : ParserBase(collection_backend, parent) {} +XMLParser::XMLParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : ParserBase(tagreader_client, collection_backend, parent) {} diff --git a/src/playlistparsers/xmlparser.h b/src/playlistparsers/xmlparser.h index 4bca7e061a..c731a9a46d 100644 --- a/src/playlistparsers/xmlparser.h +++ b/src/playlistparsers/xmlparser.h @@ -28,16 +28,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "parserbase.h" +class TagReaderClient; class CollectionBackendInterface; class XMLParser : public ParserBase { Q_OBJECT protected: - explicit XMLParser(SharedPtr collection_backend, QObject *parent); + explicit XMLParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent); class StreamElement { public: diff --git a/src/playlistparsers/xspfparser.cpp b/src/playlistparsers/xspfparser.cpp index feb9c2d2d5..da3f2be4f2 100644 --- a/src/playlistparsers/xspfparser.cpp +++ b/src/playlistparsers/xspfparser.cpp @@ -29,11 +29,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/settings.h" #include "utilities/xmlutils.h" -#include "utilities/timeconstants.h" -#include "settings/playlistsettingspage.h" +#include "constants/timeconstants.h" +#include "constants/playlistsettings.h" #include "xmlparser.h" #include "xspfparser.h" @@ -41,8 +41,8 @@ using namespace Qt::Literals::StringLiterals; class CollectionBackendInterface; -XSPFParser::XSPFParser(SharedPtr collection_backend, QObject *parent) - : XMLParser(collection_backend, parent) {} +XSPFParser::XSPFParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent) + : XMLParser(tagreader_client, collection_backend, parent) {} SongList XSPFParser::Load(QIODevice *device, const QString &playlist_path, const QDir &dir, const bool collection_lookup) const { @@ -140,7 +140,7 @@ Song XSPFParser::ParseTrack(QXmlStreamReader *reader, const QDir &dir, const boo } -void XSPFParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettingsPage::PathType path_type) const { +void XSPFParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, const PlaylistSettings::PathType path_type) const { QXmlStreamWriter writer(device); writer.setAutoFormatting(true); @@ -151,8 +151,8 @@ void XSPFParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, writer.writeDefaultNamespace("http://xspf.org/ns/0/"_L1); Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); - bool write_metadata = s.value("write_metadata", true).toBool(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + bool write_metadata = s.value(PlaylistSettings::kWriteMetadata, true).toBool(); s.endGroup(); StreamElement tracklist(u"trackList"_s, &writer); diff --git a/src/playlistparsers/xspfparser.h b/src/playlistparsers/xspfparser.h index 84a3014d1b..5ef4de60e6 100644 --- a/src/playlistparsers/xspfparser.h +++ b/src/playlistparsers/xspfparser.h @@ -29,20 +29,21 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" +#include "constants/playlistsettings.h" #include "core/song.h" -#include "settings/playlistsettingspage.h" #include "xmlparser.h" class QIODevice; class QXmlStreamReader; +class TagReaderClient; class CollectionBackendInterface; class XSPFParser : public XMLParser { Q_OBJECT public: - explicit XSPFParser(SharedPtr collection_backend, QObject *parent = nullptr); + explicit XSPFParser(SharedPtr tagreader_client, SharedPtr collection_backend, QObject *parent = nullptr); QString name() const override { return QStringLiteral("XSPF"); } QStringList file_extensions() const override { return QStringList() << QStringLiteral("xspf"); } @@ -52,7 +53,7 @@ class XSPFParser : public XMLParser { bool TryMagic(const QByteArray &data) const override; SongList Load(QIODevice *device, const QString &playlist_path = QLatin1String(""), const QDir &dir = QDir(), const bool collection_lookup = true) const override; - void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettingsPage::PathType path_type = PlaylistSettingsPage::PathType::Automatic) const override; + void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir(), const PlaylistSettings::PathType path_type = PlaylistSettings::PathType::Automatic) const override; private: Song ParseTrack(QXmlStreamReader *reader, const QDir &dir, const bool collection_lookup) const; diff --git a/src/qobuz/qobuzbaserequest.cpp b/src/qobuz/qobuzbaserequest.cpp index 9530c73526..bb173d9a1f 100644 --- a/src/qobuz/qobuzbaserequest.cpp +++ b/src/qobuz/qobuzbaserequest.cpp @@ -37,8 +37,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "qobuzservice.h" #include "qobuzbaserequest.h" diff --git a/src/qobuz/qobuzbaserequest.h b/src/qobuz/qobuzbaserequest.h index f633753d07..5a62b4d3eb 100644 --- a/src/qobuz/qobuzbaserequest.h +++ b/src/qobuz/qobuzbaserequest.h @@ -34,7 +34,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "qobuzservice.h" diff --git a/src/qobuz/qobuzfavoriterequest.cpp b/src/qobuz/qobuzfavoriterequest.cpp index f539f850d2..3269bc4af2 100644 --- a/src/qobuz/qobuzfavoriterequest.cpp +++ b/src/qobuz/qobuzfavoriterequest.cpp @@ -28,8 +28,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "qobuzservice.h" diff --git a/src/qobuz/qobuzfavoriterequest.h b/src/qobuz/qobuzfavoriterequest.h index 5835dcf4e7..0125eb8efc 100644 --- a/src/qobuz/qobuzfavoriterequest.h +++ b/src/qobuz/qobuzfavoriterequest.h @@ -28,7 +28,7 @@ #include #include "qobuzbaserequest.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QNetworkReply; diff --git a/src/qobuz/qobuzrequest.cpp b/src/qobuz/qobuzrequest.cpp index d30c33a60b..694aa37bc7 100644 --- a/src/qobuz/qobuzrequest.cpp +++ b/src/qobuz/qobuzrequest.cpp @@ -36,12 +36,11 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/networkaccessmanager.h" #include "core/song.h" -#include "core/application.h" -#include "utilities/timeconstants.h" +#include "core/networkaccessmanager.h" +#include "constants/timeconstants.h" #include "utilities/imageutils.h" #include "utilities/coverutils.h" #include "qobuzservice.h" @@ -61,11 +60,10 @@ constexpr int kMaxConcurrentAlbumCoverRequests = 1; constexpr int kFlushRequestsDelay = 200; } // namespace -QobuzRequest::QobuzRequest(QobuzService *service, QobuzUrlHandler *url_handler, Application *app, SharedPtr network, const Type query_type, QObject *parent) +QobuzRequest::QobuzRequest(QobuzService *service, QobuzUrlHandler *url_handler, SharedPtr network, const Type query_type, QObject *parent) : QobuzBaseRequest(service, network, parent), service_(service), url_handler_(url_handler), - app_(app), network_(network), timer_flush_requests_(new QTimer(this)), query_type_(query_type), diff --git a/src/qobuz/qobuzrequest.h b/src/qobuz/qobuzrequest.h index 6f99fa1045..96eaec8745 100644 --- a/src/qobuz/qobuzrequest.h +++ b/src/qobuz/qobuzrequest.h @@ -37,13 +37,12 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "qobuzbaserequest.h" class QNetworkReply; class QTimer; -class Application; class NetworkAccessManager; class QobuzService; class QobuzUrlHandler; @@ -53,7 +52,7 @@ class QobuzRequest : public QobuzBaseRequest { public: - explicit QobuzRequest(QobuzService *service, QobuzUrlHandler *url_handler, Application *app, SharedPtr network, const Type query_type, QObject *parent = nullptr); + explicit QobuzRequest(QobuzService *service, QobuzUrlHandler *url_handler, SharedPtr network, const Type query_type, QObject *parent = nullptr); ~QobuzRequest() override; void ReloadSettings(); @@ -173,7 +172,6 @@ class QobuzRequest : public QobuzBaseRequest { QobuzService *service_; QobuzUrlHandler *url_handler_; - Application *app_; SharedPtr network_; QTimer *timer_flush_requests_; diff --git a/src/qobuz/qobuzservice.cpp b/src/qobuz/qobuzservice.cpp index 63d9ba98e2..0216c6b1ab 100644 --- a/src/qobuz/qobuzservice.cpp +++ b/src/qobuz/qobuzservice.cpp @@ -38,14 +38,13 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" -#include "core/player.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" #include "core/database.h" #include "core/song.h" #include "core/settings.h" +#include "core/urlhandlers.h" #include "utilities/macaddrutils.h" #include "streaming/streamingsearchview.h" #include "collection/collectionbackend.h" @@ -56,8 +55,7 @@ #include "qobuzrequest.h" #include "qobuzfavoriterequest.h" #include "qobuzstreamurlrequest.h" -#include "settings/settingsdialog.h" -#include "settings/qobuzsettingspage.h" +#include "constants/qobuzsettings.h" using namespace Qt::Literals::StringLiterals; using std::make_shared; @@ -78,11 +76,15 @@ constexpr char kSongsTable[] = "qobuz_songs"; } // namespace -QobuzService::QobuzService(Application *app, QObject *parent) - : StreamingService(Song::Source::Qobuz, u"Qobuz"_s, u"qobuz"_s, QLatin1String(QobuzSettingsPage::kSettingsGroup), SettingsDialog::Page::Qobuz, app, parent), - app_(app), - network_(app->network()), - url_handler_(new QobuzUrlHandler(app, this)), +QobuzService::QobuzService(SharedPtr task_manager, + SharedPtr database, + SharedPtr network, + SharedPtr url_handlers, + SharedPtr albumcover_loader, + QObject *parent) + : StreamingService(Song::Source::Qobuz, u"Qobuz"_s, u"qobuz"_s, QLatin1String(QobuzSettings::kSettingsGroup), parent), + network_(network), + url_handler_(new QobuzUrlHandler(task_manager, this)), artists_collection_backend_(nullptr), albums_collection_backend_(nullptr), songs_collection_backend_(nullptr), @@ -108,26 +110,26 @@ QobuzService::QobuzService(Application *app, QObject *parent) login_attempts_(0), next_stream_url_request_id_(0) { - app->player()->RegisterUrlHandler(url_handler_); + url_handlers->Register(url_handler_); // Backends artists_collection_backend_ = make_shared(); - artists_collection_backend_->moveToThread(app_->database()->thread()); - artists_collection_backend_->Init(app_->database(), app->task_manager(), Song::Source::Qobuz, QLatin1String(kArtistsSongsTable)); + artists_collection_backend_->moveToThread(database->thread()); + artists_collection_backend_->Init(database, task_manager, Song::Source::Qobuz, QLatin1String(kArtistsSongsTable)); albums_collection_backend_ = make_shared(); - albums_collection_backend_->moveToThread(app_->database()->thread()); - albums_collection_backend_->Init(app_->database(), app->task_manager(), Song::Source::Qobuz, QLatin1String(kAlbumsSongsTable)); + albums_collection_backend_->moveToThread(database->thread()); + albums_collection_backend_->Init(database, task_manager, Song::Source::Qobuz, QLatin1String(kAlbumsSongsTable)); songs_collection_backend_ = make_shared(); - songs_collection_backend_->moveToThread(app_->database()->thread()); - songs_collection_backend_->Init(app_->database(), app->task_manager(), Song::Source::Qobuz, QLatin1String(kSongsTable)); + songs_collection_backend_->moveToThread(database->thread()); + songs_collection_backend_->Init(database, task_manager, Song::Source::Qobuz, QLatin1String(kSongsTable)); // Models - artists_collection_model_ = new CollectionModel(artists_collection_backend_, app_, this); - albums_collection_model_ = new CollectionModel(albums_collection_backend_, app_, this); - songs_collection_model_ = new CollectionModel(songs_collection_backend_, app_, this); + artists_collection_model_ = new CollectionModel(artists_collection_backend_, albumcover_loader, this); + albums_collection_model_ = new CollectionModel(albums_collection_backend_, albumcover_loader, this); + songs_collection_model_ = new CollectionModel(songs_collection_backend_, albumcover_loader, this); // Search @@ -205,35 +207,31 @@ void QobuzService::ExitReceived() { } -void QobuzService::ShowConfig() { - app_->OpenSettingsDialogAtPage(SettingsDialog::Page::Qobuz); -} - void QobuzService::ReloadSettings() { Settings s; - s.beginGroup(QobuzSettingsPage::kSettingsGroup); + s.beginGroup(QobuzSettings::kSettingsGroup); - app_id_ = s.value("app_id").toString(); - app_secret_ = s.value("app_secret").toString(); + app_id_ = s.value(QobuzSettings::kAppId).toString(); + app_secret_ = s.value(QobuzSettings::kAppSecret).toString(); - const bool base64_secret = s.value("base64secret", false).toBool();; + const bool base64_secret = s.value(QobuzSettings::kBase64Secret, false).toBool();; - username_ = s.value("username").toString(); - QByteArray password = s.value("password").toByteArray(); + username_ = s.value(QobuzSettings::kUsername).toString(); + QByteArray password = s.value(QobuzSettings::kPassword).toByteArray(); if (password.isEmpty()) password_.clear(); else password_ = QString::fromUtf8(QByteArray::fromBase64(password)); - format_ = s.value("format", 27).toInt(); - search_delay_ = s.value("searchdelay", 1500).toInt(); - artistssearchlimit_ = s.value("artistssearchlimit", 4).toInt(); - albumssearchlimit_ = s.value("albumssearchlimit", 10).toInt(); - songssearchlimit_ = s.value("songssearchlimit", 10).toInt(); - download_album_covers_ = s.value("downloadalbumcovers", true).toBool(); + format_ = s.value(QobuzSettings::kFormat, 27).toInt(); + search_delay_ = s.value(QobuzSettings::kSearchDelay, 1500).toInt(); + artistssearchlimit_ = s.value(QobuzSettings::kArtistsSearchLimit, 4).toInt(); + albumssearchlimit_ = s.value(QobuzSettings::kAlbumsSearchLimit, 10).toInt(); + songssearchlimit_ = s.value(QobuzSettings::kSongsSearchLimit, 10).toInt(); + download_album_covers_ = s.value(QobuzSettings::kDownloadAlbumCovers, true).toBool(); - user_id_ = s.value("user_id").toInt(); - device_id_ = s.value("device_id").toString(); - user_auth_token_ = s.value("user_auth_token").toString(); + user_id_ = s.value(QobuzSettings::kUserId).toInt(); + device_id_ = s.value(QobuzSettings::kDeviceId).toString(); + user_auth_token_ = s.value(QobuzSettings::kUserAuthToken).toString(); s.endGroup(); @@ -434,11 +432,11 @@ void QobuzService::HandleAuthReply(QNetworkReply *reply) { credential_id_ = obj_credential["id"_L1].toInt(); Settings s; - s.beginGroup(QobuzSettingsPage::kSettingsGroup); - s.setValue("user_auth_token", user_auth_token_); - s.setValue("user_id", user_id_); - s.setValue("credential_id", credential_id_); - s.setValue("device_id", device_id_); + s.beginGroup(QobuzSettings::kSettingsGroup); + s.setValue(QobuzSettings::kUserAuthToken, user_auth_token_); + s.setValue(QobuzSettings::kUserId, user_id_); + s.setValue(QobuzSettings::kCredentialsId, credential_id_); + s.setValue(QobuzSettings::kDeviceId, device_id_); s.endGroup(); qLog(Debug) << "Qobuz: Login successful" << "user id" << user_id_ << "device id" << device_id_; @@ -459,7 +457,7 @@ void QobuzService::Logout() { credential_id_ = -1; Settings s; - s.beginGroup(QobuzSettingsPage::kSettingsGroup); + s.beginGroup(QobuzSettings::kSettingsGroup); s.remove("user_id"); s.remove("credential_id"); s.remove("device_id"); @@ -520,7 +518,7 @@ void QobuzService::GetArtists() { } ResetArtistsRequest(); - artists_request_.reset(new QobuzRequest(this, url_handler_, app_, network_, QobuzBaseRequest::Type::FavouriteArtists), [](QobuzRequest *request) { request->deleteLater(); }); + artists_request_.reset(new QobuzRequest(this, url_handler_, network_, QobuzBaseRequest::Type::FavouriteArtists), [](QobuzRequest *request) { request->deleteLater(); }); QObject::connect(&*artists_request_, &QobuzRequest::Results, this, &QobuzService::ArtistsResultsReceived); QObject::connect(&*artists_request_, &QobuzRequest::UpdateStatus, this, &QobuzService::ArtistsUpdateStatusReceived); QObject::connect(&*artists_request_, &QobuzRequest::UpdateProgress, this, &QobuzService::ArtistsUpdateProgressReceived); @@ -570,7 +568,7 @@ void QobuzService::GetAlbums() { } ResetAlbumsRequest(); - albums_request_.reset(new QobuzRequest(this, url_handler_, app_, network_, QobuzBaseRequest::Type::FavouriteAlbums), [](QobuzRequest *request) { request->deleteLater(); }); + albums_request_.reset(new QobuzRequest(this, url_handler_, network_, QobuzBaseRequest::Type::FavouriteAlbums), [](QobuzRequest *request) { request->deleteLater(); }); QObject::connect(&*albums_request_, &QobuzRequest::Results, this, &QobuzService::AlbumsResultsReceived); QObject::connect(&*albums_request_, &QobuzRequest::UpdateStatus, this, &QobuzService::AlbumsUpdateStatusReceived); QObject::connect(&*albums_request_, &QobuzRequest::UpdateProgress, this, &QobuzService::AlbumsUpdateProgressReceived); @@ -620,7 +618,7 @@ void QobuzService::GetSongs() { } ResetSongsRequest(); - songs_request_.reset(new QobuzRequest(this, url_handler_, app_, network_, QobuzBaseRequest::Type::FavouriteSongs), [](QobuzRequest *request) { request->deleteLater(); }); + songs_request_.reset(new QobuzRequest(this, url_handler_, network_, QobuzBaseRequest::Type::FavouriteSongs), [](QobuzRequest *request) { request->deleteLater(); }); QObject::connect(&*songs_request_, &QobuzRequest::Results, this, &QobuzService::SongsResultsReceived); QObject::connect(&*songs_request_, &QobuzRequest::UpdateStatus, this, &QobuzService::SongsUpdateStatusReceived); QObject::connect(&*songs_request_, &QobuzRequest::UpdateProgress, this, &QobuzService::SongsUpdateProgressReceived); @@ -699,7 +697,7 @@ void QobuzService::SendSearch() { break; } - search_request_.reset(new QobuzRequest(this, url_handler_, app_, network_, query_type), [](QobuzRequest *request) { request->deleteLater(); } ); + search_request_.reset(new QobuzRequest(this, url_handler_, network_, query_type), [](QobuzRequest *request) { request->deleteLater(); } ); QObject::connect(&*search_request_, &QobuzRequest::Results, this, &QobuzService::SearchResultsReceived); QObject::connect(&*search_request_, &QobuzRequest::UpdateStatus, this, &QobuzService::SearchUpdateStatus); diff --git a/src/qobuz/qobuzservice.h b/src/qobuz/qobuzservice.h index cc8b6f6337..a28ebae92f 100644 --- a/src/qobuz/qobuzservice.h +++ b/src/qobuz/qobuzservice.h @@ -37,15 +37,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "streaming/streamingservice.h" #include "streaming/streamingsearchview.h" class QTimer; class QNetworkReply; -class Application; +class TaskManager; +class Database; +class UrlHandlers; class NetworkAccessManager; +class AlbumCoverLoader; class QobuzUrlHandler; class QobuzRequest; class QobuzFavoriteRequest; @@ -58,7 +61,13 @@ class QobuzService : public StreamingService { Q_OBJECT public: - explicit QobuzService(Application *app, QObject *parent = nullptr); + explicit QobuzService(SharedPtr task_manager, + SharedPtr database, + SharedPtr network, + SharedPtr url_handlers, + SharedPtr albumcover_loader, + QObject *parent = nullptr); + ~QobuzService(); static const Song::Source kSource; @@ -74,7 +83,6 @@ class QobuzService : public StreamingService { int max_login_attempts() const { return kLoginAttempts; } - Application *app() const { return app_; } QString app_id() const { return app_id_; } QString app_secret() const { return app_secret_; } QString username() const { return username_; } @@ -110,7 +118,6 @@ class QobuzService : public StreamingService { CollectionFilter *songs_collection_filter_model() override { return songs_collection_model_->filter(); } public Q_SLOTS: - void ShowConfig() override; void TryLogin(); void SendLogin(); void SendLoginWithCredentials(const QString &app_id, const QString &username, const QString &password); @@ -148,7 +155,6 @@ class QobuzService : public StreamingService { void SendSearch(); void LoginError(const QString &error = QString(), const QVariant &debug = QVariant()); - Application *app_; SharedPtr network_; QobuzUrlHandler *url_handler_; diff --git a/src/qobuz/qobuzstreamurlrequest.cpp b/src/qobuz/qobuzstreamurlrequest.cpp index ae820faa93..05f6cdb661 100644 --- a/src/qobuz/qobuzstreamurlrequest.cpp +++ b/src/qobuz/qobuzstreamurlrequest.cpp @@ -34,11 +34,11 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/song.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "qobuzservice.h" #include "qobuzbaserequest.h" #include "qobuzstreamurlrequest.h" diff --git a/src/qobuz/qobuzstreamurlrequest.h b/src/qobuz/qobuzstreamurlrequest.h index 69ba2e28b9..6e866f95ec 100644 --- a/src/qobuz/qobuzstreamurlrequest.h +++ b/src/qobuz/qobuzstreamurlrequest.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "qobuzbaserequest.h" diff --git a/src/qobuz/qobuzurlhandler.cpp b/src/qobuz/qobuzurlhandler.cpp index 0248a7aa4a..9824c7d9e5 100644 --- a/src/qobuz/qobuzurlhandler.cpp +++ b/src/qobuz/qobuzurlhandler.cpp @@ -23,15 +23,14 @@ #include #include -#include "core/application.h" #include "core/taskmanager.h" #include "core/song.h" #include "qobuz/qobuzservice.h" #include "qobuzurlhandler.h" -QobuzUrlHandler::QobuzUrlHandler(Application *app, QobuzService *service) +QobuzUrlHandler::QobuzUrlHandler(SharedPtr task_manager, QobuzService *service) : UrlHandler(service), - app_(app), + task_manager_(task_manager), service_(service) { QObject::connect(service, &QobuzService::StreamURLFailure, this, &QobuzUrlHandler::GetStreamURLFailure); @@ -42,7 +41,7 @@ QobuzUrlHandler::QobuzUrlHandler(Application *app, QobuzService *service) UrlHandler::LoadResult QobuzUrlHandler::StartLoading(const QUrl &url) { Request req; - req.task_id = app_->task_manager()->StartTask(QStringLiteral("Loading %1 stream...").arg(url.scheme())); + req.task_id = task_manager_->StartTask(QStringLiteral("Loading %1 stream...").arg(url.scheme())); QString error; req.id = service_->GetStreamURL(url, error); if (req.id == 0) { @@ -80,5 +79,5 @@ void QobuzUrlHandler::GetStreamURLSuccess(const uint id, const QUrl &media_url, } void QobuzUrlHandler::CancelTask(const int task_id) { - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); } diff --git a/src/qobuz/qobuzurlhandler.h b/src/qobuz/qobuzurlhandler.h index ec792be6c7..b3690fa5f1 100644 --- a/src/qobuz/qobuzurlhandler.h +++ b/src/qobuz/qobuzurlhandler.h @@ -30,13 +30,13 @@ #include "core/song.h" #include "qobuz/qobuzservice.h" -class Application; +class TaskManager; class QobuzUrlHandler : public UrlHandler { Q_OBJECT public: - explicit QobuzUrlHandler(Application *app, QobuzService *service); + explicit QobuzUrlHandler(SharedPtr task_manager, QobuzService *service); QString scheme() const { return service_->url_scheme(); } LoadResult StartLoading(const QUrl &url); @@ -54,7 +54,7 @@ class QobuzUrlHandler : public UrlHandler { uint id; int task_id; }; - Application *app_; + SharedPtr task_manager_; QobuzService *service_; QMap requests_; }; diff --git a/src/queue/queueview.cpp b/src/queue/queueview.cpp index 0c5390a351..68badd0831 100644 --- a/src/queue/queueview.cpp +++ b/src/queue/queueview.cpp @@ -34,7 +34,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/iconloader.h" #include "core/settings.h" #include "playlist/playlist.h" @@ -43,7 +43,7 @@ #include "queue.h" #include "queueview.h" #include "ui_queueview.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" using namespace Qt::Literals::StringLiterals; @@ -91,8 +91,8 @@ void QueueView::SetPlaylistManager(SharedPtr playlist_manager) void QueueView::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeLeftPanelButtons, 22).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeLeftPanelButtons, 22).toInt(); s.endGroup(); ui_->move_down->setIconSize(QSize(iconsize, iconsize)); diff --git a/src/queue/queueview.h b/src/queue/queueview.h index bbf51b72e4..5bca8a36f2 100644 --- a/src/queue/queueview.h +++ b/src/queue/queueview.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class Playlist; class PlaylistManager; diff --git a/src/radios/radiobackend.cpp b/src/radios/radiobackend.cpp index 06ab16fb03..7d1c38857b 100644 --- a/src/radios/radiobackend.cpp +++ b/src/radios/radiobackend.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/database.h" #include "core/sqlquery.h" #include "core/song.h" diff --git a/src/radios/radiobackend.h b/src/radios/radiobackend.h index 7d4bb507b0..926f6a1d6e 100644 --- a/src/radios/radiobackend.h +++ b/src/radios/radiobackend.h @@ -22,7 +22,7 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "radiochannel.h" class QThread; diff --git a/src/radios/radiomodel.cpp b/src/radios/radiomodel.cpp index 599855e392..718501b0ae 100644 --- a/src/radios/radiomodel.cpp +++ b/src/radios/radiomodel.cpp @@ -28,9 +28,8 @@ #include #include -#include "core/application.h" +#include "core/song.h" #include "core/simpletreemodel.h" -#include "playlist/playlistmanager.h" #include "covermanager/albumcoverloader.h" #include "covermanager/albumcoverloaderresult.h" #include "radiomodel.h" @@ -45,12 +44,13 @@ namespace { constexpr int kTreeIconSize = 22; } -RadioModel::RadioModel(Application *app, QObject *parent) +RadioModel::RadioModel(SharedPtr albumcover_loader, SharedPtr radio_services, QObject *parent) : SimpleTreeModel(new RadioItem(this), parent), - app_(app) { + albumcover_loader_(albumcover_loader), + radio_services_(radio_services) { - if (app_) { - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &RadioModel::AlbumCoverLoaded); + if (albumcover_loader_) { + QObject::connect(&*albumcover_loader, &AlbumCoverLoader::AlbumCoverLoaded, this, &RadioModel::AlbumCoverLoaded); } } @@ -109,12 +109,12 @@ QVariant RadioModel::data(const RadioItem *item, int role) const { return QVariant::fromValue(item->source); break; case Role_Homepage:{ - RadioService *service = app_->radio_services()->ServiceBySource(item->source); + RadioService *service = radio_services_->ServiceBySource(item->source); if (service) return service->Homepage(); break; } case Role_Donate:{ - RadioService *service = app_->radio_services()->ServiceBySource(item->source); + RadioService *service = radio_services_->ServiceBySource(item->source); if (service) return service->Donate(); break; } @@ -141,7 +141,7 @@ QMimeData *RadioModel::mimeData(const QModelIndexList &indexes) const { } data->setUrls(urls); - data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs); + data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs); return data; @@ -287,7 +287,7 @@ QPixmap RadioModel::ChannelIcon(const QModelIndex &idx) { if (!songs.isEmpty()) { Song song = songs.first(); song.set_art_automatic(item->channel.thumbnail_url); - const quint64 id = app_->album_cover_loader()->LoadImageAsync(AlbumCoverLoaderOptions(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage, QSize(kTreeIconSize, kTreeIconSize)), song); + const quint64 id = albumcover_loader_->LoadImageAsync(AlbumCoverLoaderOptions(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage, QSize(kTreeIconSize, kTreeIconSize)), song); pending_art_[id] = ItemAndCacheKey(item, cache_key); pending_cache_keys_.insert(cache_key); } diff --git a/src/radios/radiomodel.h b/src/radios/radiomodel.h index 2b5fabe768..a44a9e2667 100644 --- a/src/radios/radiomodel.h +++ b/src/radios/radiomodel.h @@ -31,6 +31,7 @@ #include #include +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/simpletreemodel.h" #include "covermanager/albumcoverloaderresult.h" @@ -39,14 +40,14 @@ class QMimeData; -class Application; -class Database; +class AlbumCoverLoader; +class RadioServices; class RadioModel : public SimpleTreeModel { Q_OBJECT public: - explicit RadioModel(Application *app, QObject *parent = nullptr); + explicit RadioModel(SharedPtr albumcover_loader, SharedPtr radio_services, QObject *parent = nullptr); ~RadioModel() override; enum Role { @@ -88,7 +89,9 @@ class RadioModel : public SimpleTreeModel { private: using ItemAndCacheKey = QPair; - Application *app_; + SharedPtr albumcover_loader_; + SharedPtr radio_services_; + QMap container_nodes_; QList items_; QMap pending_art_; diff --git a/src/radios/radioparadiseservice.cpp b/src/radios/radioparadiseservice.cpp index 9f471b4cef..ed9b9589fe 100644 --- a/src/radios/radioparadiseservice.cpp +++ b/src/radios/radioparadiseservice.cpp @@ -25,9 +25,8 @@ #include #include -#include "core/application.h" -#include "core/networkaccessmanager.h" #include "core/taskmanager.h" +#include "core/networkaccessmanager.h" #include "core/iconloader.h" #include "radioparadiseservice.h" #include "radiochannel.h" @@ -38,8 +37,8 @@ namespace { constexpr char kApiChannelsUrl[] = "https://api.radioparadise.com/api/list_streams"; } -RadioParadiseService::RadioParadiseService(Application *app, SharedPtr network, QObject *parent) - : RadioService(Song::Source::RadioParadise, u"Radio Paradise"_s, IconLoader::Load(u"radioparadise"_s), app, network, parent) {} +RadioParadiseService::RadioParadiseService(SharedPtr task_manager, SharedPtr network, QObject *parent) + : RadioService(Song::Source::RadioParadise, u"Radio Paradise"_s, IconLoader::Load(u"radioparadise"_s), task_manager, network, parent) {} QUrl RadioParadiseService::Homepage() { return QUrl(u"https://radioparadise.com/"_s); } QUrl RadioParadiseService::Donate() { return QUrl(u"https://payments.radioparadise.com/rp2s-content.php?name=Support&file=support"_s); } @@ -65,7 +64,7 @@ void RadioParadiseService::GetChannels() { QNetworkRequest req(url); QNetworkReply *reply = network_->get(req); replies_ << reply; - const int task_id = app_->task_manager()->StartTask(tr("Getting %1 channels").arg(name_)); + const int task_id = task_manager_->StartTask(tr("Getting %1 channels").arg(name_)); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, task_id]() { GetChannelsReply(reply, task_id); }); } @@ -77,14 +76,14 @@ void RadioParadiseService::GetChannelsReply(QNetworkReply *reply, const int task QJsonObject object = ExtractJsonObj(reply); if (object.isEmpty()) { - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(); return; } if (!object.contains("channels"_L1) || !object["channels"_L1].isArray()) { Error(u"Missing JSON channels array."_s, object); - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(); return; } @@ -123,7 +122,7 @@ void RadioParadiseService::GetChannelsReply(QNetworkReply *reply, const int task } } - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(channels); diff --git a/src/radios/radioparadiseservice.h b/src/radios/radioparadiseservice.h index bc0d654470..52393a198c 100644 --- a/src/radios/radioparadiseservice.h +++ b/src/radios/radioparadiseservice.h @@ -26,7 +26,7 @@ #include "radioservice.h" #include "radiochannel.h" -class Application; +class TaskManager; class NetworkAccessManager; class QNetworkReply; @@ -34,7 +34,7 @@ class RadioParadiseService : public RadioService { Q_OBJECT public: - explicit RadioParadiseService(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit RadioParadiseService(SharedPtr task_manager, SharedPtr network, QObject *parent = nullptr); QUrl Homepage() override; QUrl Donate() override; diff --git a/src/radios/radioservice.cpp b/src/radios/radioservice.cpp index 39535118a2..36b1ddbd01 100644 --- a/src/radios/radioservice.cpp +++ b/src/radios/radioservice.cpp @@ -26,14 +26,13 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "radioservice.h" -RadioService::RadioService(const Song::Source source, const QString &name, const QIcon &icon, Application *app, SharedPtr network, QObject *parent) +RadioService::RadioService(const Song::Source source, const QString &name, const QIcon &icon, SharedPtr task_manager, SharedPtr network, QObject *parent) : QObject(parent), - app_(app), + task_manager_(task_manager), network_(network), source_(source), name_(name), diff --git a/src/radios/radioservice.h b/src/radios/radioservice.h index 15678f04fb..547f205cf4 100644 --- a/src/radios/radioservice.h +++ b/src/radios/radioservice.h @@ -30,20 +30,20 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "radiochannel.h" class QNetworkReply; -class Application; +class TaskManager; class NetworkAccessManager; class RadioService : public QObject { Q_OBJECT public: - explicit RadioService(const Song::Source source, const QString &name, const QIcon &icon, Application *app, SharedPtr network, QObject *parent = nullptr); + explicit RadioService(const Song::Source source, const QString &name, const QIcon &icon, SharedPtr task_manager, SharedPtr network, QObject *parent = nullptr); Song::Source source() const { return source_; } QString name() const { return name_; } @@ -66,7 +66,7 @@ class RadioService : public QObject { void Error(const QString &error, const QVariant &debug = QVariant()); protected: - Application *app_; + SharedPtr task_manager_; SharedPtr network_; Song::Source source_; QString name_; diff --git a/src/radios/radioservices.cpp b/src/radios/radioservices.cpp index 03b21a0289..da326880ac 100644 --- a/src/radios/radioservices.cpp +++ b/src/radios/radioservices.cpp @@ -22,9 +22,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/database.h" #include "core/networkaccessmanager.h" #include "radioservices.h" @@ -37,16 +36,16 @@ using std::make_shared; -RadioServices::RadioServices(Application *app, QObject *parent) +RadioServices::RadioServices(SharedPtr task_manager, SharedPtr network, SharedPtr database, SharedPtr albumcover_loader, QObject *parent) : QObject(parent), - network_(app->network()), + network_(network), backend_(nullptr), - model_(new RadioModel(app, this)), + model_(new RadioModel(albumcover_loader, SharedPtr(this))), sort_model_(new QSortFilterProxyModel(this)), channels_refresh_(false) { - backend_ = make_shared(app->database()); - app->MoveToThread(&*backend_, app->database()->thread()); + backend_ = make_shared(database); + backend_->moveToThread(database->thread()); QObject::connect(&*backend_, &RadioBackend::NewChannels, this, &RadioServices::GotChannelsFromBackend); @@ -56,8 +55,8 @@ RadioServices::RadioServices(Application *app, QObject *parent) sort_model_->setSortLocaleAware(true); sort_model_->sort(0); - AddService(new SomaFMService(app, network_, this)); - AddService(new RadioParadiseService(app, network_, this)); + AddService(new SomaFMService(task_manager, network_, this)); + AddService(new RadioParadiseService(task_manager, network_, this)); } diff --git a/src/radios/radioservices.h b/src/radios/radioservices.h index eed10bc500..ce14f31116 100644 --- a/src/radios/radioservices.h +++ b/src/radios/radioservices.h @@ -23,14 +23,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "radiochannel.h" class QSortFilterProxyModel; -class Application; +class TaskManager; +class Database; class NetworkAccessManager; +class AlbumCoverLoader; class RadioBackend; class RadioModel; class RadioService; @@ -39,7 +41,7 @@ class RadioServices : public QObject { Q_OBJECT public: - explicit RadioServices(Application *app, QObject *parent = nullptr); + explicit RadioServices(SharedPtr task_manager, SharedPtr network, SharedPtr database, SharedPtr albumcover_loader, QObject *parent = nullptr); void AddService(RadioService *service); void RemoveService(RadioService *service); diff --git a/src/radios/radioviewcontainer.cpp b/src/radios/radioviewcontainer.cpp index 1a79478d80..85d4fa2ecd 100644 --- a/src/radios/radioviewcontainer.cpp +++ b/src/radios/radioviewcontainer.cpp @@ -23,7 +23,7 @@ #include "core/iconloader.h" #include "core/settings.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" #include "radioviewcontainer.h" #include "ui_radioviewcontainer.h" @@ -48,8 +48,8 @@ RadioViewContainer::~RadioViewContainer() { delete ui_; } void RadioViewContainer::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeLeftPanelButtons, 22).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeLeftPanelButtons, 22).toInt(); s.endGroup(); ui_->refresh->setIconSize(QSize(iconsize, iconsize)); diff --git a/src/radios/somafmservice.cpp b/src/radios/somafmservice.cpp index 0cb11c0698..95434e6747 100644 --- a/src/radios/somafmservice.cpp +++ b/src/radios/somafmservice.cpp @@ -28,7 +28,6 @@ #include #include -#include "core/application.h" #include "core/networkaccessmanager.h" #include "core/taskmanager.h" #include "core/iconloader.h" @@ -42,8 +41,8 @@ namespace { constexpr char kApiChannelsUrl[] = "https://somafm.com/channels.json"; } -SomaFMService::SomaFMService(Application *app, SharedPtr network, QObject *parent) - : RadioService(Song::Source::SomaFM, u"SomaFM"_s, IconLoader::Load(u"somafm"_s), app, network, parent) {} +SomaFMService::SomaFMService(SharedPtr task_manager, SharedPtr network, QObject *parent) + : RadioService(Song::Source::SomaFM, u"SomaFM"_s, IconLoader::Load(u"somafm"_s), task_manager, network, parent) {} SomaFMService::~SomaFMService() { Abort(); @@ -73,7 +72,7 @@ void SomaFMService::GetChannels() { QNetworkRequest req(url); QNetworkReply *reply = network_->get(req); replies_ << reply; - const int task_id = app_->task_manager()->StartTask(tr("Getting %1 channels").arg(name_)); + const int task_id = task_manager_->StartTask(tr("Getting %1 channels").arg(name_)); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, task_id]() { GetChannelsReply(reply, task_id); }); } @@ -85,14 +84,14 @@ void SomaFMService::GetChannelsReply(QNetworkReply *reply, const int task_id) { QJsonObject object = ExtractJsonObj(reply); if (object.isEmpty()) { - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(); return; } if (!object.contains("channels"_L1) || !object["channels"_L1].isArray()) { Error(u"Missing JSON channels array."_s, object); - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(); return; } @@ -129,7 +128,7 @@ void SomaFMService::GetChannelsReply(QNetworkReply *reply, const int task_id) { } if (channels.isEmpty()) { - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(); } else { @@ -154,7 +153,7 @@ void SomaFMService::GetStreamUrlsReply(QNetworkReply *reply, const int task_id, if (replies_.contains(reply)) replies_.removeAll(reply); reply->deleteLater(); - PlaylistParser parser; + PlaylistParser parser(nullptr, nullptr); SongList songs = parser.LoadFromDevice(reply); if (!songs.isEmpty()) { channel.url = songs.first().url(); @@ -163,7 +162,7 @@ void SomaFMService::GetStreamUrlsReply(QNetworkReply *reply, const int task_id, channels_ << channel; if (replies_.isEmpty()) { - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); Q_EMIT NewChannels(channels_); channels_.clear(); } diff --git a/src/radios/somafmservice.h b/src/radios/somafmservice.h index 6163bf650e..a16d0c4128 100644 --- a/src/radios/somafmservice.h +++ b/src/radios/somafmservice.h @@ -28,13 +28,15 @@ #include "radiochannel.h" class QNetworkReply; + +class TaskManager; class NetworkAccessManager; class SomaFMService : public RadioService { Q_OBJECT public: - explicit SomaFMService(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit SomaFMService(SharedPtr task_manager, SharedPtr network, QObject *parent = nullptr); ~SomaFMService(); QUrl Homepage() override; diff --git a/src/scrobbler/audioscrobbler.cpp b/src/scrobbler/audioscrobbler.cpp index 1e0a681df5..704342ab6d 100644 --- a/src/scrobbler/audioscrobbler.cpp +++ b/src/scrobbler/audioscrobbler.cpp @@ -25,22 +25,19 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/song.h" -#include "settings/settingsdialog.h" #include "audioscrobbler.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "scrobblerservice.h" using std::make_shared; -AudioScrobbler::AudioScrobbler(Application *app, QObject *parent) +AudioScrobbler::AudioScrobbler(QObject *parent) : QObject(parent), - app_(app), - settings_(make_shared(app)) { + settings_(make_shared()) { ReloadSettings(); @@ -122,10 +119,6 @@ void AudioScrobbler::ToggleOffline() { } -void AudioScrobbler::ShowConfig() { - app_->OpenSettingsDialogAtPage(SettingsDialog::Page::Scrobbler); -} - void AudioScrobbler::UpdateNowPlaying(const Song &song) { if (!settings_->sources().contains(song.source())) return; diff --git a/src/scrobbler/audioscrobbler.h b/src/scrobbler/audioscrobbler.h index c53c1361d0..3726080ff6 100644 --- a/src/scrobbler/audioscrobbler.h +++ b/src/scrobbler/audioscrobbler.h @@ -30,11 +30,10 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" -class Application; class ScrobblerService; class Song; @@ -42,7 +41,7 @@ class AudioScrobbler : public QObject { Q_OBJECT public: - explicit AudioScrobbler(Application *app, QObject *parent = nullptr); + explicit AudioScrobbler(QObject *parent = nullptr); ~AudioScrobbler(); void AddService(SharedPtr service); @@ -59,7 +58,7 @@ class AudioScrobbler : public QObject { } void ReloadSettings(); - SharedPtr settings() { return settings_; } + SharedPtr settings() { return settings_; } bool enabled() const { return settings_->enabled(); } bool offline() const { return settings_->offline(); } @@ -71,8 +70,6 @@ class AudioScrobbler : public QObject { bool strip_remastered() const { return settings_->strip_remastered(); } QList sources() const { return settings_->sources(); } - void ShowConfig(); - void UpdateNowPlaying(const Song &song); void ClearPlaying(); void Scrobble(const Song &song, const qint64 scrobble_point); @@ -89,8 +86,7 @@ class AudioScrobbler : public QObject { void ErrorMessage(const QString &error); private: - Application *app_; - SharedPtr settings_; + SharedPtr settings_; QMap> services_; Q_DISABLE_COPY(AudioScrobbler) diff --git a/src/scrobbler/lastfmimport.cpp b/src/scrobbler/lastfmimport.cpp index 600669635a..7e8ab22489 100644 --- a/src/scrobbler/lastfmimport.cpp +++ b/src/scrobbler/lastfmimport.cpp @@ -38,8 +38,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/settings.h" diff --git a/src/scrobbler/lastfmimport.h b/src/scrobbler/lastfmimport.h index 8964ba59f5..48f2b52722 100644 --- a/src/scrobbler/lastfmimport.h +++ b/src/scrobbler/lastfmimport.h @@ -31,7 +31,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class QTimer; class QNetworkReply; diff --git a/src/scrobbler/lastfmscrobbler.cpp b/src/scrobbler/lastfmscrobbler.cpp index 4703c1edc3..381aecdb8e 100644 --- a/src/scrobbler/lastfmscrobbler.cpp +++ b/src/scrobbler/lastfmscrobbler.cpp @@ -21,10 +21,10 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "lastfmscrobbler.h" const char *LastFMScrobbler::kName = "Last.fm"; @@ -36,5 +36,5 @@ constexpr char kAuthUrl[] = "https://www.last.fm/api/auth/"; constexpr char kCacheFile[] = "lastfmscrobbler.cache"; } // namespace -LastFMScrobbler::LastFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent) +LastFMScrobbler::LastFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent) : ScrobblingAPI20(QLatin1String(kName), QLatin1String(kSettingsGroup), QLatin1String(kAuthUrl), QLatin1String(kApiUrl), true, QLatin1String(kCacheFile), settings, network, parent) {} diff --git a/src/scrobbler/lastfmscrobbler.h b/src/scrobbler/lastfmscrobbler.h index f6863229e6..f493e12ae3 100644 --- a/src/scrobbler/lastfmscrobbler.h +++ b/src/scrobbler/lastfmscrobbler.h @@ -25,17 +25,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "scrobblingapi20.h" -class AudioScrobbler; +class ScrobblerSettingsService; class NetworkAccessManager; class LastFMScrobbler : public ScrobblingAPI20 { Q_OBJECT public: - explicit LastFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent = nullptr); + explicit LastFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent = nullptr); static const char *kName; static const char *kSettingsGroup; diff --git a/src/scrobbler/librefmscrobbler.cpp b/src/scrobbler/librefmscrobbler.cpp index 08cdbc1234..bcc1cec647 100644 --- a/src/scrobbler/librefmscrobbler.cpp +++ b/src/scrobbler/librefmscrobbler.cpp @@ -21,10 +21,10 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "scrobblingapi20.h" #include "librefmscrobbler.h" @@ -34,5 +34,5 @@ const char *LibreFMScrobbler::kAuthUrl = "https://www.libre.fm/api/auth/"; const char *LibreFMScrobbler::kApiUrl = "https://libre.fm/2.0/"; const char *LibreFMScrobbler::kCacheFile = "librefmscrobbler.cache"; -LibreFMScrobbler::LibreFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent) +LibreFMScrobbler::LibreFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent) : ScrobblingAPI20(QLatin1String(kName), QLatin1String(kSettingsGroup), QLatin1String(kAuthUrl), QLatin1String(kApiUrl), false, QLatin1String(kCacheFile), settings, network, parent) {} diff --git a/src/scrobbler/librefmscrobbler.h b/src/scrobbler/librefmscrobbler.h index 920c8e1e9b..0d695270a9 100644 --- a/src/scrobbler/librefmscrobbler.h +++ b/src/scrobbler/librefmscrobbler.h @@ -25,17 +25,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "scrobblingapi20.h" -class ScrobblerSettings; +class ScrobblerSettingsService; class NetworkAccessManager; class LibreFMScrobbler : public ScrobblingAPI20 { Q_OBJECT public: - explicit LibreFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent = nullptr); + explicit LibreFMScrobbler(SharedPtr settings, SharedPtr network, QObject *parent = nullptr); static const char *kName; static const char *kSettingsGroup; diff --git a/src/scrobbler/listenbrainzscrobbler.cpp b/src/scrobbler/listenbrainzscrobbler.cpp index 9ac39e44ed..6d90cad50c 100644 --- a/src/scrobbler/listenbrainzscrobbler.cpp +++ b/src/scrobbler/listenbrainzscrobbler.cpp @@ -41,16 +41,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "core/logging.h" #include "core/settings.h" #include "core/localredirectserver.h" -#include "utilities/timeconstants.h" -#include "settings/scrobblersettingspage.h" +#include "constants/timeconstants.h" +#include "constants/scrobblersettings.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "scrobblerservice.h" #include "scrobblercache.h" #include "scrobblercacheitem.h" @@ -73,7 +73,7 @@ constexpr char kCacheFile[] = "listenbrainzscrobbler.cache"; constexpr int kScrobblesPerRequest = 10; } // namespace -ListenBrainzScrobbler::ListenBrainzScrobbler(SharedPtr settings, SharedPtr network, QObject *parent) +ListenBrainzScrobbler::ListenBrainzScrobbler(SharedPtr settings, SharedPtr network, QObject *parent) : ScrobblerService(QLatin1String(kName), settings, parent), network_(network), cache_(new ScrobblerCache(QLatin1String(kCacheFile), this)), @@ -119,12 +119,12 @@ void ListenBrainzScrobbler::ReloadSettings() { Settings s; s.beginGroup(kSettingsGroup); - enabled_ = s.value("enabled", false).toBool(); - user_token_ = s.value("user_token").toString(); + enabled_ = s.value(ScrobblerSettings::kEnabled, false).toBool(); + user_token_ = s.value(ScrobblerSettings::kUserToken).toString(); s.endGroup(); - s.beginGroup(ScrobblerSettingsPage::kSettingsGroup); - prefer_albumartist_ = s.value("albumartist", false).toBool(); + s.beginGroup(ScrobblerSettings::kSettingsGroup); + prefer_albumartist_ = s.value(ScrobblerSettings::kAlbumArtist, false).toBool(); s.endGroup(); } @@ -632,7 +632,10 @@ void ListenBrainzScrobbler::Love() { if (!song_playing_.is_valid() || !song_playing_.is_metadata_good()) return; - if (!authenticated()) settings_->ShowConfig(); + if (!authenticated()) { + Q_EMIT OpenSettingsDialog(); + return; + } if (song_playing_.musicbrainz_recording_id().isEmpty()) { Error(tr("Missing MusicBrainz recording ID for %1 %2 %3").arg(song_playing_.artist(), song_playing_.album(), song_playing_.title())); diff --git a/src/scrobbler/listenbrainzscrobbler.h b/src/scrobbler/listenbrainzscrobbler.h index 8e8d84005d..ae047d77cc 100644 --- a/src/scrobbler/listenbrainzscrobbler.h +++ b/src/scrobbler/listenbrainzscrobbler.h @@ -32,7 +32,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "scrobblerservice.h" #include "scrobblercache.h" @@ -40,7 +40,7 @@ class QNetworkReply; -class ScrobblerSettings; +class ScrobblerSettingsService; class NetworkAccessManager; class LocalRedirectServer; @@ -48,7 +48,7 @@ class ListenBrainzScrobbler : public ScrobblerService { Q_OBJECT public: - explicit ListenBrainzScrobbler(SharedPtr settings, SharedPtr network, QObject *parent = nullptr); + explicit ListenBrainzScrobbler(SharedPtr settings, SharedPtr network, QObject *parent = nullptr); ~ListenBrainzScrobbler() override; static const char *kName; @@ -64,7 +64,6 @@ class ListenBrainzScrobbler : public ScrobblerService { void Authenticate(); void Logout(); - void ShowConfig(); void Submit() override; void UpdateNowPlaying(const Song &song) override; void ClearPlaying() override; diff --git a/src/scrobbler/scrobblercacheitem.h b/src/scrobbler/scrobblercacheitem.h index e274e0da94..8acceede66 100644 --- a/src/scrobbler/scrobblercacheitem.h +++ b/src/scrobbler/scrobblercacheitem.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "scrobblemetadata.h" class ScrobblerCacheItem { diff --git a/src/scrobbler/scrobblerservice.cpp b/src/scrobbler/scrobblerservice.cpp index 716a1d4f90..1c1b85b4fd 100644 --- a/src/scrobbler/scrobblerservice.cpp +++ b/src/scrobbler/scrobblerservice.cpp @@ -27,11 +27,11 @@ #include #include "scrobblerservice.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "core/song.h" -ScrobblerService::ScrobblerService(const QString &name, SharedPtr settings, QObject *parent) : QObject(parent), name_(name), settings_(settings) {} +ScrobblerService::ScrobblerService(const QString &name, SharedPtr settings, QObject *parent) : QObject(parent), name_(name), settings_(settings) {} bool ScrobblerService::ExtractJsonObj(const QByteArray &data, QJsonObject &json_obj, QString &error_description) { diff --git a/src/scrobbler/scrobblerservice.h b/src/scrobbler/scrobblerservice.h index 1b304c78f7..96ed0e1736 100644 --- a/src/scrobbler/scrobblerservice.h +++ b/src/scrobbler/scrobblerservice.h @@ -30,16 +30,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" class ScrobblerService : public QObject { Q_OBJECT public: - explicit ScrobblerService(const QString &name, SharedPtr settings, QObject *parent); + explicit ScrobblerService(const QString &name, SharedPtr settings, QObject *parent); QString name() const { return name_; } @@ -72,10 +72,11 @@ class ScrobblerService : public QObject { Q_SIGNALS: void ErrorMessage(const QString &error); + void OpenSettingsDialog(); protected: QString name_; - SharedPtr settings_; + SharedPtr settings_; }; using ScrobblerServicePtr = SharedPtr; diff --git a/src/scrobbler/scrobblersettings.cpp b/src/scrobbler/scrobblersettingsservice.cpp similarity index 80% rename from src/scrobbler/scrobblersettings.cpp rename to src/scrobbler/scrobblersettingsservice.cpp index 3bc4e0931d..29ea1e1c3b 100644 --- a/src/scrobbler/scrobblersettings.cpp +++ b/src/scrobbler/scrobblersettingsservice.cpp @@ -23,16 +23,13 @@ #include #include -#include "core/application.h" #include "core/song.h" #include "core/settings.h" -#include "settings/settingsdialog.h" -#include "settings/scrobblersettingspage.h" -#include "scrobblersettings.h" +#include "constants/scrobblersettings.h" +#include "scrobblersettingsservice.h" -ScrobblerSettings::ScrobblerSettings(Application *app, QObject *parent) +ScrobblerSettingsService::ScrobblerSettingsService(QObject *parent) : QObject(parent), - app_(app), enabled_(false), offline_(false), scrobble_button_(false), @@ -46,10 +43,10 @@ ScrobblerSettings::ScrobblerSettings(Application *app, QObject *parent) } -void ScrobblerSettings::ReloadSettings() { +void ScrobblerSettingsService::ReloadSettings() { Settings s; - s.beginGroup(ScrobblerSettingsPage::kSettingsGroup); + s.beginGroup(ScrobblerSettings::kSettingsGroup); enabled_ = s.value("enabled", false).toBool(); offline_ = s.value("offline", false).toBool(); scrobble_button_ = s.value("scrobble_button", false).toBool(); @@ -88,13 +85,13 @@ void ScrobblerSettings::ReloadSettings() { } -void ScrobblerSettings::ToggleScrobbling() { +void ScrobblerSettingsService::ToggleScrobbling() { bool enabled_old_ = enabled_; enabled_ = !enabled_; Settings s; - s.beginGroup(ScrobblerSettingsPage::kSettingsGroup); + s.beginGroup(ScrobblerSettings::kSettingsGroup); s.setValue("enabled", enabled_); s.endGroup(); @@ -102,13 +99,13 @@ void ScrobblerSettings::ToggleScrobbling() { } -void ScrobblerSettings::ToggleOffline() { +void ScrobblerSettingsService::ToggleOffline() { bool offline_old_ = offline_; offline_ = !offline_; Settings s; - s.beginGroup(ScrobblerSettingsPage::kSettingsGroup); + s.beginGroup(ScrobblerSettings::kSettingsGroup); s.setValue("offline", offline_); s.endGroup(); @@ -116,10 +113,6 @@ void ScrobblerSettings::ToggleOffline() { } -void ScrobblerSettings::ShowConfig() { - app_->OpenSettingsDialogAtPage(SettingsDialog::Page::Scrobbler); -} - -void ScrobblerSettings::ErrorReceived(const QString &error) { +void ScrobblerSettingsService::ErrorReceived(const QString &error) { Q_EMIT ErrorMessage(error); } diff --git a/src/scrobbler/scrobblersettings.h b/src/scrobbler/scrobblersettingsservice.h similarity index 87% rename from src/scrobbler/scrobblersettings.h rename to src/scrobbler/scrobblersettingsservice.h index a5c5b815de..6e844f8643 100644 --- a/src/scrobbler/scrobblersettings.h +++ b/src/scrobbler/scrobblersettingsservice.h @@ -17,8 +17,8 @@ * */ -#ifndef SCROBBLERSETTINGS_H -#define SCROBBLERSETTINGS_H +#ifndef SCROBBLERSETTINGSSERVICE_H +#define SCROBBLERSETTINGSSERVICE_H #include "config.h" @@ -29,14 +29,13 @@ #include "core/song.h" -class Application; class Song; -class ScrobblerSettings : public QObject { +class ScrobblerSettingsService : public QObject { Q_OBJECT public: - explicit ScrobblerSettings(Application *app, QObject *parent = nullptr); + explicit ScrobblerSettingsService(QObject *parent = nullptr); void ReloadSettings(); @@ -50,8 +49,6 @@ class ScrobblerSettings : public QObject { bool strip_remastered() const { return strip_remastered_; } QList sources() const { return sources_; } - void ShowConfig(); - public Q_SLOTS: void ToggleScrobbling(); void ToggleOffline(); @@ -65,8 +62,6 @@ class ScrobblerSettings : public QObject { void LoveButtonVisibilityChanged(const bool value); private: - Application *app_; - bool enabled_; bool offline_; bool scrobble_button_; @@ -77,7 +72,7 @@ class ScrobblerSettings : public QObject { bool strip_remastered_; QList sources_; - Q_DISABLE_COPY(ScrobblerSettings) + Q_DISABLE_COPY(ScrobblerSettingsService) }; -#endif // SCROBBLERSETTINGS_H +#endif // SCROBBLERSETTINGSSERVICE_H diff --git a/src/scrobbler/scrobblingapi20.cpp b/src/scrobbler/scrobblingapi20.cpp index 1bb201bb78..38650f462c 100644 --- a/src/scrobbler/scrobblingapi20.cpp +++ b/src/scrobbler/scrobblingapi20.cpp @@ -45,16 +45,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "core/logging.h" #include "core/settings.h" #include "core/localredirectserver.h" -#include "utilities/timeconstants.h" -#include "settings/scrobblersettingspage.h" +#include "constants/timeconstants.h" +#include "constants/scrobblersettings.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "scrobblerservice.h" #include "scrobblingapi20.h" #include "scrobblercache.h" @@ -70,7 +70,7 @@ constexpr char kSecret[] = "80fd738f49596e9709b1bf9319c444a8"; constexpr int kScrobblesPerRequest = 50; } -ScrobblingAPI20::ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, SharedPtr settings, SharedPtr network, QObject *parent) +ScrobblingAPI20::ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, SharedPtr settings, SharedPtr network, QObject *parent) : ScrobblerService(name, settings, parent), name_(name), settings_group_(settings_group), @@ -118,11 +118,11 @@ void ScrobblingAPI20::ReloadSettings() { Settings s; s.beginGroup(settings_group_); - enabled_ = s.value("enabled", false).toBool(); + enabled_ = s.value(ScrobblerSettings::kEnabled, false).toBool(); s.endGroup(); - s.beginGroup(ScrobblerSettingsPage::kSettingsGroup); - prefer_albumartist_ = s.value("albumartist", false).toBool(); + s.beginGroup(ScrobblerSettings::kSettingsGroup); + prefer_albumartist_ = s.value(ScrobblerSettings::kAlbumArtist, false).toBool(); s.endGroup(); } @@ -828,7 +828,10 @@ void ScrobblingAPI20::Love() { if (!song_playing_.is_valid() || !song_playing_.is_metadata_good()) return; - if (!authenticated()) settings_->ShowConfig(); + if (!authenticated()) { + Q_EMIT OpenSettingsDialog(); + return; + } qLog(Debug) << name_ << "Sending love for song" << song_playing_.artist() << song_playing_.album() << song_playing_.title(); diff --git a/src/scrobbler/scrobblingapi20.h b/src/scrobbler/scrobblingapi20.h index 68e38a9b1a..bd55b1b8af 100644 --- a/src/scrobbler/scrobblingapi20.h +++ b/src/scrobbler/scrobblingapi20.h @@ -30,7 +30,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "scrobblerservice.h" #include "scrobblercache.h" @@ -38,7 +38,7 @@ class QNetworkReply; -class ScrobblerSettings; +class ScrobblerSettingsService; class NetworkAccessManager; class LocalRedirectServer; @@ -46,7 +46,7 @@ class ScrobblingAPI20 : public ScrobblerService { Q_OBJECT public: - explicit ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, SharedPtr settings, SharedPtr network, QObject *parent = nullptr); + explicit ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, SharedPtr settings, SharedPtr network, QObject *parent = nullptr); ~ScrobblingAPI20() override; static const char *kApiKey; diff --git a/src/scrobbler/subsonicscrobbler.cpp b/src/scrobbler/subsonicscrobbler.cpp index 58174a69a2..3d026db5a5 100644 --- a/src/scrobbler/subsonicscrobbler.cpp +++ b/src/scrobbler/subsonicscrobbler.cpp @@ -27,16 +27,15 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/logging.h" -#include "utilities/timeconstants.h" -#include "settings/subsonicsettingspage.h" -#include "streaming/streamingservices.h" +#include "core/settings.h" +#include "constants/timeconstants.h" +#include "constants/subsonicsettings.h" #include "subsonic/subsonicservice.h" -#include "scrobblersettings.h" +#include "scrobblersettingsservice.h" #include "scrobblerservice.h" #include "subsonicscrobbler.h" @@ -44,10 +43,9 @@ namespace { constexpr char kName[] = "Subsonic"; } -SubsonicScrobbler::SubsonicScrobbler(SharedPtr settings, Application *app, QObject *parent) +SubsonicScrobbler::SubsonicScrobbler(SharedPtr settings, SharedPtr service, QObject *parent) : ScrobblerService(QLatin1String(kName), settings, parent), - app_(app), - service_(nullptr), + service_(service), enabled_(false), submitted_(false) { @@ -61,7 +59,7 @@ SubsonicScrobbler::SubsonicScrobbler(SharedPtr settings, Appl void SubsonicScrobbler::ReloadSettings() { Settings s; - s.beginGroup(SubsonicSettingsPage::kSettingsGroup); + s.beginGroup(SubsonicSettings::kSettingsGroup); enabled_ = s.value("serversidescrobbling", false).toBool(); s.endGroup(); @@ -69,10 +67,6 @@ void SubsonicScrobbler::ReloadSettings() { SubsonicServicePtr SubsonicScrobbler::service() { - if (!service_) { - service_ = app_->streaming_services()->Service(); - } - return service_; } diff --git a/src/scrobbler/subsonicscrobbler.h b/src/scrobbler/subsonicscrobbler.h index f59c28024d..e291445667 100644 --- a/src/scrobbler/subsonicscrobbler.h +++ b/src/scrobbler/subsonicscrobbler.h @@ -30,19 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "scrobblerservice.h" -class Application; -class ScrobblerSettings; +class ScrobblerSettingsService; class SubsonicService; class SubsonicScrobbler : public ScrobblerService { Q_OBJECT public: - explicit SubsonicScrobbler(SharedPtr settings, Application *app, QObject *parent = nullptr); + explicit SubsonicScrobbler(SharedPtr settings, SharedPtr service, QObject *parent = nullptr); void ReloadSettings() override; @@ -63,7 +62,6 @@ class SubsonicScrobbler : public ScrobblerService { void Submit() override; private: - Application *app_; SharedPtr service_; bool enabled_; bool submitted_; diff --git a/src/settings/appearancesettingspage.cpp b/src/settings/appearancesettingspage.cpp index 8e9998bdf6..211e709a95 100644 --- a/src/settings/appearancesettingspage.cpp +++ b/src/settings/appearancesettingspage.cpp @@ -43,48 +43,18 @@ #include #include "appearancesettingspage.h" -#include "utilities/colorutils.h" +#include "constants/appearancesettings.h" +#include "constants/filefilterconstants.h" #include "core/iconloader.h" #include "core/stylehelper.h" #include "core/settings.h" -#include "covermanager/albumcoverchoicecontroller.h" +#include "widgets/fancytabwidget.h" #include "settingspage.h" #include "settingsdialog.h" #include "ui_appearancesettingspage.h" using namespace Qt::Literals::StringLiterals; - -const char *AppearanceSettingsPage::kSettingsGroup = "Appearance"; - -const char *AppearanceSettingsPage::kStyle = "style"; -const char *AppearanceSettingsPage::kSystemThemeIcons = "system_icons"; - -const char *AppearanceSettingsPage::kBackgroundImageType = "background_image_type"; -const char *AppearanceSettingsPage::kBackgroundImageFilename = "background_image_file"; -const char *AppearanceSettingsPage::kBackgroundImagePosition = "background_image_position"; -const char *AppearanceSettingsPage::kBackgroundImageStretch = "background_image_stretch"; -const char *AppearanceSettingsPage::kBackgroundImageDoNotCut = "background_image_do_not_cut"; -const char *AppearanceSettingsPage::kBackgroundImageKeepAspectRatio = "background_image_keep_aspect_ratio"; -const char *AppearanceSettingsPage::kBackgroundImageMaxSize = "background_image_max_size"; - -const char *AppearanceSettingsPage::kBlurRadius = "blur_radius"; -const char *AppearanceSettingsPage::kOpacityLevel = "opacity_level"; - -const int AppearanceSettingsPage::kDefaultBlurRadius = 0; -const int AppearanceSettingsPage::kDefaultOpacityLevel = 40; - -const char *AppearanceSettingsPage::kTabBarSystemColor = "tab_system_color"; -const char *AppearanceSettingsPage::kTabBarGradient = "tab_gradient"; -const char *AppearanceSettingsPage::kTabBarColor = "tab_color"; - -const char *AppearanceSettingsPage::kIconSizeTabbarSmallMode = "icon_size_tabbar_small_mode"; -const char *AppearanceSettingsPage::kIconSizeTabbarLargeMode = "icon_size_tabbar_large_mode"; -const char *AppearanceSettingsPage::kIconSizePlayControlButtons = "icon_size_play_control_buttons"; -const char *AppearanceSettingsPage::kIconSizePlaylistButtons = "icon_size_playlist_buttons"; -const char *AppearanceSettingsPage::kIconSizeLeftPanelButtons = "icon_size_left_panel_buttons"; -const char *AppearanceSettingsPage::kIconSizeConfigureButtons = "icon_size_configure_buttons"; - -const char *AppearanceSettingsPage::kPlaylistPlayingSongColor = "playlist_playing_song_color"; +using namespace AppearanceSettings; AppearanceSettingsPage::AppearanceSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), @@ -160,7 +130,7 @@ void AppearanceSettingsPage::Load() { ui_->tabbar_system_color->setChecked(tabbar_system_color); ui_->tabbar_custom_color->setChecked(!tabbar_system_color); - current_tabbar_bg_color_ = s.value(kTabBarColor, DefaultTabbarBgColor()).value(); + current_tabbar_bg_color_ = s.value(kTabBarColor, FancyTabWidget::DefaultTabbarBgColor()).value(); UpdateColorSelectorColor(ui_->select_tabbar_color, current_tabbar_bg_color_); TabBarSystemColor(ui_->tabbar_system_color->isChecked()); @@ -303,7 +273,7 @@ void AppearanceSettingsPage::UpdateColorSelectorColor(QWidget *color_selector, c void AppearanceSettingsPage::SelectBackgroundImage() { - QString selected_filename = QFileDialog::getOpenFileName(this, tr("Select background image"), background_image_filename_, tr(AlbumCoverChoiceController::kLoadImageFileFilter) + u";;"_s + tr(AlbumCoverChoiceController::kAllFilesFilter)); + QString selected_filename = QFileDialog::getOpenFileName(this, tr("Select background image"), background_image_filename_, tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (selected_filename.isEmpty()) return; background_image_filename_ = selected_filename; ui_->background_image_filename->setText(background_image_filename_); @@ -321,7 +291,7 @@ void AppearanceSettingsPage::OpacityLevelChanged(int percent) { void AppearanceSettingsPage::TabBarSystemColor(bool checked) { if (checked) { - current_tabbar_bg_color_ = DefaultTabbarBgColor(); + current_tabbar_bg_color_ = FancyTabWidget::DefaultTabbarBgColor(); UpdateColorSelectorColor(ui_->select_tabbar_color, current_tabbar_bg_color_); } ui_->layout_tabbar_color->setEnabled(!checked); @@ -370,12 +340,3 @@ void AppearanceSettingsPage::PlaylistPlayingSongSelectColor() { } -QColor AppearanceSettingsPage::DefaultTabbarBgColor() { - - QColor color = StyleHelper::highlightColor(); - if (Utilities::IsColorDark(color)) { - color = color.lighter(130); - } - return color; - -} diff --git a/src/settings/appearancesettingspage.h b/src/settings/appearancesettingspage.h index eca26c0be0..62b53ad067 100644 --- a/src/settings/appearancesettingspage.h +++ b/src/settings/appearancesettingspage.h @@ -29,6 +29,7 @@ #include #include "settingspage.h" +#include "constants/appearancesettings.h" class QWidget; @@ -42,60 +43,9 @@ class AppearanceSettingsPage : public SettingsPage { explicit AppearanceSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~AppearanceSettingsPage() override; - static const char *kSettingsGroup; - - static const char *kStyle; - - static const char *kBackgroundImageType; - static const char *kBackgroundImageFilename; - static const char *kBackgroundImagePosition; - static const char *kBackgroundImageStretch; - static const char *kBackgroundImageDoNotCut; - static const char *kBackgroundImageKeepAspectRatio; - static const char *kBackgroundImageMaxSize; - - static const char *kBlurRadius; - static const char *kOpacityLevel; - - static const int kDefaultBlurRadius; - static const int kDefaultOpacityLevel; - - static const char *kSystemThemeIcons; - - static const char *kTabBarSystemColor; - static const char *kTabBarGradient; - static const char *kTabBarColor; - - static const char *kIconSizeTabbarSmallMode; - static const char *kIconSizeTabbarLargeMode; - static const char *kIconSizePlayControlButtons; - static const char *kIconSizePlaylistButtons; - static const char *kIconSizeLeftPanelButtons; - static const char *kIconSizeConfigureButtons; - - static const char *kPlaylistPlayingSongColor; - - enum class BackgroundImageType { - Default, - None, - Custom, - Album, - Strawbs - }; - - enum class BackgroundImagePosition { - UpperLeft = 1, - UpperRight = 2, - Middle = 3, - BottomLeft = 4, - BottomRight = 5 - }; - void Load() override; void Save() override; - static QColor DefaultTabbarBgColor(); - private Q_SLOTS: void SelectBackgroundImage(); void BlurLevelChanged(int); @@ -112,7 +62,7 @@ class AppearanceSettingsPage : public SettingsPage { Ui_AppearanceSettingsPage *ui_; QColor current_tabbar_bg_color_; - BackgroundImageType background_image_type_; + AppearanceSettings::BackgroundImageType background_image_type_; QString background_image_filename_; QColor current_playlist_playing_song_color_; }; diff --git a/src/settings/backendsettingspage.cpp b/src/settings/backendsettingspage.cpp index eb81a43cef..2a6a635a55 100644 --- a/src/settings/backendsettingspage.cpp +++ b/src/settings/backendsettingspage.cpp @@ -41,11 +41,11 @@ #include "backendsettingspage.h" -#include "core/application.h" +#include "constants/backendsettings.h" #include "core/iconloader.h" -#include "core/player.h" #include "core/logging.h" #include "core/settings.h" +#include "core/player.h" #include "engine/enginebase.h" #include "engine/enginedevice.h" #include "engine/devicefinders.h" @@ -58,11 +58,7 @@ #include "ui_backendsettingspage.h" using namespace Qt::Literals::StringLiterals; - -const char *BackendSettingsPage::kSettingsGroup = "Backend"; -const qint64 BackendSettingsPage::kDefaultBufferDuration = 4000; -const double BackendSettingsPage::kDefaultBufferLowWatermark = 0.33; -const double BackendSettingsPage::kDefaultBufferHighWatermark = 0.99; +using namespace BackendSettings; namespace { constexpr char kOutputAutomaticallySelect[] = "Automatically select"; @@ -128,22 +124,22 @@ void BackendSettingsPage::Load() { Settings s; s.beginGroup(kSettingsGroup); - EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::None)).toString()); - if (enginetype == EngineBase::Type::None && engine()) enginetype = engine()->type(); + EngineBase::Type enginetype = EngineBase::TypeFromName(s.value(kEngine, EngineBase::Name(EngineBase::Type::None)).toString()); + if (enginetype == EngineBase::Type::None && dialog()->engine()) enginetype = dialog()->engine()->type(); ui_->combobox_engine->clear(); ui_->combobox_engine->addItem(IconLoader::Load(u"gstreamer"_s), EngineBase::Description(EngineBase::Type::GStreamer), static_cast(EngineBase::Type::GStreamer)); enginetype_current_ = enginetype; - output_current_ = s.value("output", QString()).toString(); - device_current_ = s.value("device", QVariant()); + output_current_ = s.value(kOutput, QString()).toString(); + device_current_ = s.value(kDevice, QVariant()); ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(enginetype))); #ifdef HAVE_ALSA ui_->lineedit_device->show(); ui_->widget_alsa_plugin->show(); - const ALSAPluginType alsa_plugin_type = static_cast(s.value("alsaplugin", static_cast(ALSAPluginType::PCM)).toInt()); + const ALSAPluginType alsa_plugin_type = static_cast(s.value(kALSAPlugin, static_cast(ALSAPluginType::PCM)).toInt()); switch (alsa_plugin_type) { case ALSAPluginType::HW: ui_->radiobutton_alsa_hw->setChecked(true); @@ -161,34 +157,34 @@ void BackendSettingsPage::Load() { #endif #ifdef Q_OS_WIN32 - ui_->checkbox_exclusive_mode->setChecked(s.value("exclusive_mode", false).toBool()); + ui_->checkbox_exclusive_mode->setChecked(s.value(kExclusiveMode, false).toBool()); #endif if (EngineInitialized()) Load_Engine(enginetype); - ui_->checkbox_volume_control->setChecked(s.value("volume_control", true).toBool()); + ui_->checkbox_volume_control->setChecked(s.value(kVolumeControl, true).toBool()); - ui_->checkbox_channels->setChecked(s.value("channels_enabled", false).toBool()); - ui_->spinbox_channels->setValue(s.value("channels", 2).toInt()); + ui_->checkbox_channels->setChecked(s.value(kChannelsEnabled, false).toBool()); + ui_->spinbox_channels->setValue(s.value(kChannels, 2).toInt()); ui_->widget_channels->setEnabled(ui_->checkbox_channels->isChecked()); - ui_->checkbox_bs2b->setChecked(s.value("bs2b", false).toBool()); + ui_->checkbox_bs2b->setChecked(s.value(kBS2B, false).toBool()); - ui_->checkbox_http2->setChecked(s.value("http2", false).toBool()); - ui_->checkbox_strict_ssl->setChecked(s.value("strict_ssl", false).toBool()); + ui_->checkbox_http2->setChecked(s.value(kHTTP2, false).toBool()); + ui_->checkbox_strict_ssl->setChecked(s.value(kStrictSSL, false).toBool()); - ui_->spinbox_bufferduration->setValue(s.value("bufferduration", kDefaultBufferDuration).toInt()); - ui_->spinbox_low_watermark->setValue(s.value("bufferlowwatermark", kDefaultBufferLowWatermark).toDouble()); - ui_->spinbox_high_watermark->setValue(s.value("bufferhighwatermark", kDefaultBufferHighWatermark).toDouble()); + ui_->spinbox_bufferduration->setValue(s.value(kBufferDuration, kDefaultBufferDuration).toInt()); + ui_->spinbox_low_watermark->setValue(s.value(kBufferLowWatermark, kDefaultBufferLowWatermark).toDouble()); + ui_->spinbox_high_watermark->setValue(s.value(kBufferHighWatermark, kDefaultBufferHighWatermark).toDouble()); - ui_->radiobutton_replaygain->setChecked(s.value("rgenabled", false).toBool()); - ui_->combobox_replaygainmode->setCurrentIndex(s.value("rgmode", 0).toInt()); - ui_->stickyslider_replaygainpreamp->setValue(static_cast(s.value("rgpreamp", 0.0).toDouble() * 10 + 600)); - ui_->checkbox_replaygaincompression->setChecked(s.value("rgcompression", true).toBool()); - ui_->stickyslider_replaygainfallbackgain->setValue(static_cast(s.value("rgfallbackgain", 0.0).toDouble() * 10 + 600)); + ui_->radiobutton_replaygain->setChecked(s.value(kRgEnabled, false).toBool()); + ui_->combobox_replaygainmode->setCurrentIndex(s.value(kRgMode, 0).toInt()); + ui_->stickyslider_replaygainpreamp->setValue(static_cast(s.value(kRgPreamp, 0.0).toDouble() * 10 + 600)); + ui_->checkbox_replaygaincompression->setChecked(s.value(kRgCompression, true).toBool()); + ui_->stickyslider_replaygainfallbackgain->setValue(static_cast(s.value(kRgFallbackGain, 0.0).toDouble() * 10 + 600)); - ui_->radiobutton_ebur128_loudness_normalization->setChecked(s.value("ebur128_loudness_normalization", false).toBool()); - ui_->stickyslider_ebur128_target_level->setValue(static_cast(s.value("ebur128_target_level_lufs", -23.0).toDouble() * 10)); + ui_->radiobutton_ebur128_loudness_normalization->setChecked(s.value(kEBUR128LoudnessNormalization, false).toBool()); + ui_->stickyslider_ebur128_target_level->setValue(static_cast(s.value(kEBUR128TargetLevelLUFS, -23.0).toDouble() * 10)); #ifdef HAVE_ALSA bool fade_default = false; @@ -196,17 +192,17 @@ void BackendSettingsPage::Load() { bool fade_default = true; #endif - ui_->checkbox_fadeout_stop->setChecked(s.value("FadeoutEnabled", fade_default).toBool()); - ui_->checkbox_fadeout_cross->setChecked(s.value("CrossfadeEnabled", fade_default).toBool()); - ui_->checkbox_fadeout_auto->setChecked(s.value("AutoCrossfadeEnabled", false).toBool()); - ui_->checkbox_fadeout_samealbum->setChecked(s.value("NoCrossfadeSameAlbum", true).toBool()); - ui_->checkbox_fadeout_pauseresume->setChecked(s.value("FadeoutPauseEnabled", false).toBool()); - ui_->spinbox_fadeduration->setValue(s.value("FadeoutDuration", 2000).toInt()); - ui_->spinbox_fadeduration_pauseresume->setValue(s.value("FadeoutPauseDuration", 250).toInt()); + ui_->checkbox_fadeout_stop->setChecked(s.value(kFadeoutEnabled, fade_default).toBool()); + ui_->checkbox_fadeout_cross->setChecked(s.value(kCrossfadeEnabled, fade_default).toBool()); + ui_->checkbox_fadeout_auto->setChecked(s.value(kAutoCrossfadeEnabled, false).toBool()); + ui_->checkbox_fadeout_samealbum->setChecked(s.value(kNoCrossfadeSameAlbum, true).toBool()); + ui_->checkbox_fadeout_pauseresume->setChecked(s.value(kFadeoutPauseEnabled, false).toBool()); + ui_->spinbox_fadeduration->setValue(s.value(kFadeoutDuration, 2000).toInt()); + ui_->spinbox_fadeduration_pauseresume->setValue(s.value(kFadeoutPauseDuration, 250).toInt()); if (!EngineInitialized()) return; - if (engine()->state() == EngineBase::State::Empty) { + if (dialog()->engine()->state() == EngineBase::State::Empty) { if (ui_->combobox_engine->count() > 1) ui_->combobox_engine->setEnabled(true); else ui_->combobox_engine->setEnabled(false); } @@ -229,7 +225,7 @@ void BackendSettingsPage::Load() { enginetype = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex()).value(); QString output_name; if (ui_->combobox_output->currentText().isEmpty()) { - output_name = engine()->DefaultOutput(); + output_name = dialog()->engine()->DefaultOutput(); } else { EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); @@ -250,7 +246,7 @@ void BackendSettingsPage::Load() { bool BackendSettingsPage::EngineInitialized() { - if (!engine() || engine()->type() == EngineBase::Type::None) { + if (!dialog()->engine() || dialog()->engine()->type() == EngineBase::Type::None) { errordialog_.ShowMessage(u"Engine is not initialized! Please restart."_s); return false; } @@ -277,12 +273,12 @@ void BackendSettingsPage::Load_Engine(const EngineBase::Type enginetype) { ui_->groupbox_replaygain->setEnabled(false); ui_->groupbox_ebur128->setEnabled(false); - if (engine()->type() != enginetype) { + if (dialog()->engine()->type() != enginetype) { qLog(Debug) << "Switching engine."; - EngineBase::Type new_enginetype = dialog()->app()->player()->CreateEngine(enginetype); - dialog()->app()->player()->Init(); + EngineBase::Type new_enginetype = dialog()->player()->CreateEngine(enginetype); + dialog()->player()->Init(); if (new_enginetype != enginetype) { - ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(engine()->type()))); + ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(dialog()->engine()->type()))); } set_changed(); } @@ -297,10 +293,10 @@ void BackendSettingsPage::Load_Output(QString output, QVariant device) { if (!EngineInitialized()) return; - if (output.isEmpty()) output = engine()->DefaultOutput(); + if (output.isEmpty()) output = dialog()->engine()->DefaultOutput(); ui_->combobox_output->clear(); - const EngineBase::OutputDetailsList outputs = engine()->GetOutputsList(); + const EngineBase::OutputDetailsList outputs = dialog()->engine()->GetOutputsList(); for (const EngineBase::OutputDetails &o : outputs) { ui_->combobox_output->addItem(IconLoader::Load(o.iconname), o.description, QVariant::fromValue(o)); } @@ -316,8 +312,8 @@ void BackendSettingsPage::Load_Output(QString output, QVariant device) { } } if (!found) { // Output is invalid for this engine, reset to default output. - output = engine()->DefaultOutput(); - device = (engine()->CustomDeviceSupport(output) ? QString() : QVariant()); + output = dialog()->engine()->DefaultOutput(); + device = (dialog()->engine()->CustomDeviceSupport(output) ? QString() : QVariant()); for (int i = 0; i < ui_->combobox_output->count(); ++i) { EngineBase::OutputDetails o = ui_->combobox_output->itemData(i).value(); if (o.name == output) { @@ -327,7 +323,7 @@ void BackendSettingsPage::Load_Output(QString output, QVariant device) { } } - if (engine()->type() == EngineBase::Type::GStreamer) { + if (dialog()->engine()->type() == EngineBase::Type::GStreamer) { ui_->groupbox_buffer->setEnabled(true); ui_->groupbox_replaygain->setEnabled(true); ui_->groupbox_ebur128->setEnabled(true); @@ -339,7 +335,7 @@ void BackendSettingsPage::Load_Output(QString output, QVariant device) { } #ifdef Q_OS_WIN32 - ui_->widget_exclusive_mode->setEnabled(engine()->ExclusiveModeSupport(output)); + ui_->widget_exclusive_mode->setEnabled(dialog()->engine()->ExclusiveModeSupport(output)); #endif if (ui_->combobox_output->count() >= 1) Load_Device(output, device); @@ -359,11 +355,11 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev ui_->lineedit_device->clear(); #ifdef Q_OS_WIN - if (engine()->type() != EngineBase::Type::GStreamer) + if (dialog()->engine()->type() != EngineBase::Type::GStreamer) #endif ui_->combobox_device->addItem(IconLoader::Load(u"soundcard"_s), QLatin1String(kOutputAutomaticallySelect), QVariant()); - const QList device_finders = dialog()->app()->device_finders()->ListFinders(); + const QList device_finders = dialog()->device_finders()->ListFinders(); for (DeviceFinder *f : device_finders) { if (!f->outputs().contains(output)) continue; const EngineDeviceList engine_devices = f->ListDevices(); @@ -374,7 +370,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev } } - if (engine()->CustomDeviceSupport(output)) { + if (dialog()->engine()->CustomDeviceSupport(output)) { ui_->combobox_device->addItem(IconLoader::Load(u"soundcard"_s), QLatin1String(kOutputCustom), QVariant()); ui_->lineedit_device->setEnabled(true); } @@ -383,7 +379,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev } #ifdef HAVE_ALSA - if (engine()->ALSADeviceSupport(output)) { + if (dialog()->engine()->ALSADeviceSupport(output)) { ui_->widget_alsa_plugin->setEnabled(true); ui_->radiobutton_alsa_hw->setEnabled(true); ui_->radiobutton_alsa_plughw->setEnabled(true); @@ -435,7 +431,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev } // This allows a custom ALSA device string ie: "hw:0,0" even if it is not listed. - if (engine()->CustomDeviceSupport(output) && device.metaType().id() == QMetaType::QString && !device.toString().isEmpty()) { + if (dialog()->engine()->CustomDeviceSupport(output) && device.metaType().id() == QMetaType::QString && !device.toString().isEmpty()) { ui_->lineedit_device->setText(device.toString()); if (!found) { for (int i = 0; i < ui_->combobox_device->count(); ++i) { @@ -447,7 +443,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev } } - ui_->combobox_device->setEnabled(devices > 0 || engine()->CustomDeviceSupport(output)); + ui_->combobox_device->setEnabled(devices > 0 || dialog()->engine()->CustomDeviceSupport(output)); FadingOptionsChanged(); @@ -463,7 +459,7 @@ void BackendSettingsPage::Save() { QVariant device_value; if (ui_->combobox_output->currentText().isEmpty()) { - output_name = engine()->DefaultOutput(); + output_name = dialog()->engine()->DefaultOutput(); } else { EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); @@ -477,51 +473,51 @@ void BackendSettingsPage::Save() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("engine", EngineBase::Name(enginetype)); - s.setValue("output", output_name); - s.setValue("device", device_value); + s.setValue(kEngine, EngineBase::Name(enginetype)); + s.setValue(kOutput, output_name); + s.setValue(kDevice, device_value); #ifdef HAVE_ALSA - if (ui_->radiobutton_alsa_hw->isChecked()) s.setValue("alsaplugin", static_cast(ALSAPluginType::HW)); - else if (ui_->radiobutton_alsa_plughw->isChecked()) s.setValue("alsaplugin", static_cast(ALSAPluginType::PlugHW)); - else if (ui_->radiobutton_alsa_pcm->isChecked()) s.setValue("alsaplugin", static_cast(ALSAPluginType::PCM)); - else s.remove("alsaplugin"); + if (ui_->radiobutton_alsa_hw->isChecked()) s.setValue(kALSAPlugin, static_cast(ALSAPluginType::HW)); + else if (ui_->radiobutton_alsa_plughw->isChecked()) s.setValue(kALSAPlugin, static_cast(ALSAPluginType::PlugHW)); + else if (ui_->radiobutton_alsa_pcm->isChecked()) s.setValue(kALSAPlugin, static_cast(ALSAPluginType::PCM)); + else s.remove(kALSAPlugin); #endif #ifdef Q_OS_WIN32 - s.setValue("exclusive_mode", ui_->checkbox_exclusive_mode->isChecked()); + s.setValue(kExclusiveMode, ui_->checkbox_exclusive_mode->isChecked()); #endif - s.setValue("volume_control", ui_->checkbox_volume_control->isChecked()); + s.setValue(kVolumeControl, ui_->checkbox_volume_control->isChecked()); - s.setValue("channels_enabled", ui_->checkbox_channels->isChecked()); - s.setValue("channels", ui_->spinbox_channels->value()); + s.setValue(kChannelsEnabled, ui_->checkbox_channels->isChecked()); + s.setValue(kChannels, ui_->spinbox_channels->value()); - s.setValue("bs2b", ui_->checkbox_bs2b->isChecked()); + s.setValue(kBS2B, ui_->checkbox_bs2b->isChecked()); - s.setValue("http2", ui_->checkbox_http2->isChecked()); - s.setValue("strict_ssl", ui_->checkbox_strict_ssl->isChecked()); + s.setValue(kHTTP2, ui_->checkbox_http2->isChecked()); + s.setValue(kStrictSSL, ui_->checkbox_strict_ssl->isChecked()); - s.setValue("bufferduration", ui_->spinbox_bufferduration->value()); - s.setValue("bufferlowwatermark", ui_->spinbox_low_watermark->value()); - s.setValue("bufferhighwatermark", ui_->spinbox_high_watermark->value()); + s.setValue(kBufferDuration, ui_->spinbox_bufferduration->value()); + s.setValue(kBufferLowWatermark, ui_->spinbox_low_watermark->value()); + s.setValue(kBufferHighWatermark, ui_->spinbox_high_watermark->value()); - s.setValue("rgenabled", ui_->radiobutton_replaygain->isChecked()); - s.setValue("rgmode", ui_->combobox_replaygainmode->currentIndex()); - s.setValue("rgpreamp", static_cast(ui_->stickyslider_replaygainpreamp->value()) / 10 - 60); - s.setValue("rgfallbackgain", static_cast(ui_->stickyslider_replaygainfallbackgain->value()) / 10 - 60); - s.setValue("rgcompression", ui_->checkbox_replaygaincompression->isChecked()); + s.setValue(kRgEnabled, ui_->radiobutton_replaygain->isChecked()); + s.setValue(kRgMode, ui_->combobox_replaygainmode->currentIndex()); + s.setValue(kRgPreamp, static_cast(ui_->stickyslider_replaygainpreamp->value()) / 10 - 60); + s.setValue(kRgFallbackGain, static_cast(ui_->stickyslider_replaygainfallbackgain->value()) / 10 - 60); + s.setValue(kRgCompression, ui_->checkbox_replaygaincompression->isChecked()); - s.setValue("ebur128_loudness_normalization", ui_->radiobutton_ebur128_loudness_normalization->isChecked()); - s.setValue("ebur128_target_level_lufs", static_cast(ui_->stickyslider_ebur128_target_level->value()) / 10); + s.setValue(kEBUR128LoudnessNormalization, ui_->radiobutton_ebur128_loudness_normalization->isChecked()); + s.setValue(kEBUR128TargetLevelLUFS, static_cast(ui_->stickyslider_ebur128_target_level->value()) / 10); - s.setValue("FadeoutEnabled", ui_->checkbox_fadeout_stop->isChecked()); - s.setValue("CrossfadeEnabled", ui_->checkbox_fadeout_cross->isChecked()); - s.setValue("AutoCrossfadeEnabled", ui_->checkbox_fadeout_auto->isChecked()); - s.setValue("NoCrossfadeSameAlbum", ui_->checkbox_fadeout_samealbum->isChecked()); - s.setValue("FadeoutPauseEnabled", ui_->checkbox_fadeout_pauseresume->isChecked()); - s.setValue("FadeoutDuration", ui_->spinbox_fadeduration->value()); - s.setValue("FadeoutPauseDuration", ui_->spinbox_fadeduration_pauseresume->value()); + s.setValue(kFadeoutEnabled, ui_->checkbox_fadeout_stop->isChecked()); + s.setValue(kCrossfadeEnabled, ui_->checkbox_fadeout_cross->isChecked()); + s.setValue(kAutoCrossfadeEnabled, ui_->checkbox_fadeout_auto->isChecked()); + s.setValue(kNoCrossfadeSameAlbum, ui_->checkbox_fadeout_samealbum->isChecked()); + s.setValue(kFadeoutPauseEnabled, ui_->checkbox_fadeout_pauseresume->isChecked()); + s.setValue(kFadeoutDuration, ui_->spinbox_fadeduration->value()); + s.setValue(kFadeoutPauseDuration, ui_->spinbox_fadeduration_pauseresume->value()); s.endGroup(); @@ -529,9 +525,9 @@ void BackendSettingsPage::Save() { void BackendSettingsPage::Cancel() { - if (engine() && engine()->type() != enginetype_current_) { // Reset engine back to the original because user cancelled. - dialog()->app()->player()->CreateEngine(enginetype_current_); - dialog()->app()->player()->Init(); + if (dialog()->engine() && dialog()->engine()->type() != enginetype_current_) { // Reset engine back to the original because user cancelled. + dialog()->player()->CreateEngine(enginetype_current_); + dialog()->player()->Init(); } } @@ -543,11 +539,11 @@ void BackendSettingsPage::EngineChanged(const int index) { QVariant v = ui_->combobox_engine->itemData(index); EngineBase::Type enginetype = v.value(); - if (engine()->type() == enginetype) return; + if (dialog()->engine()->type() == enginetype) return; - if (engine()->state() != EngineBase::State::Empty) { + if (dialog()->engine()->state() != EngineBase::State::Empty) { errordialog_.ShowMessage(u"Can't switch engine while playing!"_s); - ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(engine()->type()))); + ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(dialog()->engine()->type()))); return; } @@ -563,7 +559,7 @@ void BackendSettingsPage::OutputChanged(const int index) { EngineBase::OutputDetails output = ui_->combobox_output->itemData(index).value(); #ifdef Q_OS_WIN32 - ui_->widget_exclusive_mode->setEnabled(engine()->ExclusiveModeSupport(output.name)); + ui_->widget_exclusive_mode->setEnabled(dialog()->engine()->ExclusiveModeSupport(output.name)); #endif Load_Device(output.name, QVariant()); @@ -577,7 +573,7 @@ void BackendSettingsPage::DeviceSelectionChanged(int index) { EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); QVariant device = ui_->combobox_device->itemData(index).value(); - if (engine()->CustomDeviceSupport(output.name)) { + if (dialog()->engine()->CustomDeviceSupport(output.name)) { ui_->lineedit_device->setEnabled(true); if (ui_->combobox_device->currentText() != QLatin1String(kOutputCustom)) { if (device.metaType().id() == QMetaType::QString) @@ -602,7 +598,7 @@ void BackendSettingsPage::DeviceStringChanged() { bool found = false; #ifdef HAVE_ALSA - if (engine()->ALSADeviceSupport(output.name)) { + if (dialog()->engine()->ALSADeviceSupport(output.name)) { if (ui_->lineedit_device->text().contains(kRegex_ALSA_HW) && !ui_->radiobutton_alsa_hw->isChecked()) { ui_->radiobutton_alsa_hw->setChecked(true); SwitchALSADevices(ALSAPluginType::HW); @@ -630,7 +626,7 @@ void BackendSettingsPage::DeviceStringChanged() { } } - if (engine()->CustomDeviceSupport(output.name)) { + if (dialog()->engine()->CustomDeviceSupport(output.name)) { ui_->lineedit_device->setEnabled(true); if ((!found) && (ui_->combobox_device->currentText() != QLatin1String(kOutputCustom))) { for (int i = 0; i < ui_->combobox_device->count(); ++i) { @@ -711,7 +707,7 @@ void BackendSettingsPage::radiobutton_alsa_hw_clicked(const bool checked) { if (!configloaded_ || !EngineInitialized()) return; EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); - if (!engine()->ALSADeviceSupport(output.name)) return; + if (!dialog()->engine()->ALSADeviceSupport(output.name)) return; SwitchALSADevices(ALSAPluginType::HW); @@ -740,7 +736,7 @@ void BackendSettingsPage::radiobutton_alsa_plughw_clicked(const bool checked) { if (!configloaded_ || !EngineInitialized()) return; EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); - if (!engine()->ALSADeviceSupport(output.name)) return; + if (!dialog()->engine()->ALSADeviceSupport(output.name)) return; SwitchALSADevices(ALSAPluginType::PlugHW); @@ -769,7 +765,7 @@ void BackendSettingsPage::radiobutton_alsa_pcm_clicked(const bool checked) { if (!configloaded_ || !EngineInitialized()) return; EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); - if (!engine()->ALSADeviceSupport(output.name)) return; + if (!dialog()->engine()->ALSADeviceSupport(output.name)) return; SwitchALSADevices(ALSAPluginType::PCM); @@ -827,8 +823,8 @@ void BackendSettingsPage::FadingOptionsChanged() { if (!configloaded_ || !EngineInitialized()) return; EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); - if (engine()->type() == EngineBase::Type::GStreamer && - (!engine()->ALSADeviceSupport(output.name) || ui_->lineedit_device->text().isEmpty() || (!ui_->lineedit_device->text().contains(kRegex_ALSA_HW) && !ui_->lineedit_device->text().contains(kRegex_ALSA_PlugHW)))) { + if (dialog()->engine()->type() == EngineBase::Type::GStreamer && + (!dialog()->engine()->ALSADeviceSupport(output.name) || ui_->lineedit_device->text().isEmpty() || (!ui_->lineedit_device->text().contains(kRegex_ALSA_HW) && !ui_->lineedit_device->text().contains(kRegex_ALSA_PlugHW)))) { ui_->groupbox_fading->setEnabled(true); } else { diff --git a/src/settings/backendsettingspage.h b/src/settings/backendsettingspage.h index 4e20a12bdf..6cada70907 100644 --- a/src/settings/backendsettingspage.h +++ b/src/settings/backendsettingspage.h @@ -26,9 +26,6 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" -#include "core/player.h" #include "engine/enginebase.h" #include "dialogs/errordialog.h" #include "settingspage.h" @@ -43,17 +40,10 @@ class BackendSettingsPage : public SettingsPage { explicit BackendSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~BackendSettingsPage() override; - static const char *kSettingsGroup; - static const qint64 kDefaultBufferDuration; - static const double kDefaultBufferLowWatermark; - static const double kDefaultBufferHighWatermark; - void Load() override; void Save() override; void Cancel() override; - SharedPtr engine() const { return dialog()->app()->player()->engine(); } - #ifdef HAVE_ALSA enum class ALSAPluginType { HW = 1, diff --git a/src/settings/behavioursettingspage.cpp b/src/settings/behavioursettingspage.cpp index fd7e20ea36..781e9283ab 100644 --- a/src/settings/behavioursettingspage.cpp +++ b/src/settings/behavioursettingspage.cpp @@ -39,6 +39,7 @@ #include #include +#include "constants/behavioursettings.h" #include "core/iconloader.h" #include "core/settings.h" #include "settings/settingspage.h" @@ -46,11 +47,10 @@ #include "ui_behavioursettingspage.h" using namespace Qt::Literals::StringLiterals; +using namespace BehaviourSettings; class SettingsDialog; -const char *BehaviourSettingsPage::kSettingsGroup = "Behaviour"; - #ifdef HAVE_TRANSLATIONS namespace { bool LocaleAwareCompare(const QString &a, const QString &b) { @@ -151,26 +151,26 @@ void BehaviourSettingsPage::Load() { #ifdef Q_OS_MACOS ui_->checkbox_keeprunning->setEnabled(true); - ui_->checkbox_keeprunning->setChecked(s.value("keeprunning", false).toBool()); + ui_->checkbox_keeprunning->setChecked(s.value(kKeepRunning, false).toBool()); #else const bool systemtray_available = QSystemTrayIcon::isSystemTrayAvailable(); ui_->checkbox_showtrayicon->setEnabled(systemtray_available); - ui_->checkbox_showtrayicon->setChecked(systemtray_available && s.value("showtrayicon", true).toBool()); + ui_->checkbox_showtrayicon->setChecked(systemtray_available && s.value(kShowTrayIcon, true).toBool()); ui_->checkbox_keeprunning->setEnabled(systemtray_available && ui_->checkbox_showtrayicon->isChecked()); - ui_->checkbox_keeprunning->setChecked(s.value("keeprunning", false).toBool()); + ui_->checkbox_keeprunning->setChecked(s.value(kKeepRunning, false).toBool()); ui_->checkbox_trayicon_progress->setEnabled(systemtray_available && ui_->checkbox_showtrayicon->isChecked()); - ui_->checkbox_trayicon_progress->setChecked(systemtray_available && ui_->checkbox_showtrayicon->isChecked() && s.value("trayicon_progress", false).toBool()); + ui_->checkbox_trayicon_progress->setChecked(systemtray_available && ui_->checkbox_showtrayicon->isChecked() && s.value(kTrayIconProgress, false).toBool()); ui_->radiobutton_hide->setEnabled(systemtray_available && ui_->checkbox_showtrayicon->isChecked()); #ifdef HAVE_DBUS - ui_->checkbox_taskbar_progress->setChecked(s.value("taskbar_progress", true).toBool()); + ui_->checkbox_taskbar_progress->setChecked(s.value(kTaskbarProgress, true).toBool()); #endif #endif - ui_->checkbox_resumeplayback->setChecked(s.value("resumeplayback", false).toBool()); - ui_->checkbox_playingwidget->setChecked(s.value("playing_widget", true).toBool()); + ui_->checkbox_resumeplayback->setChecked(s.value(kResumePlayback, false).toBool()); + ui_->checkbox_playingwidget->setChecked(s.value(kPlayingWidget, true).toBool()); #ifndef Q_OS_MACOS - const StartupBehaviour startup_behaviour = static_cast(s.value("startupbehaviour", static_cast(StartupBehaviour::Remember)).toInt()); + const StartupBehaviour startup_behaviour = static_cast(s.value(kStartupBehaviour, static_cast(StartupBehaviour::Remember)).toInt()); switch (startup_behaviour) { case StartupBehaviour::Show: ui_->radiobutton_show->setChecked(true); @@ -188,13 +188,13 @@ void BehaviourSettingsPage::Load() { } ; [[fallthrough]]; - case BehaviourSettingsPage::StartupBehaviour::Remember: + case StartupBehaviour::Remember: ui_->radiobutton_remember->setChecked(true); break; } #endif - QString name = language_map_.key(s.value("language").toString()); + QString name = language_map_.key(s.value(kLanguage).toString()); if (name.isEmpty()) { ui_->combobox_language->setCurrentIndex(0); } @@ -202,19 +202,19 @@ void BehaviourSettingsPage::Load() { ui_->combobox_language->setCurrentIndex(ui_->combobox_language->findText(name)); } - ui_->combobox_menuplaymode->setCurrentIndex(ui_->combobox_menuplaymode->findData(s.value("menu_playmode", static_cast(PlayBehaviour::Never)).toInt())); + ui_->combobox_menuplaymode->setCurrentIndex(ui_->combobox_menuplaymode->findData(s.value(kMenuPlayMode, static_cast(PlayBehaviour::Never)).toInt())); - ui_->combobox_previousmode->setCurrentIndex(ui_->combobox_previousmode->findData(s.value("menu_previousmode", static_cast(PreviousBehaviour::DontRestart)).toInt())); + ui_->combobox_previousmode->setCurrentIndex(ui_->combobox_previousmode->findData(s.value(kMenuPreviousMode, static_cast(PreviousBehaviour::DontRestart)).toInt())); - ui_->combobox_doubleclickaddmode->setCurrentIndex(ui_->combobox_doubleclickaddmode->findData(s.value("doubleclick_addmode", static_cast(AddBehaviour::Append)).toInt())); + ui_->combobox_doubleclickaddmode->setCurrentIndex(ui_->combobox_doubleclickaddmode->findData(s.value(kDoubleClickAddMode, static_cast(AddBehaviour::Append)).toInt())); - ui_->combobox_doubleclickplaymode->setCurrentIndex(ui_->combobox_doubleclickplaymode->findData(s.value("doubleclick_playmode", static_cast(PlayBehaviour::Never)).toInt())); + ui_->combobox_doubleclickplaymode->setCurrentIndex(ui_->combobox_doubleclickplaymode->findData(s.value(kDoubleClickPlayMode, static_cast(PlayBehaviour::Never)).toInt())); - ui_->combobox_doubleclickplaylistaddmode->setCurrentIndex(ui_->combobox_doubleclickplaylistaddmode->findData(s.value("doubleclick_playlist_addmode", static_cast(PlaylistAddBehaviour::Play)).toInt())); + ui_->combobox_doubleclickplaylistaddmode->setCurrentIndex(ui_->combobox_doubleclickplaylistaddmode->findData(s.value(kDoubleClickPlaylistAddMode, static_cast(PlaylistAddBehaviour::Play)).toInt())); - ui_->spinbox_seekstepsec->setValue(s.value("seek_step_sec", 10).toInt()); + ui_->spinbox_seekstepsec->setValue(s.value(kSeekStepSec, 10).toInt()); - ui_->spinbox_volumeincrement->setValue(s.value("volume_increment", 5).toInt()); + ui_->spinbox_volumeincrement->setValue(s.value(kVolumeIncrement, 5).toInt()); s.endGroup(); @@ -229,14 +229,14 @@ void BehaviourSettingsPage::Save() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("showtrayicon", ui_->checkbox_showtrayicon->isChecked()); - s.setValue("keeprunning", ui_->checkbox_keeprunning->isChecked()); - s.setValue("trayicon_progress", ui_->checkbox_trayicon_progress->isChecked()); + s.setValue(kShowTrayIcon, ui_->checkbox_showtrayicon->isChecked()); + s.setValue(kKeepRunning, ui_->checkbox_keeprunning->isChecked()); + s.setValue(kTrayIconProgress, ui_->checkbox_trayicon_progress->isChecked()); #if defined(HAVE_DBUS) && !defined(Q_OS_MACOS) - s.setValue("taskbar_progress", ui_->checkbox_taskbar_progress->isChecked()); + s.setValue(kTaskbarProgress, ui_->checkbox_taskbar_progress->isChecked()); #endif - s.setValue("resumeplayback", ui_->checkbox_resumeplayback->isChecked()); - s.setValue("playing_widget", ui_->checkbox_playingwidget->isChecked()); + s.setValue(kResumePlayback, ui_->checkbox_resumeplayback->isChecked()); + s.setValue(kPlayingWidget, ui_->checkbox_playingwidget->isChecked()); StartupBehaviour startup_behaviour = StartupBehaviour::Remember; if (ui_->radiobutton_remember->isChecked()) startup_behaviour = StartupBehaviour::Remember; @@ -244,9 +244,9 @@ void BehaviourSettingsPage::Save() { if (ui_->radiobutton_hide->isChecked()) startup_behaviour = StartupBehaviour::Hide; if (ui_->radiobutton_show_maximized->isChecked()) startup_behaviour = StartupBehaviour::ShowMaximized; if (ui_->radiobutton_show_minimized->isChecked()) startup_behaviour = StartupBehaviour::ShowMinimized; - s.setValue("startupbehaviour", static_cast(startup_behaviour)); + s.setValue(kStartupBehaviour, static_cast(startup_behaviour)); - s.setValue("language", language_map_.contains(ui_->combobox_language->currentText()) ? language_map_[ui_->combobox_language->currentText()] : QString()); + s.setValue(kLanguage, language_map_.contains(ui_->combobox_language->currentText()) ? language_map_[ui_->combobox_language->currentText()] : QString()); const PlayBehaviour menu_playmode = static_cast(ui_->combobox_menuplaymode->currentData().toInt()); @@ -257,15 +257,15 @@ void BehaviourSettingsPage::Save() { const PlaylistAddBehaviour doubleclick_playlist_addmode = static_cast(ui_->combobox_doubleclickplaylistaddmode->currentData().toInt()); - s.setValue("menu_playmode", static_cast(menu_playmode)); - s.setValue("menu_previousmode", static_cast(menu_previousmode)); - s.setValue("doubleclick_addmode", static_cast(doubleclick_addmode)); - s.setValue("doubleclick_playmode", static_cast(doubleclick_playmode)); - s.setValue("doubleclick_playlist_addmode", static_cast(doubleclick_playlist_addmode)); + s.setValue(kMenuPlayMode, static_cast(menu_playmode)); + s.setValue(kMenuPreviousMode, static_cast(menu_previousmode)); + s.setValue(kDoubleClickAddMode, static_cast(doubleclick_addmode)); + s.setValue(kDoubleClickPlayMode, static_cast(doubleclick_playmode)); + s.setValue(kDoubleClickPlaylistAddMode, static_cast(doubleclick_playlist_addmode)); - s.setValue("seek_step_sec", ui_->spinbox_seekstepsec->value()); + s.setValue(kSeekStepSec, ui_->spinbox_seekstepsec->value()); - s.setValue("volume_increment", ui_->spinbox_volumeincrement->value()); + s.setValue(kVolumeIncrement, ui_->spinbox_volumeincrement->value()); s.endGroup(); diff --git a/src/settings/behavioursettingspage.h b/src/settings/behavioursettingspage.h index fa44bcfae3..ebce1f247f 100644 --- a/src/settings/behavioursettingspage.h +++ b/src/settings/behavioursettingspage.h @@ -40,40 +40,6 @@ class BehaviourSettingsPage : public SettingsPage { explicit BehaviourSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~BehaviourSettingsPage() override; - static const char *kSettingsGroup; - - // Don't change the values - enum class StartupBehaviour { - Remember = 1, - Show = 2, - Hide = 3, - ShowMaximized = 4, - ShowMinimized = 5 - }; - - enum class PlayBehaviour { - Never = 1, - IfStopped = 2, - Always = 3 - }; - - enum class PreviousBehaviour { - DontRestart = 1, - Restart = 2 - }; - - enum class AddBehaviour { - Append = 1, - Enqueue = 2, - Load = 3, - OpenInNew = 4 - }; - - enum class PlaylistAddBehaviour { - Play = 1, - Enqueue = 2 - }; - void Load() override; void Save() override; diff --git a/src/settings/collectionsettingspage.cpp b/src/settings/collectionsettingspage.cpp index 86f5764861..e72963a380 100644 --- a/src/settings/collectionsettingspage.cpp +++ b/src/settings/collectionsettingspage.cpp @@ -43,12 +43,10 @@ #include #include -#include "core/application.h" #include "core/iconloader.h" #include "core/settings.h" #include "utilities/strutils.h" -#include "utilities/timeutils.h" -#include "collection/collection.h" +#include "collection/collectionlibrary.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" #include "collection/collectiondirectory.h" @@ -58,25 +56,18 @@ #include "playlist/playlistdelegates.h" #include "settings/settingsdialog.h" #include "settings/settingspage.h" +#include "constants/collectionsettings.h" #include "ui_collectionsettingspage.h" using namespace Qt::Literals::StringLiterals; - -const char *CollectionSettingsPage::kSettingsGroup = "Collection"; -const char *CollectionSettingsPage::kSettingsCacheSize = "cache_size"; -const char *CollectionSettingsPage::kSettingsCacheSizeUnit = "cache_size_unit"; -const char *CollectionSettingsPage::kSettingsDiskCacheEnable = "disk_cache_enable"; -const char *CollectionSettingsPage::kSettingsDiskCacheSize = "disk_cache_size"; -const char *CollectionSettingsPage::kSettingsDiskCacheSizeUnit = "disk_cache_size_unit"; -const int CollectionSettingsPage::kSettingsCacheSizeDefault = 160; -const int CollectionSettingsPage::kSettingsDiskCacheSizeDefault = 360; +using namespace CollectionSettings; CollectionSettingsPage::CollectionSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), ui_(new Ui_CollectionSettingsPage), - collection_backend_(dialog->app()->collection_backend()), + collection_backend_(dialog->collection()->backend()), collectionsettings_directory_model_(new CollectionSettingsDirectoryModel(this)), - collection_directory_model_(dialog->collection_directory_model()), + collection_directory_model_(dialog->collection()->model()->directory_model()), initialized_model_(false) { ui_->setupUi(this); @@ -105,7 +96,7 @@ CollectionSettingsPage::CollectionSettingsPage(SettingsDialog *dialog, QWidget * #else QObject::connect(ui_->checkbox_disk_cache, &QCheckBox::stateChanged, this, &CollectionSettingsPage::DiskCacheEnable); #endif - QObject::connect(ui_->button_clear_disk_cache, &QPushButton::clicked, dialog->app(), &Application::ClearPixmapDiskCache); + QObject::connect(ui_->button_clear_disk_cache, &QPushButton::clicked, this, &CollectionSettingsPage::ClearPixmapDiskCache); QObject::connect(ui_->combobox_cache_size, QOverload::of(&QComboBox::currentIndexChanged), this, &CollectionSettingsPage::CacheSizeUnitChanged); @@ -147,19 +138,19 @@ void CollectionSettingsPage::Load() { Settings s; s.beginGroup(kSettingsGroup); - ui_->auto_open->setChecked(s.value("auto_open", true).toBool()); - ui_->show_dividers->setChecked(s.value("show_dividers", true).toBool()); - ui_->pretty_covers->setChecked(s.value("pretty_covers", true).toBool()); - ui_->various_artists->setChecked(s.value("various_artists", true).toBool()); - ui_->sort_skips_articles->setChecked(s.value("sort_skips_articles", true).toBool()); - ui_->startup_scan->setChecked(s.value("startup_scan", true).toBool()); - ui_->monitor->setChecked(s.value("monitor", true).toBool()); - ui_->song_tracking->setChecked(s.value("song_tracking", false).toBool()); - ui_->song_ebur128_loudness_analysis->setChecked(s.value("song_ebur128_loudness_analysis", false).toBool()); - ui_->mark_songs_unavailable->setChecked(ui_->song_tracking->isChecked() ? true : s.value("mark_songs_unavailable", true).toBool()); - ui_->expire_unavailable_songs_days->setValue(s.value("expire_unavailable_songs", 60).toInt()); - - QStringList filters = s.value("cover_art_patterns", QStringList() << u"front"_s << u"cover"_s).toStringList(); + ui_->auto_open->setChecked(s.value(kAutoOpen, true).toBool()); + ui_->show_dividers->setChecked(s.value(kShowDividers, true).toBool()); + ui_->pretty_covers->setChecked(s.value(kPrettyCovers, true).toBool()); + ui_->various_artists->setChecked(s.value(kVariousArtists, true).toBool()); + ui_->sort_skips_articles->setChecked(s.value(kSortSkipsArticles, true).toBool()); + ui_->startup_scan->setChecked(s.value(kStartupScan, true).toBool()); + ui_->monitor->setChecked(s.value(kMonitor, true).toBool()); + ui_->song_tracking->setChecked(s.value(kSongTracking, false).toBool()); + ui_->song_ebur128_loudness_analysis->setChecked(s.value(kSongENUR128LoudnessAnalysis, false).toBool()); + ui_->mark_songs_unavailable->setChecked(ui_->song_tracking->isChecked() ? true : s.value(kMarkSongsUnavailable, true).toBool()); + ui_->expire_unavailable_songs_days->setValue(s.value(kExpireUnavailableSongs, 60).toInt()); + + QStringList filters = s.value(kCoverArtPatterns, QStringList() << u"front"_s << u"cover"_s).toStringList(); ui_->cover_art_patterns->setText(filters.join(u',')); ui_->spinbox_cache_size->setValue(s.value(kSettingsCacheSize, kSettingsCacheSizeDefault).toInt()); @@ -168,18 +159,18 @@ void CollectionSettingsPage::Load() { ui_->spinbox_disk_cache_size->setValue(s.value(kSettingsDiskCacheSize, kSettingsDiskCacheSizeDefault).toInt()); ui_->combobox_disk_cache_size->setCurrentIndex(ui_->combobox_disk_cache_size->findData(s.value(kSettingsDiskCacheSizeUnit, static_cast(CacheSizeUnit::MB)).toInt())); - ui_->checkbox_save_playcounts->setChecked(s.value("save_playcounts", false).toBool()); - ui_->checkbox_save_ratings->setChecked(s.value("save_ratings", false).toBool()); - ui_->checkbox_overwrite_playcount->setChecked(s.value("overwrite_playcount", false).toBool()); - ui_->checkbox_overwrite_rating->setChecked(s.value("overwrite_rating", false).toBool()); + ui_->checkbox_save_playcounts->setChecked(s.value(kSavePlayCounts, false).toBool()); + ui_->checkbox_save_ratings->setChecked(s.value(kSaveRatings, false).toBool()); + ui_->checkbox_overwrite_playcount->setChecked(s.value(kOverwritePlaycount, false).toBool()); + ui_->checkbox_overwrite_rating->setChecked(s.value(kOverwriteRating, false).toBool()); - ui_->checkbox_delete_files->setChecked(s.value("delete_files", false).toBool()); + ui_->checkbox_delete_files->setChecked(s.value(kDeleteFiles, false).toBool()); s.endGroup(); DiskCacheEnable(ui_->checkbox_disk_cache->checkState()); - ui_->disk_cache_in_use->setText((dialog()->app()->collection_model()->icon_cache_disk_size() == 0 ? u"empty"_s : Utilities::PrettySize(dialog()->app()->collection_model()->icon_cache_disk_size()))); + UpdateIconDiskCacheSize(); Init(ui_->layout_collectionsettingspage->parentWidget()); if (!Settings().childGroups().contains(QLatin1String(kSettingsGroup))) set_changed(); @@ -191,23 +182,23 @@ void CollectionSettingsPage::Save() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("auto_open", ui_->auto_open->isChecked()); - s.setValue("show_dividers", ui_->show_dividers->isChecked()); - s.setValue("pretty_covers", ui_->pretty_covers->isChecked()); - s.setValue("various_artists", ui_->various_artists->isChecked()); - s.setValue("sort_skips_articles", ui_->sort_skips_articles->isChecked()); - s.setValue("startup_scan", ui_->startup_scan->isChecked()); - s.setValue("monitor", ui_->monitor->isChecked()); - s.setValue("song_tracking", ui_->song_tracking->isChecked()); - s.setValue("song_ebur128_loudness_analysis", ui_->song_ebur128_loudness_analysis->isChecked()); - s.setValue("mark_songs_unavailable", ui_->song_tracking->isChecked() ? true : ui_->mark_songs_unavailable->isChecked()); - s.setValue("expire_unavailable_songs", ui_->expire_unavailable_songs_days->value()); + s.setValue(kAutoOpen, ui_->auto_open->isChecked()); + s.setValue(kShowDividers, ui_->show_dividers->isChecked()); + s.setValue(kPrettyCovers, ui_->pretty_covers->isChecked()); + s.setValue(kVariousArtists, ui_->various_artists->isChecked()); + s.setValue(kSortSkipsArticles, ui_->sort_skips_articles->isChecked()); + s.setValue(kStartupScan, ui_->startup_scan->isChecked()); + s.setValue(kMonitor, ui_->monitor->isChecked()); + s.setValue(kSongTracking, ui_->song_tracking->isChecked()); + s.setValue(kSongENUR128LoudnessAnalysis, ui_->song_ebur128_loudness_analysis->isChecked()); + s.setValue(kMarkSongsUnavailable, ui_->song_tracking->isChecked() ? true : ui_->mark_songs_unavailable->isChecked()); + s.setValue(kExpireUnavailableSongs, ui_->expire_unavailable_songs_days->value()); QString filter_text = ui_->cover_art_patterns->text(); const QStringList filters = filter_text.split(u',', Qt::SkipEmptyParts); - s.setValue("cover_art_patterns", filters); + s.setValue(kCoverArtPatterns, filters); s.setValue(kSettingsCacheSize, ui_->spinbox_cache_size->value()); s.setValue(kSettingsCacheSizeUnit, ui_->combobox_cache_size->currentData().toInt()); @@ -215,12 +206,12 @@ void CollectionSettingsPage::Save() { s.setValue(kSettingsDiskCacheSize, ui_->spinbox_disk_cache_size->value()); s.setValue(kSettingsDiskCacheSizeUnit, ui_->combobox_disk_cache_size->currentData().toInt()); - s.setValue("save_playcounts", ui_->checkbox_save_playcounts->isChecked()); - s.setValue("save_ratings", ui_->checkbox_save_ratings->isChecked()); - s.setValue("overwrite_playcount", ui_->checkbox_overwrite_playcount->isChecked()); - s.setValue("overwrite_rating", ui_->checkbox_overwrite_rating->isChecked()); + s.setValue(kSavePlayCounts, ui_->checkbox_save_playcounts->isChecked()); + s.setValue(kSaveRatings, ui_->checkbox_save_ratings->isChecked()); + s.setValue(kOverwritePlaycount, ui_->checkbox_overwrite_playcount->isChecked()); + s.setValue(kOverwriteRating, ui_->checkbox_overwrite_rating->isChecked()); - s.setValue("delete_files", ui_->checkbox_delete_files->isChecked()); + s.setValue(kDeleteFiles, ui_->checkbox_delete_files->isChecked()); s.endGroup(); @@ -245,14 +236,14 @@ void CollectionSettingsPage::AddDirectory() { Settings s; s.beginGroup(kSettingsGroup); - QString path = s.value("last_path", QStandardPaths::writableLocation(QStandardPaths::MusicLocation)).toString(); + QString path = s.value(kLastPath, QStandardPaths::writableLocation(QStandardPaths::MusicLocation)).toString(); path = QDir::cleanPath(QFileDialog::getExistingDirectory(this, tr("Add directory..."), path)); if (!path.isEmpty()) { collectionsettings_directory_model_->AddDirectory(path); } - s.setValue("last_path", path); + s.setValue(kLastPath, path); set_changed(); @@ -297,7 +288,9 @@ void CollectionSettingsPage::DiskCacheEnable(const int state) { void CollectionSettingsPage::ClearPixmapDiskCache() { - ui_->disk_cache_in_use->setText(u"empty"_s); + dialog()->collection()->model()->ClearIconDiskCache(); + + UpdateIconDiskCacheSize(); } @@ -331,6 +324,12 @@ void CollectionSettingsPage::DiskCacheSizeUnitChanged(int index) { } +void CollectionSettingsPage::UpdateIconDiskCacheSize() { + + ui_->disk_cache_in_use->setText(dialog()->collection()->model()->icon_disk_cache_size() == 0 ? u"empty"_s : Utilities::PrettySize(dialog()->collection()->model()->icon_disk_cache_size())); + +} + void CollectionSettingsPage::WriteAllSongsStatisticsToFiles() { QMessageBox confirmation_dialog(QMessageBox::Question, tr("Write all playcounts and ratings to files"), tr("Are you sure you want to write song playcounts and ratings to file for all songs in your collection?"), QMessageBox::Yes | QMessageBox::Cancel); @@ -338,6 +337,6 @@ void CollectionSettingsPage::WriteAllSongsStatisticsToFiles() { return; } - dialog()->app()->collection()->SyncPlaycountAndRatingToFilesAsync(); + dialog()->collection()->SyncPlaycountAndRatingToFilesAsync(); } diff --git a/src/settings/collectionsettingspage.h b/src/settings/collectionsettingspage.h index 2d3b20e2cb..216ad79d3c 100644 --- a/src/settings/collectionsettingspage.h +++ b/src/settings/collectionsettingspage.h @@ -30,7 +30,7 @@ #include "settingspage.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class QModelIndex; class SettingsDialog; @@ -46,22 +46,6 @@ class CollectionSettingsPage : public SettingsPage { explicit CollectionSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~CollectionSettingsPage() override; - static const char *kSettingsGroup; - static const char *kSettingsCacheSize; - static const char *kSettingsCacheSizeUnit; - static const char *kSettingsDiskCacheEnable; - static const char *kSettingsDiskCacheSize; - static const char *kSettingsDiskCacheSizeUnit; - static const int kSettingsCacheSizeDefault; - static const int kSettingsDiskCacheSizeDefault; - - enum class CacheSizeUnit { - KB, - MB, - GB, - TB - }; - void Load() override; void Save() override; @@ -81,6 +65,9 @@ class CollectionSettingsPage : public SettingsPage { void DiskCacheSizeUnitChanged(int index); void WriteAllSongsStatisticsToFiles(); + private: + void UpdateIconDiskCacheSize(); + private: Ui_CollectionSettingsPage *ui_; SharedPtr collection_backend_; diff --git a/src/settings/contextsettingspage.cpp b/src/settings/contextsettingspage.cpp index f83bed704d..60f4144bc3 100644 --- a/src/settings/contextsettingspage.cpp +++ b/src/settings/contextsettingspage.cpp @@ -36,30 +36,17 @@ #include #include +#include "constants/mainwindowsettings.h" #include "core/iconloader.h" -#include "core/mainwindow.h" #include "core/settings.h" +#include "constants/contextsettings.h" #include "settingspage.h" #include "settingsdialog.h" #include "contextsettingspage.h" #include "ui_contextsettingspage.h" using namespace Qt::Literals::StringLiterals; - -const char *ContextSettingsPage::kSettingsGroup = "Context"; -const char *ContextSettingsPage::kSettingsTitleFmt = "TitleFmt"; -const char *ContextSettingsPage::kSettingsSummaryFmt = "SummaryFmt"; - -const char *ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsOrder::NELEMS)] = { - "AlbumEnable", - "TechnicalDataEnable", - "SongLyricsEnable", - "SearchCoverEnable", - "SearchLyricsEnable", -}; - -const char ContextSettingsPage::kDefaultFontFamily[] = "Noto Sans"; -const qreal ContextSettingsPage::kDefaultFontSizeHeadline = 11; +using namespace ContextSettings; ContextSettingsPage::ContextSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), @@ -68,11 +55,11 @@ ContextSettingsPage::ContextSettingsPage(SettingsDialog *dialog, QWidget *parent ui_->setupUi(this); setWindowIcon(IconLoader::Load(u"view-choose"_s, true, 0, 32)); - checkboxes_[static_cast(ContextSettingsOrder::ALBUM)] = ui_->checkbox_album; - checkboxes_[static_cast(ContextSettingsOrder::TECHNICAL_DATA)] = ui_->checkbox_technical_data; - checkboxes_[static_cast(ContextSettingsOrder::SONG_LYRICS)] = ui_->checkbox_song_lyrics; - checkboxes_[static_cast(ContextSettingsOrder::SEARCH_COVER)] = ui_->checkbox_search_cover; - checkboxes_[static_cast(ContextSettingsOrder::SEARCH_LYRICS)] = ui_->checkbox_search_lyrics; + checkboxes_[QLatin1String(kAlbum)] = ui_->checkbox_album; + checkboxes_[QLatin1String(kTechnicalData)] = ui_->checkbox_technical_data; + checkboxes_[QLatin1String(kSongLyrics)] = ui_->checkbox_song_lyrics; + checkboxes_[QLatin1String(kSearchCover)] = ui_->checkbox_search_cover; + checkboxes_[QLatin1String(kSearchLyrics)] = ui_->checkbox_search_lyrics; // Create and populate the helper menus QMenu *menu = new QMenu(this); @@ -137,8 +124,8 @@ void ContextSettingsPage::Load() { ui_->context_custom_text1->setText(s.value(kSettingsTitleFmt, u"%title% - %artist%"_s).toString()); ui_->context_custom_text2->setText(s.value(kSettingsSummaryFmt, u"%album%"_s).toString()); - for (int i = 0; i < static_cast(ContextSettingsOrder::NELEMS); ++i) { - checkboxes_[i]->setChecked(s.value(kSettingsGroupEnable[i], checkboxes_[i]->isChecked()).toBool()); + for (const QString &i : checkboxes_.keys()) { + checkboxes_[i]->setChecked(s.value(i, checkboxes_[i]->isChecked()).toBool()); } // Fonts @@ -150,15 +137,15 @@ void ContextSettingsPage::Load() { else { default_font = font().family(); } - ui_->font_headline->setCurrentFont(s.value("font_headline", default_font).toString()); - ui_->font_normal->setCurrentFont(s.value("font_normal", default_font).toString()); - ui_->font_size_headline->setValue(s.value("font_size_headline", kDefaultFontSizeHeadline).toReal()); - ui_->font_size_normal->setValue(s.value("font_size_normal", font().pointSizeF()).toReal()); + ui_->font_headline->setCurrentFont(s.value(kFontHeadline, default_font).toString()); + ui_->font_normal->setCurrentFont(s.value(kFontNormal, default_font).toString()); + ui_->font_size_headline->setValue(s.value(kFontSizeHeadline, kDefaultFontSizeHeadline).toReal()); + ui_->font_size_normal->setValue(s.value(kFontSizeNormal, font().pointSizeF()).toReal()); s.endGroup(); - s.beginGroup(MainWindow::kSettingsGroup); - ui_->checkbox_search_cover->setChecked(s.value("search_for_cover_auto", true).toBool()); + s.beginGroup(MainWindowSettings::kSettingsGroup); + ui_->checkbox_search_cover->setChecked(s.value(MainWindowSettings::kSearchForCoverAuto, true).toBool()); s.endGroup(); Init(ui_->layout_contextsettingspage->parentWidget()); @@ -174,17 +161,17 @@ void ContextSettingsPage::Save() { s.beginGroup(kSettingsGroup); s.setValue(kSettingsTitleFmt, ui_->context_custom_text1->text()); s.setValue(kSettingsSummaryFmt, ui_->context_custom_text2->text()); - for (int i = 0; i < static_cast(ContextSettingsOrder::NELEMS); ++i) { - s.setValue(kSettingsGroupEnable[i], checkboxes_[i]->isChecked()); + for (const QString &i : checkboxes_.keys()) { + s.setValue(i, checkboxes_[i]->isChecked()); } - s.setValue("font_headline", ui_->font_headline->currentFont().family()); - s.setValue("font_normal", ui_->font_normal->currentFont().family()); - s.setValue("font_size_headline", ui_->font_size_headline->value()); - s.setValue("font_size_normal", ui_->font_size_normal->value()); + s.setValue(kFontHeadline, ui_->font_headline->currentFont().family()); + s.setValue(kFontNormal, ui_->font_normal->currentFont().family()); + s.setValue(kFontSizeHeadline, ui_->font_size_headline->value()); + s.setValue(kFontSizeNormal, ui_->font_size_normal->value()); s.endGroup(); - s.beginGroup(MainWindow::kSettingsGroup); - s.setValue("search_for_cover_auto", ui_->checkbox_search_cover->isChecked()); + s.beginGroup(MainWindowSettings::kSettingsGroup); + s.setValue(MainWindowSettings::kSearchForCoverAuto, ui_->checkbox_search_cover->isChecked()); s.endGroup(); } diff --git a/src/settings/contextsettingspage.h b/src/settings/contextsettingspage.h index 0e2d743935..79d4dca88a 100644 --- a/src/settings/contextsettingspage.h +++ b/src/settings/contextsettingspage.h @@ -25,6 +25,7 @@ #include "config.h" #include +#include #include #include "settingspage.h" @@ -42,22 +43,6 @@ class ContextSettingsPage : public SettingsPage { explicit ContextSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~ContextSettingsPage() override; - enum class ContextSettingsOrder { - ALBUM, - TECHNICAL_DATA, - SONG_LYRICS, - SEARCH_COVER, - SEARCH_LYRICS, - NELEMS - }; - - static const char *kSettingsGroup; - static const char *kSettingsTitleFmt; - static const char *kSettingsSummaryFmt; - static const char *kSettingsGroupEnable[static_cast(ContextSettingsOrder::NELEMS)]; - static const char kDefaultFontFamily[]; - static const qreal kDefaultFontSizeHeadline; - void Load() override; void Save() override; @@ -70,7 +55,7 @@ class ContextSettingsPage : public SettingsPage { private: Ui_ContextSettingsPage *ui_; - QCheckBox *checkboxes_[static_cast(ContextSettingsOrder::NELEMS)] {}; + QHash checkboxes_; }; #endif // CONTEXTSETTINGSPAGE_H diff --git a/src/settings/coverssettingspage.cpp b/src/settings/coverssettingspage.cpp index 0ec3804c1e..119bfbb171 100644 --- a/src/settings/coverssettingspage.cpp +++ b/src/settings/coverssettingspage.cpp @@ -38,25 +38,16 @@ #include "settingsdialog.h" #include "coverssettingspage.h" #include "ui_coverssettingspage.h" -#include "core/application.h" #include "core/iconloader.h" #include "core/settings.h" #include "utilities/coveroptions.h" #include "covermanager/coverproviders.h" #include "covermanager/coverprovider.h" #include "widgets/loginstatewidget.h" +#include "constants/coverssettings.h" using namespace Qt::Literals::StringLiterals; - -const char *CoversSettingsPage::kSettingsGroup = "Covers"; -const char *CoversSettingsPage::kProviders = "providers"; -const char *CoversSettingsPage::kTypes = "types"; -const char *CoversSettingsPage::kSaveType = "save_type"; -const char *CoversSettingsPage::kSaveFilename = "save_filename"; -const char *CoversSettingsPage::kSavePattern = "save_pattern"; -const char *CoversSettingsPage::kSaveOverwrite = "save_overwrite"; -const char *CoversSettingsPage::kSaveLowercase = "save_lowercase"; -const char *CoversSettingsPage::kSaveReplaceSpaces = "save_replace_spaces"; +using namespace CoversSettings; CoversSettingsPage::CoversSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), @@ -101,7 +92,7 @@ void CoversSettingsPage::Load() { ui_->providers->clear(); - QList cover_providers_sorted = dialog()->app()->cover_providers()->List(); + QList cover_providers_sorted = dialog()->cover_providers()->List(); std::stable_sort(cover_providers_sorted.begin(), cover_providers_sorted.end(), ProviderCompareOrder); for (CoverProvider *provider : std::as_const(cover_providers_sorted)) { @@ -213,7 +204,7 @@ void CoversSettingsPage::Save() { void CoversSettingsPage::ProvidersCurrentItemChanged(QListWidgetItem *item_current, QListWidgetItem *item_previous) { if (item_previous) { - CoverProvider *provider = dialog()->app()->cover_providers()->ProviderByName(item_previous->text()); + CoverProvider *provider = dialog()->cover_providers()->ProviderByName(item_previous->text()); if (provider && provider->AuthenticationRequired()) DisconnectAuthentication(provider); } @@ -221,7 +212,7 @@ void CoversSettingsPage::ProvidersCurrentItemChanged(QListWidgetItem *item_curre const int row = ui_->providers->row(item_current); ui_->providers_up->setEnabled(row != 0); ui_->providers_down->setEnabled(row != ui_->providers->count() - 1); - CoverProvider *provider = dialog()->app()->cover_providers()->ProviderByName(item_current->text()); + CoverProvider *provider = dialog()->cover_providers()->ProviderByName(item_current->text()); if (provider) { if (provider->AuthenticationRequired()) { if (provider->name() == "Tidal"_L1 && !provider->IsAuthenticated()) { @@ -324,7 +315,7 @@ void CoversSettingsPage::DisconnectAuthentication(CoverProvider *provider) const void CoversSettingsPage::AuthenticateClicked() { if (!ui_->providers->currentItem()) return; - CoverProvider *provider = dialog()->app()->cover_providers()->ProviderByName(ui_->providers->currentItem()->text()); + CoverProvider *provider = dialog()->cover_providers()->ProviderByName(ui_->providers->currentItem()->text()); if (!provider) return; ui_->button_authenticate->setEnabled(false); ui_->login_state->SetLoggedIn(LoginStateWidget::State::LoginInProgress); @@ -337,7 +328,7 @@ void CoversSettingsPage::AuthenticateClicked() { void CoversSettingsPage::LogoutClicked() { if (!ui_->providers->currentItem()) return; - CoverProvider *provider = dialog()->app()->cover_providers()->ProviderByName(ui_->providers->currentItem()->text()); + CoverProvider *provider = dialog()->cover_providers()->ProviderByName(ui_->providers->currentItem()->text()); if (!provider) return; provider->Deauthenticate(); diff --git a/src/settings/coverssettingspage.h b/src/settings/coverssettingspage.h index c45bb0337e..4c71baed47 100644 --- a/src/settings/coverssettingspage.h +++ b/src/settings/coverssettingspage.h @@ -41,16 +41,6 @@ class CoversSettingsPage : public SettingsPage { explicit CoversSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~CoversSettingsPage() override; - static const char *kSettingsGroup; - static const char *kProviders; - static const char *kTypes; - static const char *kSaveType; - static const char *kSaveFilename; - static const char *kSavePattern; - static const char *kSaveOverwrite; - static const char *kSaveLowercase; - static const char *kSaveReplaceSpaces; - void Load() override; void Save() override; diff --git a/src/settings/globalshortcutssettingspage.cpp b/src/settings/globalshortcutssettingspage.cpp index 72e765dd05..2568022ea3 100644 --- a/src/settings/globalshortcutssettingspage.cpp +++ b/src/settings/globalshortcutssettingspage.cpp @@ -42,6 +42,7 @@ #include "core/logging.h" #include "core/settings.h" #include "utilities/envutils.h" +#include "constants/globalshortcutssettings.h" #include "globalshortcuts/globalshortcutgrabber.h" #include "globalshortcuts/globalshortcutsmanager.h" #include "settingspage.h" @@ -51,7 +52,7 @@ using namespace Qt::Literals::StringLiterals; -const char *GlobalShortcutsSettingsPage::kSettingsGroup = "GlobalShortcuts"; +using namespace GlobalShortcutsSettings; GlobalShortcutsSettingsPage::GlobalShortcutsSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), @@ -184,25 +185,25 @@ void GlobalShortcutsSettingsPage::Load() { #ifdef HAVE_KDE_GLOBALSHORTCUTS if (ui_->widget_kde->isVisibleTo(this)) { - ui_->checkbox_kde->setChecked(s.value("use_kde", true).toBool()); + ui_->checkbox_kde->setChecked(s.value(kUseKDE, true).toBool()); } #endif #ifdef HAVE_GNOME_GLOBALSHORTCUTS if (ui_->widget_gnome->isVisibleTo(this)) { - ui_->checkbox_gnome->setChecked(s.value("use_gnome", true).toBool()); + ui_->checkbox_gnome->setChecked(s.value(kUseGnome, true).toBool()); } #endif #ifdef HAVE_MATE_GLOBALSHORTCUTS if (ui_->widget_mate->isVisibleTo(this)) { - ui_->checkbox_mate->setChecked(s.value("use_mate", true).toBool()); + ui_->checkbox_mate->setChecked(s.value(kUseMate, true).toBool()); } #endif #ifdef HAVE_X11_GLOBALSHORTCUTS if (ui_->widget_x11->isVisibleTo(this)) { - ui_->checkbox_x11->setChecked(s.value("use_x11", false).toBool()); + ui_->checkbox_x11->setChecked(s.value(kUseX11, false).toBool()); } #endif @@ -235,19 +236,19 @@ void GlobalShortcutsSettingsPage::Save() { } #ifdef HAVE_KDE_GLOBALSHORTCUTS - s.setValue("use_kde", ui_->checkbox_kde->isChecked()); + s.setValue(kUseKDE, ui_->checkbox_kde->isChecked()); #endif #ifdef HAVE_GNOME_GLOBALSHORTCUTS - s.setValue("use_gnome", ui_->checkbox_gnome->isChecked()); + s.setValue(kUseGnome, ui_->checkbox_gnome->isChecked()); #endif #ifdef HAVE_MATE_GLOBALSHORTCUTS - s.setValue("use_mate", ui_->checkbox_mate->isChecked()); + s.setValue(kUseMate, ui_->checkbox_mate->isChecked()); #endif #ifdef HAVE_X11_GLOBALSHORTCUTS - s.setValue("use_x11", ui_->checkbox_x11->isChecked()); + s.setValue(kUseX11, ui_->checkbox_x11->isChecked()); #endif s.endGroup(); diff --git a/src/settings/globalshortcutssettingspage.h b/src/settings/globalshortcutssettingspage.h index 36b08b02b5..83b438cf3f 100644 --- a/src/settings/globalshortcutssettingspage.h +++ b/src/settings/globalshortcutssettingspage.h @@ -29,7 +29,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" #include "globalshortcuts/globalshortcutsmanager.h" #include "settingspage.h" @@ -45,8 +45,6 @@ class GlobalShortcutsSettingsPage : public SettingsPage { explicit GlobalShortcutsSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~GlobalShortcutsSettingsPage() override; - static const char *kSettingsGroup; - void Load() override; void Save() override; diff --git a/src/settings/lyricssettingspage.cpp b/src/settings/lyricssettingspage.cpp index 481367a825..b018147435 100644 --- a/src/settings/lyricssettingspage.cpp +++ b/src/settings/lyricssettingspage.cpp @@ -38,7 +38,7 @@ #include "settingsdialog.h" #include "lyricssettingspage.h" #include "ui_lyricssettingspage.h" -#include "core/application.h" +#include "constants/lyricssettings.h" #include "core/iconloader.h" #include "core/settings.h" #include "lyrics/lyricsproviders.h" @@ -46,8 +46,7 @@ #include "widgets/loginstatewidget.h" using namespace Qt::Literals::StringLiterals; - -const char *LyricsSettingsPage::kSettingsGroup = "Lyrics"; +using namespace LyricsSettings; LyricsSettingsPage::LyricsSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), @@ -81,7 +80,7 @@ void LyricsSettingsPage::Load() { ui_->providers->clear(); - QList lyrics_providers_sorted = dialog()->app()->lyrics_providers()->List(); + QList lyrics_providers_sorted = dialog()->lyrics_providers()->List(); std::stable_sort(lyrics_providers_sorted.begin(), lyrics_providers_sorted.end(), ProviderCompareOrder); for (LyricsProvider *provider : std::as_const(lyrics_providers_sorted)) { @@ -107,7 +106,7 @@ void LyricsSettingsPage::Save() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("providers", providers); + s.setValue(kProviders, providers); s.endGroup(); } @@ -115,7 +114,7 @@ void LyricsSettingsPage::Save() { void LyricsSettingsPage::CurrentItemChanged(QListWidgetItem *item_current, QListWidgetItem *item_previous) { if (item_previous) { - LyricsProvider *provider = dialog()->app()->lyrics_providers()->ProviderByName(item_previous->text()); + LyricsProvider *provider = dialog()->lyrics_providers()->ProviderByName(item_previous->text()); if (provider && provider->AuthenticationRequired()) DisconnectAuthentication(provider); } @@ -123,7 +122,7 @@ void LyricsSettingsPage::CurrentItemChanged(QListWidgetItem *item_current, QList const int row = ui_->providers->row(item_current); ui_->providers_up->setEnabled(row != 0); ui_->providers_down->setEnabled(row != ui_->providers->count() - 1); - LyricsProvider *provider = dialog()->app()->lyrics_providers()->ProviderByName(item_current->text()); + LyricsProvider *provider = dialog()->lyrics_providers()->ProviderByName(item_current->text()); if (provider) { if (provider->AuthenticationRequired()) { ui_->login_state->SetLoggedIn(provider->IsAuthenticated() ? LoginStateWidget::State::LoggedIn : LoginStateWidget::State::LoggedOut); @@ -212,7 +211,7 @@ void LyricsSettingsPage::DisconnectAuthentication(LyricsProvider *provider) cons void LyricsSettingsPage::AuthenticateClicked() { if (!ui_->providers->currentItem()) return; - LyricsProvider *provider = dialog()->app()->lyrics_providers()->ProviderByName(ui_->providers->currentItem()->text()); + LyricsProvider *provider = dialog()->lyrics_providers()->ProviderByName(ui_->providers->currentItem()->text()); if (!provider) return; ui_->button_authenticate->setEnabled(false); ui_->login_state->SetLoggedIn(LoginStateWidget::State::LoginInProgress); @@ -225,7 +224,7 @@ void LyricsSettingsPage::AuthenticateClicked() { void LyricsSettingsPage::LogoutClicked() { if (!ui_->providers->currentItem()) return; - LyricsProvider *provider = dialog()->app()->lyrics_providers()->ProviderByName(ui_->providers->currentItem()->text()); + LyricsProvider *provider = dialog()->lyrics_providers()->ProviderByName(ui_->providers->currentItem()->text()); if (!provider) return; provider->Deauthenticate(); diff --git a/src/settings/lyricssettingspage.h b/src/settings/lyricssettingspage.h index 742a0768c7..70a061a2be 100644 --- a/src/settings/lyricssettingspage.h +++ b/src/settings/lyricssettingspage.h @@ -41,8 +41,6 @@ class LyricsSettingsPage : public SettingsPage { explicit LyricsSettingsPage(SettingsDialog *dialog, QWidget *parent = nullptr); ~LyricsSettingsPage() override; - static const char *kSettingsGroup; - void Load() override; void Save() override; diff --git a/src/settings/moodbarsettingspage.cpp b/src/settings/moodbarsettingspage.cpp index 59cb65bd29..3ed9aaa541 100644 --- a/src/settings/moodbarsettingspage.cpp +++ b/src/settings/moodbarsettingspage.cpp @@ -42,14 +42,17 @@ # include "moodbar/moodbarrenderer.h" #endif +#include "constants/moodbarsettings.h" #include "moodbarsettingspage.h" #include "ui_moodbarsettingspage.h" using namespace Qt::Literals::StringLiterals; +using namespace MoodbarSettings; -const char *MoodbarSettingsPage::kSettingsGroup = "Moodbar"; -const int MoodbarSettingsPage::kMoodbarPreviewWidth = 150; -const int MoodbarSettingsPage::kMoodbarPreviewHeight = 18; +namespace { +constexpr int kMoodbarPreviewWidth = 150; +constexpr int kMoodbarPreviewHeight = 18; +} MoodbarSettingsPage::MoodbarSettingsPage(SettingsDialog *dialog, QWidget *parent) : SettingsPage(dialog, parent), @@ -69,10 +72,10 @@ void MoodbarSettingsPage::Load() { Settings s; s.beginGroup(kSettingsGroup); - ui_->moodbar_enabled->setChecked(s.value("enabled", false).toBool()); - ui_->moodbar_show->setChecked(s.value("show", false).toBool()); - ui_->moodbar_style->setCurrentIndex(s.value("style", 0).toInt()); - ui_->moodbar_save->setChecked(s.value("save", false).toBool()); + ui_->moodbar_enabled->setChecked(s.value(kEnabled, false).toBool()); + ui_->moodbar_show->setChecked(s.value(kShow, false).toBool()); + ui_->moodbar_style->setCurrentIndex(s.value(kStyle, 0).toInt()); + ui_->moodbar_save->setChecked(s.value(kSave, false).toBool()); s.endGroup(); InitMoodbarPreviews(); @@ -87,10 +90,10 @@ void MoodbarSettingsPage::Save() { Settings s; s.beginGroup(kSettingsGroup); - s.setValue("enabled", ui_->moodbar_enabled->isChecked()); - s.setValue("show", ui_->moodbar_show->isChecked()); - s.setValue("style", ui_->moodbar_style->currentIndex()); - s.setValue("save", ui_->moodbar_save->isChecked()); + s.setValue(kEnabled, ui_->moodbar_enabled->isChecked()); + s.setValue(kShow, ui_->moodbar_show->isChecked()); + s.setValue(kStyle, ui_->moodbar_style->currentIndex()); + s.setValue(kSave, ui_->moodbar_save->isChecked()); s.endGroup(); } @@ -114,9 +117,9 @@ void MoodbarSettingsPage::InitMoodbarPreviews() { file.close(); // Render and set each preview - for (int i = 0; i < static_cast(MoodbarRenderer::MoodbarStyle::StyleCount); ++i) { + for (int i = 0; i < static_cast(Style::StyleCount); ++i) { - const MoodbarRenderer::MoodbarStyle style = static_cast(i); + const Style style = static_cast