Refactoring
This commit is contained in:
parent
dfcf715291
commit
8da2b9cd94
252
CMakeLists.txt
252
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,9 +406,11 @@ 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
|
||||
src/core/memorydatabase.cpp
|
||||
src/core/sqlquery.cpp
|
||||
src/core/sqlrow.cpp
|
||||
src/core/metatypes.cpp
|
||||
@ -433,14 +435,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 +465,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 +490,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 +549,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 +580,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
|
||||
@ -633,6 +680,7 @@ set(SOURCES
|
||||
|
||||
src/settings/settingsdialog.cpp
|
||||
src/settings/settingspage.cpp
|
||||
src/settings/settingsitemdelegate.cpp
|
||||
src/settings/behavioursettingspage.cpp
|
||||
src/settings/collectionsettingspage.cpp
|
||||
src/settings/collectionsettingsdirectorymodel.cpp
|
||||
@ -667,8 +715,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 +765,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 +795,22 @@ 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
|
||||
|
||||
src/device/devicemanager.cpp
|
||||
src/device/devicelister.cpp
|
||||
src/device/devicedatabasebackend.cpp
|
||||
src/device/deviceinfo.cpp
|
||||
src/device/deviceproperties.cpp
|
||||
src/device/filesystemdevice.cpp
|
||||
src/device/connecteddevice.cpp
|
||||
src/device/devicestatefiltermodel.cpp
|
||||
src/device/deviceviewcontainer.cpp
|
||||
src/device/deviceview.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
@ -756,7 +818,9 @@ set(HEADERS
|
||||
src/core/mainwindow.h
|
||||
src/core/application.h
|
||||
src/core/player.h
|
||||
src/core/playerinterface.h
|
||||
src/core/database.h
|
||||
src/core/memorydatabase.h
|
||||
src/core/deletefiles.h
|
||||
src/core/filesystemwatcherinterface.h
|
||||
src/core/mergedproxymodel.h
|
||||
@ -769,11 +833,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 +868,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 +891,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 +900,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
|
||||
@ -910,6 +976,7 @@ set(HEADERS
|
||||
|
||||
src/settings/settingsdialog.h
|
||||
src/settings/settingspage.h
|
||||
src/settings/settingsitemdelegate.h
|
||||
src/settings/behavioursettingspage.h
|
||||
src/settings/collectionsettingspage.h
|
||||
src/settings/collectionsettingsdirectorymodel.h
|
||||
@ -944,8 +1011,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 +1058,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 +1085,19 @@ set(HEADERS
|
||||
src/transcoder/transcoderoptionsaac.h
|
||||
src/transcoder/transcoderoptionsasf.h
|
||||
src/transcoder/transcoderoptionsmp3.h
|
||||
|
||||
src/fileview/fileview.h
|
||||
src/fileview/fileviewlist.h
|
||||
|
||||
src/device/devicemanager.h
|
||||
src/device/devicelister.h
|
||||
src/device/devicedatabasebackend.h
|
||||
src/device/deviceproperties.h
|
||||
src/device/filesystemdevice.h
|
||||
src/device/connecteddevice.h
|
||||
src/device/devicestatefiltermodel.h
|
||||
src/device/deviceviewcontainer.h
|
||||
src/device/deviceview.h
|
||||
)
|
||||
|
||||
set(UI
|
||||
@ -1081,7 +1159,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 +1183,11 @@ set(UI
|
||||
src/transcoder/transcoderoptionsspeex.ui
|
||||
src/transcoder/transcoderoptionsasf.ui
|
||||
src/transcoder/transcoderoptionsmp3.ui
|
||||
|
||||
src/fileview/fileview.ui
|
||||
|
||||
src/device/deviceproperties.ui
|
||||
src/device/deviceviewcontainer.ui
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
@ -1114,54 +1196,80 @@ 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
|
||||
)
|
||||
|
||||
if(HAVE_GLOBALSHORTCUTS)
|
||||
|
||||
optional_source(HAVE_GLOBALSHORTCUTS
|
||||
SOURCES src/globalshortcuts/globalshortcutsmanager.cpp src/globalshortcuts/globalshortcutsbackend.cpp src/globalshortcuts/globalshortcutgrabber.cpp src/settings/globalshortcutssettingspage.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsmanager.h src/globalshortcuts/globalshortcutsbackend.h src/globalshortcuts/globalshortcutgrabber.h src/settings/globalshortcutssettingspage.h
|
||||
UI src/globalshortcuts/globalshortcutgrabber.ui src/settings/globalshortcutssettingspage.ui
|
||||
)
|
||||
optional_source(HAVE_KDE_GLOBALSHORTCUTS
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-kde.cpp src/globalshortcuts/globalshortcutsbackend-gnome.cpp src/globalshortcuts/globalshortcutsbackend-mate.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-kde.h src/globalshortcuts/globalshortcutsbackend-gnome.h src/globalshortcuts/globalshortcutsbackend-mate.h
|
||||
)
|
||||
|
||||
if(HAVE_KDE_GLOBALSHORTCUTS)
|
||||
optional_source(HAVE_KDE_GLOBALSHORTCUTS
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-kde.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-kde.h
|
||||
)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.kde.KGlobalAccel.xml kglobalaccel)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.kde.KGlobalAccel.Component.xml kglobalaccelcomponent)
|
||||
endif()
|
||||
|
||||
if(HAVE_GNOME_GLOBALSHORTCUTS)
|
||||
optional_source(HAVE_GNOME_GLOBALSHORTCUTS
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-gnome.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-gnome.h
|
||||
)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.gnome.SettingsDaemon.MediaKeys.xml gnomesettingsdaemon)
|
||||
endif()
|
||||
|
||||
if(HAVE_MATE_GLOBALSHORTCUTS)
|
||||
optional_source(HAVE_MATE_GLOBALSHORTCUTS
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-mate.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-mate.h
|
||||
)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.mate.SettingsDaemon.MediaKeys.xml matesettingsdaemon)
|
||||
endif()
|
||||
|
||||
optional_source(HAVE_X11_GLOBALSHORTCUTS
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-x11.cpp src/globalshortcuts/globalshortcut.cpp src/globalshortcuts/globalshortcut-x11.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-x11.h src/globalshortcuts/globalshortcut.h
|
||||
)
|
||||
|
||||
optional_source(APPLE
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-macos.mm src/globalshortcuts/globalshortcutgrabber.mm
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-macos.h src/globalshortcuts/globalshortcutgrabber.h
|
||||
)
|
||||
|
||||
optional_source(WIN32
|
||||
SOURCES src/globalshortcuts/globalshortcutsbackend-win.cpp src/globalshortcuts/globalshortcut.cpp src/globalshortcuts/globalshortcut-win.cpp
|
||||
HEADERS src/globalshortcuts/globalshortcutsbackend-win.h src/globalshortcuts/globalshortcut.h
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
optional_source(HAVE_ALSA SOURCES src/engine/alsadevicefinder.cpp src/engine/alsapcmdevicefinder.cpp)
|
||||
@ -1207,8 +1315,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
|
||||
@ -1221,57 +1329,17 @@ optional_source(HAVE_MOODBAR
|
||||
src/settings/moodbarsettingspage.ui
|
||||
)
|
||||
|
||||
if(HAVE_KDE_GLOBALSHORTCUTS)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.kde.KGlobalAccel.xml kglobalaccel)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.kde.KGlobalAccel.Component.xml kglobalaccelcomponent)
|
||||
endif()
|
||||
|
||||
if(HAVE_GNOME_GLOBALSHORTCUTS)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.gnome.SettingsDaemon.MediaKeys.xml gnomesettingsdaemon)
|
||||
endif()
|
||||
|
||||
if(HAVE_MATE_GLOBALSHORTCUTS)
|
||||
qt_add_dbus_interface(SOURCES src/globalshortcuts/org.mate.SettingsDaemon.MediaKeys.xml matesettingsdaemon)
|
||||
endif()
|
||||
|
||||
optional_source(UNIX
|
||||
SOURCES
|
||||
src/device/connecteddevice.cpp
|
||||
src/device/devicedatabasebackend.cpp
|
||||
src/device/devicelister.cpp
|
||||
src/device/devicemanager.cpp
|
||||
src/device/devicestatefiltermodel.cpp
|
||||
src/device/filesystemdevice.cpp
|
||||
src/device/deviceviewcontainer.cpp
|
||||
src/device/deviceview.cpp
|
||||
src/device/deviceproperties.cpp
|
||||
src/device/deviceinfo.cpp
|
||||
HEADERS
|
||||
src/device/connecteddevice.h
|
||||
src/device/devicedatabasebackend.h
|
||||
src/device/devicelister.h
|
||||
src/device/devicemanager.h
|
||||
src/device/devicestatefiltermodel.h
|
||||
src/device/filesystemdevice.h
|
||||
src/device/deviceviewcontainer.h
|
||||
src/device/deviceview.h
|
||||
src/device/deviceproperties.h
|
||||
UI
|
||||
src/device/deviceproperties.ui
|
||||
src/device/deviceviewcontainer.ui
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
optional_source(HAVE_GIO SOURCES src/device/giolister.cpp HEADERS src/device/giolister.h)
|
||||
endif()
|
||||
|
||||
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 +1488,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 +1497,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 +1505,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 PUBLIC ${SINGLEAPPLICATION_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H)
|
||||
target_include_directories(strawberry_lib SYSTEM PRIVATE ${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS})
|
||||
target_include_directories(strawberry_lib SYSTEM PUBLIC ${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 +1548,11 @@ target_link_libraries(strawberry_lib PRIVATE
|
||||
$<$<BOOL:${FREEBSD}>:execinfo>
|
||||
$<$<BOOL:${WIN32}>:dsound dwmapi getopt-win::getopt>
|
||||
$<$<BOOL:${MSVC}>: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 +1564,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
|
||||
$<$<BOOL:${HAVE_DBUS}>: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)
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <QString>
|
||||
#include <QPainter>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "analyzer/fht.h"
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
class QTimer;
|
||||
|
@ -45,13 +45,11 @@
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlError>
|
||||
|
||||
#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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <QUrl>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
#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);
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/filesystemmusicstorage.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/musicstorage.h"
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <QStringList>
|
||||
#include <QIcon>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "collectiondirectory.h"
|
||||
|
||||
class QModelIndex;
|
||||
|
@ -28,10 +28,9 @@
|
||||
#include <QUrl>
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -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 {
|
||||
|
32
src/collection/collectionitem.cpp
Normal file
32
src/collection/collectionitem.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "collectionitem.h"
|
||||
|
||||
CollectionItem::CollectionItem(SimpleTreeModel<CollectionItem> *_model)
|
||||
: SimpleTreeItem<CollectionItem>(_model),
|
||||
type(Type::Root),
|
||||
container_level(-1),
|
||||
compilation_artist_node_(nullptr) {}
|
||||
|
||||
CollectionItem::CollectionItem(const Type _type, CollectionItem *_parent)
|
||||
: SimpleTreeItem<CollectionItem>(_parent),
|
||||
type(_type),
|
||||
container_level(-1),
|
||||
compilation_artist_node_(nullptr) {}
|
@ -1,8 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -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<CollectionItem> {
|
||||
LoadingIndicator,
|
||||
};
|
||||
|
||||
explicit CollectionItem(SimpleTreeModel<CollectionItem> *_model)
|
||||
: SimpleTreeItem<CollectionItem>(_model),
|
||||
type(Type::Root),
|
||||
container_level(-1),
|
||||
compilation_artist_node_(nullptr) {}
|
||||
|
||||
explicit CollectionItem(const Type _type, CollectionItem *_parent = nullptr)
|
||||
: SimpleTreeItem<CollectionItem>(_parent),
|
||||
type(_type),
|
||||
container_level(-1),
|
||||
compilation_artist_node_(nullptr) {}
|
||||
explicit CollectionItem(SimpleTreeModel<CollectionItem> *_model);
|
||||
explicit CollectionItem(const Type _type, CollectionItem *_parent = nullptr);
|
||||
|
||||
Type type;
|
||||
int container_level;
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <QSettings>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#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(const SharedPtr<Database> database,
|
||||
const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<AlbumCoverLoader> 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<CollectionBackend>();
|
||||
backend()->moveToThread(app->database()->thread());
|
||||
qLog(Debug) << &*backend_ << "moved to thread" << app->database()->thread();
|
||||
backend()->moveToThread(database->thread());
|
||||
qLog(Debug) << &*backend_ << "moved to thread" << database->thread();
|
||||
|
||||
backend_->Init(app->database(), app->task_manager(), Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable));
|
||||
backend_->Init(database, task_manager, Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable));
|
||||
|
||||
model_ = new CollectionModel(backend_, app_, this);
|
||||
model_ = new CollectionModel(backend_, 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());
|
||||
|
||||
@ -106,14 +109,11 @@ void SCollection::Init() {
|
||||
|
||||
watcher_thread_->start(QThread::IdlePriority);
|
||||
|
||||
watcher_->set_backend(backend_);
|
||||
watcher_->set_task_manager(app_->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 +125,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 +155,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 +170,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);
|
||||
}
|
||||
|
||||
}
|
@ -29,22 +29,30 @@
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class Thread;
|
||||
class Database;
|
||||
class TaskManager;
|
||||
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(const SharedPtr<Database> database,
|
||||
const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~CollectionLibrary() override;
|
||||
|
||||
static const char *kSongsTable;
|
||||
static const char *kFtsTable;
|
||||
@ -78,15 +86,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<TaskManager> task_manager_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
|
||||
SharedPtr<CollectionBackend> backend_;
|
||||
CollectionModel *model_;
|
||||
|
@ -53,14 +53,13 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
|
||||
#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<CollectionBackend> backend, Application *app, QObject *parent)
|
||||
CollectionModel::CollectionModel(const SharedPtr<CollectionBackend> backend, const SharedPtr<AlbumCoverLoader> albumcover_loader, QObject *parent)
|
||||
: SimpleTreeModel<CollectionItem>(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<CollectionBackend> backend, Applicati
|
||||
total_song_count_(0),
|
||||
total_artist_count_(0),
|
||||
total_album_count_(0),
|
||||
loading_(false) {
|
||||
loading_(false),
|
||||
icon_disk_cache_(nullptr) {
|
||||
|
||||
setObjectName(backend_->source() == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(backend_->source()), QLatin1String(metaObject()->className())));
|
||||
|
||||
@ -108,8 +104,8 @@ CollectionModel::CollectionModel(SharedPtr<CollectionBackend> backend, Applicati
|
||||
filter_->setSortRole(Role_SortText);
|
||||
filter_->sort(0);
|
||||
|
||||
if (app_) {
|
||||
QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded);
|
||||
if (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<CollectionBackend> backend, Applicati
|
||||
pixmap_no_cover_ = nocover.pixmap(nocover_sizes.last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
if (app_ && !sIconCache) {
|
||||
sIconCache = new QNetworkDiskCache(this);
|
||||
sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir));
|
||||
QObject::connect(app_, &Application::ClearPixmapDiskCache, this, &CollectionModel::ClearDiskCache);
|
||||
if (!qgetenv("DISPLAY").isEmpty() && !icon_disk_cache_) {
|
||||
icon_disk_cache_ = new QNetworkDiskCache(this);
|
||||
icon_disk_cache_->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir) + u'-' + Song::TextForSource(backend_->source()));
|
||||
}
|
||||
|
||||
QObject::connect(&*backend_, &CollectionBackend::SongsAdded, this, &CollectionModel::AddReAddOrUpdate);
|
||||
@ -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();
|
||||
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(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool();
|
||||
QPixmapCache::setCacheLimit(static_cast<int>(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit, CollectionSettingsPage::kSettingsCacheSizeDefault) / 1024));
|
||||
if (sIconCache) {
|
||||
sIconCache->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault));
|
||||
use_disk_cache_ = settings.value(CollectionSettings::kSettingsDiskCacheEnable, false).toBool();
|
||||
QPixmapCache::setCacheLimit(static_cast<int>(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<QIODevice> disk_cache_img(sIconCache->data(AlbumIconPixmapDiskCacheKey(cache_key)));
|
||||
if (use_disk_cache_ && icon_disk_cache_) {
|
||||
ScopedPtr<QIODevice> disk_cache_img(icon_disk_cache_->data(AlbumIconPixmapDiskCacheKey(cache_key)));
|
||||
if (disk_cache_img) {
|
||||
QImage cached_image;
|
||||
if (cached_image.load(&*disk_cache_img, "XPM")) {
|
||||
@ -932,7 +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<QIODevice> disk_cache_img(sIconCache->data(disk_cache_key));
|
||||
ScopedPtr<QIODevice> disk_cache_img(icon_disk_cache_->data(disk_cache_key));
|
||||
if (!disk_cache_img) {
|
||||
QNetworkCacheMetaData disk_cache_metadata;
|
||||
disk_cache_metadata.setSaveToDisk(true);
|
||||
disk_cache_metadata.setUrl(disk_cache_key);
|
||||
// Qt 6 now ignores any entry without headers, so add a fake header.
|
||||
disk_cache_metadata.setRawHeaders(QNetworkCacheMetaData::RawHeaderList() << qMakePair(QByteArray("collection-thumbnail"), cache_key.toUtf8()));
|
||||
QIODevice *device_iconcache = sIconCache->prepare(disk_cache_metadata);
|
||||
QIODevice *device_iconcache = icon_disk_cache_->prepare(disk_cache_metadata);
|
||||
if (device_iconcache) {
|
||||
result.image_scaled.save(device_iconcache, "XPM");
|
||||
sIconCache->insert(device_iconcache);
|
||||
icon_disk_cache_->insert(device_iconcache);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<int>(CollectionSettingsPage::CacheSizeUnit::MB)).toInt() + 1;
|
||||
int unit = s->value(size_unit_id, static_cast<int>(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) {
|
||||
|
@ -44,10 +44,9 @@
|
||||
#include <QNetworkDiskCache>
|
||||
#include <QQueue>
|
||||
|
||||
#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<CollectionItem> {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CollectionModel(SharedPtr<CollectionBackend> backend, Application *app, QObject *parent = nullptr);
|
||||
explicit CollectionModel(const SharedPtr<CollectionBackend> backend, const SharedPtr<AlbumCoverLoader> albumcover_loader, QObject *parent = nullptr);
|
||||
~CollectionModel() override;
|
||||
|
||||
static const int kPrettyCoverSize;
|
||||
@ -156,7 +155,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
int total_artist_count() const { return total_artist_count_; }
|
||||
int total_album_count() const { return total_album_count_; }
|
||||
|
||||
quint64 icon_cache_disk_size() { return sIconCache->cacheSize(); }
|
||||
quint64 icon_disk_cache_size() { return icon_disk_cache_->cacheSize(); }
|
||||
|
||||
const CollectionModel::Grouping GetGroupBy() const { return options_current_.group_by; }
|
||||
void SetGroupBy(const CollectionModel::Grouping g, const std::optional<bool> separate_albums_by_grouping = std::optional<bool>());
|
||||
@ -218,6 +217,8 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
void AddReAddOrUpdate(const SongList &songs);
|
||||
void RemoveSongs(const SongList &songs);
|
||||
|
||||
void ClearIconDiskCache();
|
||||
|
||||
private:
|
||||
void Clear();
|
||||
void BeginReset();
|
||||
@ -238,7 +239,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
void CreateDividerItem(const QString ÷r_key, const QString &display_text, CollectionItem *parent);
|
||||
CollectionItem *CreateContainerItem(const GroupBy group_by, const int container_level, const QString &container_key, const Song &song, CollectionItem *parent);
|
||||
void CreateSongItem(const Song &song, CollectionItem *parent);
|
||||
void SetSongItemData(CollectionItem *item, const Song &song);
|
||||
void SetSongItemData(CollectionItem *item, const Song &song) const;
|
||||
CollectionItem *CreateCompilationArtistNode(CollectionItem *parent);
|
||||
|
||||
void LoadSongsFromSqlAsync();
|
||||
@ -267,15 +268,12 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
void TotalArtistCountUpdatedSlot(const int count);
|
||||
void TotalAlbumCountUpdatedSlot(const int count);
|
||||
|
||||
static void ClearDiskCache();
|
||||
|
||||
void RowsInserted(const QModelIndex &parent, const int first, const int last);
|
||||
void RowsRemoved(const QModelIndex &parent, const int first, const int last);
|
||||
|
||||
private:
|
||||
static QNetworkDiskCache *sIconCache;
|
||||
SharedPtr<CollectionBackend> backend_;
|
||||
Application *app_;
|
||||
const SharedPtr<CollectionBackend> backend_;
|
||||
const SharedPtr<AlbumCoverLoader> albumcover_loader_;
|
||||
CollectionDirectoryModel *dir_model_;
|
||||
CollectionFilter *filter_;
|
||||
QTimer *timer_reload_;
|
||||
@ -310,6 +308,8 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
using ItemAndCacheKey = QPair<CollectionItem*, QString>;
|
||||
QMap<quint64, ItemAndCacheKey> pending_art_;
|
||||
QSet<QString> pending_cache_keys_;
|
||||
|
||||
QNetworkDiskCache *icon_disk_cache_;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(CollectionModel::Grouping)
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "collectiontask.h"
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
class TaskManager;
|
||||
|
||||
|
@ -50,20 +50,20 @@
|
||||
#include <QKeyEvent>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#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 "collectionmodel.h"
|
||||
#include "collectionfilter.h"
|
||||
#include "collectionfilterwidget.h"
|
||||
#include "collectionitem.h"
|
||||
#include "collectionitemdelegate.h"
|
||||
#include "collectionmodel.h"
|
||||
#include "collectionview.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "device/devicemanager.h"
|
||||
@ -73,15 +73,16 @@
|
||||
#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),
|
||||
model_(nullptr),
|
||||
filter_(nullptr),
|
||||
filter_widget_(nullptr),
|
||||
total_song_count_(-1),
|
||||
total_artist_count_(-1),
|
||||
total_album_count_(-1),
|
||||
@ -123,6 +124,35 @@ CollectionView::CollectionView(QWidget *parent)
|
||||
|
||||
CollectionView::~CollectionView() = default;
|
||||
|
||||
void CollectionView::Init(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<NetworkAccessManager> network,
|
||||
const SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
const SharedPtr<CoverProviders> cover_providers,
|
||||
const SharedPtr<LyricsProviders> lyrics_providers,
|
||||
const SharedPtr<CollectionLibrary> collection,
|
||||
const SharedPtr<DeviceManager> device_manager,
|
||||
const SharedPtr<StreamingServices> 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;
|
||||
backend_ = collection_->backend();
|
||||
model_ = collection_->model();
|
||||
filter_ = collection_->model()->filter();
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::SaveFocus() {
|
||||
|
||||
const QModelIndex current = currentIndex();
|
||||
@ -142,8 +172,8 @@ void CollectionView::SaveFocus() {
|
||||
|
||||
switch (item_type) {
|
||||
case CollectionItem::Type::Song:{
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
SongList songs = app_->collection_model()->GetChildSongs(index);
|
||||
QModelIndex index = filter_->mapToSource(current);
|
||||
SongList songs = model_->GetChildSongs(index);
|
||||
if (!songs.isEmpty()) {
|
||||
last_selected_song_ = songs.last();
|
||||
}
|
||||
@ -210,8 +240,8 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) {
|
||||
break;
|
||||
case CollectionItem::Type::Song:
|
||||
if (!last_selected_song_.url().isEmpty()) {
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
const SongList songs = app_->collection_model()->GetChildSongs(index);
|
||||
QModelIndex index = filter_->mapToSource(current);
|
||||
const SongList songs = 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 +271,7 @@ bool CollectionView::RestoreLevelFocus(const QModelIndex &parent) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
@ -248,22 +279,14 @@ 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::SetFilterWidget(CollectionFilterWidget *filter_widget) { filter_widget_ = filter_widget; }
|
||||
|
||||
void CollectionView::TotalSongCountUpdated(const int count) {
|
||||
|
||||
@ -353,7 +376,7 @@ void CollectionView::mouseReleaseEvent(QMouseEvent *e) {
|
||||
QTreeView::mouseReleaseEvent(e);
|
||||
|
||||
if (total_song_count_ == 0) {
|
||||
Q_EMIT ShowConfigDialog();
|
||||
Q_EMIT ShowSettingsDialog();
|
||||
}
|
||||
|
||||
}
|
||||
@ -414,11 +437,11 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
||||
|
||||
context_menu_->addSeparator();
|
||||
|
||||
context_menu_->addMenu(filter_->menu());
|
||||
context_menu_->addMenu(filter_widget_->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 +449,16 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
||||
context_menu_index_ = indexAt(e->pos());
|
||||
if (!context_menu_index_.isValid()) return;
|
||||
|
||||
context_menu_index_ = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(context_menu_index_);
|
||||
context_menu_index_ = filter_->mapToSource(context_menu_index_);
|
||||
|
||||
const QModelIndexList selected_indexes = qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
const QModelIndexList selected_indexes = filter_->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 (model_->data(idx, CollectionModel::Role_Editable).toBool()) {
|
||||
++regular_editable;
|
||||
}
|
||||
}
|
||||
@ -502,7 +525,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 = backend_->GetSongsByAlbum(album);
|
||||
QSet<QString> other_artists;
|
||||
for (const Song &s : all_of_album) {
|
||||
if (!albums.contains(album, s.artist()) && !other_artists.contains(s.artist())) {
|
||||
@ -520,7 +543,7 @@ void CollectionView::SetShowInVarious(const bool on) {
|
||||
|
||||
const QSet<QString> albums_set = QSet<QString>(albums.keyBegin(), albums.keyEnd());
|
||||
for (const QString &album : albums_set) {
|
||||
app_->collection_backend()->ForceCompilation(album, albums.values(album), on);
|
||||
backend_->ForceCompilation(album, albums.values(album), on);
|
||||
}
|
||||
|
||||
}
|
||||
@ -584,11 +607,12 @@ void CollectionView::SearchForThis() {
|
||||
return;
|
||||
}
|
||||
QString search;
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
|
||||
QModelIndex index = filter_->mapToSource(current);
|
||||
|
||||
switch (item_type) {
|
||||
case CollectionItem::Type::Song:{
|
||||
SongList songs = app_->collection_model()->GetChildSongs(index);
|
||||
SongList songs = model_->GetChildSongs(index);
|
||||
if (!songs.isEmpty()) {
|
||||
last_selected_song_ = songs.last();
|
||||
}
|
||||
@ -601,8 +625,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 = model_->IndexToItem(index);
|
||||
const CollectionModel::GroupBy group_by = model_->GetGroupBy()[item->container_level];
|
||||
while (!item->children.isEmpty()) {
|
||||
item = item->children.constFirst();
|
||||
}
|
||||
@ -663,7 +687,7 @@ void CollectionView::SearchForThis() {
|
||||
return;
|
||||
}
|
||||
|
||||
filter_->ShowInCollection(search);
|
||||
filter_widget_->ShowInCollection(search);
|
||||
|
||||
}
|
||||
|
||||
@ -688,18 +712,18 @@ void CollectionView::scrollTo(const QModelIndex &idx, ScrollHint hint) {
|
||||
|
||||
SongList CollectionView::GetSelectedSongs() const {
|
||||
|
||||
QModelIndexList selected_indexes = qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
return app_->collection_model()->GetChildSongs(selected_indexes);
|
||||
QModelIndexList selected_indexes = filter_->mapSelectionToSource(selectionModel()->selection()).indexes();
|
||||
return model_->GetChildSongs(selected_indexes);
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::Organize() {
|
||||
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(app_->task_manager(), app_->collection_backend(), this);
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(task_manager_, tagreader_client_, backend_, this);
|
||||
}
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model());
|
||||
organize_dialog_->SetDestinationModel(model_->directory_model());
|
||||
organize_dialog_->SetCopy(false);
|
||||
const SongList songs = GetSelectedSongs();
|
||||
if (organize_dialog_->SetSongs(songs)) {
|
||||
@ -714,7 +738,7 @@ void CollectionView::Organize() {
|
||||
void CollectionView::EditTracks() {
|
||||
|
||||
if (!edit_tag_dialog_) {
|
||||
edit_tag_dialog_ = make_unique<EditTagDialog>(app_, this);
|
||||
edit_tag_dialog_ = make_unique<EditTagDialog>(network_, tagreader_client_, 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 +753,7 @@ void CollectionView::EditTagError(const QString &message) {
|
||||
|
||||
void CollectionView::RescanSongs() {
|
||||
|
||||
app_->collection()->Rescan(GetSelectedSongs());
|
||||
collection_->Rescan(GetSelectedSongs());
|
||||
|
||||
}
|
||||
|
||||
@ -737,10 +761,10 @@ void CollectionView::CopyToDevice() {
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(app_->task_manager(), nullptr, this);
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(task_manager_, 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 +836,9 @@ void CollectionView::Delete() {
|
||||
if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return;
|
||||
|
||||
// We can cheat and always take the storage of the first directory, since they'll all be FilesystemMusicStorage in a collection and deleting doesn't check the actual directory.
|
||||
SharedPtr<MusicStorage> storage = app_->collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value<SharedPtr<MusicStorage>>();
|
||||
SharedPtr<MusicStorage> storage = model_->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value<SharedPtr<MusicStorage>>();
|
||||
|
||||
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, true);
|
||||
DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, true);
|
||||
QObject::connect(delete_files, &DeleteFiles::Finished, this, &CollectionView::DeleteFilesFinished);
|
||||
delete_files->Start(songs);
|
||||
|
||||
|
@ -30,10 +30,12 @@
|
||||
#include <QPixmap>
|
||||
#include <QSet>
|
||||
|
||||
#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,20 @@ class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
class QKeyEvent;
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class TagReaderClient;
|
||||
class NetworkAccessManager;
|
||||
class CollectionLibrary;
|
||||
class CollectionBackend;
|
||||
class CollectionModel;
|
||||
class CollectionFilter;
|
||||
class CollectionFilterWidget;
|
||||
class DeviceManager;
|
||||
class StreamingServices;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class CoverProviders;
|
||||
class LyricsProviders;
|
||||
class EditTagDialog;
|
||||
class OrganizeDialog;
|
||||
|
||||
@ -57,8 +71,18 @@ 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 SetFilter(CollectionFilterWidget *filter);
|
||||
void Init(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<NetworkAccessManager> network,
|
||||
const SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
const SharedPtr<CoverProviders> cover_providers,
|
||||
const SharedPtr<LyricsProviders> lyrics_providers,
|
||||
const SharedPtr<CollectionLibrary> collection,
|
||||
const SharedPtr<DeviceManager> device_manager,
|
||||
const SharedPtr<StreamingServices> streaming_services);
|
||||
|
||||
void SetFilterWidget(CollectionFilterWidget *filter_widget);
|
||||
|
||||
// QTreeView
|
||||
void keyboardSearch(const QString &search) override;
|
||||
@ -82,7 +106,7 @@ class CollectionView : public AutoExpandingTreeView {
|
||||
void EditTagError(const QString &message);
|
||||
|
||||
Q_SIGNALS:
|
||||
void ShowConfigDialog();
|
||||
void ShowSettingsDialog();
|
||||
|
||||
void TotalSongCountUpdated_();
|
||||
void TotalArtistCountUpdated_();
|
||||
@ -120,8 +144,21 @@ class CollectionView : public AutoExpandingTreeView {
|
||||
void SaveContainerPath(const QModelIndex &child);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
CollectionFilterWidget *filter_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<TagReaderClient> tagreader_client_;
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
SharedPtr<DeviceManager> device_manager_;
|
||||
SharedPtr<AlbumCoverLoader> albumcover_loader_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
SharedPtr<CollectionLibrary> collection_;
|
||||
SharedPtr<CoverProviders> cover_providers_;
|
||||
SharedPtr<LyricsProviders> lyrics_providers_;
|
||||
SharedPtr<StreamingServices> streaming_services_;
|
||||
|
||||
SharedPtr<CollectionBackend> backend_;
|
||||
CollectionModel *model_;
|
||||
CollectionFilter *filter_;
|
||||
CollectionFilterWidget *filter_widget_;
|
||||
|
||||
int total_song_count_;
|
||||
int total_artist_count_;
|
||||
|
@ -31,7 +31,7 @@
|
||||
CollectionViewContainer::CollectionViewContainer(QWidget *parent) : QWidget(parent), ui_(new Ui_CollectionViewContainer) {
|
||||
|
||||
ui_->setupUi(this);
|
||||
view()->SetFilter(filter_widget());
|
||||
view()->SetFilterWidget(filter_widget());
|
||||
|
||||
QObject::connect(filter_widget(), &CollectionFilterWidget::UpPressed, view(), &CollectionView::UpAndFocus);
|
||||
QObject::connect(filter_widget(), &CollectionFilterWidget::DownPressed, view(), &CollectionView::DownAndFocus);
|
||||
|
@ -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,
|
||||
const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<CollectionBackend> 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);
|
||||
|
@ -36,28 +36,32 @@
|
||||
#include <QMutex>
|
||||
|
||||
#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,
|
||||
const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<CollectionBackend> backend,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~CollectionWatcher();
|
||||
|
||||
Song::Source source() { return source_; }
|
||||
Song::Source source() const { return source_; }
|
||||
|
||||
void set_backend(SharedPtr<CollectionBackend> backend) { backend_ = backend; }
|
||||
void set_task_manager(SharedPtr<TaskManager> task_manager) { task_manager_ = task_manager; }
|
||||
void set_device_name(const QString &device_name) { device_name_ = device_name; }
|
||||
|
||||
void IncrementalScanAsync();
|
||||
@ -213,9 +217,12 @@ class CollectionWatcher : public QObject {
|
||||
QString FindCueFilename(const QString &filename);
|
||||
|
||||
private:
|
||||
Song::Source source_;
|
||||
SharedPtr<CollectionBackend> backend_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
const Song::Source source_;
|
||||
|
||||
const SharedPtr<TaskManager> task_manager_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
const SharedPtr<CollectionBackend> backend_;
|
||||
|
||||
QString device_name_;
|
||||
|
||||
FileSystemWatcherInterface *fs_watcher_;
|
||||
|
@ -28,13 +28,13 @@
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
75
src/constants/appearancesettings.h
Normal file
75
src/constants/appearancesettings.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
64
src/constants/backendsettings.h
Normal file
64
src/constants/backendsettings.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDSETTINGS_H
|
||||
#define BACKENDSETTINGS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
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
|
76
src/constants/behavioursettings.h
Normal file
76
src/constants/behavioursettings.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
62
src/constants/collectionsettings.h
Normal file
62
src/constants/collectionsettings.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
48
src/constants/contextsettings.h
Normal file
48
src/constants/contextsettings.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONTEXTSETTINGS_H
|
||||
#define CONTEXTSETTINGS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
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
|
37
src/constants/coverssettings.h
Normal file
37
src/constants/coverssettings.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
39
src/constants/filefilterconstants.h
Normal file
39
src/constants/filefilterconstants.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FILEFILTERCONSTANTS_H
|
||||
#define FILEFILTERCONSTANTS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
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
|
@ -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!#\\$%&'()\\-@\\^_`{}~/. ]";
|
33
src/constants/globalshortcutssettings.h
Normal file
33
src/constants/globalshortcutssettings.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
30
src/constants/lyricssettings.h
Normal file
30
src/constants/lyricssettings.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LYRICSSETTINGS_H
|
||||
#define LYRICSSETTINGS_H
|
||||
|
||||
namespace LyricsSettings {
|
||||
|
||||
constexpr char kSettingsGroup[] = "Lyrics";
|
||||
constexpr char kProviders[] = "providers";
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // LYRICSSETTINGS_H
|
37
src/constants/mainwindowsettings.h
Normal file
37
src/constants/mainwindowsettings.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
43
src/constants/moodbarsettings.h
Normal file
43
src/constants/moodbarsettings.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
37
src/constants/networkproxysettings.h
Normal file
37
src/constants/networkproxysettings.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
68
src/constants/notificationssettings.h
Normal file
68
src/constants/notificationssettings.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NOTIFICATIONSSETTINGS_H
|
||||
#define NOTIFICATIONSSETTINGS_H
|
||||
|
||||
#include <QRgb>
|
||||
|
||||
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
|
70
src/constants/playlistsettings.h
Normal file
70
src/constants/playlistsettings.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTSETTINGS_H
|
||||
#define PLAYLISTSETTINGS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
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
|
47
src/constants/qobuzsettings.h
Normal file
47
src/constants/qobuzsettings.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
40
src/constants/scrobblersettings.h
Normal file
40
src/constants/scrobblersettings.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
42
src/constants/spotifysettings.h
Normal file
42
src/constants/spotifysettings.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
45
src/constants/subsonicsettings.h
Normal file
45
src/constants/subsonicsettings.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef 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
|
52
src/constants/tidalsettings.h
Normal file
52
src/constants/tidalsettings.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
34
src/constants/timeconstants.h
Normal file
34
src/constants/timeconstants.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it wiLL be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TIMECONSTANTS_H
|
||||
#define TIMECONSTANTS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
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
|
29
src/constants/transcodersettings.h
Normal file
29
src/constants/transcodersettings.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it wiLL be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TRANSCODERSETTINGS_H
|
||||
#define TRANSCODERSETTINGS_H
|
||||
|
||||
namespace TranscoderSettings {
|
||||
constexpr char kSettingsGroup[] = "Transcoder";
|
||||
}
|
||||
|
||||
#endif // TRANSCODERSETTINGS_H
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <QContextMenuEvent>
|
||||
#include <QPaintEvent>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "utilities/imageutils.h"
|
||||
#include "covermanager/albumcoverchoicecontroller.h"
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
#include <QPixmap>
|
||||
#include <QMovie>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/scoped_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
class QMenu;
|
||||
class QTimeLine;
|
||||
|
@ -50,8 +50,6 @@
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDropEvent>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/strutils.h"
|
||||
@ -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<LyricsProviders> lyrics_providers) {
|
||||
|
||||
app_ = app;
|
||||
collectionview_ = collectionview;
|
||||
album_cover_choice_controller_ = album_cover_choice_controller;
|
||||
|
||||
widget_album_->Init(this, album_cover_choice_controller_);
|
||||
lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this);
|
||||
lyrics_fetcher_ = new LyricsFetcher(lyrics_providers, this);
|
||||
|
||||
QObject::connect(collectionview_, &CollectionView::TotalSongCountUpdated_, this, &ContextView::UpdateNoSong);
|
||||
QObject::connect(collectionview_, &CollectionView::TotalArtistCountUpdated_, this, &ContextView::UpdateNoSong);
|
||||
@ -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<int>(ContextSettingsPage::ContextSettingsOrder::ALBUM)], true).toBool());
|
||||
action_show_data_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast<int>(ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA)], false).toBool());
|
||||
action_show_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast<int>(ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS)], true).toBool());
|
||||
action_search_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast<int>(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<int>(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<int>(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<int>(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<int>(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();
|
||||
|
@ -46,9 +46,9 @@ class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
|
||||
class ResizableTextEdit;
|
||||
class Application;
|
||||
class CollectionView;
|
||||
class AlbumCoverChoiceController;
|
||||
class LyricsProviders;
|
||||
class LyricsFetcher;
|
||||
|
||||
class ContextView : public QWidget {
|
||||
@ -57,7 +57,7 @@ class ContextView : public QWidget {
|
||||
public:
|
||||
explicit ContextView(QWidget *parent = nullptr);
|
||||
|
||||
void Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller);
|
||||
void Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr<LyricsProviders> lyrics_providers);
|
||||
|
||||
ContextAlbum *album_widget() const { return widget_album_; }
|
||||
bool album_enabled() const { return action_show_album_->isChecked(); }
|
||||
@ -101,7 +101,6 @@ class ContextView : public QWidget {
|
||||
void AlbumCoverLoaded(const Song &song, const QImage &image);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
CollectionView *collectionview_;
|
||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||
LyricsFetcher *lyrics_fetcher_;
|
||||
|
@ -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<TidalService>(), app->network()));
|
||||
#endif
|
||||
#ifdef HAVE_SPOTIFY
|
||||
cover_providers->AddProvider(new SpotifyCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new SpotifyCoverProvider(app->streaming_services()->Service<SpotifyService>(), app->network()));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
cover_providers->AddProvider(new QobuzCoverProvider(app, app->network()));
|
||||
cover_providers->AddProvider(new QobuzCoverProvider(app->streaming_services()->Service<QobuzService>(), app->network()));
|
||||
#endif
|
||||
cover_providers->ReloadSettings();
|
||||
return cover_providers;
|
||||
}),
|
||||
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<SubsonicService>(app));
|
||||
streaming_services->AddService(make_shared<SubsonicService>(app->task_manager(), app->database(), app->url_handlers(), app->albumcover_loader()));
|
||||
#endif
|
||||
#ifdef HAVE_TIDAL
|
||||
streaming_services->AddService(make_shared<TidalService>(app));
|
||||
streaming_services->AddService(make_shared<TidalService>(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->albumcover_loader()));
|
||||
#endif
|
||||
#ifdef HAVE_SPOTIFY
|
||||
streaming_services->AddService(make_shared<SpotifyService>(app));
|
||||
streaming_services->AddService(make_shared<SpotifyService>(app->task_manager(), app->database(), app->network(), app->albumcover_loader()));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
streaming_services->AddService(make_shared<QobuzService>(app));
|
||||
streaming_services->AddService(make_shared<QobuzService>(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->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<LastFMScrobbler>(scrobbler->settings(), app->network()));
|
||||
scrobbler->AddService(make_shared<LibreFMScrobbler>(scrobbler->settings(), app->network()));
|
||||
scrobbler->AddService(make_shared<ListenBrainzScrobbler>(scrobbler->settings(), app->network()));
|
||||
#ifdef HAVE_SUBSONIC
|
||||
scrobbler->AddService(make_shared<SubsonicScrobbler>(scrobbler->settings(), app));
|
||||
scrobbler->AddService(make_shared<SubsonicScrobbler>(scrobbler->settings(), app->streaming_services()->Service<SubsonicService>(), app));
|
||||
#endif
|
||||
return scrobbler;
|
||||
}),
|
||||
#ifdef HAVE_MOODBAR
|
||||
moodbar_loader_([app]() { return new MoodbarLoader(app); }),
|
||||
moodbar_controller_([app]() { return new MoodbarController(app); }),
|
||||
moodbar_controller_([app]() { return new MoodbarController(app->player(), app->moodbar_loader()); }),
|
||||
#endif
|
||||
lastfm_import_([app]() { return new LastFMImport(app->network()); })
|
||||
{}
|
||||
|
||||
Lazy<TagReaderClient> tag_reader_client_;
|
||||
Lazy<TagReaderClient> tagreader_client_;
|
||||
Lazy<Database> database_;
|
||||
Lazy<TaskManager> task_manager_;
|
||||
Lazy<Player> player_;
|
||||
Lazy<NetworkAccessManager> network_;
|
||||
Lazy<DeviceFinders> device_finders_;
|
||||
#ifndef Q_OS_WIN
|
||||
Lazy<UrlHandlers> url_handlers_;
|
||||
Lazy<DeviceManager> device_manager_;
|
||||
#endif
|
||||
Lazy<SCollection> collection_;
|
||||
Lazy<CollectionLibrary> collection_;
|
||||
Lazy<PlaylistBackend> playlist_backend_;
|
||||
Lazy<PlaylistManager> playlist_manager_;
|
||||
Lazy<CoverProviders> cover_providers_;
|
||||
Lazy<AlbumCoverLoader> album_cover_loader_;
|
||||
Lazy<AlbumCoverLoader> albumcover_loader_;
|
||||
Lazy<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
Lazy<LyricsProviders> lyrics_providers_;
|
||||
Lazy<StreamingServices> 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<TagReaderClient> Application::tag_reader_client() const { return p_->tag_reader_client_.ptr(); }
|
||||
SharedPtr<TagReaderClient> Application::tagreader_client() const { return p_->tagreader_client_.ptr(); }
|
||||
SharedPtr<Database> Application::database() const { return p_->database_.ptr(); }
|
||||
SharedPtr<TaskManager> Application::task_manager() const { return p_->task_manager_.ptr(); }
|
||||
SharedPtr<Player> Application::player() const { return p_->player_.ptr(); }
|
||||
SharedPtr<NetworkAccessManager> Application::network() const { return p_->network_.ptr(); }
|
||||
SharedPtr<DeviceFinders> Application::device_finders() const { return p_->device_finders_.ptr(); }
|
||||
#ifndef Q_OS_WIN
|
||||
SharedPtr<UrlHandlers> Application::url_handlers() const { return p_->url_handlers_.ptr(); }
|
||||
SharedPtr<DeviceManager> Application::device_manager() const { return p_->device_manager_.ptr(); }
|
||||
#endif
|
||||
SharedPtr<SCollection> Application::collection() const { return p_->collection_.ptr(); }
|
||||
SharedPtr<CollectionLibrary> Application::collection() const { return p_->collection_.ptr(); }
|
||||
SharedPtr<CollectionBackend> Application::collection_backend() const { return collection()->backend(); }
|
||||
CollectionModel *Application::collection_model() const { return collection()->model(); }
|
||||
SharedPtr<AlbumCoverLoader> Application::album_cover_loader() const { return p_->album_cover_loader_.ptr(); }
|
||||
SharedPtr<AlbumCoverLoader> Application::albumcover_loader() const { return p_->albumcover_loader_.ptr(); }
|
||||
SharedPtr<CoverProviders> Application::cover_providers() const { return p_->cover_providers_.ptr(); }
|
||||
SharedPtr<CurrentAlbumCoverLoader> Application::current_albumcover_loader() const { return p_->current_albumcover_loader_.ptr(); }
|
||||
SharedPtr<LyricsProviders> Application::lyrics_providers() const { return p_->lyrics_providers_.ptr(); }
|
||||
|
@ -29,10 +29,8 @@
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#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<TagReaderClient> tag_reader_client() const;
|
||||
SharedPtr<TagReaderClient> tagreader_client() const;
|
||||
SharedPtr<Database> database() const;
|
||||
SharedPtr<TaskManager> task_manager() const;
|
||||
SharedPtr<Player> player() const;
|
||||
SharedPtr<NetworkAccessManager> network() const;
|
||||
SharedPtr<DeviceFinders> device_finders() const;
|
||||
#ifndef Q_OS_WIN
|
||||
SharedPtr<UrlHandlers> url_handlers() const;
|
||||
SharedPtr<DeviceManager> device_manager() const;
|
||||
#endif
|
||||
|
||||
SharedPtr<SCollection> collection() const;
|
||||
SharedPtr<CollectionLibrary> collection() const;
|
||||
SharedPtr<CollectionBackend> collection_backend() const;
|
||||
CollectionModel *collection_model() const;
|
||||
|
||||
@ -90,7 +86,7 @@ class Application : public QObject {
|
||||
SharedPtr<PlaylistManager> playlist_manager() const;
|
||||
|
||||
SharedPtr<CoverProviders> cover_providers() const;
|
||||
SharedPtr<AlbumCoverLoader> album_cover_loader() const;
|
||||
SharedPtr<AlbumCoverLoader> albumcover_loader() const;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader() const;
|
||||
|
||||
SharedPtr<LyricsProviders> 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<ApplicationImpl> p_;
|
||||
QList<QThread*> threads_;
|
||||
QList<QObject*> wait_for_exit_;
|
||||
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "core/logging.h"
|
||||
#include "taskmanager.h"
|
||||
#include "database.h"
|
||||
#include "application.h"
|
||||
#include "sqlquery.h"
|
||||
#include "scopedtransaction.h"
|
||||
|
||||
@ -62,9 +61,9 @@ constexpr char kMagicAllSongsTables[] = "%allsongstables";
|
||||
int Database::sNextConnectionId = 1;
|
||||
QMutex Database::sNextConnectionIdMutex;
|
||||
|
||||
Database::Database(Application *app, QObject *parent, const QString &database_name) :
|
||||
Database::Database(SharedPtr<TaskManager> task_manager, QObject *parent, const QString &database_name) :
|
||||
QObject(parent),
|
||||
app_(app),
|
||||
task_manager_(task_manager),
|
||||
injected_database_name_(database_name),
|
||||
query_hash_(0),
|
||||
startup_schema_version_(-1),
|
||||
@ -145,7 +144,7 @@ QSqlDatabase Database::Connect() {
|
||||
}
|
||||
|
||||
if (!db.open()) {
|
||||
app_->AddError(u"Database: "_s + db.lastError().text());
|
||||
Q_EMIT Error(u"Database: "_s + db.lastError().text());
|
||||
return db;
|
||||
}
|
||||
|
||||
@ -492,7 +491,7 @@ void Database::ReportErrors(const SqlQuery &query) {
|
||||
bool Database::IntegrityCheck(const QSqlDatabase &db) {
|
||||
|
||||
qLog(Debug) << "Starting database integrity check";
|
||||
const int task_id = app_->task_manager()->StartTask(tr("Integrity check"));
|
||||
const int task_id = task_manager_->StartTask(tr("Integrity check"));
|
||||
|
||||
bool ok = false;
|
||||
// Ask for 10 error messages at most.
|
||||
@ -509,8 +508,8 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (!error_reported) { app_->AddError(tr("Database corruption detected.")); }
|
||||
app_->AddError(u"Database: "_s + message);
|
||||
if (!error_reported) { Q_EMIT Error(tr("Database corruption detected.")); }
|
||||
Q_EMIT Error(u"Database: "_s + message);
|
||||
error_reported = true;
|
||||
}
|
||||
}
|
||||
@ -519,7 +518,7 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) {
|
||||
ReportErrors(q);
|
||||
}
|
||||
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
|
||||
return ok;
|
||||
|
||||
@ -563,7 +562,7 @@ void Database::BackupFile(const QString &filename) {
|
||||
|
||||
qLog(Debug) << "Starting database backup";
|
||||
QString dest_filename = QStringLiteral("%1.bak").arg(filename);
|
||||
const int task_id = app_->task_manager()->StartTask(tr("Backing up database"));
|
||||
const int task_id = task_manager_->StartTask(tr("Backing up database"));
|
||||
|
||||
sqlite3 *source_connection = nullptr;
|
||||
sqlite3 *dest_connection = nullptr;
|
||||
@ -575,7 +574,7 @@ void Database::BackupFile(const QString &filename) {
|
||||
if (dest_connection) {
|
||||
sqlite3_close(dest_connection);
|
||||
}
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
});
|
||||
|
||||
bool success = OpenDatabase(filename, &source_connection);
|
||||
@ -599,7 +598,7 @@ void Database::BackupFile(const QString &filename) {
|
||||
do {
|
||||
ret = sqlite3_backup_step(backup, 16);
|
||||
const int page_count = sqlite3_backup_pagecount(backup);
|
||||
app_->task_manager()->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count);
|
||||
task_manager_->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count);
|
||||
}
|
||||
while (ret == SQLITE_OK);
|
||||
|
||||
|
@ -36,16 +36,17 @@
|
||||
#include <QStringList>
|
||||
#include <QRecursiveMutex>
|
||||
|
||||
#include "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<TaskManager> task_manager, QObject *parent = nullptr, const QString &database_name = QString());
|
||||
~Database() override;
|
||||
|
||||
static const int kSchemaVersion;
|
||||
@ -102,7 +103,7 @@ class Database : public QObject {
|
||||
void BackupFile(const QString &filename);
|
||||
static bool OpenDatabase(const QString &filename, sqlite3 **connection);
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
|
||||
// Alias -> filename
|
||||
QMap<QString, AttachedDatabase> attached_databases_;
|
||||
@ -130,16 +131,4 @@ class Database : public QObject {
|
||||
|
||||
};
|
||||
|
||||
class MemoryDatabase : public Database {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MemoryDatabase(Application *app, QObject *parent = nullptr)
|
||||
: Database(app, parent, QStringLiteral(":memory:")) {}
|
||||
~MemoryDatabase() override {
|
||||
// Make sure Qt doesn't reuse the same database
|
||||
QSqlDatabase::removeDatabase(Connect().connectionName());
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DATABASE_H
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <QUrl>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "taskmanager.h"
|
||||
#include "song.h"
|
||||
#include "deletefiles.h"
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "song.h"
|
||||
|
||||
class QThread;
|
||||
|
@ -30,11 +30,11 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QSettings>
|
||||
|
||||
#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
|
||||
|
@ -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 <QApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <QWidget>
|
||||
@ -61,7 +52,14 @@
|
||||
#include <QEvent>
|
||||
#include <QFile>
|
||||
|
||||
#include <QtDebug>
|
||||
#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) {
|
||||
|
||||
|
@ -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;
|
||||
@ -258,8 +259,9 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
app_(app),
|
||||
tray_icon_(tray_icon),
|
||||
osd_(osd),
|
||||
console_([app]() {
|
||||
Console *console = new Console(app);
|
||||
console_([app, this]() {
|
||||
Console *console = new Console(app->database());
|
||||
QObject::connect(console, &Console::Error, this, &MainWindow::ShowErrorDialog);
|
||||
return console;
|
||||
}),
|
||||
edit_tag_dialog_(std::bind(&MainWindow::CreateEditTagDialog, this)),
|
||||
@ -277,7 +279,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
queue_view_(new QueueView(this)),
|
||||
settings_dialog_(std::bind(&MainWindow::CreateSettingsDialog, this)),
|
||||
cover_manager_([this, app]() {
|
||||
AlbumCoverManager *cover_manager = new AlbumCoverManager(app, app->collection_backend(), this);
|
||||
AlbumCoverManager *cover_manager = new AlbumCoverManager(app->network(), app->collection_backend(), app->tagreader_client(), app->albumcover_loader(), app->current_albumcover_loader(), app->cover_providers(), app->streaming_services(), this);
|
||||
cover_manager->Init();
|
||||
|
||||
// Cover manager connections
|
||||
@ -287,7 +289,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +302,25 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
QObject::connect(add_stream_dialog, &AddStreamDialog::accepted, this, &MainWindow::AddStreamAccepted);
|
||||
return add_stream_dialog;
|
||||
}),
|
||||
smartplaylists_view_(new SmartPlaylistsViewContainer(app, this)),
|
||||
smartplaylists_view_(new SmartPlaylistsViewContainer(app->player(),
|
||||
app->playlist_manager(),
|
||||
app->collection_backend(),
|
||||
#ifdef HAVE_MOODBAR
|
||||
app->moodbar_loader(),
|
||||
#endif
|
||||
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 +354,10 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +367,18 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
|
||||
qLog(Debug) << "Starting";
|
||||
|
||||
QObject::connect(app, &Application::ErrorAdded, this, &MainWindow::ShowErrorDialog);
|
||||
QObject::connect(app, &Application::SettingsDialogRequested, this, &MainWindow::OpenSettingsDialogAtPage);
|
||||
|
||||
// Initialize the UI
|
||||
ui_->setupUi(this);
|
||||
|
||||
setWindowIcon(IconLoader::Load(u"strawberry"_s));
|
||||
|
||||
album_cover_choice_controller_->Init(app);
|
||||
QObject::connect(&*app->database(), &Database::Error, this, &MainWindow::ShowErrorDialog);
|
||||
|
||||
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 +410,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +431,20 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
|
||||
ui_->playlist->SetManager(app_->playlist_manager());
|
||||
|
||||
ui_->playlist->view()->Init(app_);
|
||||
ui_->playlist->view()->Init(app_->player(),
|
||||
app_->playlist_manager(),
|
||||
app_->collection_backend(),
|
||||
#ifdef HAVE_MOODBAR
|
||||
app_->moodbar_loader(),
|
||||
#endif
|
||||
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_->playlist_manager(), app_->playlist_backend(), app_->device_manager());
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->collection()->model()->directory_model());
|
||||
|
||||
@ -541,9 +555,9 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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));
|
||||
|
||||
@ -597,6 +611,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, ui_->playlist, &PlaylistContainer::ActiveStopped);
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, osd_, &OSDBase::SongChanged);
|
||||
|
||||
QObject::connect(&*app_->player(), &Player::Paused, osd_, &OSDBase::Paused);
|
||||
QObject::connect(&*app_->player(), &Player::Resumed, osd_, &OSDBase::Resumed);
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, osd_, &OSDBase::Stopped);
|
||||
@ -605,6 +620,16 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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_->player(), &Player::Paused, playlist_list_, &PlaylistListContainer::ActivePaused);
|
||||
QObject::connect(&*app_->player(), &Player::Playing, playlist_list_, &PlaylistListContainer::ActivePlaying);
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, playlist_list_, &PlaylistListContainer::ActiveStopped);
|
||||
|
||||
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 +653,9 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +663,10 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +700,8 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +714,16 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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<TidalService>()) {
|
||||
QObject::connect(this, &MainWindow::AuthorizationUrlReceived, &*tidalservice, &TidalService::AuthorizationUrlReceived);
|
||||
@ -702,16 +731,20 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +806,15 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +883,14 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page);
|
||||
QObject::connect(ui_->multi_loading_indicator, &MultiLoadingIndicator::TaskCountChange, this, &MainWindow::TaskCountChanged);
|
||||
|
||||
ui_->track_slider->SetApplication(app);
|
||||
ui_->track_slider->Init();
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
// Moodbar connections
|
||||
QObject::connect(&*app_->moodbar_controller(), &MoodbarController::CurrentMoodbarDataChanged, ui_->track_slider->moodbar_style(), &MoodbarProxyStyle::SetMoodbarData);
|
||||
QObject::connect(&*app_->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 +912,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
css_loader->SetStyleSheet(this, u":/style/strawberry.css"_s);
|
||||
|
||||
// Load playlists
|
||||
app_->playlist_manager()->Init(app_->collection_backend(), app_->playlist_backend(), ui_->playlist_sequence, ui_->playlist);
|
||||
app_->playlist_manager()->Init(ui_->playlist_sequence, ui_->playlist);
|
||||
|
||||
queue_view_->SetPlaylistManager(app_->playlist_manager());
|
||||
|
||||
@ -902,10 +939,12 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::FinishedWithError, lastfm_import_dialog_, &LastFMImportDialog::FinishedWithError);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateTotal, lastfm_import_dialog_, &LastFMImportDialog::UpdateTotal);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateProgress, lastfm_import_dialog_, &LastFMImportDialog::UpdateProgress);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateLastPlayed, &*app_->collection_backend(), &CollectionBackend::UpdateLastPlayed);
|
||||
QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdatePlayCount, &*app_->collection_backend(), &CollectionBackend::UpdatePlayCount);
|
||||
|
||||
// Load settings
|
||||
qLog(Debug) << "Loading settings";
|
||||
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 +952,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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<int>() << 20 << (width() - 20));
|
||||
}
|
||||
|
||||
@ -941,40 +980,40 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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<BehaviourSettingsPage::StartupBehaviour>(s.value("startupbehaviour", static_cast<int>(BehaviourSettingsPage::StartupBehaviour::Remember)).toInt());
|
||||
s.beginGroup(BehaviourSettings::kSettingsGroup);
|
||||
startupbehaviour = static_cast<BehaviourSettings::StartupBehaviour>(s.value(BehaviourSettings::kStartupBehaviour, static_cast<int>(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 +1021,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +1055,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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 +1069,12 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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("<a href=\"https://downloads.strawberrymusicplayer.org/\">downloads.strawberrymusicplayer.org</a>")), IconLoader::Load(u"dialog-warning"_s));
|
||||
@ -1052,14 +1091,13 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> 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"<a href= \"https://www.strawberrymusicplayer.org/\">www.strawberrymusicplayer.org</a>"_s), IconLoader::Load(u"dialog-information"_s));
|
||||
}
|
||||
@ -1083,8 +1121,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 +1133,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<BehaviourSettingsPage::AddBehaviour>(s.value("doubleclick_addmode", static_cast<int>(BehaviourSettingsPage::AddBehaviour::Append)).toInt());
|
||||
doubleclick_playmode_ = static_cast<BehaviourSettingsPage::PlayBehaviour>(s.value("doubleclick_playmode", static_cast<int>(BehaviourSettingsPage::PlayBehaviour::Never)).toInt());
|
||||
doubleclick_playlist_addmode_ = static_cast<BehaviourSettingsPage::PlaylistAddBehaviour>(s.value("doubleclick_playlist_addmode", static_cast<int>(BehaviourSettingsPage::PlayBehaviour::Never)).toInt());
|
||||
menu_playmode_ = static_cast<BehaviourSettingsPage::PlayBehaviour>(s.value("menu_playmode", static_cast<int>(BehaviourSettingsPage::PlayBehaviour::Never)).toInt());
|
||||
doubleclick_addmode_ = static_cast<BehaviourSettings::AddBehaviour>(s.value(BehaviourSettings::kDoubleClickAddMode, static_cast<int>(BehaviourSettings::AddBehaviour::Append)).toInt());
|
||||
doubleclick_playmode_ = static_cast<BehaviourSettings::PlayBehaviour>(s.value(BehaviourSettings::kDoubleClickPlayMode, static_cast<int>(BehaviourSettings::PlayBehaviour::Never)).toInt());
|
||||
doubleclick_playlist_addmode_ = static_cast<BehaviourSettings::PlaylistAddBehaviour>(s.value(BehaviourSettings::kDoubleClickPlaylistAddMode, static_cast<int>(BehaviourSettings::PlayBehaviour::Never)).toInt());
|
||||
menu_playmode_ = static_cast<BehaviourSettings::PlayBehaviour>(s.value(BehaviourSettings::kMenuPlayMode, static_cast<int>(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 +1166,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 +1181,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 +1202,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 +1214,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 +1226,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 +1246,6 @@ void MainWindow::ReloadAllSettings() {
|
||||
ReloadSettings();
|
||||
|
||||
// Other settings
|
||||
app_->ReloadSettings();
|
||||
app_->collection()->ReloadSettings();
|
||||
app_->player()->ReloadSettings();
|
||||
collection_view_->ReloadSettings();
|
||||
@ -1228,18 +1265,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 +1297,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 +1542,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 +1588,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 +1766,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 +1856,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 +2203,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 +2234,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 +2270,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 +2512,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 +2605,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,10 +2876,18 @@ 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(),
|
||||
#ifdef HAVE_GLOBALSHORTCUTS
|
||||
settings_dialog->SetGlobalShortcutManager(globalshortcuts_manager_);
|
||||
globalshortcuts_manager_,
|
||||
#endif
|
||||
osd_,
|
||||
this);
|
||||
|
||||
// Settings
|
||||
QObject::connect(settings_dialog, &SettingsDialog::ReloadSettings, this, &MainWindow::ReloadAllSettings);
|
||||
@ -2838,7 +2912,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 +3012,7 @@ void MainWindow::AutoCompleteTags() {
|
||||
// Create the tag fetching stuff if it hasn't been already
|
||||
if (!tag_fetcher_) {
|
||||
tag_fetcher_ = make_unique<TagFetcher>(app_->network());
|
||||
track_selection_dialog_ = make_unique<TrackSelectionDialog>();
|
||||
track_selection_dialog_ = make_unique<TrackSelectionDialog>(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 +3060,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
|
||||
|
@ -46,19 +46,19 @@
|
||||
#include <QSettings>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "scoped_ptr.h"
|
||||
#include "shared_ptr.h"
|
||||
#include "lazy.h"
|
||||
#include "platforminterface.h"
|
||||
#include "song.h"
|
||||
#include "settings.h"
|
||||
#include "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<SystemTrayIcon> 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_;
|
||||
|
30
src/core/memorydatabase.cpp
Normal file
30
src/core/memorydatabase.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "memorydatabase.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
MemoryDatabase::MemoryDatabase(SharedPtr<TaskManager> task_manager, QObject *parent)
|
||||
: Database(task_manager, parent, u":memory:"_s) {}
|
||||
|
||||
MemoryDatabase::~MemoryDatabase() {
|
||||
// Make sure Qt doesn't reuse the same database
|
||||
Close();
|
||||
}
|
37
src/core/memorydatabase.h
Normal file
37
src/core/memorydatabase.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MEMORYDATABASE_H
|
||||
#define MEMORYDATABASE_H
|
||||
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
class TaskManager;
|
||||
|
||||
#include "database.h"
|
||||
|
||||
class MemoryDatabase : public Database {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MemoryDatabase(SharedPtr<TaskManager> task_manager, QObject *parent = nullptr);
|
||||
~MemoryDatabase() override;
|
||||
};
|
||||
|
||||
#endif // MEMORYDATABASE_H
|
@ -35,7 +35,7 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "includes/scoped_ptr.h"
|
||||
|
||||
class QMimeData;
|
||||
|
||||
|
@ -43,10 +43,9 @@
|
||||
# include <QDBusArgument>
|
||||
#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*>("MtpConnection*");
|
||||
#endif
|
||||
|
||||
qRegisterMetaType<PlaylistSettingsPage::PathType>("PlaylistSettingsPage::PathType");
|
||||
qRegisterMetaType<PlaylistSettings::PathType>("PlaylistSettings::PathType");
|
||||
|
||||
qRegisterMetaType<PlaylistGeneratorPtr>("PlaylistGeneratorPtr");
|
||||
qRegisterMetaType<SmartPlaylistSearchTerm::Field>("SmartPlaylistSearchTerm::Field");
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <QList>
|
||||
#include <QImage>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "song.h"
|
||||
|
||||
class MusicStorage {
|
||||
|
26
src/core/platforminterface.cpp
Normal file
26
src/core/platforminterface.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include "platforminterface.h"
|
||||
|
||||
PlatformInterface::PlatformInterface() = default;
|
||||
PlatformInterface::~PlatformInterface() = default;
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -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;
|
||||
|
@ -37,18 +37,21 @@
|
||||
#include <QTimer>
|
||||
#include <QSettings>
|
||||
|
||||
#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(const SharedPtr<TaskManager> task_manager, const SharedPtr<UrlHandlers> url_handlers, const SharedPtr<PlaylistManager> 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<GstEngine> gst_engine(new GstEngine(app_->task_manager()));
|
||||
ScopedPtr<GstEngine> 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<BehaviourSettingsPage::PreviousBehaviour>(s.value("menu_previousmode", static_cast<int>(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<BehaviourSettings::PreviousBehaviour>(s.value(BehaviourSettings::kMenuPreviousMode, static_cast<int>(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) const {
|
||||
|
||||
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<int>(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<int>(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<EngineBase::State>(s.value("playback_state", static_cast<int>(EngineBase::State::Empty)).toInt());
|
||||
s.beginGroup(kSettingsGroup);
|
||||
const EngineBase::State playback_state = static_cast<EngineBase::State>(s.value(kPlaybackState, static_cast<int>(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<EngineBase::State>(s.value("playback_state", static_cast<int>(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<EngineBase::State>(s.value(kPlaybackState, static_cast<int>(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<int>(EngineBase::State::Empty));
|
||||
s.setValue("playback_playlist", -1);
|
||||
s.setValue("playback_position", 0);
|
||||
s.setValue(kPlaybackState, static_cast<int>(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<Playlist*> playlists = app_->playlist_manager()->GetAllPlaylists();
|
||||
const QList<Playlist*> 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<QString, UrlHandler*>::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<UrlHandler*>(object);
|
||||
const QString scheme = url_handlers_.key(handler);
|
||||
if (!scheme.isEmpty()) {
|
||||
url_handlers_.remove(scheme);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Player::HandleAuthentication() {
|
||||
Q_EMIT Authenticated();
|
||||
}
|
||||
|
@ -31,110 +31,29 @@
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#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<EngineBase> 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(const SharedPtr<TaskManager> task_manager, const SharedPtr<UrlHandlers> url_handlers, const SharedPtr<PlaylistManager> 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) const;
|
||||
|
||||
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_;
|
||||
const SharedPtr<TaskManager> task_manager_;
|
||||
const SharedPtr<UrlHandlers> url_handlers_;
|
||||
const SharedPtr<PlaylistManager> playlist_manager_;
|
||||
SharedPtr<EngineBase> engine_;
|
||||
GstStartup *gst_startup_;
|
||||
AnalyzerContainer *analyzer_;
|
||||
@ -242,8 +160,6 @@ class Player : public PlayerInterface {
|
||||
EngineBase::State last_state_;
|
||||
int nb_errors_received_;
|
||||
|
||||
QMap<QString, UrlHandler*> url_handlers_;
|
||||
|
||||
QList<QUrl> 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
|
||||
|
24
src/core/playerinterface.cpp
Normal file
24
src/core/playerinterface.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "playerinterface.h"
|
||||
|
||||
PlayerInterface::PlayerInterface(QObject *parent) : QObject(parent) {}
|
117
src/core/playerinterface.h
Normal file
117
src/core/playerinterface.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYERINTERFACE_H
|
||||
#define PLAYERINTERFACE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#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<EngineBase> 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
|
@ -51,11 +51,11 @@
|
||||
#include <taglib/tstring.h>
|
||||
|
||||
#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<QString> artists;
|
||||
QSet<QString> 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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -509,6 +509,8 @@ class Song {
|
||||
static QString AlbumRemoveDiscMisc(const QString &album);
|
||||
static QString TitleRemoveMisc(const QString &title);
|
||||
|
||||
static QString GetNameForNewPlaylist(const QList<Song> &songs);
|
||||
|
||||
static inline QString TagLibStringToQString(const TagLib::String &s) {
|
||||
return QString::fromUtf8((s).toCString(true));
|
||||
}
|
||||
|
@ -39,15 +39,13 @@
|
||||
#include <QUrl>
|
||||
#include <QEventLoop>
|
||||
|
||||
#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<QString> SongLoader::sRawUriSchemes;
|
||||
|
||||
SongLoader::SongLoader(SharedPtr<CollectionBackendInterface> collection_backend, const SharedPtr<Player> player, QObject *parent)
|
||||
SongLoader::SongLoader(const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend,
|
||||
const SharedPtr<TagReaderClient> 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();
|
||||
}
|
||||
|
@ -38,11 +38,12 @@
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
#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<CollectionBackendInterface> collection_backend, const SharedPtr<Player> player, QObject *parent = nullptr);
|
||||
explicit SongLoader(const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend,
|
||||
const SharedPtr<TagReaderClient> 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> player_;
|
||||
SharedPtr<CollectionBackendInterface> collection_backend_;
|
||||
const SharedPtr<UrlHandlers> url_handlers_;
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
QTimer *timeout_timer_;
|
||||
PlaylistParser *playlist_parser_;
|
||||
CueParser *cue_parser_;
|
||||
|
@ -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;
|
@ -35,8 +35,8 @@
|
||||
#include <QPalette>
|
||||
#include <QEvent>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "core/logging.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "logging.h"
|
||||
#include "stylesheetloader.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <QPalette>
|
||||
#include <QString>
|
||||
|
||||
#include "shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
class QWidget;
|
||||
class QEvent;
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
Translations::Translations() {}
|
||||
Translations::Translations() = default;
|
||||
|
||||
Translations::~Translations() {
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,8 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
95
src/core/urlhandlers.cpp
Normal file
95
src/core/urlhandlers.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "core/logging.h"
|
||||
|
||||
#include "urlhandlers.h"
|
||||
#include "urlhandler.h"
|
||||
|
||||
UrlHandlers::UrlHandlers(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void UrlHandlers::Register(UrlHandler *url_handler) {
|
||||
|
||||
const QString scheme = url_handler->scheme();
|
||||
|
||||
if (url_handlers_.contains(scheme)) {
|
||||
qLog(Warning) << "Tried to register a URL handler for" << scheme << "but one was already registered";
|
||||
return;
|
||||
}
|
||||
|
||||
qLog(Info) << "Registered URL handler for" << scheme;
|
||||
url_handlers_.insert(scheme, url_handler);
|
||||
QObject::connect(url_handler, &UrlHandler::destroyed, this, &UrlHandlers::Destroyed);
|
||||
|
||||
Q_EMIT Registered(url_handler);
|
||||
|
||||
}
|
||||
|
||||
void UrlHandlers::Unregister(UrlHandler *url_handler) {
|
||||
|
||||
const QString scheme = url_handlers_.key(url_handler);
|
||||
if (scheme.isEmpty()) {
|
||||
qLog(Warning) << "Tried to unregister a URL handler for" << url_handler->scheme() << "that wasn't registered";
|
||||
return;
|
||||
}
|
||||
|
||||
qLog(Info) << "Unregistered URL handler for" << scheme;
|
||||
url_handlers_.remove(scheme);
|
||||
QObject::disconnect(url_handler, &UrlHandler::destroyed, this, &UrlHandlers::Destroyed);
|
||||
QObject::disconnect(url_handler, &UrlHandler::AsyncLoadComplete, nullptr, nullptr);
|
||||
|
||||
}
|
||||
|
||||
void UrlHandlers::Destroyed(QObject *object) {
|
||||
|
||||
UrlHandler *handler = static_cast<UrlHandler*>(object);
|
||||
const QString scheme = url_handlers_.key(handler);
|
||||
if (!scheme.isEmpty()) {
|
||||
url_handlers_.remove(scheme);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool UrlHandlers::CanHandle(const QString &scheme) const {
|
||||
|
||||
return url_handlers_.contains(scheme);
|
||||
|
||||
}
|
||||
|
||||
bool UrlHandlers::CanHandle(const QUrl &url) const {
|
||||
|
||||
return url_handlers_.contains(url.scheme());
|
||||
|
||||
}
|
||||
|
||||
UrlHandler *UrlHandlers::GetUrlHandler(const QString &scheme) const {
|
||||
|
||||
if (!CanHandle(scheme)) return nullptr;
|
||||
|
||||
return url_handlers_.value(scheme);
|
||||
|
||||
}
|
||||
|
||||
UrlHandler *UrlHandlers::GetUrlHandler(const QUrl &url) const {
|
||||
|
||||
return GetUrlHandler(url.scheme());
|
||||
|
||||
}
|
56
src/core/urlhandlers.h
Normal file
56
src/core/urlhandlers.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef URLHANDLERS_H
|
||||
#define URLHANDLERS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
class UrlHandler;
|
||||
|
||||
class UrlHandlers : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UrlHandlers(QObject *parent = nullptr);
|
||||
|
||||
void Register(UrlHandler *url_handler);
|
||||
void Unregister(UrlHandler *url_handler);
|
||||
void Destroyed(QObject *object);
|
||||
|
||||
bool CanHandle(const QString &scheme) const;
|
||||
bool CanHandle(const QUrl &url) const;
|
||||
|
||||
UrlHandler *GetUrlHandler(const QString &scheme) const;
|
||||
UrlHandler *GetUrlHandler(const QUrl &url) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void Registered(UrlHandler *url_handler);
|
||||
void UnRegistered(UrlHandler *url_handler);
|
||||
|
||||
private:
|
||||
QMap<QString, UrlHandler*> url_handlers_;
|
||||
};
|
||||
|
||||
#endif // URLHANDLERS_H
|
@ -54,20 +54,21 @@
|
||||
#include <QSettings>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "utilities/filenameconstants.h"
|
||||
#include "constants/filenameconstants.h"
|
||||
#include "constants/filefilterconstants.h"
|
||||
#include "constants/coverssettings.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 "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<QString> *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) {
|
||||
void AlbumCoverChoiceController::Init(const SharedPtr<NetworkAccessManager> network,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
const SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
const SharedPtr<CoverProviders> cover_providers,
|
||||
const SharedPtr<StreamingServices> streaming_services) {
|
||||
|
||||
app_ = app;
|
||||
network_ = network;
|
||||
tagreader_client_ = tagreader_client;
|
||||
collection_backend_ = collection_backend;
|
||||
current_albumcover_loader_ = current_albumcover_loader;
|
||||
streaming_services_ = streaming_services;
|
||||
|
||||
cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), app->network(), this);
|
||||
cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), app, this);
|
||||
cover_fetcher_ = new AlbumCoverFetcher(cover_providers, network, this);
|
||||
cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), 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<CoverOptions::CoverType>(s.value(CoversSettingsPage::kSaveType, static_cast<int>(CoverOptions::CoverType::Cache)).toInt());
|
||||
cover_options_.cover_filename = static_cast<CoverOptions::CoverFilename>(s.value(CoversSettingsPage::kSaveFilename, static_cast<int>(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<CoverOptions::CoverType>(s.value(CoversSettings::kSaveType, static_cast<int>(CoverOptions::CoverType::Cache)).toInt());
|
||||
cover_options_.cover_filename = static_cast<CoverOptions::CoverFilename>(s.value(CoversSettings::kSaveFilename, static_cast<int>(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<SongList> future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, app_->collection_backend(), effective_albumartist, effective_album, CollectionFilterOptions());
|
||||
QFuture<SongList> future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, collection_backend_, effective_albumartist, effective_album, CollectionFilterOptions());
|
||||
QFutureWatcher<SongList> *watcher = new QFutureWatcher<SongList>();
|
||||
QObject::connect(watcher, &QFutureWatcher<SongList>::finished, this, [this, watcher, cover_filename, image_data, mime_type]() {
|
||||
const SongList collection_songs = watcher->result();
|
||||
@ -736,7 +742,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToSong(const Song &song, const
|
||||
QMutexLocker l(&mutex_cover_save_tasks_);
|
||||
cover_save_tasks_.append(song);
|
||||
const bool art_embedded = !image_data.isNull();
|
||||
TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(song.url().toLocalFile(), SaveTagCoverData(cover_filename, image_data, mime_type));
|
||||
TagReaderReplyPtr reply = 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); });
|
||||
|
||||
}
|
||||
|
@ -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(const SharedPtr<NetworkAccessManager> network,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
const SharedPtr<AlbumCoverLoader> albumcover_loader,
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
const SharedPtr<CoverProviders> cover_providers,
|
||||
const SharedPtr<StreamingServices> streaming_services);
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
CoverOptions::CoverType get_save_album_cover_type() const { return (save_embedded_cover_override_ ? CoverOptions::CoverType::Embedded : cover_options_.cover_type); }
|
||||
@ -172,7 +180,12 @@ class AlbumCoverChoiceController : public QWidget {
|
||||
static bool IsKnownImageExtension(const QString &suffix);
|
||||
static QSet<QString> *sImageExtensions;
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
SharedPtr<TagReaderClient> tagreader_client_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
SharedPtr<StreamingServices> streaming_services_;
|
||||
|
||||
AlbumCoverSearcher *cover_searcher_;
|
||||
AlbumCoverFetcher *cover_fetcher_;
|
||||
|
||||
|
@ -37,7 +37,9 @@
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
const char *AlbumCoverExport::kSettingsGroup = "AlbumCoverExport";
|
||||
namespace {
|
||||
constexpr char kSettingsGroup[] = "AlbumCoverExport";
|
||||
}
|
||||
|
||||
AlbumCoverExport::AlbumCoverExport(QWidget *parent) : QDialog(parent), ui_(new Ui_AlbumCoverExport) {
|
||||
|
||||
|
@ -78,8 +78,6 @@ class AlbumCoverExport : public QDialog {
|
||||
|
||||
private:
|
||||
Ui_AlbumCoverExport *ui_;
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
};
|
||||
|
||||
#endif // ALBUMCOVEREXPORT_H
|
||||
|
@ -33,8 +33,9 @@ namespace {
|
||||
constexpr int kMaxConcurrentRequests = 3;
|
||||
}
|
||||
|
||||
AlbumCoverExporter::AlbumCoverExporter(QObject *parent)
|
||||
AlbumCoverExporter::AlbumCoverExporter(const SharedPtr<TagReaderClient> 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<int>(requests_.count());
|
||||
|
||||
}
|
||||
|
@ -27,18 +27,21 @@
|
||||
#include <QQueue>
|
||||
#include <QString>
|
||||
|
||||
#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(const SharedPtr<TagReaderClient> 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();
|
||||
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
|
||||
AlbumCoverLoaderOptions::Types cover_types_;
|
||||
AlbumCoverExport::DialogResult dialog_result_;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/song.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
#include "coversearchstatistics.h"
|
||||
#include "albumcoverimageresult.h"
|
||||
|
@ -36,8 +36,8 @@
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#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"
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "albumcoverfetcher.h"
|
||||
#include "coversearchstatistics.h"
|
||||
#include "albumcoverimageresult.h"
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#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(const SharedPtr<TagReaderClient> 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);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <QString>
|
||||
#include <QImage>
|
||||
|
||||
#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(const SharedPtr<TagReaderClient> tagreader_client, QObject *parent = nullptr);
|
||||
|
||||
void ExitAsync();
|
||||
void Stop() { stop_requested_ = true; }
|
||||
@ -125,7 +126,8 @@ class AlbumCoverLoader : public QObject {
|
||||
void LoadRemoteImageFinished(QNetworkReply *reply, AlbumCoverLoader::TaskPtr task, const AlbumCoverLoaderResult::Type result_type, const QUrl &cover_url);
|
||||
|
||||
private:
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
const SharedPtr<NetworkAccessManager> network_;
|
||||
QTimer *timer_process_tasks_;
|
||||
bool stop_requested_;
|
||||
QMutex mutex_load_image_async_;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <QSettings>
|
||||
|
||||
#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;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user