From 428eecef836cc410dd81c8a1ab6a41501d5818aa Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Tue, 22 Oct 2024 18:12:33 +0200 Subject: [PATCH] Refactoring --- CMakeLists.txt | 1121 ++--------------- src/CMakeLists.txt | 69 + src/analyzer/CMakeLists.txt | 41 + src/analyzer/analyzerbase.h | 2 +- src/analyzer/analyzercontainer.cpp | 2 +- src/analyzer/analyzercontainer.h | 2 +- src/collection/CMakeLists.txt | 82 ++ src/collection/collectionbackend.cpp | 25 +- src/collection/collectionbackend.h | 6 +- src/collection/collectiondirectorymodel.cpp | 2 +- src/collection/collectiondirectorymodel.h | 2 +- src/collection/collectionfilter.cpp | 5 +- src/collection/collectionfilterwidget.cpp | 12 +- src/collection/collectionitem.cpp | 32 + src/collection/collectionitem.h | 19 +- .../{collection.cpp => collectionlibrary.cpp} | 101 +- .../{collection.h => collectionlibrary.h} | 26 +- src/collection/collectionmodel.cpp | 82 +- src/collection/collectionmodel.h | 22 +- src/collection/collectiontask.cpp | 2 +- src/collection/collectiontask.h | 2 +- src/collection/collectionview.cpp | 118 +- src/collection/collectionview.h | 51 +- src/collection/collectionviewcontainer.cpp | 4 +- src/collection/collectionwatcher.cpp | 43 +- src/collection/collectionwatcher.h | 25 +- src/collection/groupbydialog.h | 4 +- src/collection/savedgroupingmanager.cpp | 4 +- src/constants/appearancesettings.h | 75 ++ src/constants/backendsettings.h | 64 + src/constants/behavioursettings.h | 76 ++ src/constants/collectionsettings.h | 62 + src/constants/contextsettings.h | 48 + src/constants/coverssettings.h | 37 + src/constants/filefilterconstants.h | 39 + .../filenameconstants.h | 2 +- src/constants/globalshortcutssettings.h | 33 + src/constants/lyricssettings.h | 30 + src/constants/mainwindowsettings.h | 37 + src/constants/moodbarsettings.h | 43 + src/constants/networkproxysettings.h | 37 + src/constants/notificationssettings.h | 68 + src/constants/playlistsettings.h | 70 + src/constants/qobuzsettings.h | 47 + src/constants/scrobblersettings.h | 40 + src/constants/spotifysettings.h | 42 + src/constants/subsonicsettings.h | 45 + src/constants/tidalsettings.h | 52 + src/constants/timeconstants.h | 34 + src/constants/transcodersettings.h | 29 + src/context/CMakeLists.txt | 32 + src/context/contextalbum.cpp | 2 +- src/context/contextalbum.h | 4 +- src/context/contextview.cpp | 56 +- src/context/contextview.h | 5 +- src/core/CMakeLists.txt | 95 ++ src/core/application.cpp | 128 +- src/core/application.h | 30 +- src/core/database.cpp | 21 +- src/core/database.h | 19 +- src/core/deletefiles.cpp | 2 +- src/core/deletefiles.h | 2 +- src/{engine => core}/enginemetadata.cpp | 0 src/{engine => core}/enginemetadata.h | 0 src/core/iconloader.cpp | 8 +- src/core/mac_startup.mm | 18 +- src/core/mainwindow.cpp | 398 +++--- src/core/mainwindow.h | 35 +- src/core/memorydatabase.cpp | 30 + src/core/memorydatabase.h | 37 + src/core/mergedproxymodel.h | 2 +- src/core/metatypes.cpp | 11 +- src/core/musicstorage.h | 2 +- src/core/platforminterface.cpp | 26 + src/core/platforminterface.h | 7 +- src/core/player.cpp | 290 ++--- src/core/player.h | 117 +- src/core/playerinterface.cpp | 24 + src/core/playerinterface.h | 117 ++ src/core/song.cpp | 44 +- src/core/song.h | 2 + src/core/songloader.cpp | 64 +- src/core/songloader.h | 18 +- src/{playlist => core}/songmimedata.cpp | 0 src/{playlist => core}/songmimedata.h | 4 +- src/core/stylesheetloader.cpp | 4 +- src/core/stylesheetloader.h | 2 +- src/core/translations.cpp | 2 +- src/core/urlhandler.cpp | 4 +- src/core/urlhandler.h | 4 +- src/core/urlhandlers.cpp | 95 ++ src/core/urlhandlers.h | 56 + src/covermanager/CMakeLists.txt | 119 ++ .../albumcoverchoicecontroller.cpp | 88 +- src/covermanager/albumcoverchoicecontroller.h | 27 +- src/covermanager/albumcoverexport.cpp | 4 +- src/covermanager/albumcoverexport.h | 2 - src/covermanager/albumcoverexporter.cpp | 5 +- src/covermanager/albumcoverexporter.h | 7 +- src/covermanager/albumcoverfetcher.cpp | 2 +- src/covermanager/albumcoverfetcher.h | 2 +- src/covermanager/albumcoverfetchersearch.cpp | 2 +- src/covermanager/albumcoverfetchersearch.h | 2 +- src/covermanager/albumcoverloader.cpp | 6 +- src/covermanager/albumcoverloader.h | 8 +- src/covermanager/albumcoverloaderoptions.cpp | 6 +- src/covermanager/albumcovermanager.cpp | 50 +- src/covermanager/albumcovermanager.h | 26 +- src/covermanager/albumcovermanagerlist.cpp | 4 +- src/covermanager/albumcoversearcher.cpp | 10 +- src/covermanager/albumcoversearcher.h | 6 +- src/covermanager/coverexportrunnable.cpp | 7 +- src/covermanager/coverexportrunnable.h | 10 +- src/covermanager/coverfromurldialog.cpp | 2 +- src/covermanager/coverfromurldialog.h | 2 +- src/covermanager/coverprovider.cpp | 5 +- src/covermanager/coverprovider.h | 18 +- src/covermanager/coverproviders.cpp | 6 +- src/covermanager/currentalbumcoverloader.cpp | 12 +- src/covermanager/currentalbumcoverloader.h | 11 +- src/covermanager/deezercoverprovider.cpp | 5 +- src/covermanager/deezercoverprovider.h | 3 +- src/covermanager/discogscoverprovider.cpp | 7 +- src/covermanager/discogscoverprovider.h | 5 +- src/covermanager/jsoncoverprovider.cpp | 7 +- src/covermanager/jsoncoverprovider.h | 5 +- src/covermanager/lastfmcoverprovider.cpp | 7 +- src/covermanager/lastfmcoverprovider.h | 5 +- src/covermanager/musicbrainzcoverprovider.cpp | 7 +- src/covermanager/musicbrainzcoverprovider.h | 5 +- src/covermanager/musixmatchcoverprovider.cpp | 7 +- src/covermanager/musixmatchcoverprovider.h | 4 +- src/covermanager/opentidalcoverprovider.cpp | 10 +- src/covermanager/opentidalcoverprovider.h | 5 +- src/covermanager/qobuzcoverprovider.cpp | 10 +- src/covermanager/qobuzcoverprovider.h | 5 +- src/covermanager/spotifycoverprovider.cpp | 10 +- src/covermanager/spotifycoverprovider.h | 7 +- src/covermanager/tidalcoverprovider.cpp | 10 +- src/covermanager/tidalcoverprovider.h | 7 +- src/device/CMakeLists.txt | 115 ++ src/device/cddadevice.cpp | 21 +- src/device/cddadevice.h | 26 +- src/device/cddasongloader.cpp | 4 +- src/device/cddasongloader.h | 2 +- src/device/connecteddevice.cpp | 73 +- src/device/connecteddevice.h | 32 +- src/device/devicedatabasebackend.cpp | 2 +- src/device/devicedatabasebackend.h | 2 +- src/device/devicemanager.cpp | 39 +- src/device/devicemanager.h | 23 +- src/device/deviceproperties.cpp | 24 +- src/device/deviceproperties.h | 6 +- src/device/devicestatefiltermodel.cpp | 4 +- src/device/deviceview.cpp | 57 +- src/device/deviceview.h | 17 +- src/device/filesystemdevice.cpp | 81 +- src/device/filesystemdevice.h | 24 +- src/device/giolister.cpp | 3 +- src/device/giolister.h | 2 +- src/device/gpoddevice.cpp | 39 +- src/device/gpoddevice.h | 21 +- src/device/gpodloader.cpp | 8 +- src/device/gpodloader.h | 9 +- src/device/macosdevicelister.mm | 7 +- src/device/mtpdevice.cpp | 33 +- src/device/mtpdevice.h | 24 +- src/device/mtploader.cpp | 4 +- src/device/mtploader.h | 6 +- src/device/udisks2lister.cpp | 4 +- src/device/udisks2lister.h | 6 +- src/dialogs/CMakeLists.txt | 59 + src/dialogs/about.h | 2 +- src/dialogs/addstreamdialog.h | 2 +- src/dialogs/console.cpp | 9 +- src/dialogs/console.h | 13 +- src/dialogs/edittagdialog.cpp | 67 +- src/dialogs/edittagdialog.h | 28 +- src/dialogs/lastfmimportdialog.cpp | 2 +- src/dialogs/lastfmimportdialog.h | 4 +- src/dialogs/saveplaylistsdialog.cpp | 14 +- src/dialogs/saveplaylistsdialog.h | 2 +- src/dialogs/snapdialog.cpp | 4 +- src/dialogs/trackselectiondialog.cpp | 13 +- src/dialogs/trackselectiondialog.h | 11 +- src/edittagdialog/CMakeLists.txt | 44 + src/engine/CMakeLists.txt | 89 ++ src/engine/enginebase.cpp | 89 +- src/engine/enginebase.h | 2 +- src/engine/gstengine.cpp | 6 +- src/engine/gstengine.h | 2 +- src/engine/gstenginepipeline.cpp | 10 +- src/engine/gstenginepipeline.h | 6 +- src/{moodbar => engine}/gstfastspectrum.cpp | 0 src/{moodbar => engine}/gstfastspectrum.h | 0 .../gstfastspectrumplugin.cpp | 0 .../gstfastspectrumplugin.h | 0 src/engine/gststartup.cpp | 2 +- src/engine/macosdevicefinder.cpp | 2 +- src/equalizer/CMakeLists.txt | 36 + src/fileview/CMakeLists.txt | 35 + src/{widgets => fileview}/fileview.cpp | 22 +- src/{widgets => fileview}/fileview.h | 6 +- src/{widgets => fileview}/fileview.ui | 2 +- src/{widgets => fileview}/fileviewlist.cpp | 2 +- src/{widgets => fileview}/fileviewlist.h | 0 src/filterparser/CMakeLists.txt | 18 + src/filterparser/filterparser.cpp | 27 +- src/filterparser/filterparser.h | 2 - .../filterparserfloateqcomparator.cpp | 26 + .../filterparserfloateqcomparator.h | 36 + .../filterparserfloatgecomparator.cpp | 26 + .../filterparserfloatgecomparator.h | 36 + .../filterparserfloatgtcomparator.cpp | 26 + .../filterparserfloatgtcomparator.h | 36 + .../filterparserfloatlecomparator.cpp | 26 + .../filterparserfloatlecomparator.h | 36 + .../filterparserfloatltcomparator.cpp | 26 + .../filterparserfloatltcomparator.h | 36 + .../filterparserfloatnecomparator.cpp | 26 + .../filterparserfloatnecomparator.h | 36 + .../filterparserint64eqcomparator.cpp | 26 + .../filterparserint64eqcomparator.h | 36 + .../filterparserint64gecomparator.cpp | 26 + .../filterparserint64gecomparator.h | 36 + .../filterparserint64gtcomparator.cpp | 26 + .../filterparserint64gtcomparator.h | 36 + .../filterparserint64lecomparator.cpp | 26 + .../filterparserint64lecomparator.h | 36 + .../filterparserint64ltcomparator.cpp | 26 + .../filterparserint64ltcomparator.h | 36 + .../filterparserint64necomparator.cpp | 26 + .../filterparserint64necomparator.h | 36 + .../filterparserinteqcomparator.cpp | 26 + .../filterparserinteqcomparator.h | 37 + .../filterparserintgecomparator.cpp | 26 + .../filterparserintgecomparator.h | 37 + .../filterparserintgtcomparator.cpp | 26 + .../filterparserintgtcomparator.h | 36 + .../filterparserintlecomparator.cpp | 26 + .../filterparserintlecomparator.h | 36 + .../filterparserintltcomparator.cpp | 26 + .../filterparserintltcomparator.h | 36 + .../filterparserintnecomparator.cpp | 26 + .../filterparserintnecomparator.h | 37 + .../filterparsersearchcomparators.h | 342 +---- .../filterparsersearchtermcomparator.cpp | 24 + .../filterparsersearchtermcomparator.h | 34 + .../filterparsertextcontainscomparator.cpp | 26 + .../filterparsertextcontainscomparator.h | 36 + .../filterparsertexteqcomparator.cpp | 26 + .../filterparsertexteqcomparator.h | 37 + .../filterparsertextnecomparator.cpp | 26 + .../filterparsertextnecomparator.h | 37 + .../filterparseruinteqcomparator.cpp | 26 + .../filterparseruinteqcomparator.h | 36 + .../filterparseruintgecomparator.cpp | 26 + .../filterparseruintgecomparator.h | 36 + .../filterparseruintgtcomparator.cpp | 26 + .../filterparseruintgtcomparator.h | 36 + .../filterparseruintlecomparator.cpp | 26 + .../filterparseruintlecomparator.h | 36 + .../filterparseruintltcomparator.cpp | 26 + .../filterparseruintltcomparator.h | 36 + .../filterparseruintnecomparator.cpp | 26 + .../filterparseruintnecomparator.h | 36 + src/filterparser/filtertree.cpp | 2 + src/filterparser/filtertree.h | 101 -- src/filterparser/filtertreeand.cpp | 34 + src/filterparser/filtertreeand.h | 46 + src/filterparser/filtertreecolumnterm.cpp | 31 + src/filterparser/filtertreecolumnterm.h | 48 + src/filterparser/filtertreenop.cpp | 29 + src/filterparser/filtertreenop.h | 38 + src/filterparser/filtertreenot.cpp | 30 + src/filterparser/filtertreenot.h | 44 + src/filterparser/filtertreeor.cpp | 38 + src/filterparser/filtertreeor.h | 46 + src/filterparser/filtertreeterm.cpp | 41 + src/filterparser/filtertreeterm.h | 47 + src/globalshortcuts/CMakeLists.txt | 64 + src/globalshortcuts/globalshortcut-x11.cpp | 4 +- src/globalshortcuts/globalshortcutgrabber.cpp | 2 +- src/globalshortcuts/globalshortcutgrabber.mm | 2 +- .../globalshortcutsbackend-gnome.cpp | 2 +- .../globalshortcutsbackend-kde.cpp | 4 +- .../globalshortcutsbackend-macos.h | 2 +- .../globalshortcutsbackend-macos.mm | 5 +- .../globalshortcutsbackend-mate.cpp | 2 +- .../globalshortcutsmanager.cpp | 14 +- src/{core => includes}/SBSystemPreferences.h | 0 src/{core => includes}/arraysize.h | 0 src/{core => includes}/dbus_metatypes.h | 0 src/{core => includes}/iconmapper.h | 0 src/{core => includes}/lazy.h | 0 src/{core => includes}/mac_delegate.h | 0 src/{core => includes}/mutex_protected.h | 0 src/{core => includes}/qt_blurimage.h | 0 src/{core => includes}/scoped_cftyperef.h | 0 src/{core => includes}/scoped_nsobject.h | 0 src/{core => includes}/scoped_ptr.h | 0 src/{core => includes}/scopedgobject.h | 0 src/{core => includes}/shared_ptr.h | 0 src/lyrics/CMakeLists.txt | 60 + src/lyrics/azlyricscomlyricsprovider.cpp | 4 +- src/lyrics/azlyricscomlyricsprovider.h | 4 +- src/lyrics/chartlyricsprovider.cpp | 4 +- src/lyrics/chartlyricsprovider.h | 4 +- src/lyrics/elyricsnetlyricsprovider.cpp | 4 +- src/lyrics/elyricsnetlyricsprovider.h | 4 +- src/lyrics/geniuslyricsprovider.cpp | 4 +- src/lyrics/geniuslyricsprovider.h | 4 +- src/lyrics/htmllyricsprovider.cpp | 4 +- src/lyrics/htmllyricsprovider.h | 4 +- src/lyrics/jsonlyricsprovider.cpp | 4 +- src/lyrics/jsonlyricsprovider.h | 4 +- src/lyrics/letraslyricsprovider.cpp | 4 +- src/lyrics/letraslyricsprovider.h | 4 +- src/lyrics/lololyricsprovider.cpp | 4 +- src/lyrics/lololyricsprovider.h | 4 +- src/lyrics/lyricfindlyricsprovider.cpp | 2 +- src/lyrics/lyricfindlyricsprovider.h | 2 +- src/lyrics/lyricsfetcher.cpp | 4 +- src/lyrics/lyricsfetcher.h | 6 +- src/lyrics/lyricsfetchersearch.cpp | 2 +- src/lyrics/lyricsfetchersearch.h | 4 +- src/lyrics/lyricsprovider.cpp | 4 +- src/lyrics/lyricsprovider.h | 6 +- src/lyrics/lyricsproviders.cpp | 6 +- src/lyrics/lyricsproviders.h | 4 +- src/lyrics/lyricssearchrequest.h | 2 +- src/lyrics/musixmatchlyricsprovider.cpp | 4 +- src/lyrics/musixmatchlyricsprovider.h | 4 +- src/lyrics/ovhlyricsprovider.cpp | 4 +- src/lyrics/ovhlyricsprovider.h | 4 +- src/lyrics/songlyricscomlyricsprovider.cpp | 4 +- src/lyrics/songlyricscomlyricsprovider.h | 4 +- src/macstartup/CMakeLists.txt | 22 + src/main.cpp | 40 +- src/mimedata/CMakeLists.txt | 27 + src/moodbar/CMakeLists.txt | 44 + src/moodbar/moodbarbuilder.cpp | 2 +- src/moodbar/moodbarcontroller.cpp | 24 +- src/moodbar/moodbarcontroller.h | 15 +- src/moodbar/moodbaritemdelegate.cpp | 25 +- src/moodbar/moodbaritemdelegate.h | 18 +- src/moodbar/moodbarloader.cpp | 14 +- src/moodbar/moodbarloader.h | 12 +- src/moodbar/moodbarpipeline.cpp | 3 +- src/moodbar/moodbarpipeline.h | 2 +- src/moodbar/moodbarproxystyle.cpp | 63 +- src/moodbar/moodbarproxystyle.h | 24 +- src/moodbar/moodbarrenderer.cpp | 25 +- src/moodbar/moodbarrenderer.h | 16 +- src/mpris2/CMakeLists.txt | 33 + src/mpris2/mpris2.cpp | 112 +- src/mpris2/mpris2.h | 14 +- src/musicbrainz/CMakeLists.txt | 40 + src/musicbrainz/acoustidclient.cpp | 4 +- src/musicbrainz/acoustidclient.h | 2 +- src/musicbrainz/musicbrainzclient.cpp | 2 +- src/musicbrainz/musicbrainzclient.h | 2 +- src/musicbrainz/tagfetcher.cpp | 4 +- src/musicbrainz/tagfetcher.h | 2 +- src/organize/CMakeLists.txt | 55 + src/organize/organize.cpp | 18 +- src/organize/organize.h | 23 +- src/organize/organizedialog.cpp | 17 +- src/organize/organizedialog.h | 19 +- src/organize/organizeformat.cpp | 4 +- src/osd/CMakeLists.txt | 46 + src/osd/osdbase.cpp | 70 +- src/osd/osdbase.h | 27 +- src/osd/osddbus.cpp | 6 +- src/osd/osddbus.h | 5 +- src/osd/osdmac.h | 2 +- src/osd/osdmac.mm | 4 +- src/osd/osdpretty.cpp | 45 +- src/osd/osdpretty.h | 13 +- src/player/CMakeLists.txt | 42 + src/playlist/CMakeLists.txt | 104 ++ src/playlist/playlist.cpp | 76 +- src/playlist/playlist.h | 34 +- src/playlist/playlistbackend.cpp | 95 +- src/playlist/playlistbackend.h | 18 +- src/playlist/playlistcontainer.cpp | 8 +- src/playlist/playlistcontainer.h | 2 +- src/playlist/playlistfilter.cpp | 4 +- src/playlist/playlistheader.cpp | 6 +- src/playlist/playlistitem.h | 2 +- src/playlist/playlistitemmimedata.h | 2 +- src/playlist/playlistlistcontainer.cpp | 65 +- src/playlist/playlistlistcontainer.h | 34 +- src/playlist/playlistmanager.cpp | 115 +- src/playlist/playlistmanager.h | 135 +- src/playlist/playlistmanagerinterface.cpp | 24 + src/playlist/playlistmanagerinterface.h | 138 ++ src/playlist/playlistproxystyle.h | 2 +- src/playlist/playlistsaveoptionsdialog.cpp | 16 +- src/playlist/playlistsaveoptionsdialog.h | 4 +- src/playlist/playlistsequence.h | 2 +- src/playlist/playlisttabbar.cpp | 4 +- src/playlist/playlisttabbar.h | 2 +- src/playlist/playlistundocommandbase.cpp | 25 + src/playlist/playlistundocommandbase.h | 39 + .../playlistundocommandinsertitems.cpp | 58 + src/playlist/playlistundocommandinsertitems.h | 44 + src/playlist/playlistundocommandmoveitems.cpp | 40 + src/playlist/playlistundocommandmoveitems.h | 41 + .../playlistundocommandremoveitems.cpp | 58 + src/playlist/playlistundocommandremoveitems.h | 49 + .../playlistundocommandreorderitems.cpp | 28 + .../playlistundocommandreorderitems.h | 40 + src/playlist/playlistundocommands.cpp | 149 --- src/playlist/playlistundocommands.h | 125 -- .../playlistundocommandshuffleitems.cpp | 30 + .../playlistundocommandshuffleitems.h | 33 + src/playlist/playlistundocommandsortitems.cpp | 33 + src/playlist/playlistundocommandsortitems.h | 32 + src/playlist/playlistview.cpp | 150 ++- src/playlist/playlistview.h | 36 +- src/playlist/songloaderinserter.cpp | 22 +- src/playlist/songloaderinserter.h | 20 +- src/playlistparsers/CMakeLists.txt | 47 + src/playlistparsers/asxiniparser.cpp | 10 +- src/playlistparsers/asxiniparser.h | 9 +- src/playlistparsers/asxparser.cpp | 10 +- src/playlistparsers/asxparser.h | 9 +- src/playlistparsers/cueparser.cpp | 12 +- src/playlistparsers/cueparser.h | 9 +- src/playlistparsers/m3uparser.cpp | 16 +- src/playlistparsers/m3uparser.h | 9 +- src/playlistparsers/parserbase.cpp | 22 +- src/playlistparsers/parserbase.h | 14 +- src/playlistparsers/playlistparser.cpp | 26 +- src/playlistparsers/playlistparser.h | 9 +- src/playlistparsers/plsparser.cpp | 12 +- src/playlistparsers/plsparser.h | 9 +- src/playlistparsers/wplparser.cpp | 10 +- src/playlistparsers/wplparser.h | 9 +- src/playlistparsers/xmlparser.cpp | 6 +- src/playlistparsers/xmlparser.h | 5 +- src/playlistparsers/xspfparser.cpp | 16 +- src/playlistparsers/xspfparser.h | 9 +- src/providers/CMakeLists.txt | 16 + src/qobuz/CMakeLists.txt | 41 + src/qobuz/qobuzbaserequest.cpp | 4 +- src/qobuz/qobuzbaserequest.h | 6 +- src/qobuz/qobuzfavoriterequest.cpp | 4 +- src/qobuz/qobuzfavoriterequest.h | 4 +- src/qobuz/qobuzrequest.cpp | 10 +- src/qobuz/qobuzrequest.h | 8 +- src/qobuz/qobuzservice.cpp | 96 +- src/qobuz/qobuzservice.h | 20 +- src/qobuz/qobuzstreamurlrequest.cpp | 6 +- src/qobuz/qobuzstreamurlrequest.h | 4 +- src/qobuz/qobuzurlhandler.cpp | 9 +- src/qobuz/qobuzurlhandler.h | 6 +- src/queue/CMakeLists.txt | 33 + src/queue/queueview.cpp | 8 +- src/queue/queueview.h | 2 +- src/radios/CMakeLists.txt | 54 + src/radios/radiobackend.cpp | 4 +- src/radios/radiobackend.h | 6 +- src/radios/radiomimedata.h | 2 +- src/radios/radiomodel.cpp | 20 +- src/radios/radiomodel.h | 11 +- src/radios/radioparadiseservice.cpp | 15 +- src/radios/radioparadiseservice.h | 4 +- src/radios/radioservice.cpp | 12 +- src/radios/radioservice.h | 21 +- src/radios/radioservices.cpp | 21 +- src/radios/radioservices.h | 14 +- src/radios/radioview.cpp | 2 +- src/radios/radioviewcontainer.cpp | 6 +- src/radios/radioviewcontainer.h | 2 +- src/radios/somafmservice.cpp | 17 +- src/radios/somafmservice.h | 4 +- src/scrobbler/CMakeLists.txt | 53 + src/scrobbler/audioscrobbler.cpp | 15 +- src/scrobbler/audioscrobbler.h | 14 +- src/scrobbler/lastfmimport.cpp | 4 +- src/scrobbler/lastfmimport.h | 4 +- src/scrobbler/lastfmscrobbler.cpp | 6 +- src/scrobbler/lastfmscrobbler.h | 6 +- src/scrobbler/librefmscrobbler.cpp | 6 +- src/scrobbler/librefmscrobbler.h | 6 +- src/scrobbler/listenbrainzscrobbler.cpp | 23 +- src/scrobbler/listenbrainzscrobbler.h | 9 +- src/scrobbler/scrobblercacheitem.h | 2 +- src/scrobbler/scrobblerservice.cpp | 4 +- src/scrobbler/scrobblerservice.h | 11 +- ...tings.cpp => scrobblersettingsservice.cpp} | 27 +- ...rsettings.h => scrobblersettingsservice.h} | 17 +- src/scrobbler/scrobblingapi20.cpp | 21 +- src/scrobbler/scrobblingapi20.h | 8 +- src/scrobbler/subsonicscrobbler.cpp | 24 +- src/scrobbler/subsonicscrobbler.h | 12 +- src/settings/CMakeLists.txt | 133 ++ src/settings/appearancesettingspage.cpp | 53 +- src/settings/appearancesettingspage.h | 54 +- src/settings/backendsettingspage.cpp | 204 ++- src/settings/backendsettingspage.h | 17 +- src/settings/behavioursettingspage.cpp | 68 +- src/settings/behavioursettingspage.h | 34 - src/settings/collectionsettingspage.cpp | 120 +- src/settings/collectionsettingspage.h | 30 +- src/settings/contextsettingspage.cpp | 61 +- src/settings/contextsettingspage.h | 19 +- src/settings/coverssettingspage.cpp | 26 +- src/settings/coverssettingspage.h | 17 +- src/settings/globalshortcutssettingspage.cpp | 35 +- src/settings/globalshortcutssettingspage.h | 8 +- src/settings/lyricssettingspage.cpp | 20 +- src/settings/lyricssettingspage.h | 7 +- src/settings/moodbarsettingspage.cpp | 29 +- src/settings/moodbarsettingspage.h | 5 - src/settings/networkproxysettingspage.cpp | 32 +- src/settings/networkproxysettingspage.h | 2 - src/settings/notificationssettingspage.cpp | 122 +- src/settings/notificationssettingspage.h | 8 +- src/settings/playlistsettingspage.cpp | 65 +- src/settings/playlistsettingspage.h | 11 - src/settings/qobuzsettingspage.cpp | 60 +- src/settings/qobuzsettingspage.h | 8 +- src/settings/scrobblersettingspage.cpp | 41 +- src/settings/scrobblersettingspage.h | 15 +- src/settings/settingsdialog.cpp | 86 +- src/settings/settingsdialog.h | 67 +- src/settings/settingsitemdelegate.cpp | 54 + src/settings/settingsitemdelegate.h | 39 + src/settings/settingspage.h | 4 +- src/settings/spotifysettingspage.cpp | 38 +- src/settings/spotifysettingspage.h | 8 +- src/settings/subsonicsettingspage.cpp | 47 +- src/settings/subsonicsettingspage.h | 16 +- src/settings/tidalsettingspage.cpp | 78 +- src/settings/tidalsettingspage.h | 12 +- src/settings/transcodersettingspage.cpp | 2 + src/settings/transcodersettingspage.h | 2 - src/smartplaylists/CMakeLists.txt | 77 ++ src/smartplaylists/playlistgenerator.h | 2 +- src/smartplaylists/playlistgenerator_fwd.h | 2 +- .../playlistgeneratorinserter.cpp | 2 +- .../playlistgeneratorinserter.h | 2 +- .../playlistgeneratormimedata.h | 2 +- src/smartplaylists/playlistquerygenerator.cpp | 2 +- .../smartplaylistquerywizardplugin.cpp | 41 +- .../smartplaylistquerywizardplugin.h | 29 +- ...smartplaylistquerywizardpluginsearchpage.h | 2 +- .../smartplaylistsearchpreview.cpp | 26 +- .../smartplaylistsearchpreview.h | 19 +- .../smartplaylistsearchtermwidget.cpp | 2 +- .../smartplaylistsearchtermwidget.h | 2 +- src/smartplaylists/smartplaylistsmodel.cpp | 3 +- src/smartplaylists/smartplaylistsmodel.h | 3 +- src/smartplaylists/smartplaylistsview.cpp | 2 +- .../smartplaylistsviewcontainer.cpp | 46 +- .../smartplaylistsviewcontainer.h | 31 +- src/smartplaylists/smartplaylistwizard.cpp | 21 +- src/smartplaylists/smartplaylistwizard.h | 23 +- .../smartplaylistwizardplugin.cpp | 5 +- .../smartplaylistwizardplugin.h | 8 +- src/songloader/CMakeLists.txt | 33 + src/spotify/CMakeLists.txt | 36 + src/spotify/spotifybaserequest.cpp | 3 +- src/spotify/spotifybaserequest.h | 11 +- src/spotify/spotifyfavoriterequest.cpp | 3 +- src/spotify/spotifyfavoriterequest.h | 8 +- src/spotify/spotifyrequest.cpp | 6 +- src/spotify/spotifyrequest.h | 9 +- src/spotify/spotifyservice.cpp | 107 +- src/spotify/spotifyservice.h | 24 +- src/streaming/CMakeLists.txt | 59 + src/streaming/streamingcollectionview.cpp | 9 +- src/streaming/streamingcollectionview.h | 7 +- .../streamingcollectionviewcontainer.h | 3 +- src/streaming/streamingsearchmodel.cpp | 2 +- src/streaming/streamingsearchmodel.h | 2 +- src/streaming/streamingsearchview.cpp | 29 +- src/streaming/streamingsearchview.h | 14 +- src/streaming/streamingservice.cpp | 9 +- src/streaming/streamingservice.h | 13 +- src/streaming/streamingservices.h | 2 +- src/streaming/streamingsongsview.cpp | 16 +- src/streaming/streamingsongsview.h | 18 +- src/streaming/streamingtabsview.cpp | 25 +- src/streaming/streamingtabsview.h | 19 +- src/streaming/streamplaylistitem.h | 2 +- src/streaming/streamsongmimedata.cpp | 2 +- src/streaming/streamsongmimedata.h | 4 +- src/subsonic/CMakeLists.txt | 34 + src/subsonic/subsonicbaserequest.cpp | 6 +- src/subsonic/subsonicbaserequest.h | 8 +- src/subsonic/subsonicrequest.cpp | 6 +- src/subsonic/subsonicrequest.h | 4 +- src/subsonic/subsonicscrobblerequest.cpp | 4 +- src/subsonic/subsonicscrobblerequest.h | 6 +- src/subsonic/subsonicservice.cpp | 59 +- src/subsonic/subsonicservice.h | 30 +- src/subsonic/subsonicurlhandler.cpp | 6 +- src/subsonic/subsonicurlhandler.h | 7 +- src/systemtrayicon/CMakeLists.txt | 26 + .../macsystemtrayicon.h | 4 +- .../macsystemtrayicon.mm | 7 +- .../qtsystemtrayicon.cpp | 4 +- .../qtsystemtrayicon.h | 2 +- .../systemtrayicon.cpp | 0 src/tagreader/CMakeLists.txt | 48 + src/tagreader/tagreaderclient.cpp | 14 +- src/tagreader/tagreaderclient.h | 4 +- src/tagreader/tagreadergme.cpp | 2 +- src/tagreader/tagreaderismediafilerequest.h | 2 +- src/tagreader/tagreaderloadcoverdatareply.cpp | 6 + src/tagreader/tagreaderloadcoverdatareply.h | 8 +- src/tagreader/tagreaderloadcoverdatarequest.h | 2 +- .../tagreaderloadcoverimagereply.cpp | 7 + src/tagreader/tagreaderloadcoverimagereply.h | 8 +- .../tagreaderloadcoverimagerequest.h | 2 +- src/tagreader/tagreaderreadfilereply.cpp | 7 + src/tagreader/tagreaderreadfilereply.h | 7 +- src/tagreader/tagreaderreadfilerequest.h | 2 +- src/tagreader/tagreaderreply.cpp | 10 +- src/tagreader/tagreaderreply.h | 15 +- src/tagreader/tagreaderrequest.cpp | 2 +- src/tagreader/tagreaderrequest.h | 2 +- src/tagreader/tagreadersavecoverrequest.h | 2 +- src/tagreader/tagreadersaveplaycountrequest.h | 2 +- src/tagreader/tagreadersaveratingrequest.h | 2 +- src/tagreader/tagreadertaglib.cpp | 4 +- src/tagreader/tagreadertaglib.h | 2 +- src/tagreader/tagreaderwritefilerequest.h | 2 +- src/tidal/CMakeLists.txt | 42 + src/tidal/tidalbaserequest.cpp | 4 +- src/tidal/tidalbaserequest.h | 6 +- src/tidal/tidalfavoriterequest.cpp | 4 +- src/tidal/tidalfavoriterequest.h | 6 +- src/tidal/tidalrequest.cpp | 8 +- src/tidal/tidalrequest.h | 6 +- src/tidal/tidalservice.cpp | 193 +-- src/tidal/tidalservice.h | 27 +- src/tidal/tidalstreamurlrequest.cpp | 12 +- src/tidal/tidalstreamurlrequest.h | 6 +- src/tidal/tidalurlhandler.cpp | 10 +- src/tidal/tidalurlhandler.h | 7 +- src/transcoder/CMakeLists.txt | 71 ++ src/transcoder/transcodedialog.cpp | 31 +- src/transcoder/transcodedialog.h | 2 - src/transcoder/transcoder.cpp | 2 +- src/transcoder/transcoder.h | 2 +- src/transcoder/transcoderoptionsaac.cpp | 2 +- src/transcoder/transcoderoptionsasf.cpp | 2 +- src/transcoder/transcoderoptionsdialog.cpp | 2 +- src/transcoder/transcoderoptionsflac.cpp | 2 +- src/transcoder/transcoderoptionsmp3.cpp | 2 +- src/transcoder/transcoderoptionsopus.cpp | 2 +- src/transcoder/transcoderoptionsspeex.cpp | 2 +- src/transcoder/transcoderoptionsvorbis.cpp | 2 +- src/transcoder/transcoderoptionswavpack.cpp | 2 +- src/translations/CMakeLists.txt | 0 src/translations/strawberry_en_US.ts | 125 +- src/utilities/CMakeLists.txt | 49 + src/utilities/coveroptions.cpp | 22 + src/utilities/coveroptions.h | 4 +- src/utilities/coverutils.cpp | 2 +- src/utilities/diskutils.cpp | 2 +- src/utilities/fileutils.cpp | 2 +- src/{core => utilities}/scopedwchararray.cpp | 0 src/{core => utilities}/scopedwchararray.h | 2 +- src/utilities/timeconstants.h | 32 - src/utilities/timeutils.cpp | 2 +- src/utilities/transliterate.cpp | 2 +- src/widgets/CMakeLists.txt | 91 ++ src/widgets/autoexpandingtreeview.cpp | 2 +- src/widgets/fancytabwidget.cpp | 27 +- src/widgets/fancytabwidget.h | 2 + src/widgets/loginstatewidget.cpp | 2 +- src/widgets/multiloadingindicator.cpp | 2 +- src/widgets/multiloadingindicator.h | 2 +- src/widgets/playingwidget.cpp | 8 +- src/widgets/playingwidget.h | 6 +- src/widgets/trackslider.cpp | 12 +- src/widgets/trackslider.h | 7 +- src/widgets/tracksliderpopup.cpp | 2 +- src/widgets/tracksliderslider.cpp | 2 +- tests/CMakeLists.txt | 70 +- tests/src/collectionbackend_test.cpp | 16 +- tests/src/collectionmodel_test.cpp | 10 +- tests/src/metatypes_env.h | 2 +- tests/src/organizeformat_test.cpp | 6 +- tests/src/playlist_test.cpp | 8 +- tests/src/songplaylistitem_test.cpp | 2 +- tests/src/tagreader_test.cpp | 44 +- 693 files changed, 11416 insertions(+), 6148 deletions(-) create mode 100644 src/analyzer/CMakeLists.txt create mode 100644 src/collection/CMakeLists.txt create mode 100644 src/collection/collectionitem.cpp rename src/collection/{collection.cpp => collectionlibrary.cpp} (60%) rename src/collection/{collection.h => collectionlibrary.h} (78%) create mode 100644 src/constants/appearancesettings.h create mode 100644 src/constants/backendsettings.h create mode 100644 src/constants/behavioursettings.h create mode 100644 src/constants/collectionsettings.h create mode 100644 src/constants/contextsettings.h create mode 100644 src/constants/coverssettings.h create mode 100644 src/constants/filefilterconstants.h rename src/{utilities => constants}/filenameconstants.h (97%) create mode 100644 src/constants/globalshortcutssettings.h create mode 100644 src/constants/lyricssettings.h create mode 100644 src/constants/mainwindowsettings.h create mode 100644 src/constants/moodbarsettings.h create mode 100644 src/constants/networkproxysettings.h create mode 100644 src/constants/notificationssettings.h create mode 100644 src/constants/playlistsettings.h create mode 100644 src/constants/qobuzsettings.h create mode 100644 src/constants/scrobblersettings.h create mode 100644 src/constants/spotifysettings.h create mode 100644 src/constants/subsonicsettings.h create mode 100644 src/constants/tidalsettings.h create mode 100644 src/constants/timeconstants.h create mode 100644 src/constants/transcodersettings.h create mode 100644 src/context/CMakeLists.txt create mode 100644 src/core/CMakeLists.txt rename src/{engine => core}/enginemetadata.cpp (100%) rename src/{engine => core}/enginemetadata.h (100%) create mode 100644 src/core/memorydatabase.cpp create mode 100644 src/core/memorydatabase.h create mode 100644 src/core/platforminterface.cpp create mode 100644 src/core/playerinterface.cpp create mode 100644 src/core/playerinterface.h rename src/{playlist => core}/songmimedata.cpp (100%) rename src/{playlist => core}/songmimedata.h (95%) create mode 100644 src/core/urlhandlers.cpp create mode 100644 src/core/urlhandlers.h create mode 100644 src/covermanager/CMakeLists.txt create mode 100644 src/device/CMakeLists.txt create mode 100644 src/dialogs/CMakeLists.txt create mode 100644 src/edittagdialog/CMakeLists.txt create mode 100644 src/engine/CMakeLists.txt rename src/{moodbar => engine}/gstfastspectrum.cpp (100%) rename src/{moodbar => engine}/gstfastspectrum.h (100%) rename src/{moodbar => engine}/gstfastspectrumplugin.cpp (100%) rename src/{moodbar => engine}/gstfastspectrumplugin.h (100%) create mode 100644 src/equalizer/CMakeLists.txt create mode 100644 src/fileview/CMakeLists.txt rename src/{widgets => fileview}/fileview.cpp (93%) rename src/{widgets => fileview}/fileview.h (96%) rename src/{widgets => fileview}/fileview.ui (98%) rename src/{widgets => fileview}/fileviewlist.cpp (99%) rename src/{widgets => fileview}/fileviewlist.h (100%) create mode 100644 src/filterparser/CMakeLists.txt create mode 100644 src/filterparser/filterparserfloateqcomparator.cpp create mode 100644 src/filterparser/filterparserfloateqcomparator.h create mode 100644 src/filterparser/filterparserfloatgecomparator.cpp create mode 100644 src/filterparser/filterparserfloatgecomparator.h create mode 100644 src/filterparser/filterparserfloatgtcomparator.cpp create mode 100644 src/filterparser/filterparserfloatgtcomparator.h create mode 100644 src/filterparser/filterparserfloatlecomparator.cpp create mode 100644 src/filterparser/filterparserfloatlecomparator.h create mode 100644 src/filterparser/filterparserfloatltcomparator.cpp create mode 100644 src/filterparser/filterparserfloatltcomparator.h create mode 100644 src/filterparser/filterparserfloatnecomparator.cpp create mode 100644 src/filterparser/filterparserfloatnecomparator.h create mode 100644 src/filterparser/filterparserint64eqcomparator.cpp create mode 100644 src/filterparser/filterparserint64eqcomparator.h create mode 100644 src/filterparser/filterparserint64gecomparator.cpp create mode 100644 src/filterparser/filterparserint64gecomparator.h create mode 100644 src/filterparser/filterparserint64gtcomparator.cpp create mode 100644 src/filterparser/filterparserint64gtcomparator.h create mode 100644 src/filterparser/filterparserint64lecomparator.cpp create mode 100644 src/filterparser/filterparserint64lecomparator.h create mode 100644 src/filterparser/filterparserint64ltcomparator.cpp create mode 100644 src/filterparser/filterparserint64ltcomparator.h create mode 100644 src/filterparser/filterparserint64necomparator.cpp create mode 100644 src/filterparser/filterparserint64necomparator.h create mode 100644 src/filterparser/filterparserinteqcomparator.cpp create mode 100644 src/filterparser/filterparserinteqcomparator.h create mode 100644 src/filterparser/filterparserintgecomparator.cpp create mode 100644 src/filterparser/filterparserintgecomparator.h create mode 100644 src/filterparser/filterparserintgtcomparator.cpp create mode 100644 src/filterparser/filterparserintgtcomparator.h create mode 100644 src/filterparser/filterparserintlecomparator.cpp create mode 100644 src/filterparser/filterparserintlecomparator.h create mode 100644 src/filterparser/filterparserintltcomparator.cpp create mode 100644 src/filterparser/filterparserintltcomparator.h create mode 100644 src/filterparser/filterparserintnecomparator.cpp create mode 100644 src/filterparser/filterparserintnecomparator.h create mode 100644 src/filterparser/filterparsersearchtermcomparator.cpp create mode 100644 src/filterparser/filterparsersearchtermcomparator.h create mode 100644 src/filterparser/filterparsertextcontainscomparator.cpp create mode 100644 src/filterparser/filterparsertextcontainscomparator.h create mode 100644 src/filterparser/filterparsertexteqcomparator.cpp create mode 100644 src/filterparser/filterparsertexteqcomparator.h create mode 100644 src/filterparser/filterparsertextnecomparator.cpp create mode 100644 src/filterparser/filterparsertextnecomparator.h create mode 100644 src/filterparser/filterparseruinteqcomparator.cpp create mode 100644 src/filterparser/filterparseruinteqcomparator.h create mode 100644 src/filterparser/filterparseruintgecomparator.cpp create mode 100644 src/filterparser/filterparseruintgecomparator.h create mode 100644 src/filterparser/filterparseruintgtcomparator.cpp create mode 100644 src/filterparser/filterparseruintgtcomparator.h create mode 100644 src/filterparser/filterparseruintlecomparator.cpp create mode 100644 src/filterparser/filterparseruintlecomparator.h create mode 100644 src/filterparser/filterparseruintltcomparator.cpp create mode 100644 src/filterparser/filterparseruintltcomparator.h create mode 100644 src/filterparser/filterparseruintnecomparator.cpp create mode 100644 src/filterparser/filterparseruintnecomparator.h create mode 100644 src/filterparser/filtertreeand.cpp create mode 100644 src/filterparser/filtertreeand.h create mode 100644 src/filterparser/filtertreecolumnterm.cpp create mode 100644 src/filterparser/filtertreecolumnterm.h create mode 100644 src/filterparser/filtertreenop.cpp create mode 100644 src/filterparser/filtertreenop.h create mode 100644 src/filterparser/filtertreenot.cpp create mode 100644 src/filterparser/filtertreenot.h create mode 100644 src/filterparser/filtertreeor.cpp create mode 100644 src/filterparser/filtertreeor.h create mode 100644 src/filterparser/filtertreeterm.cpp create mode 100644 src/filterparser/filtertreeterm.h create mode 100644 src/globalshortcuts/CMakeLists.txt rename src/{core => includes}/SBSystemPreferences.h (100%) rename src/{core => includes}/arraysize.h (100%) rename src/{core => includes}/dbus_metatypes.h (100%) rename src/{core => includes}/iconmapper.h (100%) rename src/{core => includes}/lazy.h (100%) rename src/{core => includes}/mac_delegate.h (100%) rename src/{core => includes}/mutex_protected.h (100%) rename src/{core => includes}/qt_blurimage.h (100%) rename src/{core => includes}/scoped_cftyperef.h (100%) rename src/{core => includes}/scoped_nsobject.h (100%) rename src/{core => includes}/scoped_ptr.h (100%) rename src/{core => includes}/scopedgobject.h (100%) rename src/{core => includes}/shared_ptr.h (100%) create mode 100644 src/lyrics/CMakeLists.txt create mode 100644 src/macstartup/CMakeLists.txt create mode 100644 src/mimedata/CMakeLists.txt create mode 100644 src/moodbar/CMakeLists.txt create mode 100644 src/mpris2/CMakeLists.txt create mode 100644 src/musicbrainz/CMakeLists.txt create mode 100644 src/organize/CMakeLists.txt create mode 100644 src/osd/CMakeLists.txt create mode 100644 src/player/CMakeLists.txt create mode 100644 src/playlist/CMakeLists.txt create mode 100644 src/playlist/playlistmanagerinterface.cpp create mode 100644 src/playlist/playlistmanagerinterface.h create mode 100644 src/playlist/playlistundocommandbase.cpp create mode 100644 src/playlist/playlistundocommandbase.h create mode 100644 src/playlist/playlistundocommandinsertitems.cpp create mode 100644 src/playlist/playlistundocommandinsertitems.h create mode 100644 src/playlist/playlistundocommandmoveitems.cpp create mode 100644 src/playlist/playlistundocommandmoveitems.h create mode 100644 src/playlist/playlistundocommandremoveitems.cpp create mode 100644 src/playlist/playlistundocommandremoveitems.h create mode 100644 src/playlist/playlistundocommandreorderitems.cpp create mode 100644 src/playlist/playlistundocommandreorderitems.h delete mode 100644 src/playlist/playlistundocommands.cpp delete mode 100644 src/playlist/playlistundocommands.h create mode 100644 src/playlist/playlistundocommandshuffleitems.cpp create mode 100644 src/playlist/playlistundocommandshuffleitems.h create mode 100644 src/playlist/playlistundocommandsortitems.cpp create mode 100644 src/playlist/playlistundocommandsortitems.h create mode 100644 src/playlistparsers/CMakeLists.txt create mode 100644 src/providers/CMakeLists.txt create mode 100644 src/qobuz/CMakeLists.txt create mode 100644 src/queue/CMakeLists.txt create mode 100644 src/radios/CMakeLists.txt create mode 100644 src/scrobbler/CMakeLists.txt rename src/scrobbler/{scrobblersettings.cpp => scrobblersettingsservice.cpp} (80%) rename src/scrobbler/{scrobblersettings.h => scrobblersettingsservice.h} (87%) create mode 100644 src/settings/CMakeLists.txt create mode 100644 src/settings/settingsitemdelegate.cpp create mode 100644 src/settings/settingsitemdelegate.h create mode 100644 src/smartplaylists/CMakeLists.txt create mode 100644 src/songloader/CMakeLists.txt create mode 100644 src/spotify/CMakeLists.txt create mode 100644 src/streaming/CMakeLists.txt create mode 100644 src/subsonic/CMakeLists.txt create mode 100644 src/systemtrayicon/CMakeLists.txt rename src/{core => systemtrayicon}/macsystemtrayicon.h (97%) rename src/{core => systemtrayicon}/macsystemtrayicon.mm (98%) rename src/{core => systemtrayicon}/qtsystemtrayicon.cpp (99%) rename src/{core => systemtrayicon}/qtsystemtrayicon.h (99%) rename src/{core => systemtrayicon}/systemtrayicon.cpp (100%) create mode 100644 src/tagreader/CMakeLists.txt create mode 100644 src/tidal/CMakeLists.txt create mode 100644 src/transcoder/CMakeLists.txt create mode 100644 src/translations/CMakeLists.txt create mode 100644 src/utilities/CMakeLists.txt create mode 100644 src/utilities/coveroptions.cpp rename src/{core => utilities}/scopedwchararray.cpp (100%) rename src/{core => utilities}/scopedwchararray.h (97%) delete mode 100644 src/utilities/timeconstants.h create mode 100644 src/widgets/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ccc45c6d5..4d1bd93074 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,9 +176,11 @@ if(UNIX AND NOT APPLE) endif() pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GOBJECT REQUIRED IMPORTED_TARGET gobject-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) -if(GIO_FOUND AND UNIX) - pkg_check_modules(GIO_UNIX IMPORTED_TARGET gio-unix-2.0) +if(UNIX AND NOT APPLE) + pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + if(GIO_FOUND AND UNIX) + pkg_check_modules(GIO_UNIX IMPORTED_TARGET gio-unix-2.0) + endif() endif() pkg_check_modules(LIBCDIO IMPORTED_TARGET libcdio) pkg_check_modules(GSTREAMER REQUIRED IMPORTED_TARGET gstreamer-1.0) @@ -327,12 +329,10 @@ optional_component(UDISKS2 ON "Devices: UDisks2 backend" optional_component(GIO ON "Devices: GIO device backend" DEPENDS "libgio" GIO_FOUND - DEPENDS "Unix or Windows" "NOT APPLE" ) optional_component(GIO_UNIX ON "Devices: GIO device backend (Unix support)" DEPENDS "libgio-unix" GIO_UNIX_FOUND - DEPENDS "Unix or Windows" "NOT APPLE" ) optional_component(AUDIOCD ON "Devices: Audio CD support" @@ -403,1006 +403,27 @@ if(WIN32 AND NOT ENABLE_WIN32_CONSOLE) endif() set(SOURCES - src/core/logging.cpp - src/core/mainwindow.cpp - src/core/application.cpp - src/core/player.cpp - src/core/commandlineoptions.cpp - src/core/database.cpp - src/core/sqlquery.cpp - src/core/sqlrow.cpp - src/core/metatypes.cpp - src/core/deletefiles.cpp - src/core/filesystemmusicstorage.cpp - src/core/filesystemwatcherinterface.cpp - src/core/mergedproxymodel.cpp - src/core/multisortfilterproxy.cpp - src/core/musicstorage.cpp - src/core/networkaccessmanager.cpp - src/core/threadsafenetworkdiskcache.cpp - src/core/networktimeouts.cpp - src/core/networkproxyfactory.cpp - src/core/qtfslistener.cpp - src/core/settings.cpp - src/core/settingsprovider.cpp - src/core/signalchecker.cpp - src/core/song.cpp - src/core/songloader.cpp - src/core/stylehelper.cpp - src/core/stylesheetloader.cpp - src/core/taskmanager.cpp - src/core/thread.cpp - src/core/urlhandler.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/utilities/strutils.cpp - src/utilities/envutils.cpp - src/utilities/colorutils.cpp - src/utilities/cryptutils.cpp - src/utilities/fileutils.cpp - src/utilities/diskutils.cpp - src/utilities/imageutils.cpp - src/utilities/macaddrutils.cpp - src/utilities/mimeutils.cpp - src/utilities/randutils.cpp - src/utilities/threadutils.cpp - src/utilities/timeutils.cpp - src/utilities/transliterate.cpp - src/utilities/xmlutils.cpp - src/utilities/filemanagerutils.cpp - src/utilities/coverutils.cpp - src/utilities/screenutils.cpp - src/utilities/textencodingutils.cpp - - src/tagreader/tagreaderclient.cpp - src/tagreader/tagreaderresult.cpp - src/tagreader/tagreaderbase.cpp - src/tagreader/tagreadertaglib.cpp - src/tagreader/tagreadergme.cpp - src/tagreader/tagreaderrequest.cpp - src/tagreader/tagreaderismediafilerequest.cpp - src/tagreader/tagreaderreadfilerequest.cpp - src/tagreader/tagreaderwritefilerequest.cpp - src/tagreader/tagreaderloadcoverdatarequest.cpp - src/tagreader/tagreaderloadcoverimagerequest.cpp - src/tagreader/tagreadersavecoverrequest.cpp - src/tagreader/tagreadersaveplaycountrequest.cpp - src/tagreader/tagreadersaveratingrequest.cpp - src/tagreader/albumcovertagdata.cpp - src/tagreader/savetagcoverdata.cpp - src/tagreader/tagreaderreply.cpp - src/tagreader/tagreaderreadfilereply.cpp - src/tagreader/tagreaderloadcoverdatareply.cpp - src/tagreader/tagreaderloadcoverimagereply.cpp - - src/filterparser/filterparser.cpp - src/filterparser/filtertree.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 - - src/analyzer/fht.cpp - src/analyzer/analyzerbase.cpp - src/analyzer/analyzercontainer.cpp - src/analyzer/blockanalyzer.cpp - src/analyzer/boomanalyzer.cpp - src/analyzer/turbineanalyzer.cpp - src/analyzer/sonogramanalyzer.cpp - src/analyzer/waverubberanalyzer.cpp - src/analyzer/rainbowanalyzer.cpp - - src/equalizer/equalizer.cpp - src/equalizer/equalizerslider.cpp - - src/context/contextview.cpp - src/context/contextalbum.cpp - - src/collection/collection.cpp - src/collection/collectionmodel.cpp - src/collection/collectionbackend.cpp - src/collection/collectionwatcher.cpp - src/collection/collectionview.cpp - src/collection/collectionitemdelegate.cpp - src/collection/collectionviewcontainer.cpp - src/collection/collectiondirectorymodel.cpp - src/collection/collectionfilteroptions.cpp - src/collection/collectionfilterwidget.cpp - src/collection/collectionfilter.cpp - src/collection/collectionplaylistitem.cpp - src/collection/collectionquery.cpp - src/collection/savedgroupingmanager.cpp - src/collection/groupbydialog.cpp - src/collection/collectiontask.cpp - src/collection/collectionmodelupdate.cpp - - src/playlist/playlist.cpp - src/playlist/playlistbackend.cpp - src/playlist/playlistcontainer.cpp - src/playlist/playlistdelegates.cpp - src/playlist/playlistfilter.cpp - src/playlist/playlistheader.cpp - src/playlist/playlistitem.cpp - src/playlist/playlistitemmimedata.cpp - src/playlist/playlistlistcontainer.cpp - src/playlist/playlistlistmodel.cpp - src/playlist/playlistlistsortfiltermodel.cpp - src/playlist/playlistlistview.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/queue/queue.cpp - src/queue/queueview.cpp - - src/playlistparsers/asxiniparser.cpp - src/playlistparsers/asxparser.cpp - src/playlistparsers/cueparser.cpp - src/playlistparsers/m3uparser.cpp - src/playlistparsers/parserbase.cpp - src/playlistparsers/playlistparser.cpp - src/playlistparsers/plsparser.cpp - src/playlistparsers/wplparser.cpp - src/playlistparsers/xmlparser.cpp - src/playlistparsers/xspfparser.cpp - - src/smartplaylists/playlistgenerator.cpp - src/smartplaylists/playlistgeneratorinserter.cpp - src/smartplaylists/playlistgeneratormimedata.cpp - src/smartplaylists/playlistquerygenerator.cpp - src/smartplaylists/smartplaylistquerywizardplugin.cpp - src/smartplaylists/smartplaylistquerywizardpluginsortpage.cpp - src/smartplaylists/smartplaylistquerywizardpluginsearchpage.cpp - src/smartplaylists/smartplaylistsearch.cpp - src/smartplaylists/smartplaylistsearchpreview.cpp - src/smartplaylists/smartplaylistsearchterm.cpp - src/smartplaylists/smartplaylistsearchtermwidget.cpp - src/smartplaylists/smartplaylistsearchtermwidgetoverlay.cpp - src/smartplaylists/smartplaylistsmodel.cpp - src/smartplaylists/smartplaylistsviewcontainer.cpp - src/smartplaylists/smartplaylistsview.cpp - src/smartplaylists/smartplaylistwizard.cpp - src/smartplaylists/smartplaylistwizardplugin.cpp - src/smartplaylists/smartplaylistwizardtypepage.cpp - src/smartplaylists/smartplaylistwizardfinishpage.cpp - - src/covermanager/albumcovermanager.cpp - src/covermanager/albumcovermanagerlist.cpp - src/covermanager/albumcoverloader.cpp - src/covermanager/albumcoverloaderoptions.cpp - src/covermanager/albumcoverfetcher.cpp - src/covermanager/albumcoverfetchersearch.cpp - src/covermanager/albumcoversearcher.cpp - src/covermanager/albumcoverexport.cpp - src/covermanager/albumcoverexporter.cpp - src/covermanager/albumcoverchoicecontroller.cpp - src/covermanager/coverprovider.cpp - src/covermanager/coverproviders.cpp - src/covermanager/coversearchstatistics.cpp - src/covermanager/coversearchstatisticsdialog.cpp - src/covermanager/coverexportrunnable.cpp - src/covermanager/currentalbumcoverloader.cpp - src/covermanager/coverfromurldialog.cpp - src/covermanager/jsoncoverprovider.cpp - src/covermanager/lastfmcoverprovider.cpp - src/covermanager/musicbrainzcoverprovider.cpp - src/covermanager/discogscoverprovider.cpp - src/covermanager/deezercoverprovider.cpp - src/covermanager/musixmatchcoverprovider.cpp - src/covermanager/opentidalcoverprovider.cpp - - src/lyrics/lyricsproviders.cpp - src/lyrics/lyricsprovider.cpp - src/lyrics/lyricssearchrequest.h - src/lyrics/lyricssearchresult.h - src/lyrics/lyricsfetcher.cpp - src/lyrics/lyricsfetchersearch.cpp - src/lyrics/jsonlyricsprovider.cpp - src/lyrics/htmllyricsprovider.cpp - src/lyrics/ovhlyricsprovider.cpp - src/lyrics/lololyricsprovider.cpp - src/lyrics/geniuslyricsprovider.cpp - src/lyrics/musixmatchlyricsprovider.cpp - src/lyrics/chartlyricsprovider.cpp - src/lyrics/songlyricscomlyricsprovider.cpp - src/lyrics/azlyricscomlyricsprovider.cpp - src/lyrics/elyricsnetlyricsprovider.cpp - src/lyrics/letraslyricsprovider.cpp - src/lyrics/lyricfindlyricsprovider.cpp - - src/providers/musixmatchprovider.cpp - - src/settings/settingsdialog.cpp - src/settings/settingspage.cpp - src/settings/behavioursettingspage.cpp - src/settings/collectionsettingspage.cpp - src/settings/collectionsettingsdirectorymodel.cpp - src/settings/backendsettingspage.cpp - src/settings/playlistsettingspage.cpp - src/settings/scrobblersettingspage.cpp - src/settings/coverssettingspage.cpp - src/settings/lyricssettingspage.cpp - src/settings/networkproxysettingspage.cpp - src/settings/appearancesettingspage.cpp - src/settings/contextsettingspage.cpp - src/settings/notificationssettingspage.cpp - src/settings/transcodersettingspage.cpp - - src/dialogs/about.cpp - src/dialogs/console.cpp - src/dialogs/errordialog.cpp - src/dialogs/edittagdialog.cpp - src/dialogs/trackselectiondialog.cpp - src/dialogs/addstreamdialog.cpp - src/dialogs/userpassdialog.cpp - src/dialogs/deleteconfirmationdialog.cpp - src/dialogs/lastfmimportdialog.cpp - src/dialogs/messagedialog.cpp - src/dialogs/snapdialog.cpp - src/dialogs/saveplaylistsdialog.cpp - - src/widgets/autoexpandingtreeview.cpp - src/widgets/busyindicator.cpp - src/widgets/clickablelabel.cpp - src/widgets/fancytabwidget.cpp - 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 - src/widgets/lineedit.cpp - src/widgets/linetextedit.cpp - src/widgets/multiloadingindicator.cpp - src/widgets/playingwidget.cpp - src/widgets/renametablineedit.cpp - src/widgets/sliderslider.cpp - src/widgets/prettyslider.cpp - src/widgets/volumeslider.cpp - src/widgets/stickyslider.cpp - src/widgets/stretchheaderview.cpp - src/widgets/trackslider.cpp - src/widgets/tracksliderpopup.cpp - src/widgets/tracksliderslider.cpp - src/widgets/loginstatewidget.cpp - src/widgets/ratingwidget.cpp - src/widgets/resizabletextedit.cpp - - src/osd/osdbase.cpp - src/osd/osdpretty.cpp - - src/streaming/streamingservices.cpp - src/streaming/streamingservice.cpp - src/streaming/streamplaylistitem.cpp - src/streaming/streamingsearchview.cpp - src/streaming/streamingsearchmodel.cpp - src/streaming/streamingsearchsortmodel.cpp - src/streaming/streamingsearchitemdelegate.cpp - src/streaming/streamingsongsview.cpp - src/streaming/streamingtabsview.cpp - src/streaming/streamingcollectionview.cpp - src/streaming/streamingcollectionviewcontainer.cpp - src/streaming/streamingsearchview.cpp - src/streaming/streamsongmimedata.cpp - - src/radios/radioservices.cpp - src/radios/radiobackend.cpp - src/radios/radiomodel.cpp - src/radios/radioview.cpp - src/radios/radioviewcontainer.cpp - src/radios/radioservice.cpp - src/radios/radioplaylistitem.cpp - src/radios/radiochannel.cpp - src/radios/somafmservice.cpp - src/radios/radioparadiseservice.cpp - src/radios/radiomimedata.cpp - - src/scrobbler/audioscrobbler.cpp - src/scrobbler/scrobblersettings.cpp - src/scrobbler/scrobblerservice.cpp - src/scrobbler/scrobblercache.cpp - src/scrobbler/scrobblercacheitem.cpp - src/scrobbler/scrobblemetadata.cpp - src/scrobbler/scrobblingapi20.cpp - src/scrobbler/lastfmscrobbler.cpp - src/scrobbler/librefmscrobbler.cpp - src/scrobbler/listenbrainzscrobbler.cpp - src/scrobbler/lastfmimport.cpp - - src/organize/organize.cpp - src/organize/organizeformat.cpp - src/organize/organizeformatvalidator.cpp - src/organize/organizesyntaxhighlighter.cpp - src/organize/organizedialog.cpp - src/organize/organizeerrordialog.cpp - - src/transcoder/transcoder.cpp - src/transcoder/transcoderoptionsinterface.cpp - src/transcoder/transcodedialog.cpp - src/transcoder/transcoderoptionsdialog.cpp - src/transcoder/transcoderoptionsflac.cpp - src/transcoder/transcoderoptionswavpack.cpp - src/transcoder/transcoderoptionsvorbis.cpp - src/transcoder/transcoderoptionsopus.cpp - src/transcoder/transcoderoptionsspeex.cpp - src/transcoder/transcoderoptionsaac.cpp - src/transcoder/transcoderoptionsasf.cpp - src/transcoder/transcoderoptionsmp3.cpp + src/main/main.cpp + src/main/mainwindow.cpp + src/main/application.cpp + src/main/metatypes.cpp + src/main/translations.cpp ) set(HEADERS - src/core/logging.h - src/core/mainwindow.h - src/core/application.h - src/core/player.h - src/core/database.h - src/core/deletefiles.h - src/core/filesystemwatcherinterface.h - src/core/mergedproxymodel.h - src/core/multisortfilterproxy.h - src/core/networkaccessmanager.h - src/core/threadsafenetworkdiskcache.h - src/core/networktimeouts.h - src/core/qtfslistener.h - src/core/settings.h - src/core/songloader.h - src/core/taskmanager.h - src/core/thread.h - src/core/urlhandler.h - src/core/standarditemiconloader.h - src/core/mimedata.h - src/core/stylesheetloader.h - src/core/localredirectserver.h - - src/tagreader/tagreaderclient.h - src/tagreader/tagreaderreply.h - src/tagreader/tagreaderreadfilereply.h - src/tagreader/tagreaderloadcoverdatareply.h - src/tagreader/tagreaderloadcoverimagereply.h - - src/engine/enginebase.h - src/engine/devicefinders.h - src/engine/gststartup.h - src/engine/gstengine.h - src/engine/gstenginepipeline.h - - src/analyzer/analyzerbase.h - src/analyzer/analyzercontainer.h - src/analyzer/blockanalyzer.h - src/analyzer/boomanalyzer.h - src/analyzer/turbineanalyzer.h - src/analyzer/sonogramanalyzer.h - src/analyzer/waverubberanalyzer.h - src/analyzer/rainbowanalyzer.h - - src/equalizer/equalizer.h - src/equalizer/equalizerslider.h - - src/context/contextview.h - src/context/contextalbum.h - - src/collection/collection.h - src/collection/collectionmodel.h - src/collection/collectionbackend.h - src/collection/collectionwatcher.h - src/collection/collectionview.h - src/collection/collectionitemdelegate.h - src/collection/collectionviewcontainer.h - src/collection/collectiondirectorymodel.h - src/collection/collectionfilterwidget.h - src/collection/collectionfilter.h - src/collection/savedgroupingmanager.h - src/collection/groupbydialog.h - - src/playlist/playlist.h - src/playlist/playlistbackend.h - src/playlist/playlistcontainer.h - src/playlist/playlistdelegates.h - src/playlist/playlistfilter.h - src/playlist/playlistheader.h - src/playlist/playlistlistcontainer.h - src/playlist/playlistlistmodel.h - src/playlist/playlistlistview.h - src/playlist/playlistlistsortfiltermodel.h - src/playlist/playlistmanager.h - src/playlist/playlistsaveoptionsdialog.h - src/playlist/playlistsequence.h - src/playlist/playlisttabbar.h - src/playlist/playlistview.h - src/playlist/playlistproxystyle.h - src/playlist/playlistitemmimedata.h - src/playlist/songloaderinserter.h - src/playlist/songmimedata.h - src/playlist/dynamicplaylistcontrols.h - - src/queue/queue.h - src/queue/queueview.h - - src/playlistparsers/asxiniparser.h - src/playlistparsers/asxparser.h - src/playlistparsers/cueparser.h - src/playlistparsers/m3uparser.h - src/playlistparsers/parserbase.h - src/playlistparsers/playlistparser.h - src/playlistparsers/plsparser.h - src/playlistparsers/wplparser.h - src/playlistparsers/xmlparser.h - src/playlistparsers/xspfparser.h - - src/smartplaylists/playlistgenerator.h - src/smartplaylists/playlistgeneratorinserter.h - src/smartplaylists/playlistquerygenerator.h - src/smartplaylists/playlistgeneratormimedata.h - src/smartplaylists/smartplaylistquerywizardplugin.h - src/smartplaylists/smartplaylistquerywizardpluginsortpage.h - src/smartplaylists/smartplaylistquerywizardpluginsearchpage.h - src/smartplaylists/smartplaylistsearchpreview.h - src/smartplaylists/smartplaylistsearchtermwidget.h - src/smartplaylists/smartplaylistsearchtermwidgetoverlay.h - src/smartplaylists/smartplaylistsmodel.h - src/smartplaylists/smartplaylistsviewcontainer.h - src/smartplaylists/smartplaylistsview.h - src/smartplaylists/smartplaylistwizard.h - src/smartplaylists/smartplaylistwizardplugin.h - src/smartplaylists/smartplaylistwizardtypepage.h - src/smartplaylists/smartplaylistwizardfinishpage.h - - src/covermanager/albumcovermanager.h - src/covermanager/albumcovermanagerlist.h - src/covermanager/albumcoverloader.h - src/covermanager/albumcoverfetcher.h - src/covermanager/albumcoverfetchersearch.h - src/covermanager/albumcoversearcher.h - src/covermanager/albumcoverexport.h - src/covermanager/albumcoverexporter.h - src/covermanager/albumcoverchoicecontroller.h - src/covermanager/coverprovider.h - src/covermanager/coverproviders.h - src/covermanager/coversearchstatisticsdialog.h - src/covermanager/coverexportrunnable.h - src/covermanager/currentalbumcoverloader.h - src/covermanager/coverfromurldialog.h - src/covermanager/jsoncoverprovider.h - src/covermanager/lastfmcoverprovider.h - src/covermanager/musicbrainzcoverprovider.h - src/covermanager/discogscoverprovider.h - src/covermanager/deezercoverprovider.h - src/covermanager/musixmatchcoverprovider.h - src/covermanager/opentidalcoverprovider.h - - src/lyrics/lyricsproviders.h - src/lyrics/lyricsprovider.h - src/lyrics/lyricsfetcher.h - src/lyrics/lyricsfetchersearch.h - src/lyrics/jsonlyricsprovider.h - src/lyrics/htmllyricsprovider.h - src/lyrics/ovhlyricsprovider.h - src/lyrics/lololyricsprovider.h - src/lyrics/geniuslyricsprovider.h - src/lyrics/musixmatchlyricsprovider.h - src/lyrics/chartlyricsprovider.h - src/lyrics/songlyricscomlyricsprovider.h - src/lyrics/azlyricscomlyricsprovider.h - src/lyrics/elyricsnetlyricsprovider.h - src/lyrics/letraslyricsprovider.h - src/lyrics/lyricfindlyricsprovider.h - - src/settings/settingsdialog.h - src/settings/settingspage.h - src/settings/behavioursettingspage.h - src/settings/collectionsettingspage.h - src/settings/collectionsettingsdirectorymodel.h - src/settings/backendsettingspage.h - src/settings/playlistsettingspage.h - src/settings/scrobblersettingspage.h - src/settings/coverssettingspage.h - src/settings/lyricssettingspage.h - src/settings/networkproxysettingspage.h - src/settings/appearancesettingspage.h - src/settings/contextsettingspage.h - src/settings/notificationssettingspage.h - src/settings/transcodersettingspage.h - - src/dialogs/about.h - src/dialogs/errordialog.h - src/dialogs/console.h - src/dialogs/edittagdialog.h - src/dialogs/trackselectiondialog.h - src/dialogs/addstreamdialog.h - src/dialogs/userpassdialog.h - src/dialogs/deleteconfirmationdialog.h - src/dialogs/lastfmimportdialog.h - src/dialogs/messagedialog.h - src/dialogs/snapdialog.h - src/dialogs/saveplaylistsdialog.h - - src/widgets/autoexpandingtreeview.h - src/widgets/busyindicator.h - src/widgets/clickablelabel.h - src/widgets/fancytabwidget.h - 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 - src/widgets/linetextedit.h - src/widgets/multiloadingindicator.h - src/widgets/playingwidget.h - src/widgets/renametablineedit.h - src/widgets/sliderslider.h - src/widgets/prettyslider.h - src/widgets/volumeslider.h - src/widgets/stickyslider.h - src/widgets/stretchheaderview.h - src/widgets/trackslider.h - src/widgets/tracksliderpopup.h - src/widgets/tracksliderslider.h - src/widgets/loginstatewidget.h - src/widgets/searchfield.h - src/widgets/ratingwidget.h - src/widgets/forcescrollperpixel.h - src/widgets/resizabletextedit.h - - src/osd/osdbase.h - src/osd/osdpretty.h - - src/streaming/streamingservices.h - src/streaming/streamingservice.h - src/streaming/streamsongmimedata.h - src/streaming/streamingsearchmodel.h - src/streaming/streamingsearchsortmodel.h - src/streaming/streamingsearchitemdelegate.h - src/streaming/streamingsearchview.h - src/streaming/streamingsongsview.h - src/streaming/streamingtabsview.h - src/streaming/streamingcollectionview.h - src/streaming/streamingcollectionviewcontainer.h - - src/radios/radioservices.h - src/radios/radiobackend.h - src/radios/radiomodel.h - src/radios/radioview.h - src/radios/radioviewcontainer.h - src/radios/radioservice.h - src/radios/radiomimedata.h - src/radios/somafmservice.h - src/radios/radioparadiseservice.h - - src/scrobbler/audioscrobbler.h - src/scrobbler/scrobblersettings.h - src/scrobbler/scrobblerservice.h - src/scrobbler/scrobblercache.h - src/scrobbler/scrobblingapi20.h - src/scrobbler/lastfmscrobbler.h - src/scrobbler/librefmscrobbler.h - src/scrobbler/listenbrainzscrobbler.h - src/scrobbler/lastfmimport.h - - src/organize/organize.h - src/organize/organizeformatvalidator.h - src/organize/organizesyntaxhighlighter.h - src/organize/organizedialog.h - src/organize/organizeerrordialog.h - - src/transcoder/transcoder.h - src/transcoder/transcodedialog.h - src/transcoder/transcoderoptionsdialog.h - src/transcoder/transcoderoptionsinterface.h - src/transcoder/transcoderoptionsflac.h - src/transcoder/transcoderoptionswavpack.h - src/transcoder/transcoderoptionsvorbis.h - src/transcoder/transcoderoptionsopus.h - src/transcoder/transcoderoptionsspeex.h - src/transcoder/transcoderoptionsaac.h - src/transcoder/transcoderoptionsasf.h - src/transcoder/transcoderoptionsmp3.h + src/main/mainwindow.h + src/main/application.h ) set(UI - - src/core/mainwindow.ui - - src/collection/groupbydialog.ui - src/collection/collectionfilterwidget.ui - src/collection/collectionviewcontainer.ui - src/collection/savedgroupingmanager.ui - - src/playlist/playlistcontainer.ui - src/playlist/playlistlistcontainer.ui - src/playlist/playlistsaveoptionsdialog.ui - src/playlist/playlistsequence.ui - src/playlist/dynamicplaylistcontrols.ui - - src/queue/queueview.ui - - src/smartplaylists/smartplaylistquerysearchpage.ui - src/smartplaylists/smartplaylistquerysortpage.ui - src/smartplaylists/smartplaylistsearchpreview.ui - src/smartplaylists/smartplaylistsearchtermwidget.ui - src/smartplaylists/smartplaylistsviewcontainer.ui - src/smartplaylists/smartplaylistwizardfinishpage.ui - - src/covermanager/albumcoverexport.ui - src/covermanager/albumcovermanager.ui - src/covermanager/albumcoversearcher.ui - src/covermanager/coversearchstatisticsdialog.ui - src/covermanager/coverfromurldialog.ui - - src/settings/settingsdialog.ui - src/settings/behavioursettingspage.ui - src/settings/collectionsettingspage.ui - src/settings/backendsettingspage.ui - src/settings/contextsettingspage.ui - src/settings/playlistsettingspage.ui - src/settings/scrobblersettingspage.ui - src/settings/coverssettingspage.ui - src/settings/lyricssettingspage.ui - src/settings/networkproxysettingspage.ui - src/settings/appearancesettingspage.ui - src/settings/notificationssettingspage.ui - src/settings/transcodersettingspage.ui - - src/equalizer/equalizer.ui - src/equalizer/equalizerslider.ui - - src/dialogs/about.ui - src/dialogs/errordialog.ui - src/dialogs/console.ui - src/dialogs/edittagdialog.ui - src/dialogs/trackselectiondialog.ui - src/dialogs/addstreamdialog.ui - src/dialogs/userpassdialog.ui - src/dialogs/lastfmimportdialog.ui - src/dialogs/messagedialog.ui - src/dialogs/saveplaylistsdialog.ui - - src/widgets/trackslider.ui - src/widgets/fileview.ui - src/widgets/loginstatewidget.ui - - src/osd/osdpretty.ui - - src/streaming/streamingtabsview.ui - src/streaming/streamingcollectionviewcontainer.ui - src/streaming/streamingsearchview.ui - - src/radios/radioviewcontainer.ui - - src/organize/organizedialog.ui - src/organize/organizeerrordialog.ui - - src/transcoder/transcodedialog.ui - src/transcoder/transcodelogdialog.ui - src/transcoder/transcoderoptionsaac.ui - src/transcoder/transcoderoptionsdialog.ui - src/transcoder/transcoderoptionsflac.ui - src/transcoder/transcoderoptionswavpack.ui - src/transcoder/transcoderoptionsvorbis.ui - src/transcoder/transcoderoptionsopus.ui - src/transcoder/transcoderoptionsspeex.ui - src/transcoder/transcoderoptionsasf.ui - src/transcoder/transcoderoptionsmp3.ui -) - -if(APPLE) - optional_source(APPLE - SOURCES - src/utilities/macosutils.mm - src/core/scoped_nsautorelease_pool.mm - src/core/mac_startup.mm - src/core/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/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) -endif() - -optional_source(WIN32 - SOURCES - 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 - ) - 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) -optional_source(HAVE_PULSE SOURCES src/engine/pulsedevicefinder.cpp) -optional_source(MSVC SOURCES src/engine/uwpdevicefinder.cpp src/engine/asiodevicefinder.cpp) - -if(HAVE_SONGFINGERPRINTING OR HAVE_MUSICBRAINZ) - optional_source(CHROMAPRINT_FOUND SOURCES src/engine/chromaprinter.cpp) -endif() - -optional_source(HAVE_MUSICBRAINZ - SOURCES - src/musicbrainz/acoustidclient.cpp - src/musicbrainz/musicbrainzclient.cpp - src/musicbrainz/tagfetcher.cpp - HEADERS - src/musicbrainz/acoustidclient.h - src/musicbrainz/musicbrainzclient.h - src/musicbrainz/tagfetcher.h -) - -optional_source(HAVE_EBUR128 SOURCES src/engine/ebur128analysis.cpp) - -if(HAVE_DBUS) - optional_source(HAVE_DBUS SOURCES src/osd/osddbus.cpp HEADERS src/osd/osddbus.h) - qt_add_dbus_interface(SOURCES src/osd/org.freedesktop.Notifications.xml notification) -endif() - -if(HAVE_MPRIS2) - optional_source(HAVE_MPRIS2 SOURCES src/mpris2/mpris2.cpp HEADERS src/mpris2/mpris2.h) - qt_add_dbus_adaptor(SOURCES src/mpris2/org.mpris.MediaPlayer2.xml src/mpris2/mpris2.h mpris::Mpris2 mpris2_root Mpris2Root) - qt_add_dbus_adaptor(SOURCES src/mpris2/org.mpris.MediaPlayer2.Player.xml src/mpris2/mpris2.h mpris::Mpris2 mpris2_player Mpris2Player) - qt_add_dbus_adaptor(SOURCES src/mpris2/org.mpris.MediaPlayer2.TrackList.xml src/mpris2/mpris2.h mpris::Mpris2 mpris2_tracklist Mpris2TrackList) - qt_add_dbus_adaptor(SOURCES src/mpris2/org.mpris.MediaPlayer2.Playlists.xml src/mpris2/mpris2.h mpris::Mpris2 mpris2_playlists Mpris2Playlists) -endif() - -optional_source(HAVE_MOODBAR - SOURCES - src/moodbar/moodbarbuilder.cpp - src/moodbar/moodbarcontroller.cpp - src/moodbar/moodbaritemdelegate.cpp - src/moodbar/moodbarloader.cpp - src/moodbar/moodbarpipeline.cpp - src/moodbar/moodbarproxystyle.cpp - src/moodbar/moodbarrenderer.cpp - src/moodbar/gstfastspectrumplugin.cpp - src/moodbar/gstfastspectrum.cpp - src/settings/moodbarsettingspage.cpp - HEADERS - src/moodbar/moodbarcontroller.h - src/moodbar/moodbaritemdelegate.h - src/moodbar/moodbarloader.h - src/moodbar/moodbarpipeline.h - src/moodbar/moodbarproxystyle.h - src/settings/moodbarsettingspage.h - UI - 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) - 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) - qt_add_dbus_interface(SOURCES src/device/org.freedesktop.UDisks2.Drive.xml udisks2drive) - qt_add_dbus_interface(SOURCES src/device/org.freedesktop.UDisks2.Job.xml udisks2job) -endif() - -optional_source(HAVE_MTP - SOURCES - src/device/mtpconnection.cpp - src/device/mtpdevice.cpp - src/device/mtploader.cpp - HEADERS - src/device/mtpconnection.h - src/device/mtpdevice.h - src/device/mtploader.h -) - -optional_source(HAVE_AUDIOCD - SOURCES - src/device/cddadevice.cpp - src/device/cddalister.cpp - src/device/cddasongloader.cpp - HEADERS - src/device/cddadevice.h - src/device/cddalister.h - src/device/cddasongloader.h -) - -optional_source(HAVE_GPOD - SOURCES - src/device/gpoddevice.cpp - src/device/gpodloader.cpp - HEADERS - src/device/gpoddevice.h - src/device/gpodloader.h -) - -optional_source(HAVE_SUBSONIC - SOURCES - src/subsonic/subsonicservice.cpp - src/subsonic/subsonicurlhandler.cpp - src/subsonic/subsonicbaserequest.cpp - src/subsonic/subsonicrequest.cpp - src/subsonic/subsonicscrobblerequest.cpp - src/settings/subsonicsettingspage.cpp - src/scrobbler/subsonicscrobbler.cpp - HEADERS - src/subsonic/subsonicservice.h - src/subsonic/subsonicurlhandler.h - src/subsonic/subsonicbaserequest.h - src/subsonic/subsonicrequest.h - src/subsonic/subsonicscrobblerequest.h - src/settings/subsonicsettingspage.h - src/scrobbler/subsonicscrobbler.h - UI - src/settings/subsonicsettingspage.ui -) - -optional_source(HAVE_TIDAL - SOURCES - src/tidal/tidalservice.cpp - src/tidal/tidalurlhandler.cpp - src/tidal/tidalbaserequest.cpp - src/tidal/tidalrequest.cpp - src/tidal/tidalstreamurlrequest.cpp - src/tidal/tidalfavoriterequest.cpp - src/settings/tidalsettingspage.cpp - src/covermanager/tidalcoverprovider.cpp - HEADERS - src/tidal/tidalservice.h - src/tidal/tidalurlhandler.h - src/tidal/tidalbaserequest.h - src/tidal/tidalrequest.h - src/tidal/tidalstreamurlrequest.h - src/tidal/tidalfavoriterequest.h - src/settings/tidalsettingspage.h - src/covermanager/tidalcoverprovider.h - UI - src/settings/tidalsettingspage.ui -) - -optional_source(HAVE_SPOTIFY - SOURCES - src/spotify/spotifyservice.cpp - src/spotify/spotifybaserequest.cpp - src/spotify/spotifyrequest.cpp - src/spotify/spotifyfavoriterequest.cpp - src/settings/spotifysettingspage.cpp - src/covermanager/spotifycoverprovider.cpp - HEADERS - src/spotify/spotifyservice.h - src/spotify/spotifybaserequest.h - src/spotify/spotifyrequest.h - src/spotify/spotifyfavoriterequest.h - src/settings/spotifysettingspage.h - src/covermanager/spotifycoverprovider.h - UI - src/settings/spotifysettingspage.ui -) - -optional_source(HAVE_QOBUZ - SOURCES - src/qobuz/qobuzservice.cpp - src/qobuz/qobuzurlhandler.cpp - src/qobuz/qobuzbaserequest.cpp - src/qobuz/qobuzrequest.cpp - src/qobuz/qobuzstreamurlrequest.cpp - src/qobuz/qobuzfavoriterequest.cpp - src/settings/qobuzsettingspage.cpp - src/covermanager/qobuzcoverprovider.cpp - HEADERS - src/qobuz/qobuzservice.h - src/qobuz/qobuzurlhandler.h - src/qobuz/qobuzbaserequest.h - src/qobuz/qobuzrequest.h - src/qobuz/qobuzstreamurlrequest.h - src/qobuz/qobuzfavoriterequest.h - src/settings/qobuzsettingspage.h - src/covermanager/qobuzcoverprovider.h - UI - src/settings/qobuzsettingspage.ui + src/main/mainwindow.ui ) qt_wrap_cpp(SOURCES ${HEADERS}) qt_wrap_ui(SOURCES ${UI}) qt_add_resources(SOURCES data/data.qrc data/icons.qrc) -add_library(strawberry_lib STATIC ${SOURCES}) - -target_sources(strawberry PRIVATE src/main.cpp) +target_sources(strawberry PRIVATE ${SOURCES}) if(WIN32) target_sources(strawberry PRIVATE windres.rc) @@ -1436,85 +457,87 @@ target_include_directories(strawberry PRIVATE ${CMAKE_BINARY_DIR}/src ) -target_include_directories(strawberry_lib PRIVATE - ${CMAKE_SOURCE_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_BINARY_DIR}/src -) - if(SINGLEAPPLICATION_INCLUDE_DIRS) target_include_directories(strawberry SYSTEM PRIVATE ${SINGLEAPPLICATION_INCLUDE_DIRS}) endif() -if(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H) - target_include_directories(strawberry_lib SYSTEM PRIVATE ${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) -endif() +# if(APPLE) +# target_link_libraries(strawberry PRIVATE +# "-framework Foundation" +# "-framework AppKit" +# "-framework Carbon" +# "-framework CoreAudio" +# "-framework DiskArbitration" +# "-framework IOKit" +# "-framework ScriptingBridge" +# SPMediaKeyTap +# ) +# endif() -target_link_libraries(strawberry_lib PRIVATE +target_link_libraries(strawberry PRIVATE ${CMAKE_THREAD_LIBS_INIT} + $<$:execinfo> PkgConfig::GLIB PkgConfig::GOBJECT - PkgConfig::SQLITE PkgConfig::GSTREAMER PkgConfig::GSTREAMER_BASE PkgConfig::GSTREAMER_AUDIO PkgConfig::GSTREAMER_APP PkgConfig::GSTREAMER_TAG PkgConfig::GSTREAMER_PBUTILS - ${TAGLIB_LIBRARIES} Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Concurrent - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets $<$:Qt${QT_VERSION_MAJOR}::DBus> - ICU::uc - ICU::i18n - $<$:ALSA::ALSA> - $<$:PkgConfig::LIBPULSE> - $<$:PkgConfig::CHROMAPRINT> - $<$:PkgConfig::FFTW3> - $<$:PkgConfig::LIBEBUR128> - $<$:X11::X11_xcb> - $<$:PkgConfig::GIO> - $<$:PkgConfig::GIO_UNIX> - $<$:PkgConfig::LIBCDIO> - $<$:PkgConfig::LIBMTP> - $<$:PkgConfig::LIBGPOD PkgConfig::GDK_PIXBUF> + ${SINGLEAPPLICATION_LIBRARIES} $<$:PkgConfig::QTSPARKLE> - $<$:execinfo> - $<$:dsound dwmapi getopt-win::getopt> - $<$:WindowsApp> + strawberry_core + strawberry_utilities + strawberry_mimedata + strawberry_osd + strawberry_tagreader + strawberry_widgets + strawberry_engine + strawberry_lyrics + strawberry_filterparser + strawberry_analyzer + strawberry_transcoder + strawberry_musicbrainz + strawberry_collection + strawberry_playlist + strawberry_playlistparsers + strawberry_equalizer + strawberry_edittagdialog + strawberry_smartplaylists + strawberry_fileview + strawberry_transcoder + strawberry_organize + strawberry_context + strawberry_moodbar + strawberry_scrobbler + strawberry_queue + strawberry_radios + strawberry_device + strawberry_settings + strawberry_providers + strawberry_player + strawberry_songloader + strawberry_systemtrayicon ) -if(APPLE) - target_link_libraries(strawberry_lib PRIVATE - "-framework Foundation" - "-framework AppKit" - "-framework Carbon" - "-framework CoreAudio" - "-framework DiskArbitration" - "-framework IOKit" - "-framework ScriptingBridge" - SPMediaKeyTap - ) +if(HAVE_MPRIS2) + target_link_libraries(strawberry PRIVATE strawberry_mpris2) endif() -target_link_libraries(strawberry PRIVATE - ${CMAKE_THREAD_LIBS_INIT} - PkgConfig::GLIB - PkgConfig::GOBJECT - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Widgets - $<$:Qt${QT_VERSION_MAJOR}::DBus> - ${SINGLEAPPLICATION_LIBRARIES} - strawberry_lib -) +if(HAVE_GLOBALSHORTCUTS) + target_link_libraries(strawberry PRIVATE strawberry_globalshortcuts) +endif() + +if(APPLE) + target_link_libraries(strawberry PRIVATE strawberry_macstartup) +endif() if(NOT APPLE) install(TARGETS strawberry RUNTIME DESTINATION bin) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e97086cc3d..9747f7a360 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,2 +1,71 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h) + +add_subdirectory(utilities) +add_subdirectory(core) +add_subdirectory(mimedata) +add_subdirectory(osd) +add_subdirectory(tagreader) +add_subdirectory(widgets) +add_subdirectory(dialogs) +add_subdirectory(engine) +add_subdirectory(lyrics) +add_subdirectory(filterparser) +add_subdirectory(analyzer) +add_subdirectory(transcoder) +add_subdirectory(collection) +add_subdirectory(playlist) +add_subdirectory(playlistparsers) +add_subdirectory(equalizer) +add_subdirectory(edittagdialog) +add_subdirectory(smartplaylists) +add_subdirectory(settings) +add_subdirectory(device) +add_subdirectory(covermanager) +add_subdirectory(fileview) +add_subdirectory(player) +add_subdirectory(radios) +add_subdirectory(streaming) +add_subdirectory(scrobbler) +add_subdirectory(organize) +add_subdirectory(context) +add_subdirectory(queue) +add_subdirectory(providers) +add_subdirectory(songloader) +add_subdirectory(systemtrayicon) + +if(HAVE_MUSICBRAINZ) + add_subdirectory(musicbrainz) +endif() + +if(HAVE_GLOBALSHORTCUTS) + add_subdirectory(globalshortcuts) +endif() + +if(HAVE_MOODBAR) + add_subdirectory(moodbar) +endif() + +if(HAVE_MPRIS2) + add_subdirectory(mpris2) +endif() + +if(HAVE_SUBSONIC) + add_subdirectory(subsonic) +endif() + +if(HAVE_TIDAL) + add_subdirectory(tidal) +endif() + +if(HAVE_SPOTIFY) + add_subdirectory(spotify) +endif() + +if(HAVE_QOBUZ) + add_subdirectory(qobuz) +endif() + +if(APPLE) + add_subdirectory(macstartup) +endif() diff --git a/src/analyzer/CMakeLists.txt b/src/analyzer/CMakeLists.txt new file mode 100644 index 0000000000..efdc62e049 --- /dev/null +++ b/src/analyzer/CMakeLists.txt @@ -0,0 +1,41 @@ +set(ANALYZER_SOURCES + fht.cpp + analyzerbase.cpp + analyzercontainer.cpp + blockanalyzer.cpp + boomanalyzer.cpp + turbineanalyzer.cpp + sonogramanalyzer.cpp + waverubberanalyzer.cpp + rainbowanalyzer.cpp +) + +set(ANALYZER_HEADERS + analyzerbase.h + analyzercontainer.h + blockanalyzer.h + boomanalyzer.h + turbineanalyzer.h + sonogramanalyzer.h + waverubberanalyzer.h + rainbowanalyzer.h +) + +qt_wrap_cpp(ANALYZER_SOURCES ${ANALYZER_HEADERS}) + +add_library(strawberry_analyzer STATIC ${ANALYZER_SOURCES}) + +target_include_directories(strawberry_analyzer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_analyzer PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_core + strawberry_engine +) diff --git a/src/analyzer/analyzerbase.h b/src/analyzer/analyzerbase.h index de8c9bdf5f..b7263e608d 100644 --- a/src/analyzer/analyzerbase.h +++ b/src/analyzer/analyzerbase.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "analyzer/fht.h" #include "engine/enginebase.h" diff --git a/src/analyzer/analyzercontainer.cpp b/src/analyzer/analyzercontainer.cpp index 3ead830e44..1b4c33cb7b 100644 --- a/src/analyzer/analyzercontainer.cpp +++ b/src/analyzer/analyzercontainer.cpp @@ -44,8 +44,8 @@ #include "waverubberanalyzer.h" #include "rainbowanalyzer.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/settings.h" #include "engine/enginebase.h" diff --git a/src/analyzer/analyzercontainer.h b/src/analyzer/analyzercontainer.h index 94ddaa70c3..20f36eafac 100644 --- a/src/analyzer/analyzercontainer.h +++ b/src/analyzer/analyzercontainer.h @@ -30,7 +30,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "engine/enginebase.h" class QTimer; diff --git a/src/collection/CMakeLists.txt b/src/collection/CMakeLists.txt new file mode 100644 index 0000000000..9288777777 --- /dev/null +++ b/src/collection/CMakeLists.txt @@ -0,0 +1,82 @@ +set(COLLECTION_SOURCES + collectionlibrary.cpp + collectionmodel.cpp + collectionbackend.cpp + collectionwatcher.cpp + collectionview.cpp + collectionitemdelegate.cpp + collectionviewcontainer.cpp + collectiondirectorymodel.cpp + collectionfilteroptions.cpp + collectionfilterwidget.cpp + collectionfilter.cpp + collectionplaylistitem.cpp + collectionquery.cpp + savedgroupingmanager.cpp + groupbydialog.cpp + collectiontask.cpp + collectionmodelupdate.cpp + collectionitem.cpp +) + +set(COLLECTION_HEADERS + collectionlibrary.h + collectionmodel.h + collectionbackend.h + collectionwatcher.h + collectionview.h + collectionitemdelegate.h + collectionviewcontainer.h + collectiondirectorymodel.h + collectionfilterwidget.h + collectionfilter.h + savedgroupingmanager.h + groupbydialog.h +) + +set(COLLECTION_UI + groupbydialog.ui + collectionfilterwidget.ui + collectionviewcontainer.ui + savedgroupingmanager.ui +) + +qt_wrap_cpp(COLLECTION_SOURCES ${COLLECTION_HEADERS}) +qt_wrap_ui(COLLECTION_SOURCES ${COLLECTION_UI}) + +add_library(strawberry_collection STATIC ${COLLECTION_SOURCES}) + +target_include_directories(strawberry_collection PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_collection PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + PkgConfig::GSTREAMER + PkgConfig::GSTREAMER_BASE + PkgConfig::GSTREAMER_AUDIO + PkgConfig::GSTREAMER_APP + PkgConfig::GSTREAMER_TAG + PkgConfig::GSTREAMER_PBUTILS + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core + strawberry_mimedata + strawberry_engine + strawberry_tagreader + strawberry_covermanager + strawberry_filterparser + strawberry_dialogs + strawberry_edittagdialog + strawberry_organize + strawberry_playlistparsers +) diff --git a/src/collection/collectionbackend.cpp b/src/collection/collectionbackend.cpp index d573f721ad..45ed9e8fd7 100644 --- a/src/collection/collectionbackend.cpp +++ b/src/collection/collectionbackend.cpp @@ -45,13 +45,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/database.h" #include "core/scopedtransaction.h" #include "core/song.h" -#include "core/sqlrow.h" -#include "smartplaylists/smartplaylistsearch.h" #include "collectiondirectory.h" #include "collectionbackend.h" @@ -1932,37 +1930,26 @@ void CollectionBackend::DeleteAll() { } -SongList CollectionBackend::SmartPlaylistsFindSongs(const SmartPlaylistSearch &search) { +SongList CollectionBackend::ExecuteQuery(const QString &sql) { QMutexLocker l(db_->Mutex()); QSqlDatabase db(db_->Connect()); - // Build the query - QString sql = search.ToSql(songs_table()); - - // Run the query - SongList ret; SqlQuery query(db); query.prepare(sql); if (!query.Exec()) { db_->ReportErrors(query); - return ret; + return SongList(); } - // Read the results + SongList songs; while (query.next()) { Song song; song.InitFromQuery(query, true); - ret << song; + songs << song; } - return ret; - -} - -SongList CollectionBackend::SmartPlaylistsGetAllSongs() { - // Get all the songs! - return SmartPlaylistsFindSongs(SmartPlaylistSearch(SmartPlaylistSearch::SearchType::All, SmartPlaylistSearch::TermList(), SmartPlaylistSearch::SortType::FieldAsc, SmartPlaylistSearchTerm::Field::Artist, -1)); + return songs; } diff --git a/src/collection/collectionbackend.h b/src/collection/collectionbackend.h index eeaa159ac9..0e996cf087 100644 --- a/src/collection/collectionbackend.h +++ b/src/collection/collectionbackend.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "collectionfilteroptions.h" #include "collectionquery.h" @@ -45,7 +45,6 @@ class QThread; class TaskManager; class Database; -class SmartPlaylistSearch; class CollectionBackendInterface : public QObject { Q_OBJECT @@ -227,8 +226,7 @@ class CollectionBackend : public CollectionBackendInterface { SongList GetSongsByFingerprint(const QString &fingerprint) override; - SongList SmartPlaylistsGetAllSongs(); - SongList SmartPlaylistsFindSongs(const SmartPlaylistSearch &search); + SongList ExecuteQuery(const QString &sql); void AddOrUpdateSongsAsync(const SongList &songs); void UpdateSongsBySongIDAsync(const SongMap &new_songs); diff --git a/src/collection/collectiondirectorymodel.cpp b/src/collection/collectiondirectorymodel.cpp index a83727f9db..029f15953e 100644 --- a/src/collection/collectiondirectorymodel.cpp +++ b/src/collection/collectiondirectorymodel.cpp @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/filesystemmusicstorage.h" #include "core/iconloader.h" #include "core/musicstorage.h" diff --git a/src/collection/collectiondirectorymodel.h b/src/collection/collectiondirectorymodel.h index dae601fc11..0d0da2c68d 100644 --- a/src/collection/collectiondirectorymodel.h +++ b/src/collection/collectiondirectorymodel.h @@ -33,7 +33,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "collectiondirectory.h" class QModelIndex; diff --git a/src/collection/collectionfilter.cpp b/src/collection/collectionfilter.cpp index b43d3a8b90..3294772332 100644 --- a/src/collection/collectionfilter.cpp +++ b/src/collection/collectionfilter.cpp @@ -28,10 +28,9 @@ #include #include "core/song.h" +#include "mimedata/songmimedata.h" #include "filterparser/filterparser.h" #include "filterparser/filtertree.h" -#include "playlist/songmimedata.h" -#include "playlist/playlistmanager.h" #include "collectionbackend.h" #include "collectionfilter.h" #include "collectionmodel.h" @@ -95,7 +94,7 @@ QMimeData *CollectionFilter::mimeData(const QModelIndexList &indexes) const { } data->setUrls(urls); - data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs); + data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs); return data; diff --git a/src/collection/collectionfilterwidget.cpp b/src/collection/collectionfilterwidget.cpp index 3a650f73ce..e124f2e418 100644 --- a/src/collection/collectionfilterwidget.cpp +++ b/src/collection/collectionfilterwidget.cpp @@ -53,10 +53,10 @@ #include "savedgroupingmanager.h" #include "collectionfilterwidget.h" #include "groupbydialog.h" -#include "ui_collectionfilterwidget.h" +#include "collection/ui_collectionfilterwidget.h" #include "widgets/searchfield.h" -#include "settings/collectionsettingspage.h" -#include "settings/appearancesettingspage.h" +#include "constants/collectionsettings.h" +#include "constants/appearancesettings.h" using namespace Qt::Literals::StringLiterals; @@ -204,8 +204,8 @@ void CollectionFilterWidget::setFilter(CollectionFilter *filter) { void CollectionFilterWidget::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeConfigureButtons, 20).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeConfigureButtons, 20).toInt(); s.endGroup(); ui_->options->setIconSize(QSize(iconsize, iconsize)); ui_->search_field->setIconSize(iconsize); @@ -345,7 +345,7 @@ void CollectionFilterWidget::SaveGroupBy() { qLog(Debug) << "Saving current grouping to" << name; Settings s; - if (settings_group_.isEmpty() || settings_group_ == QLatin1String(CollectionSettingsPage::kSettingsGroup)) { + if (settings_group_.isEmpty() || settings_group_ == QLatin1String(CollectionSettings::kSettingsGroup)) { s.beginGroup(SavedGroupingManager::kSavedGroupingsSettingsGroup); } else { diff --git a/src/collection/collectionitem.cpp b/src/collection/collectionitem.cpp new file mode 100644 index 0000000000..20987b75c1 --- /dev/null +++ b/src/collection/collectionitem.cpp @@ -0,0 +1,32 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "collectionitem.h" + +CollectionItem::CollectionItem(SimpleTreeModel *_model) + : SimpleTreeItem(_model), + type(Type::Root), + container_level(-1), + compilation_artist_node_(nullptr) {} + +CollectionItem::CollectionItem(const Type _type, CollectionItem *_parent) + : SimpleTreeItem(_parent), + type(_type), + container_level(-1), + compilation_artist_node_(nullptr) {} diff --git a/src/collection/collectionitem.h b/src/collection/collectionitem.h index 14655ee961..4c6017a143 100644 --- a/src/collection/collectionitem.h +++ b/src/collection/collectionitem.h @@ -1,8 +1,6 @@ /* * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2018-2021, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +20,6 @@ #ifndef COLLECTIONITEM_H #define COLLECTIONITEM_H -#include "config.h" - #include "core/simpletreeitem.h" #include "core/song.h" @@ -37,17 +33,8 @@ class CollectionItem : public SimpleTreeItem { LoadingIndicator, }; - explicit CollectionItem(SimpleTreeModel *_model) - : SimpleTreeItem(_model), - type(Type::Root), - container_level(-1), - compilation_artist_node_(nullptr) {} - - explicit CollectionItem(const Type _type, CollectionItem *_parent = nullptr) - : SimpleTreeItem(_parent), - type(_type), - container_level(-1), - compilation_artist_node_(nullptr) {} + explicit CollectionItem(SimpleTreeModel *_model); + explicit CollectionItem(const Type _type, CollectionItem *_parent = nullptr); Type type; int container_level; diff --git a/src/collection/collection.cpp b/src/collection/collectionlibrary.cpp similarity index 60% rename from src/collection/collection.cpp rename to src/collection/collectionlibrary.cpp index 9546c597e5..7595b82eb6 100644 --- a/src/collection/collection.cpp +++ b/src/collection/collectionlibrary.cpp @@ -30,7 +30,6 @@ #include #include -#include "core/application.h" #include "core/taskmanager.h" #include "core/database.h" #include "core/thread.h" @@ -39,22 +38,26 @@ #include "core/settings.h" #include "tagreader/tagreaderclient.h" #include "utilities/threadutils.h" -#include "collection.h" +#include "collectionlibrary.h" #include "collectionwatcher.h" #include "collectionbackend.h" #include "collectionmodel.h" -#include "scrobbler/lastfmimport.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" using std::make_shared; -const char *SCollection::kSongsTable = "songs"; -const char *SCollection::kDirsTable = "directories"; -const char *SCollection::kSubdirsTable = "subdirectories"; +const char *CollectionLibrary::kSongsTable = "songs"; +const char *CollectionLibrary::kDirsTable = "directories"; +const char *CollectionLibrary::kSubdirsTable = "subdirectories"; -SCollection::SCollection(Application *app, QObject *parent) +CollectionLibrary::CollectionLibrary(const SharedPtr database, + const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + QObject *parent) : QObject(parent), - app_(app), + task_manager_(task_manager), + tagreader_client_(tagreader_client), backend_(nullptr), model_(nullptr), watcher_(nullptr), @@ -68,18 +71,18 @@ SCollection::SCollection(Application *app, QObject *parent) original_thread_ = thread(); backend_ = make_shared(); - backend()->moveToThread(app->database()->thread()); - qLog(Debug) << &*backend_ << "moved to thread" << app->database()->thread(); + backend()->moveToThread(database->thread()); + qLog(Debug) << &*backend_ << "moved to thread" << database->thread(); - backend_->Init(app->database(), app->task_manager(), Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable)); + backend_->Init(database, task_manager, Song::Source::Collection, QLatin1String(kSongsTable), QLatin1String(kDirsTable), QLatin1String(kSubdirsTable)); - model_ = new CollectionModel(backend_, app_, this); + model_ = new CollectionModel(backend_, albumcover_loader, this); ReloadSettings(); } -SCollection::~SCollection() { +CollectionLibrary::~CollectionLibrary() { if (watcher_) { watcher_->Abort(); @@ -92,9 +95,9 @@ SCollection::~SCollection() { } -void SCollection::Init() { +void CollectionLibrary::Init() { - watcher_ = new CollectionWatcher(Song::Source::Collection); + watcher_ = new CollectionWatcher(Song::Source::Collection, task_manager_, tagreader_client_, backend_); watcher_thread_ = new Thread(this); watcher_thread_->setObjectName(watcher_->objectName()); @@ -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); } } diff --git a/src/collection/collection.h b/src/collection/collectionlibrary.h similarity index 78% rename from src/collection/collection.h rename to src/collection/collectionlibrary.h index 62db686cb8..3ee9d47a91 100644 --- a/src/collection/collection.h +++ b/src/collection/collectionlibrary.h @@ -29,22 +29,30 @@ #include #include -#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, + const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr 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 task_manager_; + const SharedPtr tagreader_client_; + SharedPtr backend_; CollectionModel *model_; diff --git a/src/collection/collectionmodel.cpp b/src/collection/collectionmodel.cpp index 37a403fcb3..dd84b0eeb2 100644 --- a/src/collection/collectionmodel.cpp +++ b/src/collection/collectionmodel.cpp @@ -53,14 +53,13 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/database.h" #include "core/iconloader.h" #include "core/logging.h" -#include "core/sqlrow.h" #include "core/settings.h" +#include "mimedata/songmimedata.h" #include "collectionfilteroptions.h" #include "collectionquery.h" #include "collectionbackend.h" @@ -69,12 +68,10 @@ #include "collectionmodel.h" #include "collectionmodelupdate.h" #include "collectionfilter.h" -#include "playlist/playlistmanager.h" -#include "playlist/songmimedata.h" #include "covermanager/albumcoverloaderoptions.h" #include "covermanager/albumcoverloaderresult.h" #include "covermanager/albumcoverloader.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" using namespace std::chrono_literals; using namespace Qt::Literals::StringLiterals; @@ -85,12 +82,10 @@ constexpr char kPixmapDiskCacheDir[] = "pixmapcache"; constexpr char kVariousArtists[] = QT_TR_NOOP("Various artists"); } // namespace -QNetworkDiskCache *CollectionModel::sIconCache = nullptr; - -CollectionModel::CollectionModel(SharedPtr backend, Application *app, QObject *parent) +CollectionModel::CollectionModel(const SharedPtr backend, const SharedPtr albumcover_loader, QObject *parent) : SimpleTreeModel(new CollectionItem(this), parent), backend_(backend), - app_(app), + albumcover_loader_(albumcover_loader), dir_model_(new CollectionDirectoryModel(backend, this)), filter_(new CollectionFilter(this)), timer_reload_(new QTimer(this)), @@ -100,7 +95,8 @@ CollectionModel::CollectionModel(SharedPtr backend, Applicati total_song_count_(0), total_artist_count_(0), total_album_count_(0), - loading_(false) { + loading_(false), + icon_disk_cache_(nullptr) { setObjectName(backend_->source() == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(backend_->source()), QLatin1String(metaObject()->className()))); @@ -108,8 +104,8 @@ CollectionModel::CollectionModel(SharedPtr backend, Applicati filter_->setSortRole(Role_SortText); filter_->sort(0); - if (app_) { - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded); + if (albumcover_loader_) { + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &CollectionModel::AlbumCoverLoaded); } QIcon nocover = IconLoader::Load(u"cdcase"_s); @@ -118,10 +114,9 @@ CollectionModel::CollectionModel(SharedPtr backend, Applicati pixmap_no_cover_ = nocover.pixmap(nocover_sizes.last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } - if (app_ && !sIconCache) { - sIconCache = new QNetworkDiskCache(this); - sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir)); - QObject::connect(app_, &Application::ClearPixmapDiskCache, this, &CollectionModel::ClearDiskCache); + if (!qgetenv("DISPLAY").isEmpty() && !icon_disk_cache_) { + icon_disk_cache_ = new QNetworkDiskCache(this); + icon_disk_cache_->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/' + QLatin1String(kPixmapDiskCacheDir) + u'-' + Song::TextForSource(backend_->source())); } QObject::connect(&*backend_, &CollectionBackend::SongsAdded, this, &CollectionModel::AddReAddOrUpdate); @@ -230,16 +225,16 @@ void CollectionModel::ScheduleReset() { void CollectionModel::ReloadSettings() { Settings settings; - settings.beginGroup(CollectionSettingsPage::kSettingsGroup); - const bool show_pretty_covers = settings.value("pretty_covers", true).toBool(); - const bool show_dividers= settings.value("show_dividers", true).toBool(); - const bool show_various_artists = settings.value("various_artists", true).toBool(); - const bool sort_skips_articles = settings.value("sort_skips_articles", true).toBool(); - - use_disk_cache_ = settings.value(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool(); - QPixmapCache::setCacheLimit(static_cast(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit, CollectionSettingsPage::kSettingsCacheSizeDefault) / 1024)); - if (sIconCache) { - sIconCache->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault)); + settings.beginGroup(CollectionSettings::kSettingsGroup); + const bool show_pretty_covers = settings.value(CollectionSettings::kPrettyCovers, true).toBool(); + const bool show_dividers= settings.value(CollectionSettings::kShowDividers, true).toBool(); + const bool show_various_artists = settings.value(CollectionSettings::kVariousArtists, true).toBool(); + const bool sort_skips_articles = settings.value(CollectionSettings::kSortSkipsArticles, true).toBool(); + + use_disk_cache_ = settings.value(CollectionSettings::kSettingsDiskCacheEnable, false).toBool(); + QPixmapCache::setCacheLimit(static_cast(MaximumCacheSize(&settings, CollectionSettings::kSettingsCacheSize, CollectionSettings::kSettingsCacheSizeUnit, CollectionSettings::kSettingsCacheSizeDefault) / 1024)); + if (icon_disk_cache_) { + icon_disk_cache_->setMaximumCacheSize(MaximumCacheSize(&settings, CollectionSettings::kSettingsDiskCacheSize, CollectionSettings::kSettingsDiskCacheSizeUnit, CollectionSettings::kSettingsDiskCacheSizeDefault)); } settings.endGroup(); @@ -258,7 +253,7 @@ void CollectionModel::ReloadSettings() { } if (!use_disk_cache_) { - ClearDiskCache(); + ClearIconDiskCache(); } } @@ -427,7 +422,7 @@ QMimeData *CollectionModel::mimeData(const QModelIndexList &indexes) const { } data->setUrls(urls); - data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs); + data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs); return data; @@ -778,7 +773,7 @@ void CollectionModel::CreateSongItem(const Song &song, CollectionItem *parent) { } -void CollectionModel::SetSongItemData(CollectionItem *item, const Song &song) { +void CollectionModel::SetSongItemData(CollectionItem *item, const Song &song) const { item->display_text = song.TitleWithCompilationArtist(); item->sort_text = HasParentAlbumGroupBy(item->parent) ? SortTextForSong(song) : SortText(song.title()); @@ -879,7 +874,7 @@ void CollectionModel::ClearItemPixmapCache(CollectionItem *item) { // Remove from pixmap cache const QString cache_key = AlbumIconPixmapCacheKey(ItemToIndex(item)); QPixmapCache::remove(cache_key); - if (use_disk_cache_ && sIconCache) sIconCache->remove(AlbumIconPixmapDiskCacheKey(cache_key)); + if (use_disk_cache_ && icon_disk_cache_) icon_disk_cache_->remove(AlbumIconPixmapDiskCacheKey(cache_key)); if (pending_cache_keys_.contains(cache_key)) { pending_cache_keys_.remove(cache_key); } @@ -910,8 +905,8 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) { } // Try to load it from the disk cache - if (use_disk_cache_ && sIconCache) { - ScopedPtr disk_cache_img(sIconCache->data(AlbumIconPixmapDiskCacheKey(cache_key))); + if (use_disk_cache_ && icon_disk_cache_) { + ScopedPtr disk_cache_img(icon_disk_cache_->data(AlbumIconPixmapDiskCacheKey(cache_key))); if (disk_cache_img) { QImage cached_image; if (cached_image.load(&*disk_cache_img, "XPM")) { @@ -932,7 +927,7 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) { AlbumCoverLoaderOptions cover_loader_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage); cover_loader_options.desired_scaled_size = QSize(kPrettyCoverSize, kPrettyCoverSize); cover_loader_options.types = cover_types_; - const quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options, songs.first()); + const quint64 id = albumcover_loader_->LoadImageAsync(cover_loader_options, songs.first()); pending_art_[id] = ItemAndCacheKey(item, cache_key); pending_cache_keys_.insert(cache_key); } @@ -965,19 +960,19 @@ void CollectionModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderR } // If we have a valid cover not already in the disk cache - if (use_disk_cache_ && sIconCache && result.success && !result.image_scaled.isNull()) { + if (use_disk_cache_ && icon_disk_cache_ && result.success && !result.image_scaled.isNull()) { const QUrl disk_cache_key = AlbumIconPixmapDiskCacheKey(cache_key); - ScopedPtr disk_cache_img(sIconCache->data(disk_cache_key)); + ScopedPtr disk_cache_img(icon_disk_cache_->data(disk_cache_key)); if (!disk_cache_img) { QNetworkCacheMetaData disk_cache_metadata; disk_cache_metadata.setSaveToDisk(true); disk_cache_metadata.setUrl(disk_cache_key); // Qt 6 now ignores any entry without headers, so add a fake header. disk_cache_metadata.setRawHeaders(QNetworkCacheMetaData::RawHeaderList() << qMakePair(QByteArray("collection-thumbnail"), cache_key.toUtf8())); - QIODevice *device_iconcache = sIconCache->prepare(disk_cache_metadata); + QIODevice *device_iconcache = icon_disk_cache_->prepare(disk_cache_metadata); if (device_iconcache) { result.image_scaled.save(device_iconcache, "XPM"); - sIconCache->insert(device_iconcache); + icon_disk_cache_->insert(device_iconcache); } } } @@ -1450,7 +1445,7 @@ bool CollectionModel::HasParentAlbumGroupBy(CollectionItem *item) const { qint64 CollectionModel::MaximumCacheSize(Settings *s, const char *size_id, const char *size_unit_id, const qint64 cache_size_default) { qint64 size = s->value(size_id, cache_size_default).toInt(); - int unit = s->value(size_unit_id, static_cast(CollectionSettingsPage::CacheSizeUnit::MB)).toInt() + 1; + int unit = s->value(size_unit_id, static_cast(CollectionSettings::CacheSizeUnit::MB)).toInt() + 1; do { size *= 1024; @@ -1553,8 +1548,11 @@ void CollectionModel::TotalAlbumCountUpdatedSlot(const int count) { } -void CollectionModel::ClearDiskCache() { - if (sIconCache) sIconCache->clear(); +void CollectionModel::ClearIconDiskCache() { + + if (icon_disk_cache_) icon_disk_cache_->clear(); + QPixmapCache::clear(); + } void CollectionModel::RowsInserted(const QModelIndex &parent, const int first, const int last) { diff --git a/src/collection/collectionmodel.h b/src/collection/collectionmodel.h index d9bab5fc1e..cb95f6282f 100644 --- a/src/collection/collectionmodel.h +++ b/src/collection/collectionmodel.h @@ -44,10 +44,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/simpletreemodel.h" #include "core/song.h" -#include "core/sqlrow.h" #include "covermanager/albumcoverloaderoptions.h" #include "covermanager/albumcoverloaderresult.h" #include "collectionmodelupdate.h" @@ -57,16 +56,16 @@ class QTimer; class Settings; -class Application; class CollectionBackend; class CollectionDirectoryModel; class CollectionFilter; +class AlbumCoverLoader; class CollectionModel : public SimpleTreeModel { Q_OBJECT public: - explicit CollectionModel(SharedPtr backend, Application *app, QObject *parent = nullptr); + explicit CollectionModel(const SharedPtr backend, const SharedPtr albumcover_loader, QObject *parent = nullptr); ~CollectionModel() override; static const int kPrettyCoverSize; @@ -156,7 +155,7 @@ class CollectionModel : public SimpleTreeModel { int total_artist_count() const { return total_artist_count_; } int total_album_count() const { return total_album_count_; } - quint64 icon_cache_disk_size() { return sIconCache->cacheSize(); } + quint64 icon_disk_cache_size() { return icon_disk_cache_->cacheSize(); } const CollectionModel::Grouping GetGroupBy() const { return options_current_.group_by; } void SetGroupBy(const CollectionModel::Grouping g, const std::optional separate_albums_by_grouping = std::optional()); @@ -218,6 +217,8 @@ class CollectionModel : public SimpleTreeModel { void AddReAddOrUpdate(const SongList &songs); void RemoveSongs(const SongList &songs); + void ClearIconDiskCache(); + private: void Clear(); void BeginReset(); @@ -238,7 +239,7 @@ class CollectionModel : public SimpleTreeModel { void CreateDividerItem(const QString ÷r_key, const QString &display_text, CollectionItem *parent); CollectionItem *CreateContainerItem(const GroupBy group_by, const int container_level, const QString &container_key, const Song &song, CollectionItem *parent); void CreateSongItem(const Song &song, CollectionItem *parent); - void SetSongItemData(CollectionItem *item, const Song &song); + void SetSongItemData(CollectionItem *item, const Song &song) const; CollectionItem *CreateCompilationArtistNode(CollectionItem *parent); void LoadSongsFromSqlAsync(); @@ -267,15 +268,12 @@ class CollectionModel : public SimpleTreeModel { void TotalArtistCountUpdatedSlot(const int count); void TotalAlbumCountUpdatedSlot(const int count); - static void ClearDiskCache(); - void RowsInserted(const QModelIndex &parent, const int first, const int last); void RowsRemoved(const QModelIndex &parent, const int first, const int last); private: - static QNetworkDiskCache *sIconCache; - SharedPtr backend_; - Application *app_; + const SharedPtr backend_; + const SharedPtr albumcover_loader_; CollectionDirectoryModel *dir_model_; CollectionFilter *filter_; QTimer *timer_reload_; @@ -310,6 +308,8 @@ class CollectionModel : public SimpleTreeModel { using ItemAndCacheKey = QPair; QMap pending_art_; QSet pending_cache_keys_; + + QNetworkDiskCache *icon_disk_cache_; }; Q_DECLARE_METATYPE(CollectionModel::Grouping) diff --git a/src/collection/collectiontask.cpp b/src/collection/collectiontask.cpp index 78eee232f9..c7ca2c9b55 100644 --- a/src/collection/collectiontask.cpp +++ b/src/collection/collectiontask.cpp @@ -19,7 +19,7 @@ #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/taskmanager.h" #include "collectiontask.h" diff --git a/src/collection/collectiontask.h b/src/collection/collectiontask.h index c93e828d01..5a3dd223e7 100644 --- a/src/collection/collectiontask.h +++ b/src/collection/collectiontask.h @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" class TaskManager; diff --git a/src/collection/collectionview.cpp b/src/collection/collectionview.cpp index bff8db2f24..1a2705c274 100644 --- a/src/collection/collectionview.cpp +++ b/src/collection/collectionview.cpp @@ -50,38 +50,39 @@ #include #include -#include "core/application.h" #include "core/iconloader.h" -#include "core/mimedata.h" +#include "mimedata/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" # include "device/devicestatefiltermodel.h" #endif -#include "dialogs/edittagdialog.h" +#include "edittagdialog/edittagdialog.h" #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 task_manager, + const SharedPtr tagreader_client, + const SharedPtr network, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr lyrics_providers, + const SharedPtr collection, + const SharedPtr device_manager, + const SharedPtr streaming_services) { + + task_manager_ = task_manager; + tagreader_client_ = tagreader_client; + network_ = network; + albumcover_loader_ = albumcover_loader; + current_albumcover_loader_ = current_albumcover_loader; + cover_providers_ = cover_providers; + lyrics_providers_ = lyrics_providers; + collection_ = collection; + device_manager_ = device_manager; + streaming_services_ = streaming_services; + 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(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(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(model())->mapToSource(context_menu_index_); + context_menu_index_ = filter_->mapToSource(context_menu_index_); - const QModelIndexList selected_indexes = qobject_cast(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 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 albums_set = QSet(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(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(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(app_->task_manager(), app_->collection_backend(), this); + organize_dialog_ = make_unique(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(app_, this); + edit_tag_dialog_ = make_unique(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(app_->task_manager(), nullptr, this); + organize_dialog_ = make_unique(task_manager_, tagreader_client_, nullptr, this); } - organize_dialog_->SetDestinationModel(app_->device_manager()->connected_devices_model(), true); + organize_dialog_->SetDestinationModel(device_manager_->connected_devices_model(), true); organize_dialog_->SetCopy(true); organize_dialog_->SetSongs(GetSelectedSongs()); organize_dialog_->show(); @@ -812,9 +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 storage = app_->collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value>(); + SharedPtr storage = model_->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value>(); - DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, true); + DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, true); QObject::connect(delete_files, &DeleteFiles::Finished, this, &CollectionView::DeleteFilesFinished); delete_files->Start(songs); diff --git a/src/collection/collectionview.h b/src/collection/collectionview.h index 4959c00616..f970c55289 100644 --- a/src/collection/collectionview.h +++ b/src/collection/collectionview.h @@ -30,10 +30,12 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "widgets/autoexpandingtreeview.h" +class QSortFilterProxyModel; class QMenu; class QAction; class QContextMenuEvent; @@ -41,8 +43,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 task_manager, + const SharedPtr tagreader_client, + const SharedPtr network, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr lyrics_providers, + const SharedPtr collection, + const SharedPtr device_manager, + const SharedPtr 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 task_manager_; + SharedPtr tagreader_client_; + SharedPtr network_; + SharedPtr device_manager_; + SharedPtr albumcover_loader_; + SharedPtr current_albumcover_loader_; + SharedPtr collection_; + SharedPtr cover_providers_; + SharedPtr lyrics_providers_; + SharedPtr streaming_services_; + + SharedPtr backend_; + CollectionModel *model_; + CollectionFilter *filter_; + CollectionFilterWidget *filter_widget_; int total_song_count_; int total_artist_count_; diff --git a/src/collection/collectionviewcontainer.cpp b/src/collection/collectionviewcontainer.cpp index 53745f33ee..97e58e225d 100644 --- a/src/collection/collectionviewcontainer.cpp +++ b/src/collection/collectionviewcontainer.cpp @@ -26,12 +26,12 @@ #include "collectionfilterwidget.h" #include "collectionview.h" #include "collectionviewcontainer.h" -#include "ui_collectionviewcontainer.h" +#include "collection/ui_collectionviewcontainer.h" 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); diff --git a/src/collection/collectionwatcher.cpp b/src/collection/collectionwatcher.cpp index 0672b8b89e..db2bec81f2 100644 --- a/src/collection/collectionwatcher.cpp +++ b/src/collection/collectionwatcher.cpp @@ -50,13 +50,13 @@ #include "core/taskmanager.h" #include "core/settings.h" #include "utilities/imageutils.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "tagreader/tagreaderclient.h" #include "collectiondirectory.h" #include "collectionbackend.h" #include "collectionwatcher.h" #include "playlistparsers/cueparser.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" #include "engine/ebur128measures.h" #ifdef HAVE_SONGFINGERPRINTING # include "engine/chromaprinter.h" @@ -75,11 +75,16 @@ using namespace Qt::Literals::StringLiterals; QStringList CollectionWatcher::sValidImages = QStringList() << u"jpg"_s << u"png"_s << u"gif"_s << u"jpeg"_s; -CollectionWatcher::CollectionWatcher(const Song::Source source, QObject *parent) +CollectionWatcher::CollectionWatcher(const Song::Source source, + const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr backend, + QObject *parent) : QObject(parent), source_(source), - backend_(nullptr), - task_manager_(nullptr), + task_manager_(task_manager), + tagreader_client_(tagreader_client), + backend_(backend), fs_watcher_(FileSystemWatcherInterface::Create(this)), original_thread_(nullptr), scan_on_startup_(true), @@ -96,7 +101,7 @@ CollectionWatcher::CollectionWatcher(const Song::Source source, QObject *parent) periodic_scan_timer_(new QTimer(this)), rescan_paused_(false), total_watches_(0), - cue_parser_(new CueParser(backend_, this)), + cue_parser_(new CueParser(tagreader_client, backend, this)), last_scan_time_(0) { setObjectName(source_ == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(source_), QLatin1String(metaObject()->className()))); @@ -196,29 +201,29 @@ void CollectionWatcher::ReloadSettings() { const bool was_monitoring_before = monitor_; Settings s; - s.beginGroup(CollectionSettingsPage::kSettingsGroup); + s.beginGroup(CollectionSettings::kSettingsGroup); if (source_ == Song::Source::Collection) { - scan_on_startup_ = s.value("startup_scan", true).toBool(); - monitor_ = s.value("monitor", true).toBool(); + scan_on_startup_ = s.value(CollectionSettings::kStartupScan, true).toBool(); + monitor_ = s.value(CollectionSettings::kMonitor, true).toBool(); } else { scan_on_startup_ = true; monitor_ = true; } - const QStringList filters = s.value("cover_art_patterns", QStringList() << u"front"_s << u"cover"_s).toStringList(); + const QStringList filters = s.value(CollectionSettings::kCoverArtPatterns, QStringList() << u"front"_s << u"cover"_s).toStringList(); if (source_ == Song::Source::Collection) { - song_tracking_ = s.value("song_tracking", false).toBool(); - song_ebur128_loudness_analysis_ = s.value("song_ebur128_loudness_analysis", false).toBool(); - mark_songs_unavailable_ = song_tracking_ ? true : s.value("mark_songs_unavailable", true).toBool(); + song_tracking_ = s.value(CollectionSettings::kSongTracking, false).toBool(); + song_ebur128_loudness_analysis_ = s.value(CollectionSettings::kSongENUR128LoudnessAnalysis, false).toBool(); + mark_songs_unavailable_ = song_tracking_ ? true : s.value(CollectionSettings::kMarkSongsUnavailable, true).toBool(); } else { song_tracking_ = false; song_ebur128_loudness_analysis_ = false; mark_songs_unavailable_ = false; } - expire_unavailable_songs_days_ = s.value("expire_unavailable_songs", 60).toInt(); - overwrite_playcount_ = s.value("overwrite_playcount", false).toBool(); - overwrite_rating_ = s.value("overwrite_rating", false).toBool(); + expire_unavailable_songs_days_ = s.value(CollectionSettings::kExpireUnavailableSongs, 60).toInt(); + overwrite_playcount_ = s.value(CollectionSettings::kOverwritePlaycount, false).toBool(); + overwrite_rating_ = s.value(CollectionSettings::kOverwriteRating, false).toBool(); s.endGroup(); best_art_filters_.clear(); @@ -575,7 +580,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu album_art[dir_part] << child; t->AddToProgress(1); } - else if (TagReaderClient::Instance()->IsMediaFileBlocking(child)) { + else if (tagreader_client_->IsMediaFileBlocking(child)) { files_on_disk << child; } else { @@ -874,7 +879,7 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, } Song song_on_disk(source_); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(file, &song_on_disk); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(file, &song_on_disk); if (result.success() && song_on_disk.is_valid()) { song_on_disk.set_source(source_); song_on_disk.set_directory_id(t->dir()); @@ -927,7 +932,7 @@ SongList CollectionWatcher::ScanNewFile(const QString &file, const QString &path } else { // It's a normal media file Song song(source_); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(file, &song); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(file, &song); if (result.success() && song.is_valid()) { song.set_source(source_); PerformEBUR128Analysis(song); diff --git a/src/collection/collectionwatcher.h b/src/collection/collectionwatcher.h index e6a1cdfba3..7c025aeaa1 100644 --- a/src/collection/collectionwatcher.h +++ b/src/collection/collectionwatcher.h @@ -36,28 +36,32 @@ #include #include "collectiondirectory.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QThread; class QTimer; +class TaskManager; +class TagReaderClient; class CollectionBackend; class FileSystemWatcherInterface; -class TaskManager; class CueParser; class CollectionWatcher : public QObject { Q_OBJECT public: - explicit CollectionWatcher(const Song::Source source, QObject *parent = nullptr); + explicit CollectionWatcher(const Song::Source source, + const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr backend, + QObject *parent = nullptr); + ~CollectionWatcher(); - Song::Source source() { return source_; } + Song::Source source() const { return source_; } - void set_backend(SharedPtr backend) { backend_ = backend; } - void set_task_manager(SharedPtr 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 backend_; - SharedPtr task_manager_; + const Song::Source source_; + + const SharedPtr task_manager_; + const SharedPtr tagreader_client_; + const SharedPtr backend_; + QString device_name_; FileSystemWatcherInterface *fs_watcher_; diff --git a/src/collection/groupbydialog.h b/src/collection/groupbydialog.h index 1f5987885c..cc1b97de86 100644 --- a/src/collection/groupbydialog.h +++ b/src/collection/groupbydialog.h @@ -28,13 +28,13 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" #include "collectionmodel.h" -#include "ui_groupbydialog.h" class QWidget; class GroupByDialogPrivate; +class Ui_GroupByDialog; class GroupByDialog : public QDialog { Q_OBJECT diff --git a/src/collection/savedgroupingmanager.cpp b/src/collection/savedgroupingmanager.cpp index ddb3bb6daa..e1449c5aa9 100644 --- a/src/collection/savedgroupingmanager.cpp +++ b/src/collection/savedgroupingmanager.cpp @@ -39,7 +39,7 @@ #include "core/logging.h" #include "core/iconloader.h" #include "core/settings.h" -#include "settings/collectionsettingspage.h" +#include "constants/collectionsettings.h" #include "collectionmodel.h" #include "savedgroupingmanager.h" #include "ui_savedgroupingmanager.h" @@ -77,7 +77,7 @@ SavedGroupingManager::~SavedGroupingManager() { QString SavedGroupingManager::GetSavedGroupingsSettingsGroup(const QString &settings_group) { - if (settings_group.isEmpty() || settings_group == QLatin1String(CollectionSettingsPage::kSettingsGroup)) { + if (settings_group.isEmpty() || settings_group == QLatin1String(CollectionSettings::kSettingsGroup)) { return QLatin1String(kSavedGroupingsSettingsGroup); } diff --git a/src/constants/appearancesettings.h b/src/constants/appearancesettings.h new file mode 100644 index 0000000000..4efaf809d0 --- /dev/null +++ b/src/constants/appearancesettings.h @@ -0,0 +1,75 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef APPEARANCESETTINGS_H +#define APPEARANCESETTINGS_H + +namespace AppearanceSettings { + +constexpr char kSettingsGroup[] = "Appearance"; + +constexpr char kStyle[] = "style"; +constexpr char kSystemThemeIcons[] = "system_icons"; + +constexpr char kBackgroundImageType[] = "background_image_type"; +constexpr char kBackgroundImageFilename[] = "background_image_file"; +constexpr char kBackgroundImagePosition[] = "background_image_position"; +constexpr char kBackgroundImageStretch[] = "background_image_stretch"; +constexpr char kBackgroundImageDoNotCut[] = "background_image_do_not_cut"; +constexpr char kBackgroundImageKeepAspectRatio[] = "background_image_keep_aspect_ratio"; +constexpr char kBackgroundImageMaxSize[] = "background_image_max_size"; + +constexpr char kBlurRadius[] = "blur_radius"; +constexpr char kOpacityLevel[] = "opacity_level"; + +constexpr int kDefaultBlurRadius = 0; +constexpr int kDefaultOpacityLevel = 40; + +constexpr char kTabBarSystemColor[] = "tab_system_color"; +constexpr char kTabBarGradient[] = "tab_gradient"; +constexpr char kTabBarColor[] = "tab_color"; + +constexpr char kIconSizeTabbarSmallMode[] = "icon_size_tabbar_small_mode"; +constexpr char kIconSizeTabbarLargeMode[] = "icon_size_tabbar_large_mode"; +constexpr char kIconSizePlayControlButtons[] = "icon_size_play_control_buttons"; +constexpr char kIconSizePlaylistButtons[] = "icon_size_playlist_buttons"; +constexpr char kIconSizeLeftPanelButtons[] = "icon_size_left_panel_buttons"; +constexpr char kIconSizeConfigureButtons[] = "icon_size_configure_buttons"; + +constexpr char kPlaylistPlayingSongColor[] = "playlist_playing_song_color"; + +enum class BackgroundImageType { + Default, + None, + Custom, + Album, + Strawbs +}; + +enum class BackgroundImagePosition { + UpperLeft = 1, + UpperRight = 2, + Middle = 3, + BottomLeft = 4, + BottomRight = 5 +}; + +} // namespace + +#endif // APPEARANCESETTINGS_H diff --git a/src/constants/backendsettings.h b/src/constants/backendsettings.h new file mode 100644 index 0000000000..37734e8148 --- /dev/null +++ b/src/constants/backendsettings.h @@ -0,0 +1,64 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef BACKENDSETTINGS_H +#define BACKENDSETTINGS_H + +#include + +namespace BackendSettings { + +constexpr char kSettingsGroup[] = "Backend"; + +constexpr char kEngine[] = "Engine"; +constexpr char kOutput[] = "Output"; +constexpr char kDevice[] = "Device"; +constexpr char kALSAPlugin[] = "alsaplugin"; +constexpr char kExclusiveMode[] = "exclusive_mode"; +constexpr char kVolumeControl[] = "volume_control"; +constexpr char kChannelsEnabled[] = "channels_enabled"; +constexpr char kChannels[] = "channels"; +constexpr char kBS2B[] = "bs2b"; +constexpr char kHTTP2[] = "http2"; +constexpr char kStrictSSL[] = "strict_ssl"; +constexpr char kBufferDuration[] = "bufferduration"; +constexpr char kBufferLowWatermark[] = "bufferlowwatermark"; +constexpr char kBufferHighWatermark[] = "bufferhighwatermark"; +constexpr char kRgEnabled[] = "rgenabled"; +constexpr char kRgMode[] = "rgmode"; +constexpr char kRgPreamp[] = "rgpreamp"; +constexpr char kRgFallbackGain[] = "rgfallbackgain"; +constexpr char kRgCompression[] = "rgcompression"; +constexpr char kEBUR128LoudnessNormalization[] = "ebur128_loudness_normalization"; +constexpr char kEBUR128TargetLevelLUFS[] = "ebur128_target_level_lufs"; +constexpr char kFadeoutEnabled[] = "FadeoutEnabled"; +constexpr char kCrossfadeEnabled[] = "CrossfadeEnabled"; +constexpr char kAutoCrossfadeEnabled[] = "AutoCrossfadeEnabled"; +constexpr char kNoCrossfadeSameAlbum[] = "NoCrossfadeSameAlbum"; +constexpr char kFadeoutPauseEnabled[] = "FadeoutPauseEnabled"; +constexpr char kFadeoutDuration[] = "FadeoutDuration"; +constexpr char kFadeoutPauseDuration[] = "FadeoutPauseDuration"; + +constexpr qint64 kDefaultBufferDuration = 4000; +constexpr double kDefaultBufferLowWatermark = 0.33; +constexpr double kDefaultBufferHighWatermark = 0.99; + +} // namespace + +#endif // BACKENDSETTINGS_H diff --git a/src/constants/behavioursettings.h b/src/constants/behavioursettings.h new file mode 100644 index 0000000000..14dd80a070 --- /dev/null +++ b/src/constants/behavioursettings.h @@ -0,0 +1,76 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef BEHAVIOURSETTINGS_H +#define BEHAVIOURSETTINGS_H + +namespace BehaviourSettings { + +constexpr char kSettingsGroup[] = "Behaviour"; + +enum class StartupBehaviour { + Remember = 1, + Show = 2, + Hide = 3, + ShowMaximized = 4, + ShowMinimized = 5 +}; + +enum class PlayBehaviour { + Never = 1, + IfStopped = 2, + Always = 3 +}; + +enum class PreviousBehaviour { + DontRestart = 1, + Restart = 2 +}; + +enum class AddBehaviour { + Append = 1, + Enqueue = 2, + Load = 3, + OpenInNew = 4 +}; + +enum class PlaylistAddBehaviour { + Play = 1, + Enqueue = 2 +}; + +constexpr char kKeepRunning[] = "keeprunning"; +constexpr char kShowTrayIcon[] = "showtrayicon"; +constexpr char kTrayIconProgress[] = "trayicon_progress"; +constexpr char kTaskbarProgress[] = "taskbar_progress"; +constexpr char kResumePlayback[] = "resumeplayback"; +constexpr char kPlayingWidget[] = "playing_widget"; +constexpr char kStartupBehaviour[] = "startupbehaviour"; +constexpr char kLanguage[] = "language"; +constexpr char kMenuPlayMode[] = "menu_playmode"; +constexpr char kMenuPreviousMode[] = "menu_previousmode"; +constexpr char kDoubleClickAddMode[] = "doubleclick_addmode"; +constexpr char kDoubleClickPlayMode[] = "doubleclick_playmode"; +constexpr char kDoubleClickPlaylistAddMode[] = "doubleclick_playlist_addmode"; +constexpr char kSeekStepSec[] = "seek_step_sec"; +constexpr char kVolumeIncrement[] = "volume_increment"; + +} // namespace + +#endif // BEHAVIOURSETTINGS_H diff --git a/src/constants/collectionsettings.h b/src/constants/collectionsettings.h new file mode 100644 index 0000000000..94f89c7e33 --- /dev/null +++ b/src/constants/collectionsettings.h @@ -0,0 +1,62 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef COLLECTIONSETTINGS_H +#define COLLECTIONSETTINGS_H + +namespace CollectionSettings { + +constexpr char kSettingsGroup[] = "Collection"; + +constexpr char kAutoOpen[] = "auto_open"; +constexpr char kShowDividers[] = "show_dividers"; +constexpr char kPrettyCovers[] = "pretty_covers"; +constexpr char kVariousArtists[] = "various_artists"; +constexpr char kSortSkipsArticles[] = "sort_skips_articles"; +constexpr char kStartupScan[] = "startup_scan"; +constexpr char kMonitor[] = "monitor"; +constexpr char kSongTracking[] = "song_tracking"; +constexpr char kSongENUR128LoudnessAnalysis[] = "song_ebur128_loudness_analysis"; +constexpr char kMarkSongsUnavailable[] = "mark_songs_unavailable"; +constexpr char kExpireUnavailableSongs[] = "expire_unavailable_songs"; +constexpr char kCoverArtPatterns[] = "cover_art_patterns"; +constexpr char kSettingsCacheSize[] = "cache_size"; +constexpr char kSettingsCacheSizeUnit[] = "cache_size_unit"; +constexpr char kSettingsDiskCacheEnable[] = "disk_cache_enable"; +constexpr char kSettingsDiskCacheSize[] = "disk_cache_size"; +constexpr char kSettingsDiskCacheSizeUnit[] = "disk_cache_size_unit"; +constexpr int kSettingsCacheSizeDefault = 160; +constexpr int kSettingsDiskCacheSizeDefault = 360; +constexpr char kSavePlayCounts[] = "save_playcounts"; +constexpr char kSaveRatings[] = "save_ratings"; +constexpr char kOverwritePlaycount[] = "overwrite_playcount"; +constexpr char kOverwriteRating[] = "overwrite_rating"; +constexpr char kDeleteFiles[] = "delete_files"; +constexpr char kLastPath[] = "last_path"; + +enum class CacheSizeUnit { + KB, + MB, + GB, + TB +}; + +} // namespace + +#endif // COLLECTIONSETTINGS_H diff --git a/src/constants/contextsettings.h b/src/constants/contextsettings.h new file mode 100644 index 0000000000..74d894c432 --- /dev/null +++ b/src/constants/contextsettings.h @@ -0,0 +1,48 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef CONTEXTSETTINGS_H +#define CONTEXTSETTINGS_H + +#include + +namespace ContextSettings { + +constexpr char kSettingsGroup[] = "Context"; + +constexpr char kAlbum[] = "AlbumEnable"; +constexpr char kTechnicalData[] = "TechnicalDataEnable"; +constexpr char kSongLyrics[] = "SongLyricsEnable"; +constexpr char kSearchCover[] = "SearchCoverEnable"; +constexpr char kSearchLyrics[] = "SearchLyricsEnable"; + +constexpr char kFontHeadline[] = "font_headline"; +constexpr char kFontNormal[] = "font_normal"; +constexpr char kFontSizeHeadline[] = "font_size_headline"; +constexpr char kFontSizeNormal[] = "font_size_normal"; + +constexpr char kSettingsTitleFmt[] = "TitleFmt"; +constexpr char kSettingsSummaryFmt[] = "SummaryFmt"; + +constexpr char kDefaultFontFamily[] = "Noto Sans"; +constexpr qreal kDefaultFontSizeHeadline = 11; + +} // namespace + +#endif // CONTEXTSETTINGS_H diff --git a/src/constants/coverssettings.h b/src/constants/coverssettings.h new file mode 100644 index 0000000000..2cef4f872d --- /dev/null +++ b/src/constants/coverssettings.h @@ -0,0 +1,37 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef COVERSSETTINGS_H +#define COVERSSETTINGS_H + +namespace CoversSettings { + +constexpr char kSettingsGroup[] = "Covers"; +constexpr char kProviders[] = "providers"; +constexpr char kTypes[] = "types"; +constexpr char kSaveType[] = "save_type"; +constexpr char kSaveFilename[] = "save_filename"; +constexpr char kSavePattern[] = "save_pattern"; +constexpr char kSaveOverwrite[] = "save_overwrite"; +constexpr char kSaveLowercase[] = "save_lowercase"; +constexpr char kSaveReplaceSpaces[] = "save_replace_spaces"; + +} // namespace + +#endif // COVERSSETTINGS_H diff --git a/src/constants/filefilterconstants.h b/src/constants/filefilterconstants.h new file mode 100644 index 0000000000..09ff7c30ad --- /dev/null +++ b/src/constants/filefilterconstants.h @@ -0,0 +1,39 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef FILEFILTERCONSTANTS_H +#define FILEFILTERCONSTANTS_H + +#include + +constexpr char kAllFilesFilterSpec[] = QT_TRANSLATE_NOOP("FileFilter", "All Files (*)"); + +constexpr char kFileFilter[] = + "*.wav *.flac *.wv *.ogg *.oga *.opus *.spx *.ape *.mpc " + "*.mp2 *.mp3 *.m4a *.mp4 *.aac *.asf *.asx *.wma " + "*.aif *.aiff *.mka *.tta *.dsf *.dsd " + "*.cue *.m3u *.m3u8 *.pls *.xspf *.asxini " + "*.ac3 *.dts " + "*.mod *.s3m *.xm *.it" + "*.spc *.vgm"; + +constexpr char kLoadImageFileFilter[] = QT_TRANSLATE_NOOP("FileFilter", "Images (*.png *.jpg *.jpeg *.bmp *.gif *.xpm *.pbm *.pgm *.ppm *.xbm)"); +constexpr char kSaveImageFileFilter[] = QT_TRANSLATE_NOOP("FileFilter", "Images (*.png *.jpg *.jpeg *.bmp *.xpm *.pbm *.ppm *.xbm)"); + +#endif // FILEFILTERCONSTANTS_H diff --git a/src/utilities/filenameconstants.h b/src/constants/filenameconstants.h similarity index 97% rename from src/utilities/filenameconstants.h rename to src/constants/filenameconstants.h index e442bcad48..61cb727ede 100644 --- a/src/utilities/filenameconstants.h +++ b/src/constants/filenameconstants.h @@ -20,7 +20,7 @@ #ifndef FILENAMECONSTANTS_H #define FILENAMECONSTANTS_H -#include "core/arraysize.h" +#include "includes/arraysize.h" constexpr char kProblematicCharactersRegex[] = "[:?*\"<>|]"; constexpr char kInvalidFatCharactersRegex[] = "[^a-zA-Z0-9!#\\$%&'()\\-@\\^_`{}~/. ]"; diff --git a/src/constants/globalshortcutssettings.h b/src/constants/globalshortcutssettings.h new file mode 100644 index 0000000000..143736d7f8 --- /dev/null +++ b/src/constants/globalshortcutssettings.h @@ -0,0 +1,33 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef GLOBALSHORTCUTSSETTINGS_H +#define GLOBALSHORTCUTSSETTINGS_H + +namespace GlobalShortcutsSettings { + +constexpr char kSettingsGroup[] = "GlobalShortcuts"; +constexpr char kUseKDE[] = "use_kde"; +constexpr char kUseGnome[] = "use_gnome"; +constexpr char kUseMate[] = "use_mate"; +constexpr char kUseX11[] = "use_x11"; + +} // namespace + +#endif // GLOBALSHORTCUTSSETTINGS_H diff --git a/src/constants/lyricssettings.h b/src/constants/lyricssettings.h new file mode 100644 index 0000000000..d539601b6c --- /dev/null +++ b/src/constants/lyricssettings.h @@ -0,0 +1,30 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef LYRICSSETTINGS_H +#define LYRICSSETTINGS_H + +namespace LyricsSettings { + +constexpr char kSettingsGroup[] = "Lyrics"; +constexpr char kProviders[] = "providers"; + +} // namespace + +#endif // LYRICSSETTINGS_H diff --git a/src/constants/mainwindowsettings.h b/src/constants/mainwindowsettings.h new file mode 100644 index 0000000000..bf83af4af2 --- /dev/null +++ b/src/constants/mainwindowsettings.h @@ -0,0 +1,37 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef MAINWINDOWSETTINGS_H +#define MAINWINDOWSETTINGS_H + +namespace MainWindowSettings { + +constexpr char kSettingsGroup[] = "MainWindow"; +constexpr char kSearchForCoverAuto[] = "search_for_cover_auto"; +constexpr char kShowSidebar[] = "show_sidebar"; +constexpr char kMaximized[] = "maximized"; +constexpr char kMinimized[] = "minimized"; +constexpr char kHidden[] = "hidden"; +constexpr char kGeometry[] = "geometry"; +constexpr char kSplitterState[] = "splitter_state"; +constexpr char kDoNotShowSponsorMessage[] = "do_not_show_sponsor_message"; + +} // namespace + +#endif // MAINWINDOWSETTINGS_H diff --git a/src/constants/moodbarsettings.h b/src/constants/moodbarsettings.h new file mode 100644 index 0000000000..9a7bd529d1 --- /dev/null +++ b/src/constants/moodbarsettings.h @@ -0,0 +1,43 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef MOODBARSETTINGS_H +#define MOODBARSETTINGS_H + +namespace MoodbarSettings { + +constexpr char kSettingsGroup[] = "Moodbar"; + +enum class Style { + Normal = 0, + Angry, + Frozen, + Happy, + SystemPalette, + StyleCount +}; + +constexpr char kEnabled[] = "enabled"; +constexpr char kShow[] = "show"; +constexpr char kStyle[] = "style"; +constexpr char kSave[] = "save"; + +} // namespace + +#endif // MOODBARSETTINGS_H diff --git a/src/constants/networkproxysettings.h b/src/constants/networkproxysettings.h new file mode 100644 index 0000000000..fe45e40fb4 --- /dev/null +++ b/src/constants/networkproxysettings.h @@ -0,0 +1,37 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef NETWORKPROXYSETTINGS_H +#define NETWORKPROXYSETTINGS_H + +namespace NetworkProxySettings { + +constexpr char kSettingsGroup[] = "NetworkProxy"; + +constexpr char kType[] = "type"; +constexpr char kHostname[] = "hostname"; +constexpr char kPort[] = "port"; +constexpr char kUseAuthentication[] = "use_authentication"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kEngine[] = "engine"; + +} // namespace + +#endif // NETWORKPROXYSETTINGS_H diff --git a/src/constants/notificationssettings.h b/src/constants/notificationssettings.h new file mode 100644 index 0000000000..cd4e958883 --- /dev/null +++ b/src/constants/notificationssettings.h @@ -0,0 +1,68 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef NOTIFICATIONSSETTINGS_H +#define NOTIFICATIONSSETTINGS_H + +#include + +namespace OSDSettings { + +constexpr char kSettingsGroup[] = "OSD"; + +constexpr char kType[] = "Behaviour"; + +enum class Type { + Disabled = 0, + Native, + TrayPopup, + Pretty +}; + +constexpr char kTimeout[] = "Timeout"; +constexpr char kShowOnVolumeChange[] = "ShowOnVolumeChange"; +constexpr char kShowOnPlayModeChange[] = "ShowOnPlayModeChange"; +constexpr char kShowOnPausePlayback[] = "ShowOnPausePlayback"; +constexpr char kShowOnResumePlayback[] = "ShowOnResumePlayback"; +constexpr char kShowArt[] = "ShowArt"; +constexpr char kCustomTextEnabled[] = "CustomTextEnabled"; +constexpr char kCustomText1[] = "CustomText1"; +constexpr char kCustomText2[] = "CustomText2"; + +} // namespace + +namespace OSDPrettySettings { + +constexpr char kSettingsGroup[] = "OSDPretty"; + +constexpr char kForegroundColor[] = "foreground_color"; +constexpr char kBackgroundColor[] = "background_color"; +constexpr char kBackgroundOpacity[] = "background_opacity"; +constexpr char kPopupScreen[] = "popup_screen"; +constexpr char kPopupPos[] = "popup_pos"; +constexpr char kFont[] = "font"; +constexpr char kDisableDuration[] = "disable_duration"; +constexpr char kFading[] = "fading"; + +constexpr QRgb kPresetBlue = qRgb(102, 150, 227); +constexpr QRgb kPresetRed = qRgb(202, 22, 16); + +} // namespace + +#endif // NOTIFICATIONSSETTINGS_H diff --git a/src/constants/playlistsettings.h b/src/constants/playlistsettings.h new file mode 100644 index 0000000000..7c43ec87cf --- /dev/null +++ b/src/constants/playlistsettings.h @@ -0,0 +1,70 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef PLAYLISTSETTINGS_H +#define PLAYLISTSETTINGS_H + +#include + +namespace PlaylistSettings { + +constexpr char kSettingsGroup[] = "Playlist"; + +enum class PathType { + Automatic = 0, // Automatically select path type + Absolute, // Always use absolute paths + Relative, // Always use relative paths + Ask_User // Only used in preferences: to ask user which of the previous values he wants to use. +}; + +constexpr char kAlternatingRowColors[] = "alternating_row_colors"; +constexpr char kShowBars[] = "show_bars"; +constexpr char kGlowEffect[] = "glow_effect"; +constexpr char kWarnClosePlaylist[] = "warn_close_playlist"; +constexpr char kContinueOnError[] = "continue_on_error"; +constexpr char kGreyoutSongsStartup[] = "greyout_songs_startup"; +constexpr char kGreyoutSongsPlay[] = "greyout_songs_play"; +constexpr char kSelectTrack[] = "select_track"; +constexpr char kShowToolbar[] = "show_toolbar"; +constexpr char kPlaylistClear[] = "playlist_clear"; +constexpr char kAutoSort[] = "auto_sort"; + +constexpr char kPathType[] = "path_type"; + +constexpr char kEditMetadataInline[] = "editmetadatainline"; +constexpr char kWriteMetadata[] = "write_metadata"; +constexpr char kDeleteFiles[] = "delete_files"; + +constexpr char kStateVersion[] = "state_version"; +constexpr char kState[] = "state"; +constexpr char kColumnAlignments[] = "column_alignments"; +constexpr char kRatingLocked[] = "rating_locked"; + +constexpr char kLastSaveFilter[] = "last_save_filter"; +constexpr char kLastSavePath[] = "last_save_path"; +constexpr char kLastSaveExtension[] = "last_save_extension"; + +constexpr char kLastSaveAllPath[] = "last_save_all_path"; +constexpr char kLastSaveAllExtension[] = "last_save_all_extension"; + +} // namespace + +Q_DECLARE_METATYPE(PlaylistSettings::PathType) + +#endif // PLAYLISTSETTINGS_H diff --git a/src/constants/qobuzsettings.h b/src/constants/qobuzsettings.h new file mode 100644 index 0000000000..f4f52b82b8 --- /dev/null +++ b/src/constants/qobuzsettings.h @@ -0,0 +1,47 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef QOBUZSETTINGS_H +#define QOBUZSETTINGS_H + +namespace QobuzSettings { + +constexpr char kSettingsGroup[] = "Qobuz"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kAppId[] = "app_id"; +constexpr char kAppSecret[] = "app_secret"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kFormat[] = "format"; +constexpr char kSearchDelay[] = "searchdelay"; +constexpr char kArtistsSearchLimit[] = "artistssearchlimit"; +constexpr char kAlbumsSearchLimit[] = "albumssearchlimit"; +constexpr char kSongsSearchLimit[] = "songssearchlimit"; +constexpr char kBase64Secret[] = "base64secret"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; + +constexpr char kUserId[] = "user_id"; +constexpr char kCredentialsId[] = "credentials_id"; +constexpr char kDeviceId[] = "device_id"; +constexpr char kUserAuthToken[] = "user_auth_token"; + +} // namespace + +#endif // QOBUZSETTINGS_H diff --git a/src/constants/scrobblersettings.h b/src/constants/scrobblersettings.h new file mode 100644 index 0000000000..5f1719eb7d --- /dev/null +++ b/src/constants/scrobblersettings.h @@ -0,0 +1,40 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef SCROBBLERSETTINGS_H +#define SCROBBLERSETTINGS_H + +namespace ScrobblerSettings { + +constexpr char kSettingsGroup[] = "Scrobbler"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kScrobbleButton[] = "scrobble_button"; +constexpr char kLoveButton[] = "love_button"; +constexpr char kOffline[] = "offline"; +constexpr char kSubmit[] = "submit"; +constexpr char kAlbumArtist[] = "albumartist"; +constexpr char kShowErrorDialog[] = "show_error_dialog"; +constexpr char kStripRemastered[] = "strip_remastered"; +constexpr char kSources[] = "sources"; +constexpr char kUserToken[] = "user_token"; + +} // namespace + +#endif // SCROBBLERSETTINGS_H diff --git a/src/constants/spotifysettings.h b/src/constants/spotifysettings.h new file mode 100644 index 0000000000..7d1090ac8a --- /dev/null +++ b/src/constants/spotifysettings.h @@ -0,0 +1,42 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef SPOTIFYSETTINGS_H +#define SPOTIFYSETTINGS_H + +namespace SpotifySettings { + +constexpr char kSettingsGroup[] = "Spotify"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kSearchDelay[] = "searchdelay"; +constexpr char kArtistsSearchLimit[] = "artistssearchlimit"; +constexpr char kAlbumsSearchLimit[] = "albumssearchlimit"; +constexpr char kSongsSearchLimit[] = "songssearchlimit"; +constexpr char kFetchAlbums[] = "fetchalbums"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; + +constexpr char kAccessToken[] = "access_token"; +constexpr char kRefreshToken[] = "refresh_token"; +constexpr char kExpiresIn[] = "expires_in"; +constexpr char kLoginTime[] = "login_time"; + +} // namespace + +#endif // SPOTIFYSETTINGS_H diff --git a/src/constants/subsonicsettings.h b/src/constants/subsonicsettings.h new file mode 100644 index 0000000000..f3841549cb --- /dev/null +++ b/src/constants/subsonicsettings.h @@ -0,0 +1,45 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + + +#ifndef SUBSONICETTINGS_H +#define SUBSONICETTINGS_H + +namespace SubsonicSettings { + +constexpr char kSettingsGroup[] = "Subsonic"; + +enum class AuthMethod { + Hex, + MD5 +}; + +constexpr char kEnabled[] = "enabled"; +constexpr char kUrl[] = "url"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kHTTP2[] = "http2"; +constexpr char kVerifyCertificate[] = "verifycertificate"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; +constexpr char kServerSideScrobbling[] = "serversidescrobbling"; +constexpr char kAuthMethod[] = "authmethod"; + +} // namespace + +#endif // SUBSONICETTINGS_H diff --git a/src/constants/tidalsettings.h b/src/constants/tidalsettings.h new file mode 100644 index 0000000000..c7c83f0b87 --- /dev/null +++ b/src/constants/tidalsettings.h @@ -0,0 +1,52 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef TIDALSETTINGS_H +#define TIDALSETTINGS_H + +namespace TidalSettings { + +constexpr char kSettingsGroup[] = "Tidal"; + +constexpr char kEnabled[] = "enabled"; +constexpr char kOAuth[] = "oauth"; +constexpr char kClientId[] = "client_id"; +constexpr char kApiToken[] = "api_token"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; +constexpr char kQuality[] = "quality"; +constexpr char kSearchDelay[] = "searchdelay"; +constexpr char kArtistsSearchLimit[] = "artistssearchlimit"; +constexpr char kAlbumsSearchLimit[] = "albumssearchlimit"; +constexpr char kSongsSearchLimit[] = "songssearchlimit"; +constexpr char kFetchAlbums[] = "fetchalbums"; +constexpr char kDownloadAlbumCovers[] = "downloadalbumcovers"; +constexpr char kCoverSize[] = "coversize"; +constexpr char kStreamUrl[] = "streamurl"; +constexpr char kAlbumExplicit[] = "album_explicit"; + +enum class StreamUrlMethod { + StreamUrl, + UrlPostPaywall, + PlaybackInfoPostPaywall +}; + +} + +#endif // TIDALSETTINGS_H diff --git a/src/constants/timeconstants.h b/src/constants/timeconstants.h new file mode 100644 index 0000000000..a2e4b012f8 --- /dev/null +++ b/src/constants/timeconstants.h @@ -0,0 +1,34 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it wiLL be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef TIMECONSTANTS_H +#define TIMECONSTANTS_H + +#include + +constexpr qint64 kMsecPerSec = 1000LL; +constexpr qint64 kUsecPerMsec = 1000LL; +constexpr qint64 kUsecPerSec = 1000000LL; +constexpr qint64 kNsecPerUsec = 1000LL; +constexpr qint64 kNsecPerMsec = 1000000LL; +constexpr qint64 kNsecPerSec = 1000000000LL; + +constexpr qint64 kSecsPerDay = 24 * 60 * 60; + +#endif // TIMECONSTANTS_H diff --git a/src/constants/transcodersettings.h b/src/constants/transcodersettings.h new file mode 100644 index 0000000000..3319984e86 --- /dev/null +++ b/src/constants/transcodersettings.h @@ -0,0 +1,29 @@ +/* +* Strawberry Music Player +* Copyright 2024, Jonas Kvinge +* +* Strawberry is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it wiLL be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + + +#ifndef TRANSCODERSETTINGS_H +#define TRANSCODERSETTINGS_H + +namespace TranscoderSettings { +constexpr char kSettingsGroup[] = "Transcoder"; +} + +#endif // TRANSCODERSETTINGS_H + diff --git a/src/context/CMakeLists.txt b/src/context/CMakeLists.txt new file mode 100644 index 0000000000..a7c761590a --- /dev/null +++ b/src/context/CMakeLists.txt @@ -0,0 +1,32 @@ +set(CONTEXT_SOURCES + contextview.cpp + contextalbum.cpp +) + +set(CONTEXT_HEADERS + contextview.h + contextalbum.h +) + +qt_wrap_cpp(CONTEXT_SOURCES ${CONTEXT_HEADERS}) + +add_library(strawberry_context STATIC ${CONTEXT_SOURCES}) + +target_include_directories(strawberry_context PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_context PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core + strawberry_collection + strawberry_covermanager + strawberry_lyrics + strawberry_widgets +) diff --git a/src/context/contextalbum.cpp b/src/context/contextalbum.cpp index fee9a8a4ec..660d9ea0e0 100644 --- a/src/context/contextalbum.cpp +++ b/src/context/contextalbum.cpp @@ -38,7 +38,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "utilities/imageutils.h" #include "covermanager/albumcoverchoicecontroller.h" diff --git a/src/context/contextalbum.h b/src/context/contextalbum.h index 7316ce4147..e7ead2496b 100644 --- a/src/context/contextalbum.h +++ b/src/context/contextalbum.h @@ -33,8 +33,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QMenu; class QTimeLine; diff --git a/src/context/contextview.cpp b/src/context/contextview.cpp index 24e9fe0c49..d74cdc19c3 100644 --- a/src/context/contextview.cpp +++ b/src/context/contextview.cpp @@ -50,8 +50,6 @@ #include #include -#include "core/application.h" -#include "core/player.h" #include "core/song.h" #include "core/settings.h" #include "utilities/strutils.h" @@ -60,7 +58,7 @@ #include "collection/collectionview.h" #include "covermanager/albumcoverchoicecontroller.h" #include "lyrics/lyricsfetcher.h" -#include "settings/contextsettingspage.h" +#include "constants/contextsettings.h" #include "contextview.h" #include "contextalbum.h" @@ -69,11 +67,10 @@ using namespace Qt::Literals::StringLiterals; namespace { constexpr int kWidgetSpacing = 50; -} +} // namespace ContextView::ContextView(QWidget *parent) : QWidget(parent), - app_(nullptr), collectionview_(nullptr), album_cover_choice_controller_(nullptr), lyrics_fetcher_(nullptr), @@ -241,14 +238,13 @@ ContextView::ContextView(QWidget *parent) } -void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller) { +void ContextView::Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr lyrics_providers) { - app_ = app; collectionview_ = collectionview; album_cover_choice_controller_ = album_cover_choice_controller; widget_album_->Init(this, album_cover_choice_controller_); - lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this); + lyrics_fetcher_ = new LyricsFetcher(lyrics_providers, this); QObject::connect(collectionview_, &CollectionView::TotalSongCountUpdated_, this, &ContextView::UpdateNoSong); QObject::connect(collectionview_, &CollectionView::TotalArtistCountUpdated_, this, &ContextView::UpdateNoSong); @@ -295,27 +291,27 @@ void ContextView::AddActions() { void ContextView::ReloadSettings() { QString default_font; - if (QFontDatabase::families().contains(QLatin1String(ContextSettingsPage::kDefaultFontFamily))) { - default_font = QLatin1String(ContextSettingsPage::kDefaultFontFamily); + if (QFontDatabase::families().contains(QLatin1String(ContextSettings::kDefaultFontFamily))) { + default_font = QLatin1String(ContextSettings::kDefaultFontFamily); } else { default_font = font().family(); } Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - title_fmt_ = s.value(ContextSettingsPage::kSettingsTitleFmt, u"%title% - %artist%"_s).toString(); - summary_fmt_ = s.value(ContextSettingsPage::kSettingsSummaryFmt, u"%album%"_s).toString(); - action_show_album_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::ALBUM)], true).toBool()); - action_show_data_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA)], false).toBool()); - action_show_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS)], true).toBool()); - action_search_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS)], true).toBool()); - font_headline_.setFamily(s.value("font_headline", default_font).toString()); - font_headline_.setPointSizeF(s.value("font_size_headline", ContextSettingsPage::kDefaultFontSizeHeadline).toReal()); + s.beginGroup(ContextSettings::kSettingsGroup); + title_fmt_ = s.value(ContextSettings::kSettingsTitleFmt, u"%title% - %artist%"_s).toString(); + summary_fmt_ = s.value(ContextSettings::kSettingsSummaryFmt, u"%album%"_s).toString(); + action_show_album_->setChecked(s.value(ContextSettings::kAlbum, true).toBool()); + action_show_data_->setChecked(s.value(ContextSettings::kTechnicalData, false).toBool()); + action_show_lyrics_->setChecked(s.value(ContextSettings::kSongLyrics, true).toBool()); + action_search_lyrics_->setChecked(s.value(ContextSettings::kSearchLyrics, true).toBool()); + font_headline_.setFamily(s.value(ContextSettings::kFontHeadline, default_font).toString()); + font_headline_.setPointSizeF(s.value(ContextSettings::kFontSizeHeadline, ContextSettings::kDefaultFontSizeHeadline).toReal()); font_nosong_.setFamily(font_headline_.family()); font_nosong_.setPointSizeF(font_headline_.pointSizeF() * 1.6F); - font_normal_.setFamily(s.value("font_normal", default_font).toString()); - font_normal_.setPointSizeF(s.value("font_size_normal", font().pointSizeF()).toReal()); + font_normal_.setFamily(s.value(ContextSettings::kFontNormal, default_font).toString()); + font_normal_.setPointSizeF(s.value(ContextSettings::kFontSizeNormal, font().pointSizeF()).toReal()); s.endGroup(); UpdateFonts(); @@ -697,9 +693,10 @@ void ContextView::AlbumCoverLoaded(const Song &song, const QImage &image) { void ContextView::ActionShowAlbum() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::ALBUM)], action_show_album_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kAlbum, action_show_album_->isChecked()); s.endGroup(); + if (song_playing_.is_valid()) SetSong(); } @@ -707,9 +704,10 @@ void ContextView::ActionShowAlbum() { void ContextView::ActionShowData() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA)], action_show_data_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kTechnicalData, action_show_data_->isChecked()); s.endGroup(); + if (song_playing_.is_valid()) SetSong(); } @@ -717,8 +715,8 @@ void ContextView::ActionShowData() { void ContextView::ActionShowLyrics() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS)], action_show_lyrics_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kSongLyrics, action_show_lyrics_->isChecked()); s.endGroup(); if (song_playing_.is_valid()) SetSong(); @@ -730,8 +728,8 @@ void ContextView::ActionShowLyrics() { void ContextView::ActionSearchLyrics() { Settings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[static_cast(ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS)], action_search_lyrics_->isChecked()); + s.beginGroup(ContextSettings::kSettingsGroup); + s.setValue(ContextSettings::kSearchLyrics, action_search_lyrics_->isChecked()); s.endGroup(); if (song_playing_.is_valid()) SetSong(); diff --git a/src/context/contextview.h b/src/context/contextview.h index ff5a0f379f..dc7c1877bf 100644 --- a/src/context/contextview.h +++ b/src/context/contextview.h @@ -46,9 +46,9 @@ class QDragEnterEvent; class QDropEvent; class ResizableTextEdit; -class Application; class CollectionView; class AlbumCoverChoiceController; +class LyricsProviders; class LyricsFetcher; class ContextView : public QWidget { @@ -57,7 +57,7 @@ class ContextView : public QWidget { public: explicit ContextView(QWidget *parent = nullptr); - void Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller); + void Init(CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller, SharedPtr lyrics_providers); ContextAlbum *album_widget() const { return widget_album_; } bool album_enabled() const { return action_show_album_->isChecked(); } @@ -101,7 +101,6 @@ class ContextView : public QWidget { void AlbumCoverLoaded(const Song &song, const QImage &image); private: - Application *app_; CollectionView *collectionview_; AlbumCoverChoiceController *album_cover_choice_controller_; LyricsFetcher *lyrics_fetcher_; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 0000000000..d3b8d4b235 --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,95 @@ +set(CORE_SOURCES + logging.cpp + commandlineoptions.cpp + database.cpp + memorydatabase.cpp + sqlquery.cpp + sqlrow.cpp + deletefiles.cpp + filesystemmusicstorage.cpp + filesystemwatcherinterface.cpp + mergedproxymodel.cpp + multisortfilterproxy.cpp + musicstorage.cpp + networkaccessmanager.cpp + threadsafenetworkdiskcache.cpp + networktimeouts.cpp + networkproxyfactory.cpp + qtfslistener.cpp + settings.cpp + settingsprovider.cpp + signalchecker.cpp + song.cpp + stylehelper.cpp + stylesheetloader.cpp + taskmanager.cpp + thread.cpp + urlhandlers.cpp + urlhandler.cpp + iconloader.cpp + standarditemiconloader.cpp + scopedtransaction.cpp + localredirectserver.cpp + temporaryfile.cpp + enginemetadata.cpp + platforminterface.cpp +) + +set(CORE_HEADERS + logging.h + database.h + memorydatabase.h + deletefiles.h + filesystemwatcherinterface.h + mergedproxymodel.h + multisortfilterproxy.h + networkaccessmanager.h + threadsafenetworkdiskcache.h + networktimeouts.h + qtfslistener.h + settings.h + taskmanager.h + thread.h + urlhandlers.h + urlhandler.h + standarditemiconloader.h + stylesheetloader.h + localredirectserver.h +) + +if(APPLE) + list(APPEND CORE_SOURCES scoped_nsautorelease_pool.mm) +endif() + +if(WIN32) + list(APPEND CORE_SOURCES windows7thumbbar.cpp) + list(APPEND CORE_HEADERS windows7thumbbar.h) +endif() + +qt_wrap_cpp(CORE_SOURCES ${CORE_HEADERS}) + +add_library(strawberry_core STATIC ${CORE_SOURCES}) + +target_include_directories(strawberry_core PRIVATE + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_core PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + PkgConfig::SQLITE + ${TAGLIB_LIBRARIES} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + $<$:Qt${QT_VERSION_MAJOR}::DBus> + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + $<$:PkgConfig::LIBGPOD PkgConfig::GDK_PIXBUF> + $<$:getopt-win::getopt> + strawberry_utilities +) diff --git a/src/core/application.cpp b/src/core/application.cpp index e98a789eb5..3c2504c6f9 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -34,18 +34,17 @@ #include "core/logging.h" -#include "shared_ptr.h" -#include "lazy.h" -#include "database.h" -#include "taskmanager.h" -#include "player.h" -#include "networkaccessmanager.h" +#include "includes/shared_ptr.h" +#include "includes/lazy.h" +#include "core/database.h" +#include "core/taskmanager.h" +#include "core/networkaccessmanager.h" +#include "player/player.h" #include "tagreader/tagreaderclient.h" #include "engine/devicefinders.h" -#ifndef Q_OS_WIN -# include "device/devicemanager.h" -#endif -#include "collection/collection.h" +#include "core/urlhandlers.h" +#include "device/devicemanager.h" +#include "collection/collectionlibrary.h" #include "playlist/playlistbackend.h" #include "playlist/playlistmanager.h" #include "covermanager/albumcoverloader.h" @@ -114,58 +113,57 @@ using namespace std::chrono_literals; class ApplicationImpl { public: explicit ApplicationImpl(Application *app) : - tag_reader_client_([app](){ + tagreader_client_([app](){ TagReaderClient *client = new TagReaderClient(); app->MoveToNewThread(client); return client; }), database_([app]() { - Database *db = new Database(app); - app->MoveToNewThread(db); - QTimer::singleShot(30s, db, &Database::DoBackup); - return db; + Database *database = new Database(app->task_manager()); + app->MoveToNewThread(database); + QTimer::singleShot(30s, database, &Database::DoBackup); + return database; }), task_manager_([]() { return new TaskManager(); }), - player_([app]() { return new Player(app); }), + player_([app]() { return new Player(app->task_manager(), app->url_handlers(), app->playlist_manager()); }), network_([]() { return new NetworkAccessManager(); }), device_finders_([]() { return new DeviceFinders(); }), -#ifndef Q_OS_WIN - device_manager_([app]() { return new DeviceManager(app); }), -#endif - collection_([app]() { return new SCollection(app); }), + url_handlers_([]() { return new UrlHandlers(); }), + device_manager_([app]() { return new DeviceManager(app->task_manager(), app->database(), app->tagreader_client(), app->albumcover_loader()); }), + collection_([app]() { return new CollectionLibrary(app->database(), app->task_manager(), app->tagreader_client(), app->albumcover_loader()); }), playlist_backend_([this, app]() { - PlaylistBackend *backend = new PlaylistBackend(app); - app->MoveToThread(backend, database_->thread()); - return backend; + PlaylistBackend *playlist_backend = new PlaylistBackend(app->database(), app->tagreader_client(), app->collection_backend()); + app->MoveToThread(playlist_backend, database_->thread()); + return playlist_backend; }), - playlist_manager_([app]() { return new PlaylistManager(app); }), + playlist_manager_([app]() { return new PlaylistManager(app->task_manager(), app->tagreader_client(), app->url_handlers(), app->playlist_backend(), app->collection_backend(), app->current_albumcover_loader()); }), cover_providers_([app]() { CoverProviders *cover_providers = new CoverProviders(); // Initialize the repository of cover providers. - cover_providers->AddProvider(new LastFmCoverProvider(app, app->network())); - cover_providers->AddProvider(new MusicbrainzCoverProvider(app, app->network())); - cover_providers->AddProvider(new DiscogsCoverProvider(app, app->network())); - cover_providers->AddProvider(new DeezerCoverProvider(app, app->network())); - cover_providers->AddProvider(new MusixmatchCoverProvider(app, app->network())); - cover_providers->AddProvider(new OpenTidalCoverProvider(app, app->network())); + cover_providers->AddProvider(new LastFmCoverProvider(app->network())); + cover_providers->AddProvider(new MusicbrainzCoverProvider(app->network())); + cover_providers->AddProvider(new DiscogsCoverProvider(app->network())); + cover_providers->AddProvider(new DeezerCoverProvider(app->network())); + cover_providers->AddProvider(new MusixmatchCoverProvider(app->network())); + cover_providers->AddProvider(new OpenTidalCoverProvider(app->network())); #ifdef HAVE_TIDAL - cover_providers->AddProvider(new TidalCoverProvider(app, app->network())); + cover_providers->AddProvider(new TidalCoverProvider(app->streaming_services()->Service(), app->network())); #endif #ifdef HAVE_SPOTIFY - cover_providers->AddProvider(new SpotifyCoverProvider(app, app->network())); + cover_providers->AddProvider(new SpotifyCoverProvider(app->streaming_services()->Service(), app->network())); #endif #ifdef HAVE_QOBUZ - cover_providers->AddProvider(new QobuzCoverProvider(app, app->network())); + cover_providers->AddProvider(new QobuzCoverProvider(app->streaming_services()->Service(), app->network())); #endif cover_providers->ReloadSettings(); return cover_providers; }), - album_cover_loader_([app]() { - AlbumCoverLoader *loader = new AlbumCoverLoader(); + albumcover_loader_([app]() { + AlbumCoverLoader *loader = new AlbumCoverLoader(app->tagreader_client()); app->MoveToNewThread(loader); return loader; }), - current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app); }), + current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app->albumcover_loader()); }), lyrics_providers_([app]() { LyricsProviders *lyrics_providers = new LyricsProviders(app); // Initialize the repository of lyrics providers. @@ -185,51 +183,50 @@ class ApplicationImpl { streaming_services_([app]() { StreamingServices *streaming_services = new StreamingServices(); #ifdef HAVE_SUBSONIC - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->url_handlers(), app->albumcover_loader())); #endif #ifdef HAVE_TIDAL - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->albumcover_loader())); #endif #ifdef HAVE_SPOTIFY - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->network(), app->albumcover_loader())); #endif #ifdef HAVE_QOBUZ - streaming_services->AddService(make_shared(app)); + streaming_services->AddService(make_shared(app->task_manager(), app->database(), app->network(), app->url_handlers(), app->albumcover_loader())); #endif return streaming_services; }), - radio_services_([app]() { return new RadioServices(app); }), + radio_services_([app]() { return new RadioServices(app->task_manager(), app->network(), app->database(), app->albumcover_loader()); }), scrobbler_([app]() { AudioScrobbler *scrobbler = new AudioScrobbler(app); scrobbler->AddService(make_shared(scrobbler->settings(), app->network())); scrobbler->AddService(make_shared(scrobbler->settings(), app->network())); scrobbler->AddService(make_shared(scrobbler->settings(), app->network())); #ifdef HAVE_SUBSONIC - scrobbler->AddService(make_shared(scrobbler->settings(), app)); + scrobbler->AddService(make_shared(scrobbler->settings(), app->streaming_services()->Service(), app)); #endif return scrobbler; }), #ifdef HAVE_MOODBAR moodbar_loader_([app]() { return new MoodbarLoader(app); }), - moodbar_controller_([app]() { return new MoodbarController(app); }), + moodbar_controller_([app]() { return new MoodbarController(app->player(), app->moodbar_loader()); }), #endif lastfm_import_([app]() { return new LastFMImport(app->network()); }) {} - Lazy tag_reader_client_; + Lazy tagreader_client_; Lazy database_; Lazy task_manager_; Lazy player_; Lazy network_; Lazy device_finders_; -#ifndef Q_OS_WIN + Lazy url_handlers_; Lazy device_manager_; -#endif - Lazy collection_; + Lazy collection_; Lazy playlist_backend_; Lazy playlist_manager_; Lazy cover_providers_; - Lazy album_cover_loader_; + Lazy albumcover_loader_; Lazy current_albumcover_loader_; Lazy lyrics_providers_; Lazy streaming_services_; @@ -250,9 +247,7 @@ Application::Application(QObject *parent) device_finders()->Init(); collection()->Init(); - tag_reader_client(); - - QObject::connect(&*database(), &Database::Error, this, &Application::ErrorAdded); + tagreader_client(); } @@ -294,32 +289,28 @@ void Application::MoveToThread(QObject *object, QThread *thread) { void Application::Exit() { - wait_for_exit_ << &*tag_reader_client() + wait_for_exit_ << &*tagreader_client() << &*collection() << &*playlist_backend() - << &*album_cover_loader() -#ifndef Q_OS_WIN + << &*albumcover_loader() << &*device_manager() -#endif << &*streaming_services() << &*radio_services()->radio_backend(); - QObject::connect(&*tag_reader_client(), &TagReaderClient::ExitFinished, this, &Application::ExitReceived); - tag_reader_client()->ExitAsync(); + QObject::connect(&*tagreader_client(), &TagReaderClient::ExitFinished, this, &Application::ExitReceived); + tagreader_client()->ExitAsync(); - QObject::connect(&*collection(), &SCollection::ExitFinished, this, &Application::ExitReceived); + QObject::connect(&*collection(), &CollectionLibrary::ExitFinished, this, &Application::ExitReceived); collection()->Exit(); QObject::connect(&*playlist_backend(), &PlaylistBackend::ExitFinished, this, &Application::ExitReceived); playlist_backend()->ExitAsync(); - QObject::connect(&*album_cover_loader(), &AlbumCoverLoader::ExitFinished, this, &Application::ExitReceived); - album_cover_loader()->ExitAsync(); + QObject::connect(&*albumcover_loader(), &AlbumCoverLoader::ExitFinished, this, &Application::ExitReceived); + albumcover_loader()->ExitAsync(); -#ifndef Q_OS_WIN QObject::connect(&*device_manager(), &DeviceManager::ExitFinished, this, &Application::ExitReceived); device_manager()->Exit(); -#endif QObject::connect(&*streaming_services(), &StreamingServices::ExitFinished, this, &Application::ExitReceived); streaming_services()->Exit(); @@ -345,23 +336,18 @@ void Application::ExitReceived() { } -void Application::AddError(const QString &message) { Q_EMIT ErrorAdded(message); } -void Application::ReloadSettings() { Q_EMIT SettingsChanged(); } -void Application::OpenSettingsDialogAtPage(SettingsDialog::Page page) { Q_EMIT SettingsDialogRequested(page); } - -SharedPtr Application::tag_reader_client() const { return p_->tag_reader_client_.ptr(); } +SharedPtr Application::tagreader_client() const { return p_->tagreader_client_.ptr(); } SharedPtr Application::database() const { return p_->database_.ptr(); } SharedPtr Application::task_manager() const { return p_->task_manager_.ptr(); } SharedPtr Application::player() const { return p_->player_.ptr(); } SharedPtr Application::network() const { return p_->network_.ptr(); } SharedPtr Application::device_finders() const { return p_->device_finders_.ptr(); } -#ifndef Q_OS_WIN +SharedPtr Application::url_handlers() const { return p_->url_handlers_.ptr(); } SharedPtr Application::device_manager() const { return p_->device_manager_.ptr(); } -#endif -SharedPtr Application::collection() const { return p_->collection_.ptr(); } +SharedPtr Application::collection() const { return p_->collection_.ptr(); } SharedPtr Application::collection_backend() const { return collection()->backend(); } CollectionModel *Application::collection_model() const { return collection()->model(); } -SharedPtr Application::album_cover_loader() const { return p_->album_cover_loader_.ptr(); } +SharedPtr Application::albumcover_loader() const { return p_->albumcover_loader_.ptr(); } SharedPtr Application::cover_providers() const { return p_->cover_providers_.ptr(); } SharedPtr Application::current_albumcover_loader() const { return p_->current_albumcover_loader_.ptr(); } SharedPtr Application::lyrics_providers() const { return p_->lyrics_providers_.ptr(); } diff --git a/src/core/application.h b/src/core/application.h index 901adf29a2..901d455338 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -29,10 +29,8 @@ #include #include -#include "scoped_ptr.h" -#include "shared_ptr.h" - -#include "settings/settingsdialog.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QThread; @@ -41,16 +39,15 @@ class ApplicationImpl; class TagReaderClient; class Database; class DeviceFinders; +class UrlHandlers; class Player; class NetworkAccessManager; -class SCollection; +class CollectionLibrary; class CollectionBackend; class CollectionModel; class PlaylistBackend; class PlaylistManager; -#ifndef Q_OS_WIN class DeviceManager; -#endif class CoverProviders; class AlbumCoverLoader; class CurrentAlbumCoverLoader; @@ -72,17 +69,16 @@ class Application : public QObject { explicit Application(QObject *parent = nullptr); ~Application() override; - SharedPtr tag_reader_client() const; + SharedPtr tagreader_client() const; SharedPtr database() const; SharedPtr task_manager() const; SharedPtr player() const; SharedPtr network() const; SharedPtr device_finders() const; -#ifndef Q_OS_WIN + SharedPtr url_handlers() const; SharedPtr device_manager() const; -#endif - SharedPtr collection() const; + SharedPtr collection() const; SharedPtr collection_backend() const; CollectionModel *collection_model() const; @@ -90,7 +86,7 @@ class Application : public QObject { SharedPtr playlist_manager() const; SharedPtr cover_providers() const; - SharedPtr album_cover_loader() const; + SharedPtr albumcover_loader() const; SharedPtr current_albumcover_loader() const; SharedPtr lyrics_providers() const; @@ -115,23 +111,13 @@ class Application : public QObject { private Q_SLOTS: void ExitReceived(); - public Q_SLOTS: - void AddError(const QString &message); - void ReloadSettings(); - void OpenSettingsDialogAtPage(SettingsDialog::Page page); - Q_SIGNALS: - void ErrorAdded(const QString &message); - void SettingsChanged(); - void SettingsDialogRequested(const SettingsDialog::Page page); void ExitFinished(); - void ClearPixmapDiskCache(); private: ScopedPtr p_; QList threads_; QList wait_for_exit_; - }; #endif // APPLICATION_H diff --git a/src/core/database.cpp b/src/core/database.cpp index 52b731b108..b38f59f357 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -45,7 +45,6 @@ #include "core/logging.h" #include "taskmanager.h" #include "database.h" -#include "application.h" #include "sqlquery.h" #include "scopedtransaction.h" @@ -62,9 +61,9 @@ constexpr char kMagicAllSongsTables[] = "%allsongstables"; int Database::sNextConnectionId = 1; QMutex Database::sNextConnectionIdMutex; -Database::Database(Application *app, QObject *parent, const QString &database_name) : +Database::Database(SharedPtr task_manager, QObject *parent, const QString &database_name) : QObject(parent), - app_(app), + task_manager_(task_manager), injected_database_name_(database_name), query_hash_(0), startup_schema_version_(-1), @@ -145,7 +144,7 @@ QSqlDatabase Database::Connect() { } if (!db.open()) { - app_->AddError(u"Database: "_s + db.lastError().text()); + Q_EMIT Error(u"Database: "_s + db.lastError().text()); return db; } @@ -492,7 +491,7 @@ void Database::ReportErrors(const SqlQuery &query) { bool Database::IntegrityCheck(const QSqlDatabase &db) { qLog(Debug) << "Starting database integrity check"; - const int task_id = app_->task_manager()->StartTask(tr("Integrity check")); + const int task_id = task_manager_->StartTask(tr("Integrity check")); bool ok = false; // Ask for 10 error messages at most. @@ -509,8 +508,8 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) { break; } else { - if (!error_reported) { app_->AddError(tr("Database corruption detected.")); } - app_->AddError(u"Database: "_s + message); + if (!error_reported) { Q_EMIT Error(tr("Database corruption detected.")); } + Q_EMIT Error(u"Database: "_s + message); error_reported = true; } } @@ -519,7 +518,7 @@ bool Database::IntegrityCheck(const QSqlDatabase &db) { ReportErrors(q); } - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); return ok; @@ -563,7 +562,7 @@ void Database::BackupFile(const QString &filename) { qLog(Debug) << "Starting database backup"; QString dest_filename = QStringLiteral("%1.bak").arg(filename); - const int task_id = app_->task_manager()->StartTask(tr("Backing up database")); + const int task_id = task_manager_->StartTask(tr("Backing up database")); sqlite3 *source_connection = nullptr; sqlite3 *dest_connection = nullptr; @@ -575,7 +574,7 @@ void Database::BackupFile(const QString &filename) { if (dest_connection) { sqlite3_close(dest_connection); } - app_->task_manager()->SetTaskFinished(task_id); + task_manager_->SetTaskFinished(task_id); }); bool success = OpenDatabase(filename, &source_connection); @@ -599,7 +598,7 @@ void Database::BackupFile(const QString &filename) { do { ret = sqlite3_backup_step(backup, 16); const int page_count = sqlite3_backup_pagecount(backup); - app_->task_manager()->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count); + task_manager_->SetTaskProgress(task_id, page_count - sqlite3_backup_remaining(backup), page_count); } while (ret == SQLITE_OK); diff --git a/src/core/database.h b/src/core/database.h index 99aa9b91af..fdb65a9700 100644 --- a/src/core/database.h +++ b/src/core/database.h @@ -36,16 +36,17 @@ #include #include +#include "includes/shared_ptr.h" #include "sqlquery.h" class QThread; -class Application; +class TaskManager; class Database : public QObject { Q_OBJECT public: - explicit Database(Application *app, QObject *parent = nullptr, const QString &database_name = QString()); + explicit Database(SharedPtr task_manager, QObject *parent = nullptr, const QString &database_name = QString()); ~Database() override; static const int kSchemaVersion; @@ -102,7 +103,7 @@ class Database : public QObject { void BackupFile(const QString &filename); static bool OpenDatabase(const QString &filename, sqlite3 **connection); - Application *app_; + SharedPtr task_manager_; // Alias -> filename QMap attached_databases_; @@ -130,16 +131,4 @@ class Database : public QObject { }; -class MemoryDatabase : public Database { - Q_OBJECT - - public: - explicit MemoryDatabase(Application *app, QObject *parent = nullptr) - : Database(app, parent, QStringLiteral(":memory:")) {} - ~MemoryDatabase() override { - // Make sure Qt doesn't reuse the same database - QSqlDatabase::removeDatabase(Connect().connectionName()); - } -}; - #endif // DATABASE_H diff --git a/src/core/deletefiles.cpp b/src/core/deletefiles.cpp index 850b630bf8..83afb74a45 100644 --- a/src/core/deletefiles.cpp +++ b/src/core/deletefiles.cpp @@ -28,7 +28,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" #include "taskmanager.h" #include "song.h" #include "deletefiles.h" diff --git a/src/core/deletefiles.h b/src/core/deletefiles.h index f817ca7639..ebe45d5b0e 100644 --- a/src/core/deletefiles.h +++ b/src/core/deletefiles.h @@ -27,7 +27,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" #include "song.h" class QThread; diff --git a/src/engine/enginemetadata.cpp b/src/core/enginemetadata.cpp similarity index 100% rename from src/engine/enginemetadata.cpp rename to src/core/enginemetadata.cpp diff --git a/src/engine/enginemetadata.h b/src/core/enginemetadata.h similarity index 100% rename from src/engine/enginemetadata.h rename to src/core/enginemetadata.h diff --git a/src/core/iconloader.cpp b/src/core/iconloader.cpp index 1f1c09edfd..8096fef3b2 100644 --- a/src/core/iconloader.cpp +++ b/src/core/iconloader.cpp @@ -30,11 +30,11 @@ #include #include -#include "core/logging.h" +#include "logging.h" #include "settings.h" -#include "iconmapper.h" -#include "settings/appearancesettingspage.h" +#include "includes/iconmapper.h" #include "iconloader.h" +#include "constants/appearancesettings.h" using namespace Qt::Literals::StringLiterals; @@ -45,7 +45,7 @@ void IconLoader::Init() { #if !defined(Q_OS_MACOS) && !defined(Q_OS_WIN) Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); + s.beginGroup(AppearanceSettings::kSettingsGroup); system_icons_ = s.value("system_icons", false).toBool(); s.endGroup(); #endif diff --git a/src/core/mac_startup.mm b/src/core/mac_startup.mm index f21a3e0146..40d031035e 100644 --- a/src/core/mac_startup.mm +++ b/src/core/mac_startup.mm @@ -45,15 +45,6 @@ #include "config.h" -#include "platforminterface.h" -#include "mac_delegate.h" -#include "mac_startup.h" -#include "scoped_cftyperef.h" -#include "core/logging.h" -#include "scoped_nsautorelease_pool.h" -#include "globalshortcuts/globalshortcutsmanager.h" -#include "globalshortcuts/globalshortcutsbackend-macos.h" - #include #include #include @@ -61,7 +52,14 @@ #include #include -#include +#include "includes/mac_delegate.h" +#include "includes/scoped_cftyperef.h" +#include "core/scoped_nsautorelease_pool.h" +#include "core/logging.h" +#include "core/platforminterface.h" +#include "mac_startup.h" +#include "globalshortcuts/globalshortcutsmanager.h" +#include "globalshortcuts/globalshortcutsbackend-macos.h" QDebug operator<<(QDebug dbg, NSObject *object) { diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 5cf039f023..835525f300 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -84,52 +84,46 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -#include "shared_ptr.h" -#include "commandlineoptions.h" -#include "mimedata.h" -#include "iconloader.h" -#include "taskmanager.h" -#include "song.h" -#include "stylehelper.h" -#include "stylesheetloader.h" +#include "constants/filefilterconstants.h" +#include "constants/timeconstants.h" +#include "constants/mainwindowsettings.h" +#include "includes/shared_ptr.h" +#include "core/commandlineoptions.h" +#include "mimedata/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 "utilities/envutils.h" #include "utilities/filemanagerutils.h" -#include "utilities/timeconstants.h" #include "utilities/screenutils.h" +#include "player/player.h" #include "engine/enginebase.h" #include "dialogs/errordialog.h" #include "dialogs/about.h" #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 "edittagdialog/edittagdialog.h" +#include "edittagdialog/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 "macstartup/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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 tray_icon, OS collection_view_->filter_widget()->AddMenuAction(collection_config_action); #ifdef HAVE_SUBSONIC + QObject::connect(subsonic_view_, &StreamingSongsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(subsonic_view_->view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); #endif #ifdef HAVE_TIDAL + QObject::connect(tidal_view_, &StreamingTabsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(tidal_view_->artists_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(tidal_view_->albums_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(tidal_view_->songs_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); + QObject::connect(tidal_view_->search_view(), &StreamingSearchView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(tidal_view_->search_view(), &StreamingSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist); if (TidalServicePtr tidalservice = app_->streaming_services()->Service()) { QObject::connect(this, &MainWindow::AuthorizationUrlReceived, &*tidalservice, &TidalService::AuthorizationUrlReceived); @@ -702,16 +731,20 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #endif #ifdef HAVE_QOBUZ + QObject::connect(qobuz_view_, &StreamingTabsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(qobuz_view_->artists_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(qobuz_view_->albums_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(qobuz_view_->songs_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); + QObject::connect(qobuz_view_->search_view(), &StreamingSearchView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(qobuz_view_->search_view(), &StreamingSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist); #endif #ifdef HAVE_SPOTIFY + QObject::connect(spotify_view_, &StreamingTabsView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(spotify_view_->artists_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(spotify_view_->albums_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); QObject::connect(spotify_view_->songs_collection_view(), &StreamingCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); + QObject::connect(spotify_view_->search_view(), &StreamingSearchView::OpenSettingsDialog, this, &MainWindow::OpenServiceSettingsDialog); QObject::connect(spotify_view_->search_view(), &StreamingSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist); #endif @@ -773,14 +806,15 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(ui_->playlist, &PlaylistContainer::UndoRedoActionsChanged, this, &MainWindow::PlaylistUndoRedoChanged); -#ifndef Q_OS_WIN - playlist_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0); + QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceError, this, &MainWindow::ShowErrorDialog); +#ifndef WIN32 QObject::connect(app_->device_manager()->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, playlist_copy_to_device_, &QAction::setDisabled); + playlist_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0); #endif - QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettings::ScrobblingEnabledChanged, this, &MainWindow::ScrobblingEnabledChanged); - QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettings::ScrobbleButtonVisibilityChanged, this, &MainWindow::ScrobbleButtonVisibilityChanged); - QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettings::LoveButtonVisibilityChanged, this, &MainWindow::LoveButtonVisibilityChanged); + QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettingsService::ScrobblingEnabledChanged, this, &MainWindow::ScrobblingEnabledChanged); + QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettingsService::ScrobbleButtonVisibilityChanged, this, &MainWindow::ScrobbleButtonVisibilityChanged); + QObject::connect(&*app_->scrobbler()->settings(), &ScrobblerSettingsService::LoveButtonVisibilityChanged, this, &MainWindow::LoveButtonVisibilityChanged); #ifdef Q_OS_MACOS mac::SetApplicationHandler(this); @@ -849,11 +883,14 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page); QObject::connect(ui_->multi_loading_indicator, &MultiLoadingIndicator::TaskCountChange, this, &MainWindow::TaskCountChanged); - ui_->track_slider->SetApplication(app); + ui_->track_slider->Init(); #ifdef HAVE_MOODBAR // Moodbar connections - QObject::connect(&*app_->moodbar_controller(), &MoodbarController::CurrentMoodbarDataChanged, ui_->track_slider->moodbar_style(), &MoodbarProxyStyle::SetMoodbarData); + QObject::connect(&*app_->moodbar_controller(), &MoodbarController::CurrentMoodbarDataChanged, ui_->track_slider->moodbar_proxy_style(), &MoodbarProxyStyle::SetMoodbarData); + QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, &*app_->moodbar_controller(), &MoodbarController::CurrentSongChanged); + QObject::connect(&*app_->player(), &Player::Stopped, &*app_->moodbar_controller(), &MoodbarController::PlaybackStopped); + QObject::connect(ui_->track_slider->moodbar_proxy_style(), &MoodbarProxyStyle::StyleChanged, &*app_->moodbar_loader(), &MoodbarLoader::StyleChanged); #endif // Playing widget @@ -875,7 +912,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS css_loader->SetStyleSheet(this, u":/style/strawberry.css"_s); // Load playlists - app_->playlist_manager()->Init(app_->collection_backend(), app_->playlist_backend(), ui_->playlist_sequence, ui_->playlist); + app_->playlist_manager()->Init(ui_->playlist_sequence, ui_->playlist); queue_view_->SetPlaylistManager(app_->playlist_manager()); @@ -902,10 +939,12 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(&*app_->lastfm_import(), &LastFMImport::FinishedWithError, lastfm_import_dialog_, &LastFMImportDialog::FinishedWithError); QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateTotal, lastfm_import_dialog_, &LastFMImportDialog::UpdateTotal); QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateProgress, lastfm_import_dialog_, &LastFMImportDialog::UpdateProgress); + QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdateLastPlayed, &*app_->collection_backend(), &CollectionBackend::UpdateLastPlayed); + QObject::connect(&*app_->lastfm_import(), &LastFMImport::UpdatePlayCount, &*app_->collection_backend(), &CollectionBackend::UpdatePlayCount); // Load settings qLog(Debug) << "Loading settings"; - settings_.beginGroup(kSettingsGroup); + settings_.beginGroup(MainWindowSettings::kSettingsGroup); // Set last used geometry to position window on the correct monitor // Set window state only if the window was last maximized @@ -913,7 +952,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS restoreGeometry(settings_.value("geometry").toByteArray()); } - if (!settings_.contains("splitter_state") || !ui_->splitter->restoreState(settings_.value("splitter_state").toByteArray())) { + if (!settings_.contains(MainWindowSettings::kSplitterState) || !ui_->splitter->restoreState(settings_.value(MainWindowSettings::kSplitterState).toByteArray())) { ui_->splitter->setSizes(QList() << 20 << (width() - 20)); } @@ -941,40 +980,40 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #ifdef Q_OS_MACOS // Always show the mainwindow on startup for macOS show(); #else - BehaviourSettingsPage::StartupBehaviour startupbehaviour = BehaviourSettingsPage::StartupBehaviour::Remember; + BehaviourSettings::StartupBehaviour startupbehaviour = BehaviourSettings::StartupBehaviour::Remember; { Settings s; - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - startupbehaviour = static_cast(s.value("startupbehaviour", static_cast(BehaviourSettingsPage::StartupBehaviour::Remember)).toInt()); + s.beginGroup(BehaviourSettings::kSettingsGroup); + startupbehaviour = static_cast(s.value(BehaviourSettings::kStartupBehaviour, static_cast(BehaviourSettings::StartupBehaviour::Remember)).toInt()); s.endGroup(); } switch (startupbehaviour) { - case BehaviourSettingsPage::StartupBehaviour::Show: + case BehaviourSettings::StartupBehaviour::Show: show(); break; - case BehaviourSettingsPage::StartupBehaviour::ShowMaximized: + case BehaviourSettings::StartupBehaviour::ShowMaximized: setWindowState(windowState() | Qt::WindowMaximized); show(); break; - case BehaviourSettingsPage::StartupBehaviour::ShowMinimized: + case BehaviourSettings::StartupBehaviour::ShowMinimized: setWindowState(windowState() | Qt::WindowMinimized); show(); break; - case BehaviourSettingsPage::StartupBehaviour::Hide: + case BehaviourSettings::StartupBehaviour::Hide: if (tray_icon_->IsSystemTrayAvailable() && tray_icon_->isVisible()) { break; } [[fallthrough]]; - case BehaviourSettingsPage::StartupBehaviour::Remember: + case BehaviourSettings::StartupBehaviour::Remember: default:{ - was_maximized_ = settings_.value("maximized", true).toBool(); + was_maximized_ = settings_.value(MainWindowSettings::kMaximized, true).toBool(); if (was_maximized_) setWindowState(windowState() | Qt::WindowMaximized); - was_minimized_ = settings_.value("minimized", false).toBool(); + was_minimized_ = settings_.value(MainWindowSettings::kMinimized, false).toBool(); if (was_minimized_) setWindowState(windowState() | Qt::WindowMinimized); - if (!tray_icon_->IsSystemTrayAvailable() || !tray_icon_->isVisible() || !settings_.value("hidden", false).toBool()) { + if (!tray_icon_->IsSystemTrayAvailable() || !tray_icon_->isVisible() || !settings_.value(MainWindowSettings::kHidden, false).toBool()) { show(); } break; @@ -982,7 +1021,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS } #endif - bool show_sidebar = settings_.value("show_sidebar", true).toBool(); + bool show_sidebar = settings_.value(MainWindowSettings::kShowSidebar, true).toBool(); ui_->sidebar_layout->setVisible(show_sidebar); ui_->action_toggle_show_sidebar->setChecked(show_sidebar); @@ -1016,7 +1055,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #ifdef Q_OS_LINUX if (!Utilities::GetEnv(u"SNAP"_s).isEmpty() && !Utilities::GetEnv(u"SNAP_NAME"_s).isEmpty()) { Settings s; - s.beginGroup(kSettingsGroup); + s.beginGroup(MainWindowSettings::kSettingsGroup); const bool ignore_snap = s.value("ignore_snap", false).toBool(); s.endGroup(); if (!ignore_snap) { @@ -1030,12 +1069,12 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS #if defined(Q_OS_MACOS) if (Utilities::ProcessTranslated()) { Settings s; - s.beginGroup(kSettingsGroup); + s.beginGroup(MainWindowSettings::kSettingsGroup); const bool ignore_rosetta = s.value("ignore_rosetta", false).toBool(); s.endGroup(); if (!ignore_rosetta) { MessageDialog *rosetta_message = new MessageDialog(this); - rosetta_message->set_settings_group(QLatin1String(kSettingsGroup)); + rosetta_message->set_settings_group(QLatin1String(MainWindowSettings::kSettingsGroup)); rosetta_message->set_do_not_show_message_again(u"ignore_rosetta"_s); rosetta_message->setAttribute(Qt::WA_DeleteOnClose); rosetta_message->ShowMessage(tr("Strawberry running under Rosetta"), tr("You are running Strawberry under Rosetta. Running Strawberry under Rosetta is unsupported and known to have issues. You should download Strawberry for the correct CPU architecture from %1").arg(QLatin1String("downloads.strawberrymusicplayer.org")), IconLoader::Load(u"dialog-warning"_s)); @@ -1052,14 +1091,13 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS s.endGroup(); #endif if (asked_permission) { - s.beginGroup(kSettingsGroup); - constexpr char do_not_show_sponsor_message_key[] = "do_not_show_sponsor_message"; - const bool do_not_show_sponsor_message = s.value(do_not_show_sponsor_message_key, false).toBool(); + s.beginGroup(MainWindowSettings::kSettingsGroup); + const bool do_not_show_sponsor_message = s.value(MainWindowSettings::kDoNotShowSponsorMessage, false).toBool(); s.endGroup(); if (!do_not_show_sponsor_message) { MessageDialog *sponsor_message = new MessageDialog(this); - sponsor_message->set_settings_group(QLatin1String(kSettingsGroup)); - sponsor_message->set_do_not_show_message_again(QLatin1String(do_not_show_sponsor_message_key)); + sponsor_message->set_settings_group(QLatin1String(MainWindowSettings::kSettingsGroup)); + sponsor_message->set_do_not_show_message_again(QLatin1String(MainWindowSettings::kDoNotShowSponsorMessage)); sponsor_message->setAttribute(Qt::WA_DeleteOnClose); sponsor_message->ShowMessage(tr("Sponsoring Strawberry"), tr("Strawberry is free and open source software. If you like Strawberry, please consider sponsoring the project. For more information about sponsorship see our website %1").arg(u"www.strawberrymusicplayer.org"_s), IconLoader::Load(u"dialog-information"_s)); } @@ -1083,8 +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(s.value("doubleclick_addmode", static_cast(BehaviourSettingsPage::AddBehaviour::Append)).toInt()); - doubleclick_playmode_ = static_cast(s.value("doubleclick_playmode", static_cast(BehaviourSettingsPage::PlayBehaviour::Never)).toInt()); - doubleclick_playlist_addmode_ = static_cast(s.value("doubleclick_playlist_addmode", static_cast(BehaviourSettingsPage::PlayBehaviour::Never)).toInt()); - menu_playmode_ = static_cast(s.value("menu_playmode", static_cast(BehaviourSettingsPage::PlayBehaviour::Never)).toInt()); + doubleclick_addmode_ = static_cast(s.value(BehaviourSettings::kDoubleClickAddMode, static_cast(BehaviourSettings::AddBehaviour::Append)).toInt()); + doubleclick_playmode_ = static_cast(s.value(BehaviourSettings::kDoubleClickPlayMode, static_cast(BehaviourSettings::PlayBehaviour::Never)).toInt()); + doubleclick_playlist_addmode_ = static_cast(s.value(BehaviourSettings::kDoubleClickPlaylistAddMode, static_cast(BehaviourSettings::PlayBehaviour::Never)).toInt()); + menu_playmode_ = static_cast(s.value(BehaviourSettings::kMenuPlayMode, static_cast(BehaviourSettings::PlayBehaviour::Never)).toInt()); s.endGroup(); - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizePlayControlButtons, 32).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizePlayControlButtons, 32).toInt(); s.endGroup(); tray_icon_->SetTrayiconProgress(trayicon_progress); @@ -1128,7 +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(app_->network()); - track_selection_dialog_ = make_unique(); + track_selection_dialog_ = make_unique(app_->tagreader_client()); track_selection_dialog_->set_save_on_close(true); QObject::connect(&*tag_fetcher_, &TagFetcher::ResultAvailable, &*track_selection_dialog_, &TrackSelectionDialog::FetchTagFinished, Qt::QueuedConnection); @@ -2986,7 +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 diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h index edd5e65546..648f165975 100644 --- a/src/core/mainwindow.h +++ b/src/core/mainwindow.h @@ -46,19 +46,19 @@ #include #include -#include "scoped_ptr.h" -#include "shared_ptr.h" -#include "lazy.h" -#include "platforminterface.h" -#include "song.h" -#include "settings.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" +#include "includes/lazy.h" +#include "core/platforminterface.h" +#include "core/song.h" +#include "core/settings.h" #include "tagreader/tagreaderclient.h" #include "engine/enginebase.h" #include "osd/osdbase.h" #include "playlist/playlist.h" #include "playlist/playlistitem.h" #include "settings/settingsdialog.h" -#include "settings/behavioursettingspage.h" +#include "constants/behavioursettings.h" #include "covermanager/albumcoverloaderresult.h" #include "covermanager/albumcoverimageresult.h" @@ -107,9 +107,6 @@ class MainWindow : public QMainWindow, public PlatformInterface { explicit MainWindow(Application *app, SharedPtr tray_icon, OSDBase *osd, const CommandlineOptions &options, QWidget *parent = nullptr); ~MainWindow() override; - static const char *kSettingsGroup; - static const char *kAllFilesFilterSpec; - void SetHiddenInTray(const bool hidden); void CommandlineOptionsReceived(const CommandlineOptions &options); @@ -202,7 +199,9 @@ class MainWindow : public QMainWindow, public PlatformInterface { void TaskCountChanged(const int count); - void ShowCollectionConfig(); + void OpenCollectionSettingsDialog(); + void OpenServiceSettingsDialog(const Song::Source source); + void ReloadSettings(); void ReloadAllSettings(); void RefreshStyleSheet(); @@ -237,7 +236,7 @@ class MainWindow : public QMainWindow, public PlatformInterface { void Exit(); void DoExit(); - void HandleNotificationPreview(const OSDBase::Behaviour type, const QString &line1, const QString &line2); + void HandleNotificationPreview(const OSDSettings::Type type, const QString &line1, const QString &line2); void ShowConsole(); @@ -274,8 +273,8 @@ class MainWindow : public QMainWindow, public PlatformInterface { void SaveSettings(); - static void ApplyAddBehaviour(const BehaviourSettingsPage::AddBehaviour b, MimeData *mimedata); - void ApplyPlayBehaviour(const BehaviourSettingsPage::PlayBehaviour b, MimeData *mimedata) const; + static void ApplyAddBehaviour(const BehaviourSettings::AddBehaviour b, MimeData *mimedata); + void ApplyPlayBehaviour(const BehaviourSettings::PlayBehaviour b, MimeData *mimedata) const; void CheckFullRescanRevisions(); @@ -385,10 +384,10 @@ class MainWindow : public QMainWindow, public PlatformInterface { #ifdef HAVE_DBUS bool taskbar_progress_; #endif - BehaviourSettingsPage::AddBehaviour doubleclick_addmode_; - BehaviourSettingsPage::PlayBehaviour doubleclick_playmode_; - BehaviourSettingsPage::PlaylistAddBehaviour doubleclick_playlist_addmode_; - BehaviourSettingsPage::PlayBehaviour menu_playmode_; + BehaviourSettings::AddBehaviour doubleclick_addmode_; + BehaviourSettings::PlayBehaviour doubleclick_playmode_; + BehaviourSettings::PlaylistAddBehaviour doubleclick_playlist_addmode_; + BehaviourSettings::PlayBehaviour menu_playmode_; bool initialized_; bool was_maximized_; diff --git a/src/core/memorydatabase.cpp b/src/core/memorydatabase.cpp new file mode 100644 index 0000000000..d4156e2eef --- /dev/null +++ b/src/core/memorydatabase.cpp @@ -0,0 +1,30 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "memorydatabase.h" + +using namespace Qt::Literals::StringLiterals; + +MemoryDatabase::MemoryDatabase(SharedPtr task_manager, QObject *parent) + : Database(task_manager, parent, u":memory:"_s) {} + +MemoryDatabase::~MemoryDatabase() { + // Make sure Qt doesn't reuse the same database + Close(); +} diff --git a/src/core/memorydatabase.h b/src/core/memorydatabase.h new file mode 100644 index 0000000000..49439a68f8 --- /dev/null +++ b/src/core/memorydatabase.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef MEMORYDATABASE_H +#define MEMORYDATABASE_H + +#include "includes/shared_ptr.h" + +class TaskManager; + +#include "database.h" + +class MemoryDatabase : public Database { + Q_OBJECT + + public: + explicit MemoryDatabase(SharedPtr task_manager, QObject *parent = nullptr); + ~MemoryDatabase() override; +}; + +#endif // MEMORYDATABASE_H diff --git a/src/core/mergedproxymodel.h b/src/core/mergedproxymodel.h index fdb6053c79..9ef897f4b9 100644 --- a/src/core/mergedproxymodel.h +++ b/src/core/mergedproxymodel.h @@ -35,7 +35,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class QMimeData; diff --git a/src/core/metatypes.cpp b/src/core/metatypes.cpp index 3f76fec6c5..551fe30878 100644 --- a/src/core/metatypes.cpp +++ b/src/core/metatypes.cpp @@ -43,10 +43,9 @@ # include #endif -#include "song.h" - +#include "core/song.h" +#include "core/enginemetadata.h" #include "engine/enginebase.h" -#include "engine/enginemetadata.h" #include "engine/gstenginepipeline.h" #include "collection/collectiondirectory.h" #include "playlist/playlistitem.h" @@ -57,7 +56,7 @@ #include "equalizer/equalizer.h" #ifdef HAVE_DBUS -# include "dbus_metatypes.h" +# include "includes/dbus_metatypes.h" #endif #ifdef HAVE_MPRIS2 @@ -74,7 +73,7 @@ # include "device/mtpconnection.h" #endif -#include "settings/playlistsettingspage.h" +#include "constants/playlistsettings.h" #include "smartplaylists/smartplaylistsearchterm.h" #include "smartplaylists/smartplaylistsitem.h" @@ -153,7 +152,7 @@ void RegisterMetaTypes() { qRegisterMetaType("MtpConnection*"); #endif - qRegisterMetaType("PlaylistSettingsPage::PathType"); + qRegisterMetaType("PlaylistSettings::PathType"); qRegisterMetaType("PlaylistGeneratorPtr"); qRegisterMetaType("SmartPlaylistSearchTerm::Field"); diff --git a/src/core/musicstorage.h b/src/core/musicstorage.h index 3d7e607481..afe5fafc80 100644 --- a/src/core/musicstorage.h +++ b/src/core/musicstorage.h @@ -35,7 +35,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" #include "song.h" class MusicStorage { diff --git a/src/core/platforminterface.cpp b/src/core/platforminterface.cpp new file mode 100644 index 0000000000..faef23b2d9 --- /dev/null +++ b/src/core/platforminterface.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include +#include + +#include "platforminterface.h" + +PlatformInterface::PlatformInterface() = default; +PlatformInterface::~PlatformInterface() = default; diff --git a/src/core/platforminterface.h b/src/core/platforminterface.h index ed8e902734..c2188e5a18 100644 --- a/src/core/platforminterface.h +++ b/src/core/platforminterface.h @@ -1,7 +1,6 @@ /* * Strawberry Music Player - * Copyright 2010, David Sansome - * Copyright 2018-2021, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +25,8 @@ class PlatformInterface { public: - PlatformInterface() = default; - virtual ~PlatformInterface() {} + explicit PlatformInterface(); + virtual ~PlatformInterface(); // Called when the application should show itself. virtual void Activate() = 0; diff --git a/src/core/player.cpp b/src/core/player.cpp index 8c9f19506b..1c0f57cfc6 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -37,18 +37,21 @@ #include #include +#include "constants/behavioursettings.h" +#include "constants/backendsettings.h" +#include "constants/playlistsettings.h" +#include "constants/timeconstants.h" + +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/settings.h" -#include "utilities/timeconstants.h" - -#include "scoped_ptr.h" -#include "shared_ptr.h" -#include "song.h" -#include "urlhandler.h" -#include "application.h" +#include "core/song.h" +#include "core/urlhandlers.h" +#include "core/urlhandler.h" +#include "core/enginemetadata.h" #include "engine/enginebase.h" -#include "engine/enginemetadata.h" #include "engine/gstengine.h" #include "engine/gststartup.h" @@ -60,18 +63,22 @@ #include "playlist/playlistsequence.h" #include "equalizer/equalizer.h" #include "analyzer/analyzercontainer.h" -#include "settings/backendsettingspage.h" -#include "settings/behavioursettingspage.h" -#include "settings/playlistsettingspage.h" using namespace std::chrono_literals; -using std::make_shared; -const char *Player::kSettingsGroup = "Player"; +namespace { +constexpr char kSettingsGroup[] = "Player"; +constexpr char kVolume[] = "volume"; +constexpr char kPlaybackState[] = "playback_state"; +constexpr char kPlaybackPlaylist[] = "playback_playlist"; +constexpr char kPlaybackPosition[] = "playback_position"; +} // namespace -Player::Player(Application *app, QObject *parent) +Player::Player(const SharedPtr task_manager, const SharedPtr url_handlers, const SharedPtr playlist_manager, QObject *parent) : PlayerInterface(parent), - app_(app), + task_manager_(task_manager), + url_handlers_(url_handlers), + playlist_manager_(playlist_manager), engine_(nullptr), gst_startup_(new GstStartup(this)), analyzer_(nullptr), @@ -89,7 +96,7 @@ Player::Player(Application *app, QObject *parent) last_pressed_previous_(QDateTime::currentDateTime()), continue_on_error_(false), greyout_(true), - menu_previousmode_(BehaviourSettingsPage::PreviousBehaviour::DontRestart), + menu_previousmode_(BehaviourSettings::PreviousBehaviour::DontRestart), seek_step_sec_(10), volume_increment_(5), play_offset_nanosec_(0) { @@ -97,8 +104,8 @@ Player::Player(Application *app, QObject *parent) setObjectName(QLatin1String(metaObject()->className())); Settings s; - s.beginGroup(BackendSettingsPage::kSettingsGroup); - EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); + s.beginGroup(BackendSettings::kSettingsGroup); + EngineBase::Type enginetype = EngineBase::TypeFromName(s.value(BackendSettings::kEngine, EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); s.endGroup(); CreateEngine(enginetype); @@ -107,6 +114,8 @@ Player::Player(Application *app, QObject *parent) timer_save_volume_->setInterval(5s); QObject::connect(timer_save_volume_, &QTimer::timeout, this, &Player::SaveVolume); + QObject::connect(&*url_handlers, &UrlHandlers::Registered, this, &Player::UrlHandlerRegistered); + } EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { @@ -118,7 +127,7 @@ EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { case EngineBase::Type::None: case EngineBase::Type::GStreamer:{ use_enginetype=EngineBase::Type::GStreamer; - ScopedPtr gst_engine(new GstEngine(app_->task_manager())); + ScopedPtr gst_engine(new GstEngine(task_manager_)); gst_engine->SetStartup(gst_startup_); engine_.reset(gst_engine.release()); break; @@ -134,10 +143,10 @@ EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { if (use_enginetype != enginetype) { // Engine was set to something else. Reset output and device. Settings s; - s.beginGroup(BackendSettingsPage::kSettingsGroup); - s.setValue("engine", EngineBase::Name(use_enginetype)); - s.setValue("output", engine_->DefaultOutput()); - s.setValue("device", QVariant()); + s.beginGroup(BackendSettings::kSettingsGroup); + s.setValue(BackendSettings::kEngine, EngineBase::Name(use_enginetype)); + s.setValue(BackendSettings::kOutput, engine_->DefaultOutput()); + s.setValue(BackendSettings::kDevice, QVariant()); s.endGroup(); } @@ -156,7 +165,7 @@ void Player::Init() { Settings s; if (!engine_) { - s.beginGroup(BackendSettingsPage::kSettingsGroup); + s.beginGroup(BackendSettings::kSettingsGroup); EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); s.endGroup(); CreateEngine(enginetype); @@ -179,10 +188,10 @@ void Player::Init() { QObject::connect(&*engine_, &EngineBase::VolumeChanged, this, &Player::SetVolumeFromEngine); // Equalizer - QObject::connect(&*equalizer_, &Equalizer::StereoBalancerEnabledChanged, &*app_->player()->engine(), &EngineBase::SetStereoBalancerEnabled); - QObject::connect(&*equalizer_, &Equalizer::StereoBalanceChanged, &*app_->player()->engine(), &EngineBase::SetStereoBalance); - QObject::connect(&*equalizer_, &Equalizer::EqualizerEnabledChanged, &*app_->player()->engine(), &EngineBase::SetEqualizerEnabled); - QObject::connect(&*equalizer_, &Equalizer::EqualizerParametersChanged, &*app_->player()->engine(), &EngineBase::SetEqualizerParameters); + QObject::connect(&*equalizer_, &Equalizer::StereoBalancerEnabledChanged, &*engine_, &EngineBase::SetStereoBalancerEnabled); + QObject::connect(&*equalizer_, &Equalizer::StereoBalanceChanged, &*engine_, &EngineBase::SetStereoBalance); + QObject::connect(&*equalizer_, &Equalizer::EqualizerEnabledChanged, &*engine_, &EngineBase::SetEqualizerEnabled); + QObject::connect(&*equalizer_, &Equalizer::EqualizerParametersChanged, &*engine_, &EngineBase::SetEqualizerParameters); engine_->SetStereoBalancerEnabled(equalizer_->is_stereo_balancer_enabled()); engine_->SetStereoBalance(equalizer_->stereo_balance()); @@ -199,26 +208,32 @@ void Player::ReloadSettings() { Settings s; - s.beginGroup(PlaylistSettingsPage::kSettingsGroup); + s.beginGroup(PlaylistSettings::kSettingsGroup); continue_on_error_ = s.value("continue_on_error", false).toBool(); greyout_ = s.value("greyout_songs_play", true).toBool(); s.endGroup(); - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); - menu_previousmode_ = static_cast(s.value("menu_previousmode", static_cast(BehaviourSettingsPage::PreviousBehaviour::DontRestart)).toInt()); - seek_step_sec_ = s.value("seek_step_sec", 10).toInt(); - volume_increment_ = s.value("volume_increment", 5).toUInt(); + s.beginGroup(BehaviourSettings::kSettingsGroup); + menu_previousmode_ = static_cast(s.value(BehaviourSettings::kMenuPreviousMode, static_cast(BehaviourSettings::PreviousBehaviour::DontRestart)).toInt()); + seek_step_sec_ = s.value(BehaviourSettings::kSeekStepSec, 10).toInt(); + volume_increment_ = s.value(BehaviourSettings::kVolumeIncrement, 5).toUInt(); s.endGroup(); engine_->ReloadSettings(); } +void Player::UrlHandlerRegistered(UrlHandler *url_handler) 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(app_->player()->GetState())); - if (app_->player()->GetState() == EngineBase::State::Playing || app_->player()->GetState() == EngineBase::State::Paused) { - s.setValue("playback_playlist", app_->playlist_manager()->active()->id()); - s.setValue("playback_position", app_->player()->engine()->position_nanosec() / kNsecPerSec); + s.setValue(kPlaybackState, static_cast(GetState())); + if (GetState() == EngineBase::State::Playing || GetState() == EngineBase::State::Paused) { + s.setValue(kPlaybackPlaylist, playlist_manager_->active()->id()); + s.setValue(kPlaybackPosition, engine_->position_nanosec() / kNsecPerSec); } else { - s.setValue("playback_playlist", -1); - s.setValue("playback_position", 0); + s.setValue(kPlaybackPlaylist, -1); + s.setValue(kPlaybackPosition, 0); } s.endGroup(); @@ -258,12 +273,12 @@ void Player::PlaylistsLoaded() { Settings s; - s.beginGroup(BehaviourSettingsPage::kSettingsGroup); + s.beginGroup(BehaviourSettings::kSettingsGroup); const bool resume_playback = s.value("resumeplayback", false).toBool(); s.endGroup(); - s.beginGroup(Player::kSettingsGroup); - const EngineBase::State playback_state = static_cast(s.value("playback_state", static_cast(EngineBase::State::Empty)).toInt()); + s.beginGroup(kSettingsGroup); + const EngineBase::State playback_state = static_cast(s.value(kPlaybackState, static_cast(EngineBase::State::Empty)).toInt()); s.endGroup(); if (resume_playback && (playback_state == EngineBase::State::Playing || playback_state == EngineBase::State::Paused)) { @@ -283,14 +298,14 @@ void Player::ResumePlayback() { Settings s; s.beginGroup(kSettingsGroup); - const EngineBase::State playback_state = static_cast(s.value("playback_state", static_cast(EngineBase::State::Empty)).toInt()); - const int playback_playlist = s.value("playback_playlist", -1).toInt(); - const int playback_position = s.value("playback_position", 0).toInt(); + const EngineBase::State playback_state = static_cast(s.value(kPlaybackState, static_cast(EngineBase::State::Empty)).toInt()); + const int playback_playlist = s.value(kPlaybackPlaylist, -1).toInt(); + const int playback_position = s.value(kPlaybackPosition, 0).toInt(); s.endGroup(); - if (playback_playlist == app_->playlist_manager()->current()->id()) { + if (playback_playlist == playlist_manager_->current()->id()) { // Set active to current to resume playback on correct playlist. - app_->playlist_manager()->SetActiveToCurrent(); + playlist_manager_->SetActiveToCurrent(); if (playback_state == EngineBase::State::Playing) { Play(playback_position * kNsecPerSec); } @@ -301,9 +316,9 @@ void Player::ResumePlayback() { // Reset saved playback status so we don't resume again from the same position. s.beginGroup(kSettingsGroup); - s.setValue("playback_state", static_cast(EngineBase::State::Empty)); - s.setValue("playback_playlist", -1); - s.setValue("playback_position", 0); + s.setValue(kPlaybackState, static_cast(EngineBase::State::Empty)); + s.setValue(kPlaybackPlaylist, -1); + s.setValue(kPlaybackPosition, 0); s.endGroup(); } @@ -315,19 +330,19 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { } // Might've been an async load, so check we're still on the same item - const int current_row = app_->playlist_manager()->active()->current_row(); + const int current_row = playlist_manager_->active()->current_row(); if (current_row == -1) { return; } - PlaylistItemPtr current_item = app_->playlist_manager()->active()->current_item(); + PlaylistItemPtr current_item = playlist_manager_->active()->current_item(); if (!current_item) { return; } - int next_row = app_->playlist_manager()->active()->next_row(); + int next_row = playlist_manager_->active()->next_row(); const bool has_next_row = next_row != -1; PlaylistItemPtr next_item; if (has_next_row) { - next_item = app_->playlist_manager()->active()->item_at(next_row); + next_item = playlist_manager_->active()->item_at(next_row); } bool is_current = false; @@ -408,10 +423,10 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { if (update) { if (is_current) { - app_->playlist_manager()->active()->UpdateItemMetadata(current_row, current_item, song, true); + playlist_manager_->active()->UpdateItemMetadata(current_row, current_item, song, true); } else if (is_next) { - app_->playlist_manager()->active()->UpdateItemMetadata(next_row, next_item, song, true); + playlist_manager_->active()->UpdateItemMetadata(next_row, next_item, song, true); } } @@ -457,13 +472,13 @@ void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist: pause_time_ = QDateTime(); play_offset_nanosec_ = 0; - Playlist *active_playlist = app_->playlist_manager()->active(); + Playlist *active_playlist = playlist_manager_->active(); // If we received too many errors in auto change, with repeat enabled, we stop if (change & EngineBase::TrackChangeType::Auto) { const PlaylistSequence::RepeatMode repeat_mode = active_playlist->RepeatMode(); if (repeat_mode != PlaylistSequence::RepeatMode::Off) { - if ((repeat_mode == PlaylistSequence::RepeatMode::Track && nb_errors_received_ >= 3) || (nb_errors_received_ >= app_->playlist_manager()->active()->filter()->rowCount())) { + if ((repeat_mode == PlaylistSequence::RepeatMode::Track && nb_errors_received_ >= 3) || (nb_errors_received_ >= playlist_manager_->active()->filter()->rowCount())) { // We received too many "Error" state changes: probably looping over a playlist which contains only unavailable elements: stop now. nb_errors_received_ = 0; Stop(); @@ -482,8 +497,8 @@ void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist: int i = active_playlist->next_row(ignore_repeat_track); if (i == -1) { - app_->playlist_manager()->active()->set_current_row(i); - app_->playlist_manager()->active()->reset_last_played(); + playlist_manager_->active()->set_current_row(i); + playlist_manager_->active()->reset_last_played(); Q_EMIT PlaylistFinished(); Stop(); return; @@ -503,9 +518,9 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con play_offset_nanosec_ = 0; Playlist *playlist = nullptr; - const QList playlists = app_->playlist_manager()->GetAllPlaylists(); + const QList playlists = playlist_manager_->GetAllPlaylists(); for (Playlist *p : playlists) { - if (playlist_name == app_->playlist_manager()->GetPlaylistName(p->id())) { + if (playlist_name == playlist_manager_->GetPlaylistName(p->id())) { playlist = p; break; } @@ -516,12 +531,12 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con return; } - app_->playlist_manager()->SetActivePlaylist(playlist->id()); - app_->playlist_manager()->SetCurrentPlaylist(playlist->id()); + playlist_manager_->SetActivePlaylist(playlist->id()); + playlist_manager_->SetCurrentPlaylist(playlist->id()); if (playlist->rowCount() == 0) return; - int i = app_->playlist_manager()->active()->current_row(); - if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); + int i = playlist_manager_->active()->current_row(); + if (i == -1) i = playlist_manager_->active()->last_played_row(); if (i == -1) i = 0; PlayAt(i, false, 0, change, autoscroll, true); @@ -530,14 +545,14 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) { - if (app_->playlist_manager()->active()->stop_after_current()) { + if (playlist_manager_->active()->stop_after_current()) { // Find what the next track would've been, and mark that one as current, so it plays next time the user presses Play. - const int next_row = app_->playlist_manager()->active()->next_row(); + const int next_row = playlist_manager_->active()->next_row(); if (next_row != -1) { - app_->playlist_manager()->active()->set_current_row(next_row, autoscroll, true); + playlist_manager_->active()->set_current_row(next_row, autoscroll, true); } - app_->playlist_manager()->active()->StopAfter(-1); + playlist_manager_->active()->StopAfter(-1); Stop(true); return true; @@ -550,7 +565,7 @@ bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) { void Player::TrackEnded() { if (current_item_ && current_item_->IsLocalCollectionItem() && current_item_->Metadata().id() != -1) { - app_->playlist_manager()->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id()); + playlist_manager_->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id()); } if (HandleStopAfter(Playlist::AutoScroll::Maybe)) return; @@ -584,10 +599,10 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll case EngineBase::State::Idle:{ pause_time_ = QDateTime(); play_offset_nanosec_ = offset_nanosec; - app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id()); - if (app_->playlist_manager()->active()->rowCount() == 0) break; - int i = app_->playlist_manager()->active()->current_row(); - if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); + playlist_manager_->SetActivePlaylist(playlist_manager_->current_id()); + if (playlist_manager_->active()->rowCount() == 0) break; + int i = playlist_manager_->active()->current_row(); + if (i == -1) i = playlist_manager_->active()->last_played_row(); if (i == -1) i = 0; PlayAt(i, false, offset_nanosec, EngineBase::TrackChangeType::First, autoscroll, true); break; @@ -600,12 +615,12 @@ void Player::UnPause() { if (current_item_ && pause_time_.isValid()) { const Song &song = current_item_->Metadata(); - if (url_handlers_.contains(song.url().scheme()) && song.stream_url_can_expire()) { + if (url_handlers_->CanHandle(song.url()) && song.stream_url_can_expire()) { const quint64 time = QDateTime::currentSecsSinceEpoch() - pause_time_.toSecsSinceEpoch(); if (time >= 30) { // Stream URL might be expired. qLog(Debug) << "Re-requesting stream URL for" << song.url(); play_offset_nanosec_ = engine_->position_nanosec(); - UrlHandler *url_handler = url_handlers_.value(song.url().scheme()); + UrlHandler *url_handler = url_handlers_->GetUrlHandler(song.url()); HandleLoadResult(url_handler->StartLoading(song.url())); return; } @@ -636,8 +651,8 @@ void Player::RestartOrPrevious() { void Player::Stop(const bool stop_after) { engine_->Stop(stop_after); - app_->playlist_manager()->active()->set_current_row(-1); - app_->playlist_manager()->active()->reset_played_indexes(); + playlist_manager_->active()->set_current_row(-1); + playlist_manager_->active()->reset_played_indexes(); current_item_.reset(); pause_time_ = QDateTime(); play_offset_nanosec_ = 0; @@ -645,13 +660,13 @@ void Player::Stop(const bool stop_after) { } void Player::StopAfterCurrent() { - app_->playlist_manager()->active()->StopAfter(app_->playlist_manager()->active()->current_row()); + playlist_manager_->active()->StopAfter(playlist_manager_->active()->current_row()); } bool Player::PreviousWouldRestartTrack() const { // Check if it has been over two seconds since previous button was pressed - return menu_previousmode_ == BehaviourSettingsPage::PreviousBehaviour::Restart && last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(QDateTime::currentDateTime()) >= 2; + return menu_previousmode_ == BehaviourSettings::PreviousBehaviour::Restart && last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(QDateTime::currentDateTime()) >= 2; } @@ -664,19 +679,19 @@ void Player::PreviousItem(const EngineBase::TrackChangeFlags change) { const bool ignore_repeat_track = change & EngineBase::TrackChangeType::Manual; - if (menu_previousmode_ == BehaviourSettingsPage::PreviousBehaviour::Restart) { + if (menu_previousmode_ == BehaviourSettings::PreviousBehaviour::Restart) { // Check if it has been over two seconds since previous button was pressed QDateTime now = QDateTime::currentDateTime(); if (last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(now) >= 2) { last_pressed_previous_ = now; - PlayAt(app_->playlist_manager()->active()->current_row(), false, 0, change, Playlist::AutoScroll::Always, false, true); + PlayAt(playlist_manager_->active()->current_row(), false, 0, change, Playlist::AutoScroll::Always, false, true); return; } last_pressed_previous_ = now; } - int i = app_->playlist_manager()->active()->previous_row(ignore_repeat_track); - app_->playlist_manager()->active()->set_current_row(i, Playlist::AutoScroll::Always, false); + int i = playlist_manager_->active()->previous_row(ignore_repeat_track); + playlist_manager_->active()->set_current_row(i, Playlist::AutoScroll::Always, false); if (i == -1) { Stop(); PlayAt(i, false, 0, change, Playlist::AutoScroll::Always, true); @@ -790,22 +805,22 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano Q_EMIT TrackSkipped(current_item_); } - if (current_item_ && app_->playlist_manager()->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(app_->playlist_manager()->active()->item_at(index)->Metadata())) { + if (current_item_ && playlist_manager_->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(playlist_manager_->active()->item_at(index)->Metadata())) { change |= EngineBase::TrackChangeType::SameAlbum; } - if (reshuffle) app_->playlist_manager()->active()->ReshuffleIndices(); + if (reshuffle) playlist_manager_->active()->ReshuffleIndices(); - app_->playlist_manager()->active()->set_current_row(index, autoscroll, false, force_inform); - if (app_->playlist_manager()->active()->current_row() == -1) { + playlist_manager_->active()->set_current_row(index, autoscroll, false, force_inform); + if (playlist_manager_->active()->current_row() == -1) { // Maybe index didn't exist in the playlist. return; } - current_item_ = app_->playlist_manager()->active()->current_item(); + current_item_ = playlist_manager_->active()->current_item(); const QUrl url = current_item_->StreamUrl(); - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_->CanHandle(url)) { // It's already loading if (loading_async_.contains(url)) { return; @@ -814,7 +829,7 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano pause_ = pause; stream_change_type_ = change; autoscroll_ = autoscroll; - UrlHandler *url_handler = url_handlers_.value(url.scheme()); + UrlHandler *url_handler = url_handlers_->GetUrlHandler(url); HandleLoadResult(url_handler->StartLoading(url)); } else { @@ -844,12 +859,12 @@ void Player::SeekTo(const quint64 seconds) { engine_->Seek(nanosec); qLog(Debug) << "Track seeked to" << nanosec << "ns - updating scrobble point"; - app_->playlist_manager()->active()->UpdateScrobblePoint(nanosec); + playlist_manager_->active()->UpdateScrobblePoint(nanosec); Q_EMIT Seeked(nanosec / 1000); if (seconds == 0) { - app_->playlist_manager()->active()->InformOfCurrentSongChange(false); + playlist_manager_->active()->InformOfCurrentSongChange(false); } } @@ -865,26 +880,26 @@ void Player::SeekBackward() { void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Current) { - const int current_row = app_->playlist_manager()->active()->current_row(); + const int current_row = playlist_manager_->active()->current_row(); if (current_row != -1) { - PlaylistItemPtr item = app_->playlist_manager()->active()->current_item(); + PlaylistItemPtr item = playlist_manager_->active()->current_item(); if (item && engine_metadata.media_url == item->Url()) { Song song = item->Metadata(); song.MergeFromEngineMetadata(engine_metadata); - app_->playlist_manager()->active()->UpdateItemMetadata(current_row, item, song, true); + playlist_manager_->active()->UpdateItemMetadata(current_row, item, song, true); return; } } } if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Next) { - const int next_row = app_->playlist_manager()->active()->next_row(); + const int next_row = playlist_manager_->active()->next_row(); if (next_row != -1) { - PlaylistItemPtr next_item = app_->playlist_manager()->active()->item_at(next_row); + PlaylistItemPtr next_item = playlist_manager_->active()->item_at(next_row); if (engine_metadata.media_url == next_item->Url()) { Song song = next_item->Metadata(); song.MergeFromEngineMetadata(engine_metadata); - app_->playlist_manager()->active()->UpdateItemMetadata(next_row, next_item, song, true); + playlist_manager_->active()->UpdateItemMetadata(next_row, next_item, song, true); } } } @@ -893,9 +908,9 @@ void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { PlaylistItemPtr Player::GetItemAt(const int pos) const { - if (pos < 0 || pos >= app_->playlist_manager()->active()->rowCount()) + if (pos < 0 || pos >= playlist_manager_->active()->rowCount()) return PlaylistItemPtr(); - return app_->playlist_manager()->active()->item_at(pos); + return playlist_manager_->active()->item_at(pos); } @@ -940,10 +955,10 @@ void Player::PlayWithPause(const quint64 offset_nanosec) { pause_time_ = QDateTime(); play_offset_nanosec_ = offset_nanosec; - app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id()); - if (app_->playlist_manager()->active()->rowCount() == 0) return; - int i = app_->playlist_manager()->active()->current_row(); - if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); + playlist_manager_->SetActivePlaylist(playlist_manager_->current_id()); + if (playlist_manager_->active()->rowCount() == 0) return; + int i = playlist_manager_->active()->current_row(); + if (i == -1) i = playlist_manager_->active()->last_played_row(); if (i == -1) i = 0; PlayAt(i, true, offset_nanosec, EngineBase::TrackChangeType::First, Playlist::AutoScroll::Always, true); @@ -959,11 +974,11 @@ void Player::TogglePrettyOSD() { void Player::TrackAboutToEnd() { - const bool has_next_row = app_->playlist_manager()->active()->next_row() != -1; + const bool has_next_row = playlist_manager_->active()->next_row() != -1; PlaylistItemPtr next_item; if (has_next_row) { - next_item = app_->playlist_manager()->active()->item_at(app_->playlist_manager()->active()->next_row()); + next_item = playlist_manager_->active()->item_at(playlist_manager_->active()->next_row()); } if (engine_->is_autocrossfade_enabled()) { @@ -989,10 +1004,10 @@ void Player::TrackAboutToEnd() { QUrl url = next_item->StreamUrl(); // Get the actual track URL rather than the stream URL. - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_->CanHandle(url)) { if (loading_async_.contains(url)) return; autoscroll_ = Playlist::AutoScroll::Maybe; - UrlHandler *url_handler = url_handlers_.value(url.scheme()); + UrlHandler *url_handler = url_handlers_->GetUrlHandler(url); const UrlHandler::LoadResult result = url_handler->StartLoading(url); switch (result.type_) { case UrlHandler::LoadResult::Type::Error: @@ -1045,57 +1060,6 @@ void Player::InvalidSongRequested(const QUrl &url) { } -void Player::RegisterUrlHandler(UrlHandler *handler) { - - const QString scheme = handler->scheme(); - - if (url_handlers_.contains(scheme)) { - qLog(Warning) << "Tried to register a URL handler for" << scheme << "but one was already registered"; - return; - } - - qLog(Info) << "Registered URL handler for" << scheme; - url_handlers_.insert(scheme, handler); - QObject::connect(handler, &UrlHandler::destroyed, this, &Player::UrlHandlerDestroyed); - QObject::connect(handler, &UrlHandler::AsyncLoadComplete, this, &Player::HandleLoadResult); - -} - -void Player::UnregisterUrlHandler(UrlHandler *handler) { - - const QString scheme = url_handlers_.key(handler); - if (scheme.isEmpty()) { - qLog(Warning) << "Tried to unregister a URL handler for" << handler->scheme() << "that wasn't registered"; - return; - } - - qLog(Info) << "Unregistered URL handler for" << scheme; - url_handlers_.remove(scheme); - QObject::disconnect(handler, &UrlHandler::destroyed, this, &Player::UrlHandlerDestroyed); - QObject::disconnect(handler, &UrlHandler::AsyncLoadComplete, this, &Player::HandleLoadResult); - -} - -const UrlHandler *Player::HandlerForUrl(const QUrl &url) const { - - QMap::const_iterator it = url_handlers_.constFind(url.scheme()); - if (it == url_handlers_.constEnd()) { - return nullptr; - } - return *it; - -} - -void Player::UrlHandlerDestroyed(QObject *object) { - - UrlHandler *handler = static_cast(object); - const QString scheme = url_handlers_.key(handler); - if (!scheme.isEmpty()) { - url_handlers_.remove(scheme); - } - -} - void Player::HandleAuthentication() { Q_EMIT Authenticated(); } diff --git a/src/core/player.h b/src/core/player.h index d14e9a76be..ec6c3aeb1a 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -31,110 +31,29 @@ #include #include -#include "shared_ptr.h" -#include "urlhandler.h" +#include "includes/shared_ptr.h" +#include "core/urlhandler.h" +#include "core/enginemetadata.h" #include "engine/enginebase.h" -#include "engine/enginemetadata.h" #include "playlist/playlist.h" #include "playlist/playlistitem.h" -#include "settings/behavioursettingspage.h" +#include "constants/behavioursettings.h" +#include "playerinterface.h" class QTimer; -class Application; class Song; +class TaskManager; +class UrlHandlers; +class PlaylistManager; class AnalyzerContainer; class Equalizer; class GstStartup; -class PlayerInterface : public QObject { - Q_OBJECT - - public: - explicit PlayerInterface(QObject *parent = nullptr) : QObject(parent) {} - - virtual SharedPtr engine() const = 0; - virtual EngineBase::State GetState() const = 0; - virtual uint GetVolume() const = 0; - - virtual PlaylistItemPtr GetCurrentItem() const = 0; - virtual PlaylistItemPtr GetItemAt(const int pos) const = 0; - - virtual void RegisterUrlHandler(UrlHandler *handler) = 0; - virtual void UnregisterUrlHandler(UrlHandler *handler) = 0; - - public Q_SLOTS: - virtual void ReloadSettings() = 0; - virtual void LoadVolume() = 0; - virtual void SaveVolume() = 0; - virtual void SavePlaybackStatus() = 0; - - virtual void PlaylistsLoaded() = 0; - - // Manual track change to the specified track - virtual void PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0; - - // If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist - virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0; - virtual void PlayPauseHelper() = 0; - virtual void RestartOrPrevious() = 0; - - // Skips this track. Might load more of the current radio station. - virtual void Next() = 0; - virtual void Previous() = 0; - virtual void PlayPlaylist(const QString &playlist_name) = 0; - virtual void SetVolumeFromEngine(const uint volume) = 0; - virtual void SetVolumeFromSlider(const int value) = 0; - virtual void SetVolume(const uint volume) = 0; - virtual void VolumeUp() = 0; - virtual void VolumeDown() = 0; - virtual void SeekTo(const quint64 seconds) = 0; - // Moves the position of the currently playing song five seconds forward. - virtual void SeekForward() = 0; - // Moves the position of the currently playing song five seconds backwards. - virtual void SeekBackward() = 0; - - virtual void CurrentMetadataChanged(const Song &metadata) = 0; - - virtual void Mute() = 0; - virtual void Pause() = 0; - virtual void Stop(const bool stop_after = false) = 0; - virtual void Play(const quint64 offset_nanosec = 0) = 0; - virtual void PlayWithPause(const quint64 offset_nanosec) = 0; - virtual void PlayHelper() = 0; - virtual void ShowOSD() = 0; - - Q_SIGNALS: - void Playing(); - void Paused(); - // Emitted only when playback is manually resumed - void Resumed(); - void Stopped(); - void Error(const QString &message = QString()); - void PlaylistFinished(); - void VolumeEnabled(const bool volume_enabled); - void VolumeChanged(const uint volume); - void TrackSkipped(PlaylistItemPtr old_track); - // Emitted when there's a manual change to the current's track position. - void Seeked(const qint64 microseconds); - - // Emitted when Player has processed a request to play another song. - // This contains the URL of the song and a flag saying whether it was able to play the song. - void SongChangeRequestProcessed(const QUrl &url, const bool valid); - - // The toggle parameter is true when user requests to toggle visibility for Pretty OSD - void ForceShowOSD(const Song &song, const bool toggle); - - void Authenticated(); - -}; - class Player : public PlayerInterface { Q_OBJECT public: - explicit Player(Application *app, QObject *parent = nullptr); - - static const char *kSettingsGroup; + explicit Player(const SharedPtr task_manager, const SharedPtr url_handlers, const SharedPtr playlist_manager, QObject *parent = nullptr); EngineBase::Type CreateEngine(EngineBase::Type Type); void Init(); @@ -146,11 +65,6 @@ class Player : public PlayerInterface { PlaylistItemPtr GetCurrentItem() const override { return current_item_; } PlaylistItemPtr GetItemAt(const int pos) const override; - void RegisterUrlHandler(UrlHandler *handler) override; - void UnregisterUrlHandler(UrlHandler *handler) override; - - const UrlHandler *HandlerForUrl(const QUrl &url) const; - bool PreviousWouldRestartTrack() const; void SetAnalyzer(AnalyzerContainer *analyzer) { analyzer_ = analyzer; } @@ -158,6 +72,7 @@ class Player : public PlayerInterface { public Q_SLOTS: void ReloadSettings() override; + void LoadVolume() override; void SaveVolume() override; void SavePlaybackStatus() override; @@ -197,6 +112,8 @@ class Player : public PlayerInterface { void EngineChanged(const EngineBase::Type Type); private Q_SLOTS: + void UrlHandlerRegistered(UrlHandler *url_handler) 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 task_manager_; + const SharedPtr url_handlers_; + const SharedPtr playlist_manager_; SharedPtr engine_; GstStartup *gst_startup_; AnalyzerContainer *analyzer_; @@ -242,8 +160,6 @@ class Player : public PlayerInterface { EngineBase::State last_state_; int nb_errors_received_; - QMap url_handlers_; - QList loading_async_; uint volume_; uint volume_before_mute_; @@ -251,13 +167,12 @@ class Player : public PlayerInterface { bool continue_on_error_; bool greyout_; - BehaviourSettingsPage::PreviousBehaviour menu_previousmode_; + BehaviourSettings::PreviousBehaviour menu_previousmode_; int seek_step_sec_; uint volume_increment_; QDateTime pause_time_; quint64 play_offset_nanosec_; - }; #endif // PLAYER_H diff --git a/src/core/playerinterface.cpp b/src/core/playerinterface.cpp new file mode 100644 index 0000000000..cb03a726bb --- /dev/null +++ b/src/core/playerinterface.cpp @@ -0,0 +1,24 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2010, David Sansome + * Copyright 2018-2021, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "playerinterface.h" + +PlayerInterface::PlayerInterface(QObject *parent) : QObject(parent) {} diff --git a/src/core/playerinterface.h b/src/core/playerinterface.h new file mode 100644 index 0000000000..0e1cf5c18e --- /dev/null +++ b/src/core/playerinterface.h @@ -0,0 +1,117 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2010, David Sansome + * Copyright 2018-2021, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef PLAYERINTERFACE_H +#define PLAYERINTERFACE_H + +#include "config.h" + +#include +#include +#include + +#include "includes/shared_ptr.h" +#include "engine/enginebase.h" +#include "playlist/playlist.h" +#include "playlist/playlistitem.h" + +class QTimer; +class Song; + +class PlayerInterface : public QObject { + Q_OBJECT + + public: + explicit PlayerInterface(QObject *parent = nullptr); + + virtual SharedPtr engine() const = 0; + virtual EngineBase::State GetState() const = 0; + virtual uint GetVolume() const = 0; + + virtual PlaylistItemPtr GetCurrentItem() const = 0; + virtual PlaylistItemPtr GetItemAt(const int pos) const = 0; + + public Q_SLOTS: + virtual void ReloadSettings() = 0; + virtual void LoadVolume() = 0; + virtual void SaveVolume() = 0; + virtual void SavePlaybackStatus() = 0; + + virtual void PlaylistsLoaded() = 0; + + // Manual track change to the specified track + virtual void PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0; + + // If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist + virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0; + virtual void PlayPauseHelper() = 0; + virtual void RestartOrPrevious() = 0; + + // Skips this track. Might load more of the current radio station. + virtual void Next() = 0; + virtual void Previous() = 0; + virtual void PlayPlaylist(const QString &playlist_name) = 0; + virtual void SetVolumeFromEngine(const uint volume) = 0; + virtual void SetVolumeFromSlider(const int value) = 0; + virtual void SetVolume(const uint volume) = 0; + virtual void VolumeUp() = 0; + virtual void VolumeDown() = 0; + virtual void SeekTo(const quint64 seconds) = 0; + // Moves the position of the currently playing song five seconds forward. + virtual void SeekForward() = 0; + // Moves the position of the currently playing song five seconds backwards. + virtual void SeekBackward() = 0; + + virtual void CurrentMetadataChanged(const Song &metadata) = 0; + + virtual void Mute() = 0; + virtual void Pause() = 0; + virtual void Stop(const bool stop_after = false) = 0; + virtual void Play(const quint64 offset_nanosec = 0) = 0; + virtual void PlayWithPause(const quint64 offset_nanosec) = 0; + virtual void PlayHelper() = 0; + virtual void ShowOSD() = 0; + + Q_SIGNALS: + void Playing(); + void Paused(); + // Emitted only when playback is manually resumed + void Resumed(); + void Stopped(); + void Error(const QString &message = QString()); + void PlaylistFinished(); + void VolumeEnabled(const bool volume_enabled); + void VolumeChanged(const uint volume); + void TrackSkipped(PlaylistItemPtr old_track); + // Emitted when there's a manual change to the current's track position. + void Seeked(const qint64 microseconds); + + // Emitted when Player has processed a request to play another song. + // This contains the URL of the song and a flag saying whether it was able to play the song. + void SongChangeRequestProcessed(const QUrl &url, const bool valid); + + // The toggle parameter is true when user requests to toggle visibility for Pretty OSD + void ForceShowOSD(const Song &song, const bool toggle); + + void Authenticated(); +}; + +#endif // PLAYERINTERFACE_H diff --git a/src/core/song.cpp b/src/core/song.cpp index 3b7774c964..2f51e27325 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -51,11 +51,11 @@ #include #include "core/iconloader.h" -#include "engine/enginemetadata.h" +#include "core/enginemetadata.h" #include "utilities/strutils.h" #include "utilities/timeutils.h" #include "utilities/coverutils.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" #include "utilities/sqlhelper.h" #include "song.h" @@ -1960,3 +1960,43 @@ QString Song::TitleRemoveMisc(const QString &title) { return StripRegexList(title, kTitleMisc); } + +QString Song::GetNameForNewPlaylist(const SongList &songs) { + + if (songs.isEmpty()) { + return QObject::tr("Playlist"); + } + + QSet artists; + QSet albums; + artists.reserve(songs.count()); + albums.reserve(songs.count()); + for (const Song &song : songs) { + artists << (song.effective_albumartist().isEmpty() ? QObject::tr("Unknown") : song.effective_albumartist()); + albums << (song.album().isEmpty() ? QObject::tr("Unknown") : song.album()); + + if (artists.size() > 1) { + break; + } + } + + bool various_artists = artists.size() > 1; + + QString result; + if (various_artists) { + result = QObject::tr("Various artists"); + } + else { + QStringList artist_names = artists.values(); + result = artist_names.first(); + } + + if (!various_artists && albums.size() == 1) { + QStringList album_names = albums.values(); + result += " - "_L1 + album_names.first(); + } + + return result; + +} + diff --git a/src/core/song.h b/src/core/song.h index fcd5136995..a0f6bc2053 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -509,6 +509,8 @@ class Song { static QString AlbumRemoveDiscMisc(const QString &album); static QString TitleRemoveMisc(const QString &title); + static QString GetNameForNewPlaylist(const QList &songs); + static inline QString TagLibStringToQString(const TagLib::String &s) { return QString::fromUtf8((s).toCString(true)); } diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index a953fc00a4..7f3c1566e1 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -39,15 +39,13 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" - -#include "shared_ptr.h" -#include "signalchecker.h" -#include "player.h" -#include "song.h" +#include "core/signalchecker.h" +#include "core/song.h" +#include "core/database.h" +#include "core/urlhandlers.h" #include "songloader.h" -#include "database.h" -#include "engine/enginebase.h" #include "tagreader/tagreaderclient.h" #include "collection/collectionbackend.h" #include "playlistparsers/cueparser.h" @@ -66,13 +64,17 @@ constexpr int kDefaultTimeout = 5000; QSet SongLoader::sRawUriSchemes; -SongLoader::SongLoader(SharedPtr collection_backend, const SharedPtr player, QObject *parent) +SongLoader::SongLoader(const SharedPtr url_handlers, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + QObject *parent) : QObject(parent), - player_(player), + url_handlers_(url_handlers), collection_backend_(collection_backend), + tagreader_client_(tagreader_client), timeout_timer_(new QTimer(this)), - playlist_parser_(new PlaylistParser(collection_backend, this)), - cue_parser_(new CueParser(collection_backend, this)), + playlist_parser_(new PlaylistParser(tagreader_client, collection_backend, this)), + cue_parser_(new CueParser(tagreader_client, collection_backend, this)), parser_(nullptr), state_(State::WaitingForType), timeout_(kDefaultTimeout), @@ -114,23 +116,16 @@ SongLoader::Result SongLoader::Load(const QUrl &url) { return LoadLocal(url_.toLocalFile()); } - if (sRawUriSchemes.contains(url_.scheme()) || player_->HandlerForUrl(url)) { + if (sRawUriSchemes.contains(url_.scheme()) || url_handlers_->CanHandle(url)) { // The URI scheme indicates that it can't possibly be a playlist, // or we have a custom handler for the URL, so add it as a raw stream. AddAsRawStream(); return Result::Success; } - if (player_->engine()->type() == EngineBase::Type::GStreamer) { - preload_func_ = std::bind(&SongLoader::LoadRemote, this); - return Result::BlockingLoadRequired; - } - else { - errors_ << tr("You need GStreamer for this URL."); - return Result::Error; - } + preload_func_ = std::bind(&SongLoader::LoadRemote, this); - return Result::Success; + return Result::BlockingLoadRequired; } @@ -165,7 +160,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) { // Assume it's just a normal file if (!Song::kRejectedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive) && - (TagReaderClient::Instance()->IsMediaFileBlocking(filename) || + (tagreader_client_->IsMediaFileBlocking(filename) || Song::kAcceptedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive))) { Song song(Song::Source::LocalFile); song.InitFromFilePartial(filename, fileinfo); @@ -183,19 +178,14 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) { SongLoader::Result SongLoader::LoadAudioCD() { #ifdef HAVE_AUDIOCD - if (player_->engine()->type() == EngineBase::Type::GStreamer) { - CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this); - QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot); - QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded); - cdda_song_loader->LoadSongs(); - return Result::Success; - } - else { -#endif - errors_ << tr("CD playback is only available with the GStreamer engine."); - return Result::Error; -#ifdef HAVE_AUDIOCD - } + CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this); + QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot); + QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded); + cdda_song_loader->LoadSongs(); + return Result::Success; +#else + errors_ << tr("Missing CDDA playback."); + return Result::Error; #endif } @@ -306,7 +296,7 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { // Assume it's just a normal file if (!Song::kRejectedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive) && - (TagReaderClient::Instance()->IsMediaFileBlocking(filename) || + (tagreader_client_->IsMediaFileBlocking(filename) || Song::kAcceptedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive))) { Song song(Song::Source::LocalFile); song.InitFromFilePartial(filename, fileinfo); @@ -346,7 +336,7 @@ void SongLoader::EffectiveSongLoad(Song *song) { else { // It's a normal media file const QString filename = song->url().toLocalFile(); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(filename, song); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(filename, song); if (!result.success()) { qLog(Error) << "Could not read file" << song->url() << result.error_string(); } diff --git a/src/core/songloader.h b/src/core/songloader.h index 1d4db35aed..0666e6827e 100644 --- a/src/core/songloader.h +++ b/src/core/songloader.h @@ -38,11 +38,12 @@ #include #include -#include "shared_ptr.h" -#include "song.h" +#include "includes/shared_ptr.h" +#include "core/song.h" class QTimer; -class Player; +class UrlHandlers; +class TagReaderClient; class CollectionBackendInterface; class PlaylistParser; class ParserBase; @@ -56,7 +57,11 @@ class SongLoader : public QObject { Q_OBJECT public: - explicit SongLoader(SharedPtr collection_backend, const SharedPtr player, QObject *parent = nullptr); + explicit SongLoader(const SharedPtr url_handlers, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + QObject *parent = nullptr); + ~SongLoader() override; enum class Result { @@ -137,8 +142,9 @@ class SongLoader : public QObject { QUrl url_; SongList songs_; - const SharedPtr player_; - SharedPtr collection_backend_; + const SharedPtr url_handlers_; + const SharedPtr collection_backend_; + const SharedPtr tagreader_client_; QTimer *timeout_timer_; PlaylistParser *playlist_parser_; CueParser *cue_parser_; diff --git a/src/playlist/songmimedata.cpp b/src/core/songmimedata.cpp similarity index 100% rename from src/playlist/songmimedata.cpp rename to src/core/songmimedata.cpp diff --git a/src/playlist/songmimedata.h b/src/core/songmimedata.h similarity index 95% rename from src/playlist/songmimedata.h rename to src/core/songmimedata.h index f206d24a1f..91f039f838 100644 --- a/src/playlist/songmimedata.h +++ b/src/core/songmimedata.h @@ -24,8 +24,8 @@ #include "config.h" -#include "core/shared_ptr.h" -#include "core/mimedata.h" +#include "includes/shared_ptr.h" +#include "mimedata.h" #include "core/song.h" class CollectionBackendInterface; diff --git a/src/core/stylesheetloader.cpp b/src/core/stylesheetloader.cpp index 73337285a0..4515ceaa03 100644 --- a/src/core/stylesheetloader.cpp +++ b/src/core/stylesheetloader.cpp @@ -35,8 +35,8 @@ #include #include -#include "shared_ptr.h" -#include "core/logging.h" +#include "includes/shared_ptr.h" +#include "logging.h" #include "stylesheetloader.h" using namespace Qt::Literals::StringLiterals; diff --git a/src/core/stylesheetloader.h b/src/core/stylesheetloader.h index b48302fedb..54fd059018 100644 --- a/src/core/stylesheetloader.h +++ b/src/core/stylesheetloader.h @@ -30,7 +30,7 @@ #include #include -#include "shared_ptr.h" +#include "includes/shared_ptr.h" class QWidget; class QEvent; diff --git a/src/core/translations.cpp b/src/core/translations.cpp index ffbea56f03..b7f2a3179c 100644 --- a/src/core/translations.cpp +++ b/src/core/translations.cpp @@ -30,7 +30,7 @@ using namespace Qt::Literals::StringLiterals; -Translations::Translations() {} +Translations::Translations() = default; Translations::~Translations() { diff --git a/src/core/urlhandler.cpp b/src/core/urlhandler.cpp index 2cd333f148..e12ed9ce17 100644 --- a/src/core/urlhandler.cpp +++ b/src/core/urlhandler.cpp @@ -1,8 +1,6 @@ /* * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2018, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/urlhandler.h b/src/core/urlhandler.h index 80d5a0e289..9fabbe184e 100644 --- a/src/core/urlhandler.h +++ b/src/core/urlhandler.h @@ -1,8 +1,6 @@ /* * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2018, Jonas Kvinge + * Copyright 2018-2024, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/urlhandlers.cpp b/src/core/urlhandlers.cpp new file mode 100644 index 0000000000..7b9916bf9f --- /dev/null +++ b/src/core/urlhandlers.cpp @@ -0,0 +1,95 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include + +#include "core/logging.h" + +#include "urlhandlers.h" +#include "urlhandler.h" + +UrlHandlers::UrlHandlers(QObject *parent) : QObject(parent) {} + +void UrlHandlers::Register(UrlHandler *url_handler) { + + const QString scheme = url_handler->scheme(); + + if (url_handlers_.contains(scheme)) { + qLog(Warning) << "Tried to register a URL handler for" << scheme << "but one was already registered"; + return; + } + + qLog(Info) << "Registered URL handler for" << scheme; + url_handlers_.insert(scheme, url_handler); + QObject::connect(url_handler, &UrlHandler::destroyed, this, &UrlHandlers::Destroyed); + + Q_EMIT Registered(url_handler); + +} + +void UrlHandlers::Unregister(UrlHandler *url_handler) { + + const QString scheme = url_handlers_.key(url_handler); + if (scheme.isEmpty()) { + qLog(Warning) << "Tried to unregister a URL handler for" << url_handler->scheme() << "that wasn't registered"; + return; + } + + qLog(Info) << "Unregistered URL handler for" << scheme; + url_handlers_.remove(scheme); + QObject::disconnect(url_handler, &UrlHandler::destroyed, this, &UrlHandlers::Destroyed); + QObject::disconnect(url_handler, &UrlHandler::AsyncLoadComplete, nullptr, nullptr); + +} + +void UrlHandlers::Destroyed(QObject *object) { + + UrlHandler *handler = static_cast(object); + const QString scheme = url_handlers_.key(handler); + if (!scheme.isEmpty()) { + url_handlers_.remove(scheme); + } + +} + +bool UrlHandlers::CanHandle(const QString &scheme) const { + + return url_handlers_.contains(scheme); + +} + +bool UrlHandlers::CanHandle(const QUrl &url) const { + + return url_handlers_.contains(url.scheme()); + +} + +UrlHandler *UrlHandlers::GetUrlHandler(const QString &scheme) const { + + if (!CanHandle(scheme)) return nullptr; + + return url_handlers_.value(scheme); + +} + +UrlHandler *UrlHandlers::GetUrlHandler(const QUrl &url) const { + + return GetUrlHandler(url.scheme()); + +} diff --git a/src/core/urlhandlers.h b/src/core/urlhandlers.h new file mode 100644 index 0000000000..c7d7219004 --- /dev/null +++ b/src/core/urlhandlers.h @@ -0,0 +1,56 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef URLHANDLERS_H +#define URLHANDLERS_H + +#include "config.h" + +#include +#include +#include +#include + +class UrlHandler; + +class UrlHandlers : public QObject { + Q_OBJECT + + public: + explicit UrlHandlers(QObject *parent = nullptr); + + void Register(UrlHandler *url_handler); + void Unregister(UrlHandler *url_handler); + void Destroyed(QObject *object); + + bool CanHandle(const QString &scheme) const; + bool CanHandle(const QUrl &url) const; + + UrlHandler *GetUrlHandler(const QString &scheme) const; + UrlHandler *GetUrlHandler(const QUrl &url) const; + + Q_SIGNALS: + void Registered(UrlHandler *url_handler); + void UnRegistered(UrlHandler *url_handler); + + private: + QMap url_handlers_; +}; + +#endif // URLHANDLERS_H diff --git a/src/covermanager/CMakeLists.txt b/src/covermanager/CMakeLists.txt new file mode 100644 index 0000000000..f902a02283 --- /dev/null +++ b/src/covermanager/CMakeLists.txt @@ -0,0 +1,119 @@ +set(COVERMANAGER_SOURCES + albumcovermanager.cpp + albumcovermanagerlist.cpp + albumcoverloader.cpp + albumcoverloaderoptions.cpp + albumcoverfetcher.cpp + albumcoverfetchersearch.cpp + albumcoversearcher.cpp + albumcoverexport.cpp + albumcoverexporter.cpp + albumcoverchoicecontroller.cpp + coverprovider.cpp + coverproviders.cpp + coversearchstatistics.cpp + coversearchstatisticsdialog.cpp + coverexportrunnable.cpp + currentalbumcoverloader.cpp + coverfromurldialog.cpp + jsoncoverprovider.cpp + lastfmcoverprovider.cpp + musicbrainzcoverprovider.cpp + discogscoverprovider.cpp + deezercoverprovider.cpp + musixmatchcoverprovider.cpp + opentidalcoverprovider.cpp +) + +set(COVERMANAGER_HEADERS + albumcovermanager.h + albumcovermanagerlist.h + albumcoverloader.h + albumcoverfetcher.h + albumcoverfetchersearch.h + albumcoversearcher.h + albumcoverexport.h + albumcoverexporter.h + albumcoverchoicecontroller.h + coverprovider.h + coverproviders.h + coversearchstatisticsdialog.h + coverexportrunnable.h + currentalbumcoverloader.h + coverfromurldialog.h + jsoncoverprovider.h + lastfmcoverprovider.h + musicbrainzcoverprovider.h + discogscoverprovider.h + deezercoverprovider.h + musixmatchcoverprovider.h + opentidalcoverprovider.h +) + +set(COVERMANAGER_UI + albumcoverexport.ui + albumcovermanager.ui + albumcoversearcher.ui + coversearchstatisticsdialog.ui + coverfromurldialog.ui +) + +if(HAVE_TIDAL) + list(APPEND COVERMANAGER_SOURCES tidalcoverprovider.cpp) + list(APPEND COVERMANAGER_HEADERS tidalcoverprovider.h) +endif() + +if(HAVE_SPOTIFY) + list(APPEND COVERMANAGER_SOURCES spotifycoverprovider.cpp) + list(APPEND COVERMANAGER_HEADERS spotifycoverprovider.h) +endif() + +if(HAVE_QOBUZ) + list(APPEND COVERMANAGER_SOURCES qobuzcoverprovider.cpp) + list(APPEND COVERMANAGER_HEADERS qobuzcoverprovider.h) +endif() + +qt_wrap_cpp(COVERMANAGER_SOURCES ${COVERMANAGER_HEADERS}) +qt_wrap_ui(COVERMANAGER_SOURCES ${COVERMANAGER_UI}) + +add_library(strawberry_covermanager STATIC ${COVERMANAGER_SOURCES}) + +target_include_directories(strawberry_covermanager PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_covermanager PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core + strawberry_tagreader + strawberry_collection + strawberry_streaming + strawberry_widgets +) + +if(HAVE_SUBSONIC) + target_link_libraries(strawberry_covermanager PRIVATE strawberry_subsonic) +endif() + +if(HAVE_TIDAL) + target_link_libraries(strawberry_covermanager PRIVATE strawberry_tidal) +endif() + +if(HAVE_SPOTIFY) + target_link_libraries(strawberry_covermanager PRIVATE strawberry_spotify) +endif() + +if(HAVE_QOBUZ) + target_link_libraries(strawberry_covermanager PRIVATE strawberry_qobuz) +endif() diff --git a/src/covermanager/albumcoverchoicecontroller.cpp b/src/covermanager/albumcoverchoicecontroller.cpp index 2b09741bf6..c4328b9dd5 100644 --- a/src/covermanager/albumcoverchoicecontroller.cpp +++ b/src/covermanager/albumcoverchoicecontroller.cpp @@ -54,20 +54,21 @@ #include #include -#include "utilities/filenameconstants.h" +#include "constants/filenameconstants.h" +#include "constants/filefilterconstants.h" +#include "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 *AlbumCoverChoiceController::sImageExtensions = nullptr; AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget *parent) : QWidget(parent), - app_(nullptr), cover_searcher_(nullptr), cover_fetcher_(nullptr), save_file_dialog_(nullptr), @@ -130,12 +126,22 @@ AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget *parent) AlbumCoverChoiceController::~AlbumCoverChoiceController() = default; -void AlbumCoverChoiceController::Init(Application *app) { - - app_ = app; - - cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), app->network(), this); - cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), app, this); +void AlbumCoverChoiceController::Init(const SharedPtr network, + const SharedPtr tagreader_client, + const SharedPtr collection_backend, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr streaming_services) { + + network_ = network; + tagreader_client_ = tagreader_client; + collection_backend_ = collection_backend; + current_albumcover_loader_ = current_albumcover_loader; + streaming_services_ = streaming_services; + + cover_fetcher_ = new AlbumCoverFetcher(cover_providers, network, this); + cover_searcher_ = new AlbumCoverSearcher(QIcon(u":/pictures/cdcase.png"_s), albumcover_loader, this); cover_searcher_->Init(cover_fetcher_); QObject::connect(cover_fetcher_, &AlbumCoverFetcher::AlbumCoverFetched, this, &AlbumCoverChoiceController::AlbumCoverFetched); @@ -145,13 +151,13 @@ void AlbumCoverChoiceController::Init(Application *app) { void AlbumCoverChoiceController::ReloadSettings() { Settings s; - s.beginGroup(CoversSettingsPage::kSettingsGroup); - cover_options_.cover_type = static_cast(s.value(CoversSettingsPage::kSaveType, static_cast(CoverOptions::CoverType::Cache)).toInt()); - cover_options_.cover_filename = static_cast(s.value(CoversSettingsPage::kSaveFilename, static_cast(CoverOptions::CoverFilename::Pattern)).toInt()); - cover_options_.cover_pattern = s.value(CoversSettingsPage::kSavePattern, u"%albumartist-%album"_s).toString(); - cover_options_.cover_overwrite = s.value(CoversSettingsPage::kSaveOverwrite, false).toBool(); - cover_options_.cover_lowercase = s.value(CoversSettingsPage::kSaveLowercase, false).toBool(); - cover_options_.cover_replace_spaces = s.value(CoversSettingsPage::kSaveReplaceSpaces, false).toBool(); + s.beginGroup(CoversSettings::kSettingsGroup); + cover_options_.cover_type = static_cast(s.value(CoversSettings::kSaveType, static_cast(CoverOptions::CoverType::Cache)).toInt()); + cover_options_.cover_filename = static_cast(s.value(CoversSettings::kSaveFilename, static_cast(CoverOptions::CoverFilename::Pattern)).toInt()); + cover_options_.cover_pattern = s.value(CoversSettings::kSavePattern, u"%albumartist-%album"_s).toString(); + cover_options_.cover_overwrite = s.value(CoversSettings::kSaveOverwrite, false).toBool(); + cover_options_.cover_lowercase = s.value(CoversSettings::kSaveLowercase, false).toBool(); + cover_options_.cover_replace_spaces = s.value(CoversSettings::kSaveReplaceSpaces, false).toBool(); s.endGroup(); cover_types_ = AlbumCoverLoaderOptions::LoadTypes(); @@ -179,7 +185,7 @@ AlbumCoverImageResult AlbumCoverChoiceController::LoadImageFromFile(Song *song) return AlbumCoverImageResult(); } - QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilter)); + QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (cover_file.isEmpty()) return AlbumCoverImageResult(); QFile file(cover_file); @@ -210,7 +216,7 @@ QUrl AlbumCoverChoiceController::LoadCoverFromFile(Song *song) { if (!song->url().isValid() || !song->url().isLocalFile() || song->effective_albumartist().isEmpty() || song->album().isEmpty()) return QUrl(); - QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilter)); + QString cover_file = QFileDialog::getOpenFileName(this, tr("Load cover from disk"), GetInitialPathForFileDialog(*song, QString()), tr(kLoadImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (cover_file.isEmpty() || QImage(cover_file).isNull()) return QUrl(); switch (get_save_album_cover_type()) { @@ -246,7 +252,7 @@ void AlbumCoverChoiceController::SaveCoverToFileManual(const Song &song, const A static const QRegularExpression regex_invalid_fat_characters(QLatin1String(kInvalidFatCharactersRegex), QRegularExpression::CaseInsensitiveOption); initial_file_name.remove(regex_invalid_fat_characters); - QString save_filename = QFileDialog::getSaveFileName(this, tr("Save album cover"), GetInitialPathForFileDialog(song, initial_file_name), tr(kSaveImageFileFilter) + u";;"_s + tr(kAllFilesFilter)); + QString save_filename = QFileDialog::getSaveFileName(this, tr("Save album cover"), GetInitialPathForFileDialog(song, initial_file_name), tr(kSaveImageFileFilter) + u";;"_s + tr(kAllFilesFilterSpec)); if (save_filename.isEmpty()) return; @@ -316,7 +322,7 @@ void AlbumCoverChoiceController::LoadCoverFromURL(Song *song) { AlbumCoverImageResult AlbumCoverChoiceController::LoadImageFromURL() { - if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(app_->network(), this); } + if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(network_, this); } return cover_from_url_dialog_->Exec(); @@ -446,7 +452,7 @@ void AlbumCoverChoiceController::ShowCover(const Song &song, const QImage &image case AlbumCoverLoaderOptions::Type::Embedded:{ if (song.art_embedded() && !song.url().isEmpty() && song.url().isValid() && song.url().isLocalFile()) { QImage image_embedded_cover; - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(song.url().toLocalFile(), image_embedded_cover); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(song.url().toLocalFile(), image_embedded_cover); if (result.success() && !image_embedded_cover.isNull()) { QPixmap pixmap = QPixmap::fromImage(image_embedded_cover); if (!pixmap.isNull()) { @@ -548,11 +554,11 @@ void AlbumCoverChoiceController::SaveArtEmbeddedToSong(Song *song, const bool ar song->set_art_unset(false); if (song->source() == Song::Source::Collection) { - app_->collection_backend()->UpdateEmbeddedAlbumArtAsync(song->effective_albumartist(), song->album(), art_embedded); + collection_backend_->UpdateEmbeddedAlbumArtAsync(song->effective_albumartist(), song->album(), art_embedded); } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -567,7 +573,7 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art // Update the backends. switch (song->source()) { case Song::Source::Collection: - app_->collection_backend()->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual); + collection_backend_->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual); break; case Song::Source::LocalFile: case Song::Source::CDDA: @@ -581,7 +587,7 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art case Song::Source::Tidal: case Song::Source::Spotify: case Song::Source::Qobuz: - StreamingServicePtr service = app_->streaming_services()->ServiceBySource(song->source()); + StreamingServicePtr service = streaming_services_->ServiceBySource(song->source()); if (!service) break; if (service->artists_collection_backend()) { service->artists_collection_backend()->UpdateManualAlbumArtAsync(song->effective_albumartist(), song->album(), art_manual); @@ -595,8 +601,8 @@ void AlbumCoverChoiceController::SaveArtManualToSong(Song *song, const QUrl &art break; } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -611,11 +617,11 @@ void AlbumCoverChoiceController::ClearAlbumCoverForSong(Song *song) { song->clear_art_manual(); if (song->source() == Song::Source::Collection) { - app_->collection_backend()->ClearAlbumArtAsync(song->effective_albumartist(), song->album(), false); + collection_backend_->ClearAlbumArtAsync(song->effective_albumartist(), song->album(), false); } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -630,11 +636,11 @@ void AlbumCoverChoiceController::UnsetAlbumCoverForSong(Song *song) { song->clear_art_automatic(); if (song->source() == Song::Source::Collection) { - app_->collection_backend()->UnsetAlbumArtAsync(song->effective_albumartist(), song->album()); + collection_backend_->UnsetAlbumArtAsync(song->effective_albumartist(), song->album()); } - if (*song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(*song); + if (*song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(*song); } } @@ -718,7 +724,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToCollectionSongs(const Song & void AlbumCoverChoiceController::SaveCoverEmbeddedToCollectionSongs(const QString &effective_albumartist, const QString &effective_album, const QString &cover_filename, const QByteArray &image_data, const QString &mime_type) { - QFuture future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, app_->collection_backend(), effective_albumartist, effective_album, CollectionFilterOptions()); + QFuture future = QtConcurrent::run(&CollectionBackend::GetAlbumSongs, collection_backend_, effective_albumartist, effective_album, CollectionFilterOptions()); QFutureWatcher *watcher = new QFutureWatcher(); QObject::connect(watcher, &QFutureWatcher::finished, this, [this, watcher, cover_filename, image_data, mime_type]() { const SongList collection_songs = watcher->result(); @@ -736,7 +742,7 @@ void AlbumCoverChoiceController::SaveCoverEmbeddedToSong(const Song &song, const QMutexLocker l(&mutex_cover_save_tasks_); cover_save_tasks_.append(song); const bool art_embedded = !image_data.isNull(); - TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(song.url().toLocalFile(), SaveTagCoverData(cover_filename, image_data, mime_type)); + TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(song.url().toLocalFile(), SaveTagCoverData(cover_filename, image_data, mime_type)); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, song, art_embedded]() { SaveEmbeddedCoverFinished(reply, song, art_embedded); }); } diff --git a/src/covermanager/albumcoverchoicecontroller.h b/src/covermanager/albumcoverchoicecontroller.h index 6132e21739..ce1962c391 100644 --- a/src/covermanager/albumcoverchoicecontroller.h +++ b/src/covermanager/albumcoverchoicecontroller.h @@ -50,25 +50,33 @@ class QMenu; class QDragEnterEvent; class QDropEvent; -class Application; +class NetworkAccessManager; +class CollectionBackend; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; class AlbumCoverFetcher; class AlbumCoverSearcher; class CoverFromURLDialog; struct CoverSearchStatistics; +class StreamingServices; // Controller for the common album cover related menu options. class AlbumCoverChoiceController : public QWidget { Q_OBJECT public: - static const char *kLoadImageFileFilter; - static const char *kSaveImageFileFilter; - static const char *kAllFilesFilter; - explicit AlbumCoverChoiceController(QWidget *parent = nullptr); ~AlbumCoverChoiceController() override; - void Init(Application *app); + void Init(const SharedPtr network, + const SharedPtr tagreader_client, + const SharedPtr collection_backend, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr streaming_services); + void ReloadSettings(); CoverOptions::CoverType get_save_album_cover_type() const { return (save_embedded_cover_override_ ? CoverOptions::CoverType::Embedded : cover_options_.cover_type); } @@ -172,7 +180,12 @@ class AlbumCoverChoiceController : public QWidget { static bool IsKnownImageExtension(const QString &suffix); static QSet *sImageExtensions; - Application *app_; + SharedPtr current_albumcover_loader_; + SharedPtr network_; + SharedPtr tagreader_client_; + SharedPtr collection_backend_; + SharedPtr streaming_services_; + AlbumCoverSearcher *cover_searcher_; AlbumCoverFetcher *cover_fetcher_; diff --git a/src/covermanager/albumcoverexport.cpp b/src/covermanager/albumcoverexport.cpp index 121c8c2d43..e1ead40079 100644 --- a/src/covermanager/albumcoverexport.cpp +++ b/src/covermanager/albumcoverexport.cpp @@ -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) { diff --git a/src/covermanager/albumcoverexport.h b/src/covermanager/albumcoverexport.h index 324fd3fcb9..6d8ec6a4bd 100644 --- a/src/covermanager/albumcoverexport.h +++ b/src/covermanager/albumcoverexport.h @@ -78,8 +78,6 @@ class AlbumCoverExport : public QDialog { private: Ui_AlbumCoverExport *ui_; - - static const char *kSettingsGroup; }; #endif // ALBUMCOVEREXPORT_H diff --git a/src/covermanager/albumcoverexporter.cpp b/src/covermanager/albumcoverexporter.cpp index a47e78b776..4b1cc5ef1f 100644 --- a/src/covermanager/albumcoverexporter.cpp +++ b/src/covermanager/albumcoverexporter.cpp @@ -33,8 +33,9 @@ namespace { constexpr int kMaxConcurrentRequests = 3; } -AlbumCoverExporter::AlbumCoverExporter(QObject *parent) +AlbumCoverExporter::AlbumCoverExporter(const SharedPtr tagreader_client, QObject *parent) : QObject(parent), + tagreader_client_(tagreader_client), thread_pool_(new QThreadPool(this)), exported_(0), skipped_(0), @@ -52,7 +53,7 @@ void AlbumCoverExporter::SetCoverTypes(const AlbumCoverLoaderOptions::Types &cov void AlbumCoverExporter::AddExportRequest(const Song &song) { - requests_.append(new CoverExportRunnable(dialog_result_, cover_types_, song)); + requests_.append(new CoverExportRunnable(tagreader_client_, dialog_result_, cover_types_, song)); all_ = static_cast(requests_.count()); } diff --git a/src/covermanager/albumcoverexporter.h b/src/covermanager/albumcoverexporter.h index c77eb3af34..95dea3dd6f 100644 --- a/src/covermanager/albumcoverexporter.h +++ b/src/covermanager/albumcoverexporter.h @@ -27,18 +27,21 @@ #include #include +#include "includes/shared_ptr.h" + #include "albumcoverloaderoptions.h" #include "albumcoverexport.h" class QThreadPool; class Song; class CoverExportRunnable; +class TagReaderClient; class AlbumCoverExporter : public QObject { Q_OBJECT public: - explicit AlbumCoverExporter(QObject *parent = nullptr); + explicit AlbumCoverExporter(const SharedPtr tagreader_client, QObject *parent = nullptr); void SetDialogResult(const AlbumCoverExport::DialogResult &dialog_result); void SetCoverTypes(const AlbumCoverLoaderOptions::Types &cover_types); @@ -58,6 +61,8 @@ class AlbumCoverExporter : public QObject { private: void AddJobsToPool(); + const SharedPtr tagreader_client_; + AlbumCoverLoaderOptions::Types cover_types_; AlbumCoverExport::DialogResult dialog_result_; diff --git a/src/covermanager/albumcoverfetcher.cpp b/src/covermanager/albumcoverfetcher.cpp index dae4169003..f57a1fcb53 100644 --- a/src/covermanager/albumcoverfetcher.cpp +++ b/src/covermanager/albumcoverfetcher.cpp @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "albumcoverfetcher.h" diff --git a/src/covermanager/albumcoverfetcher.h b/src/covermanager/albumcoverfetcher.h index ece2d46c32..b3a0c33e3a 100644 --- a/src/covermanager/albumcoverfetcher.h +++ b/src/covermanager/albumcoverfetcher.h @@ -36,7 +36,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "coversearchstatistics.h" #include "albumcoverimageresult.h" diff --git a/src/covermanager/albumcoverfetchersearch.cpp b/src/covermanager/albumcoverfetchersearch.cpp index e2d8ed6a08..00a739289b 100644 --- a/src/covermanager/albumcoverfetchersearch.cpp +++ b/src/covermanager/albumcoverfetchersearch.cpp @@ -36,8 +36,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/networktimeouts.h" #include "utilities/imageutils.h" diff --git a/src/covermanager/albumcoverfetchersearch.h b/src/covermanager/albumcoverfetchersearch.h index 99eb54b60c..b8d9bf60ba 100644 --- a/src/covermanager/albumcoverfetchersearch.h +++ b/src/covermanager/albumcoverfetchersearch.h @@ -35,7 +35,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "albumcoverfetcher.h" #include "coversearchstatistics.h" #include "albumcoverimageresult.h" diff --git a/src/covermanager/albumcoverloader.cpp b/src/covermanager/albumcoverloader.cpp index 6d016ac087..705b096357 100644 --- a/src/covermanager/albumcoverloader.cpp +++ b/src/covermanager/albumcoverloader.cpp @@ -36,6 +36,7 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" #include "core/song.h" @@ -54,8 +55,9 @@ namespace { constexpr int kMaxRedirects = 3; } -AlbumCoverLoader::AlbumCoverLoader(QObject *parent) +AlbumCoverLoader::AlbumCoverLoader(const SharedPtr tagreader_client, QObject *parent) : QObject(parent), + tagreader_client_(tagreader_client), network_(new NetworkAccessManager(this)), timer_process_tasks_(new QTimer(this)), stop_requested_(false), @@ -318,7 +320,7 @@ AlbumCoverLoader::LoadImageResult AlbumCoverLoader::LoadImage(TaskPtr task, cons AlbumCoverLoader::LoadImageResult AlbumCoverLoader::LoadEmbeddedImage(TaskPtr task) { if (task->art_embedded && task->song_url.isValid() && task->song_url.isLocalFile()) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverDataBlocking(task->song_url.toLocalFile(), task->album_cover.image_data); + const TagReaderResult result = tagreader_client_->LoadCoverDataBlocking(task->song_url.toLocalFile(), task->album_cover.image_data); if (result.success() && !task->album_cover.image_data.isEmpty() && task->album_cover.image.loadFromData(task->album_cover.image_data)) { return LoadImageResult(AlbumCoverLoaderResult::Type::Embedded, LoadImageResult::Status::Success); } diff --git a/src/covermanager/albumcoverloader.h b/src/covermanager/albumcoverloader.h index 6ea2117b54..979d879b28 100644 --- a/src/covermanager/albumcoverloader.h +++ b/src/covermanager/albumcoverloader.h @@ -32,7 +32,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "albumcoverloaderoptions.h" #include "albumcoverloaderresult.h" @@ -42,12 +42,13 @@ class QThread; class QTimer; class QNetworkReply; class NetworkAccessManager; +class TagReaderClient; class AlbumCoverLoader : public QObject { Q_OBJECT public: - explicit AlbumCoverLoader(QObject *parent = nullptr); + explicit AlbumCoverLoader(const SharedPtr 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 network_; + const SharedPtr tagreader_client_; + const SharedPtr network_; QTimer *timer_process_tasks_; bool stop_requested_; QMutex mutex_load_image_async_; diff --git a/src/covermanager/albumcoverloaderoptions.cpp b/src/covermanager/albumcoverloaderoptions.cpp index 5a6c7f3ee1..155e458d21 100644 --- a/src/covermanager/albumcoverloaderoptions.cpp +++ b/src/covermanager/albumcoverloaderoptions.cpp @@ -22,7 +22,7 @@ #include #include "core/settings.h" -#include "settings/coverssettingspage.h" +#include "constants/coverssettings.h" using namespace Qt::Literals::StringLiterals; @@ -37,9 +37,9 @@ AlbumCoverLoaderOptions::Types AlbumCoverLoaderOptions::LoadTypes() { Types cover_types; Settings s; - s.beginGroup(CoversSettingsPage::kSettingsGroup); + s.beginGroup(CoversSettings::kSettingsGroup); const QStringList all_cover_types = QStringList() << u"art_unset"_s << u"art_embedded"_s << u"art_manual"_s << u"art_automatic"_s; - const QStringList cover_types_strlist = s.value(CoversSettingsPage::kTypes, all_cover_types).toStringList(); + const QStringList cover_types_strlist = s.value(CoversSettings::kTypes, all_cover_types).toStringList(); for (const QString &cover_type_str : cover_types_strlist) { if (cover_type_str == "art_unset"_L1) { cover_types << AlbumCoverLoaderOptions::Type::Unset; diff --git a/src/covermanager/albumcovermanager.cpp b/src/covermanager/albumcovermanager.cpp index 95193c5e57..2dd24e2c59 100644 --- a/src/covermanager/albumcovermanager.cpp +++ b/src/covermanager/albumcovermanager.cpp @@ -61,13 +61,14 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/application.h" #include "core/iconloader.h" -#include "core/database.h" #include "core/settings.h" +#include "core/database.h" +#include "core/networkaccessmanager.h" +#include "mimedata/songmimedata.h" #include "utilities/strutils.h" #include "utilities/fileutils.h" #include "utilities/imageutils.h" @@ -78,8 +79,6 @@ #include "tagreader/tagreaderclient.h" #include "collection/collectionbackend.h" #include "collection/collectionquery.h" -#include "playlist/songmimedata.h" -#include "coverproviders.h" #include "albumcovermanager.h" #include "albumcoversearcher.h" #include "albumcoverchoicecontroller.h" @@ -88,6 +87,7 @@ #include "albumcoverfetcher.h" #include "albumcoverloader.h" #include "albumcoverloaderresult.h" +#include "coverproviders.h" #include "coversearchstatistics.h" #include "coversearchstatisticsdialog.h" #include "albumcoverimageresult.h" @@ -102,21 +102,31 @@ constexpr char kSettingsGroup[] = "CoverManager"; constexpr int kThumbnailSize = 120; } -AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtr collection_backend, QMainWindow *mainwindow, QWidget *parent) +AlbumCoverManager::AlbumCoverManager(const SharedPtr network, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr streaming_services, + QMainWindow *mainwindow, QWidget *parent) : QMainWindow(parent), ui_(new Ui_CoverManager), mainwindow_(mainwindow), - app_(app), + network_(network), collection_backend_(collection_backend), + tagreader_client_(tagreader_client), + albumcover_loader_(albumcover_loader), + cover_providers_(cover_providers), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), timer_album_cover_load_(new QTimer(this)), filter_all_(nullptr), filter_with_covers_(nullptr), filter_without_covers_(nullptr), - cover_fetcher_(new AlbumCoverFetcher(app_->cover_providers(), app_->network(), this)), + cover_fetcher_(new AlbumCoverFetcher(cover_providers, network, this)), cover_searcher_(nullptr), cover_export_(nullptr), - cover_exporter_(new AlbumCoverExporter(this)), + cover_exporter_(new AlbumCoverExporter(tagreader_client_, this)), artist_icon_(IconLoader::Load(u"folder-sound"_s)), all_artists_icon_(IconLoader::Load(u"library-music"_s)), image_nocover_thumbnail_(ImageUtils::GenerateNoCoverImage(QSize(120, 120), devicePixelRatio())), @@ -142,9 +152,9 @@ AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtraction_add_to_playlist->setIcon(IconLoader::Load(u"media-playback-start"_s)); ui_->action_load->setIcon(IconLoader::Load(u"media-playback-start"_s)); - album_cover_choice_controller_->Init(app_); + album_cover_choice_controller_->Init(network, tagreader_client, collection_backend, albumcover_loader, current_albumcover_loader, cover_providers, streaming_services); - cover_searcher_ = new AlbumCoverSearcher(icon_nocover_item_, app_, this); + cover_searcher_ = new AlbumCoverSearcher(icon_nocover_item_, albumcover_loader_, this); cover_export_ = new AlbumCoverExport(this); // Set up the status bar @@ -241,7 +251,7 @@ void AlbumCoverManager::Init() { s.endGroup(); - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverManager::AlbumCoverLoaded); + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverManager::AlbumCoverLoaded); cover_searcher_->Init(cover_fetcher_); @@ -320,7 +330,7 @@ void AlbumCoverManager::SaveSettings() { void AlbumCoverManager::CancelRequests() { - app_->album_cover_loader()->CancelTasks(QSet(cover_loading_tasks_.keyBegin(), cover_loading_tasks_.keyEnd())); + albumcover_loader_->CancelTasks(QSet(cover_loading_tasks_.keyBegin(), cover_loading_tasks_.keyEnd())); cover_loading_pending_.clear(); cover_loading_tasks_.clear(); cover_save_tasks_.clear(); @@ -363,7 +373,7 @@ void AlbumCoverManager::Reset() { } void AlbumCoverManager::EnableCoversButtons() { - ui_->button_fetch->setEnabled(app_->cover_providers()->HasAnyProviders()); + ui_->button_fetch->setEnabled(cover_providers_->HasAnyProviders()); ui_->export_covers->setEnabled(true); } @@ -466,7 +476,7 @@ void AlbumCoverManager::LoadAlbumCoverAsync(AlbumItem *album_item) { cover_options.types = cover_types_; cover_options.desired_scaled_size = QSize(kThumbnailSize, kThumbnailSize); cover_options.device_pixel_ratio = devicePixelRatioF(); - quint64 cover_load_id = app_->album_cover_loader()->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst()); + quint64 cover_load_id = albumcover_loader_->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst()); cover_loading_tasks_.insert(cover_load_id, album_item); } @@ -643,7 +653,7 @@ bool AlbumCoverManager::eventFilter(QObject *obj, QEvent *e) { album_cover_choice_controller_->cover_to_file_action()->setEnabled(some_with_covers); album_cover_choice_controller_->cover_from_file_action()->setEnabled(context_menu_items_.size() == 1); album_cover_choice_controller_->cover_from_url_action()->setEnabled(context_menu_items_.size() == 1); - album_cover_choice_controller_->search_for_cover_action()->setEnabled(app_->cover_providers()->HasAnyProviders()); + album_cover_choice_controller_->search_for_cover_action()->setEnabled(cover_providers_->HasAnyProviders()); album_cover_choice_controller_->unset_cover_action()->setEnabled(some_with_covers || some_clear); album_cover_choice_controller_->clear_cover_action()->setEnabled(some_with_covers || some_unset); album_cover_choice_controller_->delete_cover_action()->setEnabled(some_with_covers); @@ -757,7 +767,7 @@ void AlbumCoverManager::SaveCoverToFile() { return; case AlbumCoverLoaderOptions::Type::Embedded: if (song.art_embedded()) { - const TagReaderResult tagreaderclient_result = TagReaderClient::Instance()->LoadCoverDataBlocking(song.url().toLocalFile(), result.image_data); + const TagReaderResult tagreaderclient_result = tagreader_client_->LoadCoverDataBlocking(song.url().toLocalFile(), result.image_data); if (!tagreaderclient_result.success()) { qLog(Error) << "Could not load embedded art from" << song.url() << tagreaderclient_result.error_string(); } @@ -844,7 +854,7 @@ void AlbumCoverManager::SaveImageToAlbums(Song *song, const AlbumCoverImageResul case CoverOptions::CoverType::Embedded:{ for (const QUrl &url : std::as_const(album_item->urls)) { const bool art_embedded = !result.image_data.isEmpty(); - TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.image_data, result.mime_type)); + TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.image_data, result.mime_type)); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, album_item, url, art_embedded]() { SaveEmbeddedCoverFinished(reply, album_item, url, art_embedded); }); @@ -994,7 +1004,7 @@ void AlbumCoverManager::SaveAndSetCover(AlbumItem *album_item, const AlbumCoverI if (album_cover_choice_controller_->get_save_album_cover_type() == CoverOptions::CoverType::Embedded && Song::save_embedded_cover_supported(filetype) && !has_cue) { for (const QUrl &url : urls) { const bool art_embedded = !result.image_data.isEmpty(); - TagReaderReplyPtr reply = app_->tag_reader_client()->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.cover_url.isValid() ? result.cover_url.toLocalFile() : QString(), result.image_data, result.mime_type)); + TagReaderReplyPtr reply = tagreader_client_->SaveCoverAsync(url.toLocalFile(), SaveTagCoverData(result.cover_url.isValid() ? result.cover_url.toLocalFile() : QString(), result.image_data, result.mime_type)); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, album_item, url, art_embedded]() { SaveEmbeddedCoverFinished(reply, album_item, url, art_embedded); }); diff --git a/src/covermanager/albumcovermanager.h b/src/covermanager/albumcovermanager.h index a29a5b86a4..7264c6a559 100644 --- a/src/covermanager/albumcovermanager.h +++ b/src/covermanager/albumcovermanager.h @@ -37,7 +37,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "tagreader/tagreaderclient.h" #include "albumcoverloaderoptions.h" @@ -55,8 +55,11 @@ class QEvent; class QCloseEvent; class QShowEvent; -class Application; +class NetworkAccessManager; class CollectionBackend; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; class SongMimeData; class AlbumCoverExport; class AlbumCoverExporter; @@ -78,7 +81,15 @@ class AlbumCoverManager : public QMainWindow { Q_OBJECT public: - explicit AlbumCoverManager(Application *app, SharedPtr collection_backend, QMainWindow *mainwindow, QWidget *parent = nullptr); + explicit AlbumCoverManager(const SharedPtr network, + const SharedPtr collection_backend, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr streaming_services, + QMainWindow *mainwindow, + QWidget *parent = nullptr); ~AlbumCoverManager() override; void Reset(); @@ -190,8 +201,13 @@ class AlbumCoverManager : public QMainWindow { private: Ui_CoverManager *ui_; QMainWindow *mainwindow_; - Application *app_; - SharedPtr collection_backend_; + + const SharedPtr network_; + const SharedPtr collection_backend_; + const SharedPtr tagreader_client_; + const SharedPtr albumcover_loader_; + const SharedPtr cover_providers_; + AlbumCoverChoiceController *album_cover_choice_controller_; QTimer *timer_album_cover_load_; diff --git a/src/covermanager/albumcovermanagerlist.cpp b/src/covermanager/albumcovermanagerlist.cpp index e5e3488be0..34a031815a 100644 --- a/src/covermanager/albumcovermanagerlist.cpp +++ b/src/covermanager/albumcovermanagerlist.cpp @@ -33,10 +33,10 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" #include "core/song.h" +#include "mimedata/songmimedata.h" #include "collection/collectionbackend.h" -#include "playlist/songmimedata.h" #include "albumcovermanager.h" #include "albumcovermanagerlist.h" diff --git a/src/covermanager/albumcoversearcher.cpp b/src/covermanager/albumcoversearcher.cpp index 4b643535b0..6ec9f803cd 100644 --- a/src/covermanager/albumcoversearcher.cpp +++ b/src/covermanager/albumcoversearcher.cpp @@ -47,9 +47,7 @@ #include #include -#include "core/application.h" #include "utilities/strutils.h" -#include "utilities/timeutils.h" #include "utilities/mimeutils.h" #include "widgets/busyindicator.h" #include "widgets/forcescrollperpixel.h" @@ -114,10 +112,10 @@ void SizeOverlayDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o } -AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, Application *app, QWidget *parent) +AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, const SharedPtr albumcover_loader, QWidget *parent) : QDialog(parent), ui_(new Ui_AlbumCoverSearcher), - app_(app), + albumcover_loader_(albumcover_loader), model_(new QStandardItemModel(this)), no_cover_icon_(no_cover_icon), fetcher_(nullptr), @@ -132,7 +130,7 @@ AlbumCoverSearcher::AlbumCoverSearcher(const QIcon &no_cover_icon, Application * ui_->covers->setItemDelegate(new SizeOverlayDelegate(this)); ui_->covers->setModel(model_); - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverSearcher::AlbumCoverLoaded); + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &AlbumCoverSearcher::AlbumCoverLoaded); QObject::connect(ui_->search, &QPushButton::clicked, this, &AlbumCoverSearcher::Search); QObject::connect(ui_->covers, &GroupedIconView::doubleClicked, this, &AlbumCoverSearcher::CoverDoubleClicked); @@ -220,7 +218,7 @@ void AlbumCoverSearcher::SearchFinished(const quint64 id, const CoverProviderSea AlbumCoverLoaderOptions cover_options(AlbumCoverLoaderOptions::Option::RawImageData | AlbumCoverLoaderOptions::Option::OriginalImage | AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage); cover_options.desired_scaled_size = ui_->covers->iconSize(), ui_->covers->iconSize(); - quint64 new_id = app_->album_cover_loader()->LoadImageAsync(cover_options, false, result.image_url, QUrl(), false); + quint64 new_id = albumcover_loader_->LoadImageAsync(cover_options, false, result.image_url, QUrl(), false); QStandardItem *item = new QStandardItem; item->setIcon(no_cover_icon_); diff --git a/src/covermanager/albumcoversearcher.h b/src/covermanager/albumcoversearcher.h index c6dec1beb9..d09324fac0 100644 --- a/src/covermanager/albumcoversearcher.h +++ b/src/covermanager/albumcoversearcher.h @@ -48,7 +48,7 @@ class QPainter; class QModelIndex; class QKeyEvent; -class Application; +class AlbumCoverLoader; class Ui_AlbumCoverSearcher; class SizeOverlayDelegate : public QStyledItemDelegate { @@ -65,7 +65,7 @@ class AlbumCoverSearcher : public QDialog { Q_OBJECT public: - explicit AlbumCoverSearcher(const QIcon &no_cover_icon, Application *app, QWidget *parent); + explicit AlbumCoverSearcher(const QIcon &no_cover_icon, const SharedPtr albumcover_loader, QWidget *parent); ~AlbumCoverSearcher() override; enum Role { @@ -95,7 +95,7 @@ class AlbumCoverSearcher : public QDialog { private: Ui_AlbumCoverSearcher *ui_; - Application *app_; + SharedPtr albumcover_loader_; QStandardItemModel *model_; QIcon no_cover_icon_; diff --git a/src/covermanager/coverexportrunnable.cpp b/src/covermanager/coverexportrunnable.cpp index 232c014843..3ab21a4cf9 100644 --- a/src/covermanager/coverexportrunnable.cpp +++ b/src/covermanager/coverexportrunnable.cpp @@ -36,8 +36,9 @@ using namespace Qt::Literals::StringLiterals; -CoverExportRunnable::CoverExportRunnable(const AlbumCoverExport::DialogResult &dialog_result, const AlbumCoverLoaderOptions::Types &cover_types, const Song &song, QObject *parent) +CoverExportRunnable::CoverExportRunnable(const SharedPtr tagreader_client, const AlbumCoverExport::DialogResult &dialog_result, const AlbumCoverLoaderOptions::Types &cover_types, const Song &song, QObject *parent) : QObject(parent), + tagreader_client_(tagreader_client), dialog_result_(dialog_result), cover_types_(cover_types), song_(song) {} @@ -78,7 +79,7 @@ void CoverExportRunnable::ProcessAndExportCover() { break; case AlbumCoverLoaderOptions::Type::Embedded: if (song_.art_embedded() && dialog_result_.export_embedded_) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(song_.url().toLocalFile(), image); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(song_.url().toLocalFile(), image); if (result.success() && !image.isNull()) { extension = "jpg"_L1; } @@ -170,7 +171,7 @@ void CoverExportRunnable::ExportCover() { break; case AlbumCoverLoaderOptions::Type::Embedded: if (song_.art_embedded() && dialog_result_.export_embedded_) { - const TagReaderResult result = TagReaderClient::Instance()->LoadCoverImageBlocking(song_.url().toLocalFile(), image); + const TagReaderResult result = tagreader_client_->LoadCoverImageBlocking(song_.url().toLocalFile(), image); if (result.success() && !image.isNull()) { embedded_cover = true; extension = "jpg"_L1; diff --git a/src/covermanager/coverexportrunnable.h b/src/covermanager/coverexportrunnable.h index b58e732162..a520681f52 100644 --- a/src/covermanager/coverexportrunnable.h +++ b/src/covermanager/coverexportrunnable.h @@ -28,15 +28,22 @@ #include #include +#include "includes/shared_ptr.h" #include "core/song.h" #include "albumcoverloaderoptions.h" #include "albumcoverexport.h" +class TagReaderClient; + class CoverExportRunnable : public QObject, public QRunnable { Q_OBJECT public: - explicit CoverExportRunnable(const AlbumCoverExport::DialogResult &dialog_result, const AlbumCoverLoaderOptions::Types &cover_types, const Song &song, QObject *parent = nullptr); + explicit CoverExportRunnable(const SharedPtr tagreader_client, + const AlbumCoverExport::DialogResult &dialog_result, + const AlbumCoverLoaderOptions::Types &cover_types, + const Song &song, + QObject *parent = nullptr); void run() override; @@ -51,6 +58,7 @@ class CoverExportRunnable : public QObject, public QRunnable { void ProcessAndExportCover(); void ExportCover(); + SharedPtr tagreader_client_; AlbumCoverExport::DialogResult dialog_result_; AlbumCoverLoaderOptions::Types cover_types_; Song song_; diff --git a/src/covermanager/coverfromurldialog.cpp b/src/covermanager/coverfromurldialog.cpp index 08605fdcac..f3c3b44ed2 100644 --- a/src/covermanager/coverfromurldialog.cpp +++ b/src/covermanager/coverfromurldialog.cpp @@ -31,7 +31,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/mimeutils.h" #include "widgets/busyindicator.h" diff --git a/src/covermanager/coverfromurldialog.h b/src/covermanager/coverfromurldialog.h index 61678d039e..f511a0e0d3 100644 --- a/src/covermanager/coverfromurldialog.h +++ b/src/covermanager/coverfromurldialog.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "albumcoverimageresult.h" class QWidget; diff --git a/src/covermanager/coverprovider.cpp b/src/covermanager/coverprovider.cpp index 955dba7074..e71554c785 100644 --- a/src/covermanager/coverprovider.cpp +++ b/src/covermanager/coverprovider.cpp @@ -24,8 +24,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "coverprovider.h" -CoverProvider::CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr network, QObject *parent) : QObject(parent), app_(app), network_(network), name_(name), enabled_(enabled), order_(0), authentication_required_(authentication_required), quality_(quality), batch_(batch), allow_missing_album_(allow_missing_album) {} +CoverProvider::CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, const SharedPtr network, QObject *parent) : QObject(parent), network_(network), name_(name), enabled_(enabled), order_(0), authentication_required_(authentication_required), quality_(quality), batch_(batch), allow_missing_album_(allow_missing_album) {} diff --git a/src/covermanager/coverprovider.h b/src/covermanager/coverprovider.h index 41ea4e6eb8..d0134a0aba 100644 --- a/src/covermanager/coverprovider.h +++ b/src/covermanager/coverprovider.h @@ -30,10 +30,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "albumcoverfetcher.h" -class Application; class NetworkAccessManager; // Each implementation of this interface downloads covers from one online service. @@ -42,7 +41,7 @@ class CoverProvider : public QObject { Q_OBJECT public: - explicit CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr network, QObject *parent); + explicit CoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, const SharedPtr network, QObject *parent); // A name (very short description) of this provider, like "last.fm". QString name() const { return name_; } @@ -79,15 +78,14 @@ class CoverProvider : public QObject { using Param = QPair; using ParamList = QList; - Application *app_; - SharedPtr network_; - QString name_; + const SharedPtr network_; + const QString name_; bool enabled_; int order_; - bool authentication_required_; - float quality_; - bool batch_; - bool allow_missing_album_; + const bool authentication_required_; + const float quality_; + const bool batch_; + const bool allow_missing_album_; }; #endif // COVERPROVIDER_H diff --git a/src/covermanager/coverproviders.cpp b/src/covermanager/coverproviders.cpp index f3980a401d..34887b9b39 100644 --- a/src/covermanager/coverproviders.cpp +++ b/src/covermanager/coverproviders.cpp @@ -36,7 +36,7 @@ #include "coverprovider.h" #include "coverproviders.h" -#include "settings/coverssettingspage.h" +#include "constants/coverssettings.h" int CoverProviders::NextOrderId = 0; @@ -60,8 +60,8 @@ void CoverProviders::ReloadSettings() { } Settings s; - s.beginGroup(CoversSettingsPage::kSettingsGroup); - const QStringList providers_enabled = s.value(CoversSettingsPage::kProviders, QStringList() << all_providers.values()).toStringList(); + s.beginGroup(CoversSettings::kSettingsGroup); + const QStringList providers_enabled = s.value(CoversSettings::kProviders, QStringList() << all_providers.values()).toStringList(); s.endGroup(); int i = 0; diff --git a/src/covermanager/currentalbumcoverloader.cpp b/src/covermanager/currentalbumcoverloader.cpp index 29f7ddebd4..8829064bc3 100644 --- a/src/covermanager/currentalbumcoverloader.cpp +++ b/src/covermanager/currentalbumcoverloader.cpp @@ -29,10 +29,9 @@ #include #include -#include "core/application.h" +#include "core/logging.h" #include "core/song.h" #include "core/temporaryfile.h" -#include "playlist/playlistmanager.h" #include "albumcoverloader.h" #include "albumcoverloaderresult.h" #include "currentalbumcoverloader.h" @@ -40,9 +39,9 @@ using std::make_unique; using namespace Qt::Literals::StringLiterals; -CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(Application *app, QObject *parent) +CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(const SharedPtr albumcover_loader, QObject *parent) : QObject(parent), - app_(app), + albumcover_loader_(albumcover_loader), temp_file_pattern_(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + u"/strawberry-cover-XXXXXX.jpg"_s), id_(0) { @@ -52,8 +51,7 @@ CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(Application *app, QObject *pare options_.desired_scaled_size = QSize(120, 120); options_.default_cover = u":/pictures/cdcase.png"_s; - QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &CurrentAlbumCoverLoader::LoadAlbumCover); - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &CurrentAlbumCoverLoader::AlbumCoverReady); + QObject::connect(&*albumcover_loader, &AlbumCoverLoader::AlbumCoverLoaded, this, &CurrentAlbumCoverLoader::AlbumCoverReady); ReloadSettingsAsync(); @@ -76,7 +74,7 @@ void CurrentAlbumCoverLoader::ReloadSettings() { void CurrentAlbumCoverLoader::LoadAlbumCover(const Song &song) { last_song_ = song; - id_ = app_->album_cover_loader()->LoadImageAsync(options_, last_song_); + id_ = albumcover_loader_->LoadImageAsync(options_, last_song_); } diff --git a/src/covermanager/currentalbumcoverloader.h b/src/covermanager/currentalbumcoverloader.h index 008d622244..4f72122838 100644 --- a/src/covermanager/currentalbumcoverloader.h +++ b/src/covermanager/currentalbumcoverloader.h @@ -29,19 +29,20 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/temporaryfile.h" #include "core/song.h" #include "albumcoverloaderoptions.h" #include "albumcoverloaderresult.h" -class Application; +class AlbumCoverLoader; class CurrentAlbumCoverLoader : public QObject { Q_OBJECT public: - explicit CurrentAlbumCoverLoader(Application *app, QObject *parent = nullptr); + explicit CurrentAlbumCoverLoader(const SharedPtr albumcover_loader, QObject *parent = nullptr); ~CurrentAlbumCoverLoader() override; const AlbumCoverLoaderOptions &options() const { return options_; } @@ -61,10 +62,10 @@ class CurrentAlbumCoverLoader : public QObject { void AlbumCoverReady(const quint64 id, AlbumCoverLoaderResult result); private: - Application *app_; + const SharedPtr albumcover_loader_; AlbumCoverLoaderOptions options_; - QString temp_file_pattern_; + const QString temp_file_pattern_; ScopedPtr temp_cover_; ScopedPtr temp_cover_thumbnail_; diff --git a/src/covermanager/deezercoverprovider.cpp b/src/covermanager/deezercoverprovider.cpp index e16159e2a6..23122113b5 100644 --- a/src/covermanager/deezercoverprovider.cpp +++ b/src/covermanager/deezercoverprovider.cpp @@ -39,7 +39,6 @@ #include #include -#include "core/application.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/song.h" @@ -55,8 +54,8 @@ constexpr char kApiUrl[] = "https://api.deezer.com"; constexpr int kLimit = 10; } -DeezerCoverProvider::DeezerCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Deezer"_s, true, false, 2.0, true, true, app, network, parent) {} +DeezerCoverProvider::DeezerCoverProvider(const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Deezer"_s, true, false, 2.0, true, true, network, parent) {} DeezerCoverProvider::~DeezerCoverProvider() { diff --git a/src/covermanager/deezercoverprovider.h b/src/covermanager/deezercoverprovider.h index b84860896d..5ed4fd254f 100644 --- a/src/covermanager/deezercoverprovider.h +++ b/src/covermanager/deezercoverprovider.h @@ -34,13 +34,12 @@ class NetworkAccessManager; class QNetworkReply; -class Application; class DeezerCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit DeezerCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit DeezerCoverProvider(const SharedPtr network, QObject *parent = nullptr); ~DeezerCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/discogscoverprovider.cpp b/src/covermanager/discogscoverprovider.cpp index d45d7fbee6..af88412165 100644 --- a/src/covermanager/discogscoverprovider.cpp +++ b/src/covermanager/discogscoverprovider.cpp @@ -41,8 +41,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" #include "utilities/cryptutils.h" @@ -58,8 +57,8 @@ const char *DiscogsCoverProvider::kAccessKeyB64 = "dGh6ZnljUGJlZ1NEeXBuSFFxSVk=" const char *DiscogsCoverProvider::kSecretKeyB64 = "ZkFIcmlaSER4aHhRSlF2U3d0bm5ZVmdxeXFLWUl0UXI="; const int DiscogsCoverProvider::kRequestsDelay = 1000; -DiscogsCoverProvider::DiscogsCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Discogs"_s, false, false, 0.0, false, false, app, network, parent), +DiscogsCoverProvider::DiscogsCoverProvider(const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Discogs"_s, false, false, 0.0, false, false, network, parent), timer_flush_requests_(new QTimer(this)) { timer_flush_requests_->setInterval(kRequestsDelay); diff --git a/src/covermanager/discogscoverprovider.h b/src/covermanager/discogscoverprovider.h index 47f7667cff..83264fc4d9 100644 --- a/src/covermanager/discogscoverprovider.h +++ b/src/covermanager/discogscoverprovider.h @@ -35,20 +35,19 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "albumcoverfetcher.h" class NetworkAccessManager; class QNetworkReply; class QTimer; -class Application; class DiscogsCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit DiscogsCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit DiscogsCoverProvider(const SharedPtr network, QObject *parent = nullptr); ~DiscogsCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/jsoncoverprovider.cpp b/src/covermanager/jsoncoverprovider.cpp index 531d8c6ee9..d87a6adeb4 100644 --- a/src/covermanager/jsoncoverprovider.cpp +++ b/src/covermanager/jsoncoverprovider.cpp @@ -25,16 +25,15 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "coverprovider.h" #include "jsoncoverprovider.h" using namespace Qt::Literals::StringLiterals; -JsonCoverProvider::JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr network, QObject *parent) - : CoverProvider(name, enabled, authentication_required, quality, batch, allow_missing_album, app, network, parent) {} +JsonCoverProvider::JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, const SharedPtr network, QObject *parent) + : CoverProvider(name, enabled, authentication_required, quality, batch, allow_missing_album, network, parent) {} QJsonObject JsonCoverProvider::ExtractJsonObj(const QByteArray &data) { diff --git a/src/covermanager/jsoncoverprovider.h b/src/covermanager/jsoncoverprovider.h index e00a83908c..e1669b52fb 100644 --- a/src/covermanager/jsoncoverprovider.h +++ b/src/covermanager/jsoncoverprovider.h @@ -27,17 +27,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "coverprovider.h" -class Application; class NetworkAccessManager; class JsonCoverProvider : public CoverProvider { Q_OBJECT public: - explicit JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, Application *app, SharedPtr network, QObject *parent); + explicit JsonCoverProvider(const QString &name, const bool enabled, const bool authentication_required, const float quality, const bool batch, const bool allow_missing_album, const SharedPtr network, QObject *parent); protected: QJsonObject ExtractJsonObj(const QByteArray &data); diff --git a/src/covermanager/lastfmcoverprovider.cpp b/src/covermanager/lastfmcoverprovider.cpp index 75eb29d15e..ae40e4e37e 100644 --- a/src/covermanager/lastfmcoverprovider.cpp +++ b/src/covermanager/lastfmcoverprovider.cpp @@ -38,8 +38,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" @@ -55,8 +54,8 @@ constexpr char kApiKey[] = "211990b4c96782c05d1536e7219eb56e"; constexpr char kSecret[] = "80fd738f49596e9709b1bf9319c444a8"; } // namespace -LastFmCoverProvider::LastFmCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Last.fm"_s, true, false, 1.0, true, false, app, network, parent) {} +LastFmCoverProvider::LastFmCoverProvider(const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Last.fm"_s, true, false, 1.0, true, false, network, parent) {} LastFmCoverProvider::~LastFmCoverProvider() { diff --git a/src/covermanager/lastfmcoverprovider.h b/src/covermanager/lastfmcoverprovider.h index 231fdb9eda..29a9c7c44a 100644 --- a/src/covermanager/lastfmcoverprovider.h +++ b/src/covermanager/lastfmcoverprovider.h @@ -29,18 +29,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" class NetworkAccessManager; class QNetworkReply; -class Application; class LastFmCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit LastFmCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit LastFmCoverProvider(const SharedPtr network, QObject *parent = nullptr); ~LastFmCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/musicbrainzcoverprovider.cpp b/src/covermanager/musicbrainzcoverprovider.cpp index 4a778438e4..8dab152838 100644 --- a/src/covermanager/musicbrainzcoverprovider.cpp +++ b/src/covermanager/musicbrainzcoverprovider.cpp @@ -36,8 +36,7 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "albumcoverfetcher.h" @@ -53,8 +52,8 @@ constexpr int kLimit = 8; constexpr int kRequestsDelay = 1000; } // namespace -MusicbrainzCoverProvider::MusicbrainzCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"MusicBrainz"_s, true, false, 1.5, true, false, app, network, parent), +MusicbrainzCoverProvider::MusicbrainzCoverProvider(const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"MusicBrainz"_s, true, false, 1.5, true, false, network, parent), timer_flush_requests_(new QTimer(this)) { timer_flush_requests_->setInterval(kRequestsDelay); diff --git a/src/covermanager/musicbrainzcoverprovider.h b/src/covermanager/musicbrainzcoverprovider.h index 2ceacbf476..1b9b648de8 100644 --- a/src/covermanager/musicbrainzcoverprovider.h +++ b/src/covermanager/musicbrainzcoverprovider.h @@ -30,19 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" class QNetworkReply; class QTimer; -class Application; class NetworkAccessManager; class MusicbrainzCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit MusicbrainzCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit MusicbrainzCoverProvider(const SharedPtr network, QObject *parent = nullptr); ~MusicbrainzCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/musixmatchcoverprovider.cpp b/src/covermanager/musixmatchcoverprovider.cpp index f3bf5731fb..f1a0d4e9a5 100644 --- a/src/covermanager/musixmatchcoverprovider.cpp +++ b/src/covermanager/musixmatchcoverprovider.cpp @@ -32,18 +32,17 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/networkaccessmanager.h" -#include "providers/musixmatchprovider.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" #include "musixmatchcoverprovider.h" using namespace Qt::Literals::StringLiterals; -MusixmatchCoverProvider::MusixmatchCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Musixmatch"_s, true, false, 1.0, true, false, app, network, parent) {} +MusixmatchCoverProvider::MusixmatchCoverProvider(const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Musixmatch"_s, true, false, 1.0, true, false, network, parent) {} MusixmatchCoverProvider::~MusixmatchCoverProvider() { diff --git a/src/covermanager/musixmatchcoverprovider.h b/src/covermanager/musixmatchcoverprovider.h index 6ded62130b..52554b061f 100644 --- a/src/covermanager/musixmatchcoverprovider.h +++ b/src/covermanager/musixmatchcoverprovider.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "providers/musixmatchprovider.h" @@ -39,7 +39,7 @@ class MusixmatchCoverProvider : public JsonCoverProvider, MusixmatchProvider { Q_OBJECT public: - explicit MusixmatchCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit MusixmatchCoverProvider(const SharedPtr network, QObject *parent = nullptr); ~MusixmatchCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/opentidalcoverprovider.cpp b/src/covermanager/opentidalcoverprovider.cpp index 205f409510..bccc032bf5 100644 --- a/src/covermanager/opentidalcoverprovider.cpp +++ b/src/covermanager/opentidalcoverprovider.cpp @@ -37,12 +37,12 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/settings.h" -#include "utilities/timeconstants.h" +#include "core/song.h" +#include "constants/timeconstants.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" #include "opentidalcoverprovider.h" @@ -61,8 +61,8 @@ constexpr const int kRequestsDelay = 1000; using std::make_shared; -OpenTidalCoverProvider::OpenTidalCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"OpenTidal"_s, true, false, 2.5, true, false, app, network, parent), +OpenTidalCoverProvider::OpenTidalCoverProvider(const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"OpenTidal"_s, true, false, 2.5, true, false, network, parent), login_timer_(new QTimer(this)), timer_flush_requests_(new QTimer(this)), login_in_progress_(false), diff --git a/src/covermanager/opentidalcoverprovider.h b/src/covermanager/opentidalcoverprovider.h index 396d16c78b..906f9a0e29 100644 --- a/src/covermanager/opentidalcoverprovider.h +++ b/src/covermanager/opentidalcoverprovider.h @@ -32,11 +32,10 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" class QNetworkReply; -class Application; class NetworkAccessManager; class QTimer; @@ -44,7 +43,7 @@ class OpenTidalCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit OpenTidalCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit OpenTidalCoverProvider(const SharedPtr network, QObject *parent = nullptr); ~OpenTidalCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/qobuzcoverprovider.cpp b/src/covermanager/qobuzcoverprovider.cpp index c4b0a09c75..1cc5145c1b 100644 --- a/src/covermanager/qobuzcoverprovider.cpp +++ b/src/covermanager/qobuzcoverprovider.cpp @@ -36,12 +36,10 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/song.h" -#include "streaming/streamingservices.h" #include "qobuz/qobuzservice.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" @@ -53,9 +51,9 @@ namespace { constexpr int kLimit = 10; } -QobuzCoverProvider::QobuzCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Qobuz"_s, true, true, 2.0, true, true, app, network, parent), - service_(app->streaming_services()->Service()) {} +QobuzCoverProvider::QobuzCoverProvider(const QobuzServicePtr service, SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Qobuz"_s, true, true, 2.0, true, true, network, parent), + service_(service) {} QobuzCoverProvider::~QobuzCoverProvider() { diff --git a/src/covermanager/qobuzcoverprovider.h b/src/covermanager/qobuzcoverprovider.h index 6368d24819..f4734f91ea 100644 --- a/src/covermanager/qobuzcoverprovider.h +++ b/src/covermanager/qobuzcoverprovider.h @@ -30,19 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "qobuz/qobuzservice.h" class QNetworkReply; -class Application; class NetworkAccessManager; class QobuzCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit QobuzCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit QobuzCoverProvider(const QobuzServicePtr service, SharedPtr network, QObject *parent = nullptr); ~QobuzCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; diff --git a/src/covermanager/spotifycoverprovider.cpp b/src/covermanager/spotifycoverprovider.cpp index b33caacfe6..ec3726bc02 100644 --- a/src/covermanager/spotifycoverprovider.cpp +++ b/src/covermanager/spotifycoverprovider.cpp @@ -38,11 +38,9 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" -#include "streaming/streamingservices.h" #include "spotify/spotifyservice.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" @@ -55,9 +53,9 @@ constexpr char kApiUrl[] = "https://api.spotify.com/v1"; constexpr int kLimit = 10; } // namespace -SpotifyCoverProvider::SpotifyCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Spotify"_s, true, true, 2.5, true, true, app, network, parent), - service_(app->streaming_services()->Service()) {} +SpotifyCoverProvider::SpotifyCoverProvider(const SpotifyServicePtr service, SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Spotify"_s, true, true, 2.5, true, true, network, parent), + service_(service) {} SpotifyCoverProvider::~SpotifyCoverProvider() { diff --git a/src/covermanager/spotifycoverprovider.h b/src/covermanager/spotifycoverprovider.h index 99df10f0ba..48e6e15767 100644 --- a/src/covermanager/spotifycoverprovider.h +++ b/src/covermanager/spotifycoverprovider.h @@ -34,19 +34,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "spotify/spotifyservice.h" class QNetworkReply; -class Application; class NetworkAccessManager; class SpotifyCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit SpotifyCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit SpotifyCoverProvider(const SpotifyServicePtr service, const SharedPtr network, QObject *parent = nullptr); ~SpotifyCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; @@ -65,7 +64,7 @@ class SpotifyCoverProvider : public JsonCoverProvider { void Error(const QString &error, const QVariant &debug = QVariant()) override; private: - SharedPtr service_; + const SharedPtr service_; QList replies_; }; diff --git a/src/covermanager/tidalcoverprovider.cpp b/src/covermanager/tidalcoverprovider.cpp index 0cefaaf4ad..2d4c39f967 100644 --- a/src/covermanager/tidalcoverprovider.cpp +++ b/src/covermanager/tidalcoverprovider.cpp @@ -34,12 +34,10 @@ #include #include -#include "core/shared_ptr.h" -#include "core/application.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "core/song.h" -#include "streaming/streamingservices.h" #include "tidal/tidalservice.h" #include "albumcoverfetcher.h" #include "jsoncoverprovider.h" @@ -51,9 +49,9 @@ namespace { constexpr int kLimit = 10; } -TidalCoverProvider::TidalCoverProvider(Application *app, SharedPtr network, QObject *parent) - : JsonCoverProvider(u"Tidal"_s, true, true, 2.5, true, true, app, network, parent), - service_(app->streaming_services()->Service()) {} +TidalCoverProvider::TidalCoverProvider(const TidalServicePtr service, const SharedPtr network, QObject *parent) + : JsonCoverProvider(u"Tidal"_s, true, true, 2.5, true, true, network, parent), + service_(service) {} TidalCoverProvider::~TidalCoverProvider() { diff --git a/src/covermanager/tidalcoverprovider.h b/src/covermanager/tidalcoverprovider.h index 351d51eef5..f30893874b 100644 --- a/src/covermanager/tidalcoverprovider.h +++ b/src/covermanager/tidalcoverprovider.h @@ -32,19 +32,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsoncoverprovider.h" #include "tidal/tidalservice.h" class QNetworkReply; -class Application; class NetworkAccessManager; class TidalCoverProvider : public JsonCoverProvider { Q_OBJECT public: - explicit TidalCoverProvider(Application *app, SharedPtr network, QObject *parent = nullptr); + explicit TidalCoverProvider(const TidalServicePtr service, const SharedPtr network, QObject *parent = nullptr); ~TidalCoverProvider() override; bool StartSearch(const QString &artist, const QString &album, const QString &title, const int id) override; @@ -63,7 +62,7 @@ class TidalCoverProvider : public JsonCoverProvider { void Error(const QString &error, const QVariant &debug = QVariant()) override; private: - TidalServicePtr service_; + const TidalServicePtr service_; QList replies_; }; diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt new file mode 100644 index 0000000000..ad862c5182 --- /dev/null +++ b/src/device/CMakeLists.txt @@ -0,0 +1,115 @@ +set(DEVICE_SOURCES + connecteddevice.cpp + devicedatabasebackend.cpp + devicelister.cpp + devicemanager.cpp + devicestatefiltermodel.cpp + filesystemdevice.cpp + deviceviewcontainer.cpp + deviceview.cpp + deviceproperties.cpp + deviceinfo.cpp +) + +set(DEVICE_HEADERS + connecteddevice.h + devicedatabasebackend.h + devicelister.h + devicemanager.h + devicestatefiltermodel.h + filesystemdevice.h + deviceviewcontainer.h + deviceview.h + deviceproperties.h +) + +set(DEVICE_UI + deviceproperties.ui + deviceviewcontainer.ui +) + +if(APPLE) + list(APPEND DEVICE_SOURCES macosdevicelister.mm) + list(APPEND DEVICE_HEADERS macosdevicelister.h) +endif() + +if(UNIX) + list(APPEND DEVICE_SOURCES giolister.cpp) + list(APPEND DEVICE_HEADERS giolister.h) +endif() + +if(HAVE_UDISKS2) + list(APPEND DEVICE_SOURCES udisks2lister.cpp) + list(APPEND DEVICE_HEADERS udisks2lister.h) + set_source_files_properties(org.freedesktop.DBus.ObjectManager.xml PROPERTIES NO_NAMESPACE objectmanager INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(org.freedesktop.UDisks2.Filesystem.xml PROPERTIES NO_NAMESPACE udisks2filesystem INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(org.freedesktop.UDisks2.Block.xml PROPERTIES NO_NAMESPACE udisks2block INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(org.freedesktop.UDisks2.Drive.xml PROPERTIES NO_NAMESPACE udisks2drive INCLUDE includes/dbus_metatypes.h) + set_source_files_properties(org.freedesktop.UDisks2.Job.xml PROPERTIES NO_NAMESPACE udisks2job INCLUDE includes/dbus_metatypes.h) + qt_add_dbus_interface(DEVICE_SOURCES org.freedesktop.DBus.ObjectManager.xml objectmanager) + qt_add_dbus_interface(DEVICE_SOURCES org.freedesktop.UDisks2.Filesystem.xml udisks2filesystem) + qt_add_dbus_interface(DEVICE_SOURCES org.freedesktop.UDisks2.Block.xml udisks2block) + qt_add_dbus_interface(DEVICE_SOURCES org.freedesktop.UDisks2.Drive.xml udisks2drive) + qt_add_dbus_interface(DEVICE_SOURCES org.freedesktop.UDisks2.Job.xml udisks2job) +endif() + +if(HAVE_MTP) + list(APPEND DEVICE_SOURCES mtpconnection.cpp mtpdevice.cpp mtploader.cpp) + list(APPEND DEVICE_HEADERS mtpconnection.h mtpdevice.h mtploader.h) +endif() + +if(HAVE_AUDIOCD) + list(APPEND DEVICE_SOURCES cddadevice.cpp cddalister.cpp cddasongloader.cpp) + list(APPEND DEVICE_HEADERS cddadevice.h cddalister.h cddasongloader.h) +endif() + +if(HAVE_GPOD) + list(APPEND DEVICE_SOURCES gpoddevice.cpp gpodloader.cpp) + list(APPEND DEVICE_HEADERS gpoddevice.h gpodloader.h) +endif() + +qt_wrap_cpp(DEVICE_SOURCES ${DEVICE_HEADERS}) +qt_wrap_ui(DEVICE_SOURCES ${DEVICE_UI}) + +add_library(strawberry_device STATIC ${DEVICE_SOURCES}) + +target_include_directories(strawberry_device PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_device PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + PkgConfig::GSTREAMER + PkgConfig::GSTREAMER_BASE + PkgConfig::GSTREAMER_AUDIO + PkgConfig::GSTREAMER_APP + PkgConfig::GSTREAMER_TAG + PkgConfig::GSTREAMER_PBUTILS + $<$:PkgConfig::GIO> + $<$:PkgConfig::GIO_UNIX> + $<$:PkgConfig::LIBCDIO> + $<$:PkgConfig::LIBMTP> + $<$:PkgConfig::LIBGPOD PkgConfig::GDK_PIXBUF> + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + $<$:Qt${QT_VERSION_MAJOR}::DBus> + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core + strawberry_collection + strawberry_widgets + strawberry_musicbrainz +) + +if(APPLE) + target_link_libraries(strawberry_device PRIVATE + "-framework IOKit" + "-framework DiskArbitration" + ) +endif() diff --git a/src/device/cddadevice.cpp b/src/device/cddadevice.cpp index 7c4d4d0f24..ed0479c784 100644 --- a/src/device/cddadevice.cpp +++ b/src/device/cddadevice.cpp @@ -24,24 +24,33 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "collection/collectionmodel.h" #include "cddasongloader.h" #include "connecteddevice.h" #include "cddadevice.h" -class Application; class DeviceLister; class DeviceManager; -CddaDevice::CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, int database_id, bool first_time, QObject *parent) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), +CddaDevice::CddaDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) + : ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), cdda_song_loader_(url) { QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsLoaded, this, &CddaDevice::SongsLoaded); QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsDurationLoaded, this, &CddaDevice::SongsLoaded); QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsMetadataLoaded, this, &CddaDevice::SongsLoaded); - QObject::connect(this, &CddaDevice::SongsDiscovered, model_, &CollectionModel::AddReAddOrUpdate); + QObject::connect(this, &CddaDevice::SongsDiscovered, collection_model_, &CollectionModel::AddReAddOrUpdate); } @@ -64,7 +73,7 @@ void CddaDevice::Refresh() { void CddaDevice::SongsLoaded(const SongList &songs) { - model_->Reset(); + collection_model_->Reset(); Q_EMIT SongsDiscovered(songs); song_count_ = songs.size(); diff --git a/src/device/cddadevice.h b/src/device/cddadevice.h index 283b1e35d5..94cb23fbcd 100644 --- a/src/device/cddadevice.h +++ b/src/device/cddadevice.h @@ -24,30 +24,42 @@ #include "config.h" +#include +#include + #include #include #include #include -// These must come after Qt includes -#include -#include - -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" #include "cddasongloader.h" #include "connecteddevice.h" -class Application; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class CddaDevice : public ConnectedDevice { Q_OBJECT public: - Q_INVOKABLE explicit CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr); + Q_INVOKABLE explicit CddaDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); bool Init() override; void Refresh() override; diff --git a/src/device/cddasongloader.cpp b/src/device/cddasongloader.cpp index 9a7d16db46..16b726f011 100644 --- a/src/device/cddasongloader.cpp +++ b/src/device/cddasongloader.cpp @@ -40,10 +40,10 @@ #include #include "cddasongloader.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" -#include "utilities/timeconstants.h" +#include "constants/timeconstants.h" using std::make_shared; diff --git a/src/device/cddasongloader.h b/src/device/cddasongloader.h index 10d16d159a..0b127d6d8a 100644 --- a/src/device/cddasongloader.h +++ b/src/device/cddasongloader.h @@ -35,7 +35,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #ifdef HAVE_MUSICBRAINZ # include "musicbrainz/musicbrainzclient.h" diff --git a/src/device/connecteddevice.cpp b/src/device/connecteddevice.cpp index d981a087c9..d5bd9ae47a 100644 --- a/src/device/connecteddevice.cpp +++ b/src/device/connecteddevice.cpp @@ -26,9 +26,9 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" +#include "core/taskmanager.h" #include "core/database.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" @@ -41,47 +41,58 @@ using namespace Qt::Literals::StringLiterals; using std::make_shared; -ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) +ConnectedDevice::ConnectedDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) : QObject(parent), - app_(app), url_(url), first_time_(first_time), lister_(lister), unique_id_(unique_id), database_id_(database_id), - manager_(manager), - backend_(nullptr), - model_(nullptr), + device_manager_(device_manager), + collection_backend_(nullptr), + collection_model_(nullptr), song_count_(0) { + Q_UNUSED(tagreader_client) + qLog(Info) << "Connected" << url << unique_id << first_time; // Create the backend in the database thread. - backend_ = make_shared(); - backend_->moveToThread(app_->database()->thread()); - qLog(Debug) << &*backend_ << "for device" << unique_id_ << "moved to thread" << app_->database()->thread(); + collection_backend_ = make_shared(); + collection_backend_->moveToThread(database->thread()); + qLog(Debug) << &*collection_backend_ << "for device" << unique_id_ << "moved to thread" << database->thread(); if (url_.scheme() != "cdda"_L1) { - QObject::connect(&*backend_, &CollectionBackend::TotalSongCountUpdated, this, &ConnectedDevice::BackendTotalSongCountUpdated); + QObject::connect(&*collection_backend_, &CollectionBackend::TotalSongCountUpdated, this, &ConnectedDevice::BackendTotalSongCountUpdated); } - backend_->Init(app_->database(), - app_->task_manager(), - Song::Source::Device, - QStringLiteral("device_%1_songs").arg(database_id), - QStringLiteral("device_%1_directories").arg(database_id), - QStringLiteral("device_%1_subdirectories").arg(database_id)); + collection_backend_->Init(database, + task_manager, + Song::Source::Device, + QStringLiteral("device_%1_songs").arg(database_id), + QStringLiteral("device_%1_directories").arg(database_id), + QStringLiteral("device_%1_subdirectories").arg(database_id)); // Create the model - model_ = new CollectionModel(backend_, app_, this); + collection_model_ = new CollectionModel(collection_backend_, albumcover_loader, this); } void ConnectedDevice::InitBackendDirectory(const QString &mount_point, const bool first_time, const bool rewrite_path) { - QList directories = backend_->GetAllDirectories(); + QList directories = collection_backend_->GetAllDirectories(); if (first_time || directories.isEmpty()) { - backend_->AddDirectory(mount_point); + collection_backend_->AddDirectory(mount_point); } else { if (rewrite_path) { @@ -95,12 +106,12 @@ void ConnectedDevice::InitBackendDirectory(const QString &mount_point, const boo if (dir.path != mount_point) { // The directory is different, commence the munging. qLog(Info) << "Changing path from" << dir.path << "to" << mount_point; - backend_->ChangeDirPath(dir.id, dir.path, mount_point); + collection_backend_->ChangeDirPath(dir.id, dir.path, mount_point); } } // Load the directory properly now - backend_->LoadDirectoriesAsync(); + collection_backend_->LoadDirectoriesAsync(); } } @@ -109,8 +120,8 @@ void ConnectedDevice::ConnectAsync() { Q_EMIT DeviceConnectFinished(unique_id_, void ConnectedDevice::Close() { - QObject::connect(&*backend_, &CollectionBackend::ExitFinished, this, &ConnectedDevice::BackendCloseFinished); - backend_->ExitAsync(); + QObject::connect(&*collection_backend_, &CollectionBackend::ExitFinished, this, &ConnectedDevice::BackendCloseFinished); + collection_backend_->ExitAsync(); } @@ -122,13 +133,13 @@ void ConnectedDevice::BackendCloseFinished() { void ConnectedDevice::Eject() { - DeviceInfo *info = manager_->FindDeviceById(unique_id_); + DeviceInfo *info = device_manager_->FindDeviceById(unique_id_); if (!info) return; - QModelIndex idx = manager_->ItemToIndex(info); + QModelIndex idx = device_manager_->ItemToIndex(info); if (!idx.isValid()) return; - manager_->UnmountAsync(idx); + device_manager_->UnmountAsync(idx); } @@ -150,10 +161,10 @@ bool ConnectedDevice::FinishDelete(bool success, QString &error_text) { MusicStorage::TranscodeMode ConnectedDevice::GetTranscodeMode() const { - DeviceInfo *info = manager_->FindDeviceById(unique_id_); + DeviceInfo *info = device_manager_->FindDeviceById(unique_id_); if (!info) return MusicStorage::TranscodeMode(); - QModelIndex idx = manager_->ItemToIndex(info); + QModelIndex idx = device_manager_->ItemToIndex(info); if (!idx.isValid()) return MusicStorage::TranscodeMode(); return static_cast(idx.data(DeviceManager::Role_TranscodeMode).toInt()); @@ -162,10 +173,10 @@ MusicStorage::TranscodeMode ConnectedDevice::GetTranscodeMode() const { Song::FileType ConnectedDevice::GetTranscodeFormat() const { - DeviceInfo *info = manager_->FindDeviceById(unique_id_); + DeviceInfo *info = device_manager_->FindDeviceById(unique_id_); if (!info) return Song::FileType::Unknown; - QModelIndex idx = manager_->ItemToIndex(info); + QModelIndex idx = device_manager_->ItemToIndex(info); if (!idx.isValid()) return Song::FileType::Unknown; return static_cast(idx.data(DeviceManager::Role_TranscodeFormat).toInt()); diff --git a/src/device/connecteddevice.h b/src/device/connecteddevice.h index 724ade506c..1bcc3d1908 100644 --- a/src/device/connecteddevice.h +++ b/src/device/connecteddevice.h @@ -30,15 +30,18 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/musicstorage.h" #include "core/song.h" -class Application; +class TaskManager; +class Database; class CollectionBackend; class CollectionModel; class DeviceLister; class DeviceManager; +class TagReaderClient; +class AlbumCoverLoader; using std::enable_shared_from_this; @@ -46,7 +49,17 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab Q_OBJECT public: - explicit ConnectedDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr); + explicit ConnectedDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); Song::Source source() const override { return Song::Source::Device; } @@ -63,7 +76,7 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab DeviceLister *lister() const { return lister_; } QString unique_id() const { return unique_id_; } - CollectionModel *model() const { return model_; } + CollectionModel *collection_model() const { return collection_model_; } QUrl url() const { return url_; } qint64 song_count() const { return song_count_; } @@ -81,23 +94,20 @@ class ConnectedDevice : public QObject, public virtual MusicStorage, public enab void SongCountUpdated(const int count); void DeviceConnectFinished(const QString &id, const bool success); void DeviceCloseFinished(const QString &id); + void Error(const QString &error); protected: void InitBackendDirectory(const QString &mount_point, const bool first_time, const bool rewrite_path = true); protected: - Application *app_; - QUrl url_; bool first_time_; DeviceLister *lister_; QString unique_id_; int database_id_; - SharedPtr manager_; - - SharedPtr backend_; - CollectionModel *model_; - + DeviceManager *device_manager_; + SharedPtr collection_backend_; + CollectionModel *collection_model_; qint64 song_count_; private Q_SLOTS: diff --git a/src/device/devicedatabasebackend.cpp b/src/device/devicedatabasebackend.cpp index 1784de0253..86b0da5d13 100644 --- a/src/device/devicedatabasebackend.cpp +++ b/src/device/devicedatabasebackend.cpp @@ -32,7 +32,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/database.h" #include "core/sqlquery.h" #include "core/scopedtransaction.h" diff --git a/src/device/devicedatabasebackend.h b/src/device/devicedatabasebackend.h index 0b26c64001..4c1f11f93a 100644 --- a/src/device/devicedatabasebackend.h +++ b/src/device/devicedatabasebackend.h @@ -30,7 +30,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" diff --git a/src/device/devicemanager.cpp b/src/device/devicemanager.cpp index c19776be48..571dee134d 100644 --- a/src/device/devicemanager.cpp +++ b/src/device/devicemanager.cpp @@ -45,10 +45,9 @@ #include "devicemanager.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/database.h" #include "core/iconloader.h" #include "core/musicstorage.h" @@ -88,20 +87,27 @@ using std::make_unique; const int DeviceManager::kDeviceIconSize = 32; const int DeviceManager::kDeviceIconOverlaySize = 16; -DeviceManager::DeviceManager(Application *app, QObject *parent) +DeviceManager::DeviceManager(const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + QObject *parent) : SimpleTreeModel(new DeviceInfo(this), parent), - app_(app), + task_manager_(task_manager), + database_(database), + tagreader_client_(tagreader_client), + albumcover_loader_(albumcover_loader), not_connected_overlay_(IconLoader::Load(u"edit-delete"_s)) { setObjectName(QLatin1String(metaObject()->className())); thread_pool_.setMaxThreadCount(1); - QObject::connect(&*app_->task_manager(), &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged); + QObject::connect(&*task_manager, &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged); // Create the backend in the database thread backend_ = make_unique(); - backend_->moveToThread(app_->database()->thread()); - backend_->Init(app_->database()); + backend_->moveToThread(database->thread()); + backend_->Init(database); QObject::connect(this, &DeviceManager::DeviceCreatedFromDB, this, &DeviceManager::AddDeviceFromDB); @@ -225,6 +231,7 @@ void DeviceManager::DeviceDestroyed() { if (wait_for_exit_.isEmpty()) CloseListers(); } + void DeviceManager::LoadAllDevices() { Q_ASSERT(QThread::currentThread() != qApp->thread()); @@ -363,7 +370,7 @@ QVariant DeviceManager::data(const QModelIndex &idx, int role) const { QString ret = info->device_->url().path(); #ifdef Q_OS_WIN32 - if (ret.startsWith('/')) ret.remove(0, 1); + if (ret.startsWith(u'/')) ret.remove(0, 1); #endif return QDir::toNativeSeparators(ret); } @@ -627,7 +634,7 @@ SharedPtr DeviceManager::Connect(DeviceInfo *info) { url_strings << url.toString(); } - app_->AddError(tr("This type of device is not supported: %1").arg(url_strings.join(", "_L1))); + Q_EMIT DeviceError(tr("This type of device is not supported: %1").arg(url_strings.join(", "_L1))); return ret; } @@ -636,8 +643,11 @@ SharedPtr DeviceManager::Connect(DeviceInfo *info) { Q_ARG(QUrl, device_url), Q_ARG(DeviceLister*, info->BestBackend()->lister_), Q_ARG(QString, info->BestBackend()->unique_id_), - Q_ARG(SharedPtr, app_->device_manager()), - Q_ARG(Application*, app_), + Q_ARG(DeviceManager*, this), + Q_ARG(SharedPtr, task_manager_), + Q_ARG(SharedPtr, database_), + Q_ARG(SharedPtr, tagreader_client_), + Q_ARG(SharedPtr, albumcover_loader_), Q_ARG(int, info->database_id_), Q_ARG(bool, first_time)); @@ -664,7 +674,10 @@ SharedPtr DeviceManager::Connect(DeviceInfo *info) { QObject::connect(&*info->device_, &ConnectedDevice::SongCountUpdated, this, &DeviceManager::DeviceSongCountUpdated); QObject::connect(&*info->device_, &ConnectedDevice::DeviceConnectFinished, this, &DeviceManager::DeviceConnectFinished); QObject::connect(&*info->device_, &ConnectedDevice::DeviceCloseFinished, this, &DeviceManager::DeviceCloseFinished); + QObject::connect(&*info->device_, &ConnectedDevice::Error, this, &DeviceManager::DeviceError); + ret->ConnectAsync(); + return ret; } @@ -842,7 +855,7 @@ void DeviceManager::DeviceTaskStarted(const int id) { void DeviceManager::TasksChanged() { - const QList tasks = app_->task_manager()->GetTasks(); + const QList tasks = task_manager_->GetTasks(); QList finished_tasks = active_tasks_.values(); for (const TaskManager::Task &task : tasks) { diff --git a/src/device/devicemanager.h b/src/device/devicemanager.h index 8fd2a82a3b..68a3a46a6d 100644 --- a/src/device/devicemanager.h +++ b/src/device/devicemanager.h @@ -37,8 +37,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" #include "core/simpletreemodel.h" @@ -49,7 +49,10 @@ class QModelIndex; class QPersistentModelIndex; -class Application; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class ConnectedDevice; class DeviceLister; class DeviceStateFilterModel; @@ -58,7 +61,12 @@ class DeviceManager : public SimpleTreeModel { Q_OBJECT public: - explicit DeviceManager(Application *app, QObject *parent = nullptr); + explicit DeviceManager(const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + QObject *parent = nullptr); + ~DeviceManager() override; enum Role { @@ -123,6 +131,7 @@ class DeviceManager : public SimpleTreeModel { void DeviceConnected(const QModelIndex idx); void DeviceDisconnected(const QModelIndex idx); void DeviceCreatedFromDB(DeviceInfo *info); + void DeviceError(const QString &error); private Q_SLOTS: void PhysicalDeviceAdded(const QString &id); @@ -152,7 +161,11 @@ class DeviceManager : public SimpleTreeModel { void CloseBackend(); private: - Application *app_; + const SharedPtr task_manager_; + const SharedPtr database_; + const SharedPtr tagreader_client_; + const SharedPtr albumcover_loader_; + ScopedPtr backend_; DeviceStateFilterModel *connected_devices_model_; diff --git a/src/device/deviceproperties.cpp b/src/device/deviceproperties.cpp index 0e53f75397..f891b0d873 100644 --- a/src/device/deviceproperties.cpp +++ b/src/device/deviceproperties.cpp @@ -46,7 +46,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/iconloader.h" #include "core/musicstorage.h" #include "widgets/freespacebar.h" @@ -62,7 +62,7 @@ using namespace Qt::Literals::StringLiterals; DeviceProperties::DeviceProperties(QWidget *parent) : QDialog(parent), ui_(new Ui_DeviceProperties), - manager_(nullptr), + device_manager_(nullptr), updating_formats_(false) { ui_->setupUi(this); @@ -76,12 +76,12 @@ DeviceProperties::DeviceProperties(QWidget *parent) DeviceProperties::~DeviceProperties() { delete ui_; } -void DeviceProperties::SetDeviceManager(SharedPtr manager) { +void DeviceProperties::Init(const SharedPtr device_manager) { - manager_ = manager; - QObject::connect(&*manager_, &DeviceManager::dataChanged, this, &DeviceProperties::ModelChanged); - QObject::connect(&*manager_, &DeviceManager::rowsInserted, this, &DeviceProperties::ModelChanged); - QObject::connect(&*manager_, &DeviceManager::rowsRemoved, this, &DeviceProperties::ModelChanged); + device_manager_ = device_manager; + QObject::connect(&*device_manager_, &DeviceManager::dataChanged, this, &DeviceProperties::ModelChanged); + QObject::connect(&*device_manager_, &DeviceManager::rowsInserted, this, &DeviceProperties::ModelChanged); + QObject::connect(&*device_manager_, &DeviceManager::rowsRemoved, this, &DeviceProperties::ModelChanged); } @@ -155,7 +155,7 @@ void DeviceProperties::UpdateHardwareInfo() { // Hardware information QString id = index_.data(DeviceManager::Role_UniqueId).toString(); - if (DeviceLister *lister = manager_->GetLister(index_)) { + if (DeviceLister *lister = device_manager_->GetLister(index_)) { QVariantMap info = lister->DeviceHardwareInfo(id); // Remove empty items @@ -202,8 +202,8 @@ void DeviceProperties::UpdateHardwareInfo() { void DeviceProperties::UpdateFormats() { - DeviceLister *lister = manager_->GetLister(index_); - SharedPtr device = manager_->GetConnectedDevice(index_); + DeviceLister *lister = device_manager_->GetLister(index_); + SharedPtr device = device_manager_->GetConnectedDevice(index_); // Transcode mode MusicStorage::TranscodeMode mode = static_cast(index_.data(DeviceManager::Role_TranscodeMode).toInt()); @@ -274,11 +274,11 @@ void DeviceProperties::accept() { icon_name = ui_->icon->currentItem()->data(Qt::UserRole).toString(); } - manager_->SetDeviceOptions(index_, ui_->name->text(), icon_name, mode, format); + device_manager_->SetDeviceOptions(index_, ui_->name->text(), icon_name, mode, format); } -void DeviceProperties::OpenDevice() { manager_->Connect(index_); } +void DeviceProperties::OpenDevice() { device_manager_->Connect(index_); } void DeviceProperties::UpdateFormatsFinished() { diff --git a/src/device/deviceproperties.h b/src/device/deviceproperties.h index 74bf5286ea..2ff68eec91 100644 --- a/src/device/deviceproperties.h +++ b/src/device/deviceproperties.h @@ -33,7 +33,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QWidget; @@ -48,7 +48,7 @@ class DeviceProperties : public QDialog { explicit DeviceProperties(QWidget *parent = nullptr); ~DeviceProperties() override; - void SetDeviceManager(SharedPtr manager); + void Init(const SharedPtr device_manager); void ShowDevice(const QModelIndex &idx); public Q_SLOTS: @@ -67,7 +67,7 @@ class DeviceProperties : public QDialog { private: Ui_DeviceProperties *ui_; - SharedPtr manager_; + SharedPtr device_manager_; QPersistentModelIndex index_; bool updating_formats_; diff --git a/src/device/devicestatefiltermodel.cpp b/src/device/devicestatefiltermodel.cpp index cc897d3cb6..c57ba98ed7 100644 --- a/src/device/devicestatefiltermodel.cpp +++ b/src/device/devicestatefiltermodel.cpp @@ -43,9 +43,11 @@ bool DeviceStateFilterModel::filterAcceptsRow(const int row, const QModelIndex & return sourceModel()->index(row, 0).data(DeviceManager::Role_State).toInt() != state_ && sourceModel()->index(row, 0).data(DeviceManager::Role_CopyMusic).toBool(); } -void DeviceStateFilterModel::ProxyRowCountChanged(const QModelIndex &idx, const int, const int) { +void DeviceStateFilterModel::ProxyRowCountChanged(const QModelIndex &idx, const int first, const int last) { Q_UNUSED(idx) + Q_UNUSED(first); + Q_UNUSED(last); Q_EMIT IsEmptyChanged(rowCount() == 0); diff --git a/src/device/deviceview.cpp b/src/device/deviceview.cpp index d9b7ccdf7d..ca4cbb095c 100644 --- a/src/device/deviceview.cpp +++ b/src/device/deviceview.cpp @@ -48,12 +48,12 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/shared_ptr.h" +#include "includes/scoped_ptr.h" #include "core/iconloader.h" -#include "core/application.h" #include "core/deletefiles.h" #include "core/mergedproxymodel.h" -#include "core/mimedata.h" +#include "mimedata/mimedata.h" #include "core/musicstorage.h" #include "utilities/colorutils.h" #include "organize/organizedialog.h" @@ -61,8 +61,8 @@ #include "collection/collectiondirectorymodel.h" #include "collection/collectionmodel.h" #include "collection/collectionitemdelegate.h" -#include "connecteddevice.h" #include "devicelister.h" +#include "connecteddevice.h" #include "devicemanager.h" #include "deviceproperties.h" #include "deviceview.h" @@ -175,7 +175,6 @@ void DeviceItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op DeviceView::DeviceView(QWidget *parent) : AutoExpandingTreeView(parent), - app_(nullptr), merged_model_(nullptr), sort_model_(nullptr), properties_dialog_(new DeviceProperties), @@ -202,16 +201,20 @@ DeviceView::DeviceView(QWidget *parent) DeviceView::~DeviceView() = default; -void DeviceView::SetApplication(Application *app) { +void DeviceView::Init(const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr device_manager, + CollectionDirectoryModel *collection_directory_model) { - Q_ASSERT(app_ == nullptr); - app_ = app; + task_manager_ = task_manager; + tagreader_client_ = tagreader_client; + device_manager_ = device_manager; - QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceConnected, this, &DeviceView::DeviceConnected); - QObject::connect(&*app_->device_manager(), &DeviceManager::DeviceDisconnected, this, &DeviceView::DeviceDisconnected); + QObject::connect(&*device_manager_, &DeviceManager::DeviceConnected, this, &DeviceView::DeviceConnected); + QObject::connect(&*device_manager_, &DeviceManager::DeviceDisconnected, this, &DeviceView::DeviceDisconnected); sort_model_ = new QSortFilterProxyModel(this); - sort_model_->setSourceModel(&*app_->device_manager()); + sort_model_->setSourceModel(&*device_manager_); sort_model_->setDynamicSortFilter(true); sort_model_->setSortCaseSensitivity(Qt::CaseInsensitive); sort_model_->sort(0); @@ -222,10 +225,10 @@ void DeviceView::SetApplication(Application *app) { QObject::connect(merged_model_, &MergedProxyModel::SubModelReset, this, &AutoExpandingTreeView::RecursivelyExpandSlot); - properties_dialog_->SetDeviceManager(app_->device_manager()); + properties_dialog_->Init(device_manager_); - organize_dialog_ = make_unique(app_->task_manager(), nullptr, this); - organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model()); + organize_dialog_ = make_unique(task_manager, tagreader_client, nullptr, this); + organize_dialog_->SetDestinationModel(collection_directory_model); } @@ -257,8 +260,8 @@ void DeviceView::contextMenuEvent(QContextMenuEvent *e) { const QModelIndex collection_index = MapToCollection(menu_index_); if (device_index.isValid()) { - const bool is_plugged_in = app_->device_manager()->GetLister(device_index); - const bool is_remembered = app_->device_manager()->GetDatabaseId(device_index) != -1; + const bool is_plugged_in = device_manager_->GetLister(device_index); + const bool is_remembered = device_manager_->GetDatabaseId(device_index) != -1; forget_action_->setEnabled(is_remembered); eject_action_->setEnabled(is_plugged_in); @@ -270,7 +273,7 @@ void DeviceView::contextMenuEvent(QContextMenuEvent *e) { bool is_filesystem_device = false; if (parent_device_index.isValid()) { - SharedPtr device = app_->device_manager()->GetConnectedDevice(parent_device_index); + SharedPtr device = device_manager_->GetConnectedDevice(parent_device_index); if (device && !device->LocalPath().isEmpty()) is_filesystem_device = true; } @@ -309,21 +312,21 @@ QModelIndex DeviceView::MapToCollection(const QModelIndex &merged_model_index) c void DeviceView::Connect() { QModelIndex device_idx = MapToDevice(menu_index_); - app_->device_manager()->data(device_idx, MusicStorage::Role_StorageForceConnect); + device_manager_->data(device_idx, MusicStorage::Role_StorageForceConnect); } void DeviceView::DeviceConnected(const QModelIndex &idx) { if (!idx.isValid()) return; - SharedPtr device = app_->device_manager()->GetConnectedDevice(idx); + SharedPtr device = device_manager_->GetConnectedDevice(idx); if (!device) return; QModelIndex sort_idx = sort_model_->mapFromSource(idx); if (!sort_idx.isValid()) return; - QSortFilterProxyModel *sort_model = new QSortFilterProxyModel(device->model()); - sort_model->setSourceModel(device->model()); + QSortFilterProxyModel *sort_model = new QSortFilterProxyModel(device->collection_model()); + sort_model->setSourceModel(device->collection_model()); sort_model->setSortRole(CollectionModel::Role_SortText); sort_model->setDynamicSortFilter(true); sort_model->sort(0); @@ -341,8 +344,8 @@ void DeviceView::DeviceDisconnected(const QModelIndex &idx) { void DeviceView::Forget() { QModelIndex device_idx = MapToDevice(menu_index_); - QString unique_id = app_->device_manager()->data(device_idx, DeviceManager::Role_UniqueId).toString(); - if (app_->device_manager()->GetLister(device_idx) && app_->device_manager()->GetLister(device_idx)->AskForScan(unique_id)) { + QString unique_id = device_manager_->data(device_idx, DeviceManager::Role_UniqueId).toString(); + if (device_manager_->GetLister(device_idx) && device_manager_->GetLister(device_idx)->AskForScan(unique_id)) { ScopedPtr dialog(new QMessageBox( QMessageBox::Question, tr("Forget device"), tr("Forgetting a device will remove it from this list and Strawberry will have to rescan all the songs again next time you connect it."), @@ -353,7 +356,7 @@ void DeviceView::Forget() { if (dialog->clickedButton() != forget) return; } - app_->device_manager()->Forget(device_idx); + device_manager_->Forget(device_idx); } @@ -368,7 +371,7 @@ void DeviceView::mouseDoubleClickEvent(QMouseEvent *e) { QModelIndex merged_index = indexAt(e->pos()); QModelIndex device_index = MapToDevice(merged_index); if (device_index.isValid()) { - if (!app_->device_manager()->GetConnectedDevice(device_index)) { + if (!device_manager_->GetConnectedDevice(device_index)) { menu_index_ = merged_index; Connect(); } @@ -433,7 +436,7 @@ void DeviceView::Delete() { SharedPtr storage = device_index.data(MusicStorage::Role_Storage).value>(); - DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, false); + DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage, false); QObject::connect(delete_files, &DeleteFiles::Finished, this, &DeviceView::DeleteFinished); delete_files->Start(GetSelectedSongs()); @@ -456,7 +459,7 @@ void DeviceView::Organize() { void DeviceView::Unmount() { QModelIndex device_idx = MapToDevice(menu_index_); - app_->device_manager()->Unmount(device_idx); + device_manager_->Unmount(device_idx); } void DeviceView::DeleteFinished(const SongList &songs_with_errors) { diff --git a/src/device/deviceview.h b/src/device/deviceview.h index d8cbcecedf..fcd7ea774c 100644 --- a/src/device/deviceview.h +++ b/src/device/deviceview.h @@ -30,7 +30,8 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "collection/collectionitemdelegate.h" #include "widgets/autoexpandingtreeview.h" @@ -43,8 +44,11 @@ class QAction; class QMouseEvent; class QContextMenuEvent; -class Application; +class TaskManager; +class TagReaderClient; +class DeviceManager; class DeviceProperties; +class CollectionDirectoryModel; class MergedProxyModel; class OrganizeDialog; @@ -67,7 +71,10 @@ class DeviceView : public AutoExpandingTreeView { explicit DeviceView(QWidget *parent = nullptr); ~DeviceView() override; - void SetApplication(Application *app); + void Init(const SharedPtr task_manager, + const SharedPtr tagreader_client, + const SharedPtr device_manager, + CollectionDirectoryModel *collection_directory_model); // AutoExpandingTreeView bool CanRecursivelyExpand(const QModelIndex &idx) const override; @@ -102,7 +109,9 @@ class DeviceView : public AutoExpandingTreeView { SongList GetSelectedSongs() const; private: - Application *app_; + SharedPtr task_manager_; + SharedPtr tagreader_client_; + SharedPtr device_manager_; MergedProxyModel *merged_model_; QSortFilterProxyModel *sort_model_; diff --git a/src/device/filesystemdevice.cpp b/src/device/filesystemdevice.cpp index f31970d76d..3c728c4e80 100644 --- a/src/device/filesystemdevice.cpp +++ b/src/device/filesystemdevice.cpp @@ -25,53 +25,66 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/song.h" +#include "core/taskmanager.h" +#include "core/database.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" #include "collection/collectionwatcher.h" + +#include "covermanager/albumcoverloader.h" + #include "connecteddevice.h" #include "devicemanager.h" #include "filesystemdevice.h" class DeviceLister; -FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) +FilesystemDevice::FilesystemDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) : FilesystemMusicStorage(Song::Source::Device, url.toLocalFile()), - ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), - watcher_(new CollectionWatcher(Song::Source::Device)), + ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), + collection_watcher_(new CollectionWatcher(Song::Source::Device, task_manager, tagreader_client, collection_backend_)), watcher_thread_(new QThread(this)) { - watcher_->moveToThread(watcher_thread_); + collection_watcher_->moveToThread(watcher_thread_); watcher_thread_->start(QThread::IdlePriority); - qLog(Debug) << watcher_ << "for device" << unique_id << "moved to thread" << watcher_thread_; - - watcher_->set_device_name(manager->DeviceNameByID(unique_id)); - watcher_->set_backend(backend_); - watcher_->set_task_manager(app_->task_manager()); - - QObject::connect(&*backend_, &CollectionBackend::DirectoryAdded, watcher_, &CollectionWatcher::AddDirectory); - QObject::connect(&*backend_, &CollectionBackend::DirectoryDeleted, watcher_, &CollectionWatcher::RemoveDirectory); - QObject::connect(watcher_, &CollectionWatcher::NewOrUpdatedSongs, &*backend_, &CollectionBackend::AddOrUpdateSongs); - QObject::connect(watcher_, &CollectionWatcher::SongsMTimeUpdated, &*backend_, &CollectionBackend::UpdateMTimesOnly); - QObject::connect(watcher_, &CollectionWatcher::SongsDeleted, &*backend_, &CollectionBackend::DeleteSongs); - QObject::connect(watcher_, &CollectionWatcher::SongsUnavailable, &*backend_, &CollectionBackend::MarkSongsUnavailable); - QObject::connect(watcher_, &CollectionWatcher::SongsReadded, &*backend_, &CollectionBackend::MarkSongsUnavailable); - QObject::connect(watcher_, &CollectionWatcher::SubdirsDiscovered, &*backend_, &CollectionBackend::AddOrUpdateSubdirs); - QObject::connect(watcher_, &CollectionWatcher::SubdirsMTimeUpdated, &*backend_, &CollectionBackend::AddOrUpdateSubdirs); - QObject::connect(watcher_, &CollectionWatcher::CompilationsNeedUpdating, &*backend_, &CollectionBackend::CompilationsNeedUpdating); - QObject::connect(watcher_, &CollectionWatcher::UpdateLastSeen, &*backend_, &CollectionBackend::UpdateLastSeen); - QObject::connect(watcher_, &CollectionWatcher::ScanStarted, this, &FilesystemDevice::TaskStarted); + + qLog(Debug) << collection_watcher_ << "for device" << unique_id << "moved to thread" << watcher_thread_; + + collection_watcher_->set_device_name(device_manager->DeviceNameByID(unique_id)); + + QObject::connect(&*collection_backend_, &CollectionBackend::DirectoryAdded, collection_watcher_, &CollectionWatcher::AddDirectory); + QObject::connect(&*collection_backend_, &CollectionBackend::DirectoryDeleted, collection_watcher_, &CollectionWatcher::RemoveDirectory); + QObject::connect(collection_watcher_, &CollectionWatcher::NewOrUpdatedSongs, &*collection_backend_, &CollectionBackend::AddOrUpdateSongs); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsMTimeUpdated, &*collection_backend_, &CollectionBackend::UpdateMTimesOnly); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsDeleted, &*collection_backend_, &CollectionBackend::DeleteSongs); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsUnavailable, &*collection_backend_, &CollectionBackend::MarkSongsUnavailable); + QObject::connect(collection_watcher_, &CollectionWatcher::SongsReadded, &*collection_backend_, &CollectionBackend::MarkSongsUnavailable); + QObject::connect(collection_watcher_, &CollectionWatcher::SubdirsDiscovered, &*collection_backend_, &CollectionBackend::AddOrUpdateSubdirs); + QObject::connect(collection_watcher_, &CollectionWatcher::SubdirsMTimeUpdated, &*collection_backend_, &CollectionBackend::AddOrUpdateSubdirs); + QObject::connect(collection_watcher_, &CollectionWatcher::CompilationsNeedUpdating, &*collection_backend_, &CollectionBackend::CompilationsNeedUpdating); + QObject::connect(collection_watcher_, &CollectionWatcher::UpdateLastSeen, &*collection_backend_, &CollectionBackend::UpdateLastSeen); + QObject::connect(collection_watcher_, &CollectionWatcher::ScanStarted, this, &FilesystemDevice::TaskStarted); } FilesystemDevice::~FilesystemDevice() { - watcher_->Abort(); - watcher_->deleteLater(); + collection_watcher_->Abort(); + collection_watcher_->deleteLater(); watcher_thread_->exit(); watcher_thread_->wait(); @@ -80,7 +93,7 @@ FilesystemDevice::~FilesystemDevice() { bool FilesystemDevice::Init() { InitBackendDirectory(url_.toLocalFile(), first_time_); - model_->Init(); + collection_model_->Init(); return true; } @@ -93,15 +106,15 @@ void FilesystemDevice::Close() { Q_ASSERT(QThread::currentThread() == thread()); - wait_for_exit_ << &*backend_ << watcher_; + wait_for_exit_ << &*collection_backend_ << collection_watcher_; - QObject::disconnect(&*backend_, nullptr, watcher_, nullptr); - QObject::disconnect(watcher_, nullptr, &*backend_, nullptr); + QObject::disconnect(&*collection_backend_, nullptr, collection_watcher_, nullptr); + QObject::disconnect(collection_watcher_, nullptr, &*collection_backend_, nullptr); - QObject::connect(&*backend_, &CollectionBackend::ExitFinished, this, &FilesystemDevice::ExitFinished); - QObject::connect(watcher_, &CollectionWatcher::ExitFinished, this, &FilesystemDevice::ExitFinished); - backend_->ExitAsync(); - watcher_->ExitAsync(); + QObject::connect(&*collection_backend_, &CollectionBackend::ExitFinished, this, &FilesystemDevice::ExitFinished); + QObject::connect(collection_watcher_, &CollectionWatcher::ExitFinished, this, &FilesystemDevice::ExitFinished); + collection_backend_->ExitAsync(); + collection_watcher_->ExitAsync(); } diff --git a/src/device/filesystemdevice.h b/src/device/filesystemdevice.h index b74baec747..fa6c3294ab 100644 --- a/src/device/filesystemdevice.h +++ b/src/device/filesystemdevice.h @@ -30,21 +30,35 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/filesystemmusicstorage.h" #include "connecteddevice.h" class QThread; -class Application; -class CollectionWatcher; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; +class CollectionWatcher; class FilesystemDevice : public ConnectedDevice, public virtual FilesystemMusicStorage { Q_OBJECT public: - Q_INVOKABLE FilesystemDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr); + Q_INVOKABLE FilesystemDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); + ~FilesystemDevice() override; Song::Source source() const final { return Song::Source::Device; } @@ -59,7 +73,7 @@ class FilesystemDevice : public ConnectedDevice, public virtual FilesystemMusicS void ExitFinished(); private: - CollectionWatcher *watcher_; + CollectionWatcher *collection_watcher_; QThread *watcher_thread_; QList wait_for_exit_; }; diff --git a/src/device/giolister.cpp b/src/device/giolister.cpp index f9e0e0b0e6..dba9a1cc51 100644 --- a/src/device/giolister.cpp +++ b/src/device/giolister.cpp @@ -572,7 +572,8 @@ QString GioLister::FindUniqueIdByVolume(GVolume *volume) const { } -void GioLister::VolumeEjectFinished(GObject *object, GAsyncResult *result, gpointer) { +void GioLister::VolumeEjectFinished(GObject *object, GAsyncResult *result, gpointer instance) { + Q_UNUSED(instance) OperationFinished(std::bind(g_volume_eject_with_operation_finish, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), object, result); } diff --git a/src/device/giolister.h b/src/device/giolister.h index d19c667042..4fa574e171 100644 --- a/src/device/giolister.h +++ b/src/device/giolister.h @@ -38,7 +38,7 @@ #include #include -#include "core/scopedgobject.h" +#include "includes/scopedgobject.h" #include "devicelister.h" class GioLister : public DeviceLister { diff --git a/src/device/gpoddevice.cpp b/src/device/gpoddevice.cpp index 3fc9633417..2dfb2676f5 100644 --- a/src/device/gpoddevice.cpp +++ b/src/device/gpoddevice.cpp @@ -38,12 +38,14 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/temporaryfile.h" +#include "core/taskmanager.h" +#include "core/database.h" #include "collection/collectionbackend.h" #include "collection/collectionmodel.h" +#include "covermanager/albumcoverloader.h" #include "connecteddevice.h" #include "gpoddevice.h" #include "gpodloader.h" @@ -54,8 +56,19 @@ class DeviceManager; using std::make_shared; using namespace Qt::Literals::StringLiterals; -GPodDevice::GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), +GPodDevice::GPodDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) + : ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), + task_manager_(task_manager), loader_(nullptr), loader_thread_(nullptr), db_(nullptr), @@ -64,9 +77,9 @@ GPodDevice::GPodDevice(const QUrl &url, DeviceLister *lister, const QString &uni bool GPodDevice::Init() { InitBackendDirectory(url_.path(), first_time_); - model_->Init(); + collection_model_->Init(); - loader_ = new GPodLoader(url_.path(), app_->task_manager(), backend_, shared_from_this()); + loader_ = new GPodLoader(url_.path(), task_manager_, collection_backend_, shared_from_this()); loader_thread_ = new QThread(); loader_->moveToThread(loader_thread_); @@ -135,7 +148,9 @@ void GPodDevice::LoadFinished(Itdb_iTunesDB *db, const bool success) { } -void GPodDevice::LoaderError(const QString &message) { app_->AddError(message); } +void GPodDevice::LoaderError(const QString &message) { + Q_EMIT Error(message); +} void GPodDevice::Start() { @@ -240,7 +255,7 @@ bool GPodDevice::CopyToStorage(const CopyJob &job, QString &error_text) { error_text = tr("Could not copy %1 to %2: %3").arg(job.metadata_.url().toLocalFile(), url_.path(), QString::fromUtf8(error->message)); g_error_free(error); qLog(Error) << error_text; - app_->AddError(error_text); + Q_EMIT Error(error_text); // Need to remove the track from the db again itdb_track_remove(track); @@ -286,7 +301,7 @@ bool GPodDevice::WriteDatabase(QString &error_text) { else { error_text = tr("Writing database failed."); } - app_->AddError(error_text); + Q_EMIT Error(error_text); } return success; @@ -297,12 +312,12 @@ void GPodDevice::Finish(const bool success) { // Update the collection model if (success) { - if (!songs_to_add_.isEmpty()) backend_->AddOrUpdateSongs(songs_to_add_); - if (!songs_to_remove_.isEmpty()) backend_->DeleteSongs(songs_to_remove_); + if (!songs_to_add_.isEmpty()) collection_backend_->AddOrUpdateSongs(songs_to_add_); + if (!songs_to_remove_.isEmpty()) collection_backend_->DeleteSongs(songs_to_remove_); } // This is done in the organize thread so close the unique DB connection. - backend_->Close(); + collection_backend_->Close(); songs_to_add_.clear(); songs_to_remove_.clear(); diff --git a/src/device/gpoddevice.h b/src/device/gpoddevice.h index d299e9564f..719b69808d 100644 --- a/src/device/gpoddevice.h +++ b/src/device/gpoddevice.h @@ -34,7 +34,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "core/musicstorage.h" #include "core/temporaryfile.h" @@ -42,15 +42,29 @@ #include "gpodloader.h" class QThread; -class Application; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class GPodDevice : public ConnectedDevice, public virtual MusicStorage { Q_OBJECT public: - Q_INVOKABLE GPodDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr); + Q_INVOKABLE GPodDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); + ~GPodDevice() override; bool Init() override; @@ -86,6 +100,7 @@ class GPodDevice : public ConnectedDevice, public virtual MusicStorage { bool WriteDatabase(QString &error_text); protected: + SharedPtr task_manager_; GPodLoader *loader_; QThread *loader_thread_; diff --git a/src/device/gpodloader.cpp b/src/device/gpodloader.cpp index bd4ce910e2..df1a058de7 100644 --- a/src/device/gpodloader.cpp +++ b/src/device/gpodloader.cpp @@ -29,14 +29,18 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/song.h" #include "core/taskmanager.h" #include "collection/collectionbackend.h" #include "gpodloader.h" -GPodLoader::GPodLoader(const QString &mount_point, SharedPtr task_manager, SharedPtr backend, SharedPtr device, QObject *parent) +GPodLoader::GPodLoader(const QString &mount_point, + const SharedPtr task_manager, + const SharedPtr backend, + const SharedPtr device, + QObject *parent) : QObject(parent), device_(device), mount_point_(mount_point), diff --git a/src/device/gpodloader.h b/src/device/gpodloader.h index 418c109684..2ca9d1fc30 100644 --- a/src/device/gpodloader.h +++ b/src/device/gpodloader.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QThread; @@ -41,7 +41,12 @@ class GPodLoader : public QObject { Q_OBJECT public: - explicit GPodLoader(const QString &mount_point, SharedPtr task_manager, SharedPtr backend, SharedPtr device, QObject *parent = nullptr); + explicit GPodLoader(const QString &mount_point, + const SharedPtr task_manager, + const SharedPtr backend, + const SharedPtr device, + QObject *parent = nullptr); + ~GPodLoader() override; void set_music_path_prefix(const QString &prefix) { path_prefix_ = prefix; } diff --git a/src/device/macosdevicelister.mm b/src/device/macosdevicelister.mm index fcad47da2e..3020589e09 100644 --- a/src/device/macosdevicelister.mm +++ b/src/device/macosdevicelister.mm @@ -19,6 +19,8 @@ * */ +#include "config.h" + #include #include @@ -38,13 +40,12 @@ #include #include -#include "config.h" #include "macosdevicelister.h" #include "mtpconnection.h" +#include "includes/scoped_cftyperef.h" +#include "includes/scoped_nsobject.h" #include "core/logging.h" -#include "core/scoped_cftyperef.h" #include "core/scoped_nsautorelease_pool.h" -#include "core/scoped_nsobject.h" #import #import diff --git a/src/device/mtpdevice.cpp b/src/device/mtpdevice.cpp index 601a3cae16..19b752b04c 100644 --- a/src/device/mtpdevice.cpp +++ b/src/device/mtpdevice.cpp @@ -33,9 +33,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" -#include "core/application.h" #include "core/musicstorage.h" #include "collection/collectionmodel.h" #include "collection/collectionbackend.h" @@ -46,13 +45,27 @@ using namespace Qt::Literals::StringLiterals; +class TaskManager; +class Database; +class AlbumCoverLoader; class DeviceLister; class DeviceManager; bool MtpDevice::sInitializedLibMTP = false; -MtpDevice::MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), +MtpDevice::MtpDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent) + : ConnectedDevice(url, lister, unique_id, device_manager, task_manager, database, tagreader_client, albumcover_loader, database_id, first_time, parent), + task_manager_(task_manager), loader_(nullptr), loader_thread_(nullptr), closing_(false) { @@ -79,9 +92,9 @@ MtpDevice::~MtpDevice() { bool MtpDevice::Init() { InitBackendDirectory(u"/"_s, first_time_, false); - model_->Init(); + collection_model_->Init(); - loader_ = new MtpLoader(url_, app_->task_manager(), backend_); + loader_ = new MtpLoader(url_, task_manager_, collection_backend_); loader_thread_ = new QThread(); loader_->moveToThread(loader_thread_); @@ -132,7 +145,7 @@ void MtpDevice::LoadFinished(const bool success, MtpConnection *connection) { } void MtpDevice::LoaderError(const QString &message) { - app_->AddError(message); + Q_EMIT Error(message); } bool MtpDevice::StartCopy(QList *supported_types) { @@ -204,15 +217,15 @@ bool MtpDevice::CopyToStorage(const CopyJob &job, QString &error_text) { bool MtpDevice::FinishCopy(const bool success, QString &error_text) { if (success) { - if (!songs_to_add_.isEmpty()) backend_->AddOrUpdateSongs(songs_to_add_); - if (!songs_to_remove_.isEmpty()) backend_->DeleteSongs(songs_to_remove_); + if (!songs_to_add_.isEmpty()) collection_backend_->AddOrUpdateSongs(songs_to_add_); + if (!songs_to_remove_.isEmpty()) collection_backend_->DeleteSongs(songs_to_remove_); } songs_to_add_.clear(); songs_to_remove_.clear(); // This is done in the organize thread so close the unique DB connection. - backend_->Close(); + collection_backend_->Close(); db_busy_.unlock(); diff --git a/src/device/mtpdevice.h b/src/device/mtpdevice.h index b363d7b56d..451e6473ab 100644 --- a/src/device/mtpdevice.h +++ b/src/device/mtpdevice.h @@ -31,15 +31,18 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" #include "connecteddevice.h" class QThread; -class Application; class DeviceLister; class DeviceManager; +class TaskManager; +class Database; +class TagReaderClient; +class AlbumCoverLoader; class MtpLoader; class MtpConnection; struct LIBMTP_mtpdevice_struct; @@ -48,7 +51,18 @@ class MtpDevice : public ConnectedDevice { Q_OBJECT public: - Q_INVOKABLE MtpDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, SharedPtr manager, Application *app, const int database_id, const bool first_time, QObject *parent = nullptr); + Q_INVOKABLE MtpDevice(const QUrl &url, + DeviceLister *lister, + const QString &unique_id, + DeviceManager *device_manager, + const SharedPtr task_manager, + const SharedPtr database, + const SharedPtr tagreader_client, + const SharedPtr albumcover_loader, + const int database_id, + const bool first_time, + QObject *parent = nullptr); + ~MtpDevice() override; static QStringList url_schemes() { return QStringList() << QStringLiteral("mtp"); } @@ -82,6 +96,8 @@ class MtpDevice : public ConnectedDevice { private: static bool sInitializedLibMTP; + SharedPtr task_manager_; + MtpLoader *loader_; QThread *loader_thread_; bool closing_; diff --git a/src/device/mtploader.cpp b/src/device/mtploader.cpp index e126bf8b62..dce1b6e774 100644 --- a/src/device/mtploader.cpp +++ b/src/device/mtploader.cpp @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/taskmanager.h" #include "core/song.h" #include "collection/collectionbackend.h" @@ -37,7 +37,7 @@ using std::make_unique; -MtpLoader::MtpLoader(const QUrl &url, SharedPtr task_manager, SharedPtr backend, QObject *parent) +MtpLoader::MtpLoader(const QUrl &url, const SharedPtr task_manager, const SharedPtr backend, QObject *parent) : QObject(parent), url_(url), task_manager_(task_manager), diff --git a/src/device/mtploader.h b/src/device/mtploader.h index d7ba44de08..77e945f516 100644 --- a/src/device/mtploader.h +++ b/src/device/mtploader.h @@ -28,8 +28,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" class QThread; class TaskManager; @@ -40,7 +40,7 @@ class MtpLoader : public QObject { Q_OBJECT public: - explicit MtpLoader(const QUrl &url, SharedPtr task_manager, SharedPtr backend, QObject *parent = nullptr); + explicit MtpLoader(const QUrl &url, const SharedPtr task_manager, const SharedPtr backend, QObject *parent = nullptr); ~MtpLoader() override; bool Init(); diff --git a/src/device/udisks2lister.cpp b/src/device/udisks2lister.cpp index 93f1b75397..6e851fa8f5 100644 --- a/src/device/udisks2lister.cpp +++ b/src/device/udisks2lister.cpp @@ -41,9 +41,9 @@ #include #include +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" #include "utilities/diskutils.h" #include "udisks2lister.h" diff --git a/src/device/udisks2lister.h b/src/device/udisks2lister.h index ee5c40bf63..83309fd25d 100644 --- a/src/device/udisks2lister.h +++ b/src/device/udisks2lister.h @@ -38,9 +38,9 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" -#include "core/dbus_metatypes.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" +#include "includes/dbus_metatypes.h" #include "devicelister.h" diff --git a/src/dialogs/CMakeLists.txt b/src/dialogs/CMakeLists.txt new file mode 100644 index 0000000000..240604b94f --- /dev/null +++ b/src/dialogs/CMakeLists.txt @@ -0,0 +1,59 @@ +set(DIALOGS_SOURCES + about.cpp + console.cpp + errordialog.cpp + addstreamdialog.cpp + userpassdialog.cpp + deleteconfirmationdialog.cpp + lastfmimportdialog.cpp + messagedialog.cpp + snapdialog.cpp + saveplaylistsdialog.cpp +) + +set(DIALOGS_HEADERS + about.h + errordialog.h + console.h + addstreamdialog.h + userpassdialog.h + deleteconfirmationdialog.h + lastfmimportdialog.h + messagedialog.h + snapdialog.h + saveplaylistsdialog.h +) + +set(DIALOGS_UI + about.ui + errordialog.ui + console.ui + addstreamdialog.ui + userpassdialog.ui + lastfmimportdialog.ui + messagedialog.ui + saveplaylistsdialog.ui +) + +qt_wrap_cpp(DIALOGS_SOURCES ${DIALOGS_HEADERS}) +qt_wrap_ui(DIALOGS_SOURCES ${DIALOGS_UI}) + +add_library(strawberry_dialogs STATIC ${DIALOGS_SOURCES}) + +target_include_directories(strawberry_dialogs PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_dialogs PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core +) diff --git a/src/dialogs/about.h b/src/dialogs/about.h index dc7e734a73..b8fb9a9682 100644 --- a/src/dialogs/about.h +++ b/src/dialogs/about.h @@ -29,7 +29,7 @@ #include #include -#include "ui_about.h" +#include "dialogs/ui_about.h" class QWidget; diff --git a/src/dialogs/addstreamdialog.h b/src/dialogs/addstreamdialog.h index a7ed9609ae..79bf136680 100644 --- a/src/dialogs/addstreamdialog.h +++ b/src/dialogs/addstreamdialog.h @@ -25,7 +25,7 @@ #include #include -#include "ui_addstreamdialog.h" +#include "dialogs/ui_addstreamdialog.h" class AddStreamDialog : public QDialog { Q_OBJECT diff --git a/src/dialogs/console.cpp b/src/dialogs/console.cpp index a7903e3d8d..b462e3ad13 100644 --- a/src/dialogs/console.cpp +++ b/src/dialogs/console.cpp @@ -36,13 +36,14 @@ #include #include "console.h" + +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/application.h" #include "core/database.h" using namespace Qt::Literals::StringLiterals; -Console::Console(Application *app, QWidget *parent) : QDialog(parent), ui_{}, app_(app) { +Console::Console(const SharedPtr database, QWidget *parent) : QDialog(parent), ui_{}, database_(database) { ui_.setupUi(this); @@ -60,14 +61,16 @@ Console::Console(Application *app, QWidget *parent) : QDialog(parent), ui_{}, ap void Console::RunQuery() { - QSqlDatabase db = app_->database()->Connect(); + QSqlDatabase db = database_->Connect(); QSqlQuery query(db); if (!query.prepare(ui_.query->text())) { qLog(Error) << query.lastError(); + Q_EMIT Error(query.lastError().text()); return; } if (!query.exec()) { qLog(Error) << query.lastError(); + Q_EMIT Error(query.lastError().text()); return; } diff --git a/src/dialogs/console.h b/src/dialogs/console.h index d2ccfa28e2..b77853ad91 100644 --- a/src/dialogs/console.h +++ b/src/dialogs/console.h @@ -29,22 +29,27 @@ #include #include -#include "ui_console.h" +#include "dialogs/ui_console.h" -class Application; +#include "includes/shared_ptr.h" + +class Database; class Console : public QDialog { Q_OBJECT public: - explicit Console(Application *app, QWidget *parent = nullptr); + explicit Console(const SharedPtr database, QWidget *parent = nullptr); private Q_SLOTS: void RunQuery(); + Q_SIGNALS: + void Error(const QString &error); + private: Ui::Console ui_; - Application *app_; + const SharedPtr database_; }; #endif // CONSOLE_H diff --git a/src/dialogs/edittagdialog.cpp b/src/dialogs/edittagdialog.cpp index 28d30df1da..ef78563197 100644 --- a/src/dialogs/edittagdialog.cpp +++ b/src/dialogs/edittagdialog.cpp @@ -70,7 +70,6 @@ #include #include -#include "core/application.h" #include "core/iconloader.h" #include "core/logging.h" #include "core/settings.h" @@ -110,16 +109,28 @@ constexpr int kSmallImageSize = 128; const char EditTagDialog::kTagsDifferentHintText[] = QT_TR_NOOP("(different across multiple songs)"); const char EditTagDialog::kArtDifferentHintText[] = QT_TR_NOOP("Different art across multiple songs."); -EditTagDialog::EditTagDialog(Application *app, QWidget *parent) +EditTagDialog::EditTagDialog(const SharedPtr network, + const SharedPtr tagreader_client, + const SharedPtr collection_backend, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr lyrics_providers, + const SharedPtr streaming_services, + QWidget *parent) : QDialog(parent), ui_(new Ui_EditTagDialog), - app_(app), + tagreader_client_(tagreader_client), + collection_backend_(collection_backend), + albumcover_loader_(albumcover_loader), + current_albumcover_loader_(current_albumcover_loader), + cover_providers_(cover_providers), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), #ifdef HAVE_MUSICBRAINZ - tag_fetcher_(new TagFetcher(app->network(), this)), - results_dialog_(new TrackSelectionDialog(this)), + tag_fetcher_(new TagFetcher(network, this)), + results_dialog_(new TrackSelectionDialog(tagreader_client, this)), #endif - lyrics_fetcher_(new LyricsFetcher(app->lyrics_providers(), this)), + lyrics_fetcher_(new LyricsFetcher(lyrics_providers, this)), cover_menu_(new QMenu(this)), image_no_cover_thumbnail_(ImageUtils::GenerateNoCoverImage(QSize(128, 128), devicePixelRatioF())), loading_(false), @@ -130,7 +141,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) save_tag_pending_(0), lyrics_id_(-1) { - QObject::connect(&*app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &EditTagDialog::AlbumCoverLoaded); + QObject::connect(&*albumcover_loader_, &AlbumCoverLoader::AlbumCoverLoaded, this, &EditTagDialog::AlbumCoverLoaded); #ifdef HAVE_MUSICBRAINZ QObject::connect(tag_fetcher_, &TagFetcher::ResultAvailable, results_dialog_, &TrackSelectionDialog::FetchTagFinished, Qt::QueuedConnection); @@ -140,7 +151,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) #endif QObject::connect(lyrics_fetcher_, &LyricsFetcher::LyricsFetched, this, &EditTagDialog::UpdateLyrics); - album_cover_choice_controller_->Init(app_); + album_cover_choice_controller_->Init(network, tagreader_client, collection_backend, albumcover_loader, current_albumcover_loader, cover_providers, streaming_services); ui_->setupUi(this); ui_->splitter->setSizes(QList() << 200 << width() - 200); @@ -259,13 +270,13 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) QKeySequence(QKeySequence::Forward).toString(QKeySequence::NativeText), QKeySequence(QKeySequence::MoveToNextPage).toString(QKeySequence::NativeText))); - new TagCompleter(app_->collection_backend(), Playlist::Column::Artist, ui_->artist); - new TagCompleter(app_->collection_backend(), Playlist::Column::Album, ui_->album); - new TagCompleter(app_->collection_backend(), Playlist::Column::AlbumArtist, ui_->albumartist); - new TagCompleter(app_->collection_backend(), Playlist::Column::Genre, ui_->genre); - new TagCompleter(app_->collection_backend(), Playlist::Column::Composer, ui_->composer); - new TagCompleter(app_->collection_backend(), Playlist::Column::Performer, ui_->performer); - new TagCompleter(app_->collection_backend(), Playlist::Column::Grouping, ui_->grouping); + new TagCompleter(collection_backend, Playlist::Column::Artist, ui_->artist); + new TagCompleter(collection_backend, Playlist::Column::Album, ui_->album); + new TagCompleter(collection_backend, Playlist::Column::AlbumArtist, ui_->albumartist); + new TagCompleter(collection_backend, Playlist::Column::Genre, ui_->genre); + new TagCompleter(collection_backend, Playlist::Column::Composer, ui_->composer); + new TagCompleter(collection_backend, Playlist::Column::Performer, ui_->performer); + new TagCompleter(collection_backend, Playlist::Column::Grouping, ui_->grouping); } @@ -393,7 +404,7 @@ bool EditTagDialog::SetLoading(const QString &message) { } -QList EditTagDialog::LoadData(const SongList &songs) { +QList EditTagDialog::LoadData(const SongList &songs) const { QList ret; @@ -401,7 +412,7 @@ QList EditTagDialog::LoadData(const SongList &songs) { if (song.IsEditable()) { // Try reloading the tags from file Song copy(song); - const TagReaderResult result = TagReaderClient::Instance()->ReadFileBlocking(copy.url().toLocalFile(), ©); + const TagReaderResult result = tagreader_client_->ReadFileBlocking(copy.url().toLocalFile(), ©); if (result.success() && copy.is_valid()) { copy.MergeUserSetData(song, false, false); ret << Data(copy); @@ -424,7 +435,7 @@ void EditTagDialog::SetSongs(const SongList &s, const PlaylistItemPtrList &items collection_songs_.clear(); // Reload tags in the background - QFuture> future = QtConcurrent::run(&EditTagDialog::LoadData, s); + QFuture> future = QtConcurrent::run(&EditTagDialog::LoadData, this, s); QFutureWatcher> *watcher = new QFutureWatcher>(); QObject::connect(watcher, &QFutureWatcher>::finished, this, &EditTagDialog::SetSongsFinished); watcher->setFuture(future); @@ -725,7 +736,7 @@ void EditTagDialog::SelectionChanged() { album_cover_choice_controller_->cover_to_file_action()->setEnabled(first_song.has_valid_art() && !first_song.art_unset()); album_cover_choice_controller_->cover_from_file_action()->setEnabled(enable_change_art); album_cover_choice_controller_->cover_from_url_action()->setEnabled(enable_change_art); - album_cover_choice_controller_->search_for_cover_action()->setEnabled(app_->cover_providers()->HasAnyProviders() && enable_change_art); + album_cover_choice_controller_->search_for_cover_action()->setEnabled(cover_providers_->HasAnyProviders() && enable_change_art); album_cover_choice_controller_->unset_cover_action()->setEnabled(enable_change_art && !first_song.art_unset()); album_cover_choice_controller_->clear_cover_action()->setEnabled(enable_change_art && (!first_song.art_manual().isEmpty() || first_song.art_unset())); album_cover_choice_controller_->delete_cover_action()->setEnabled(enable_change_art && (first_song.art_embedded() || !first_song.art_automatic().isEmpty() || !first_song.art_manual().isEmpty())); @@ -734,10 +745,10 @@ void EditTagDialog::SelectionChanged() { cover_options.desired_scaled_size = QSize(kSmallImageSize, kSmallImageSize); cover_options.device_pixel_ratio = devicePixelRatioF(); if (data_.value(indexes.first().row()).cover_action_ == UpdateCoverAction::None) { - tags_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, first_song); + tags_cover_art_id_ = albumcover_loader_->LoadImageAsync(cover_options, first_song); } else { - tags_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, data_[indexes.first().row()].cover_result_); + tags_cover_art_id_ = albumcover_loader_->LoadImageAsync(cover_options, data_[indexes.first().row()].cover_result_); } } @@ -788,7 +799,7 @@ void EditTagDialog::UpdateSummaryTab(const Song &song) { cover_options.types = cover_types_; cover_options.desired_scaled_size = QSize(kSmallImageSize, kSmallImageSize); cover_options.device_pixel_ratio = devicePixelRatioF(); - summary_cover_art_id_ = app_->album_cover_loader()->LoadImageAsync(cover_options, song); + summary_cover_art_id_ = albumcover_loader_->LoadImageAsync(cover_options, song); ui_->summary->setText(u"

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

"_s); @@ -1299,7 +1310,7 @@ void EditTagDialog::SaveData() { if (save_embedded_cover) { save_tags_options |= TagReaderClient::SaveOption::Cover; } - TagReaderReplyPtr reply = TagReaderClient::Instance()->WriteFileAsync(ref.current_.url().toLocalFile(), ref.current_, save_tags_options, save_tag_cover_data); + TagReaderReplyPtr reply = tagreader_client_->WriteFileAsync(ref.current_.url().toLocalFile(), ref.current_, save_tags_options, save_tag_cover_data); QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveTagsComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_); }, Qt::QueuedConnection); } // If the cover was changed, but no tags written, make sure to update the collection. @@ -1307,8 +1318,8 @@ void EditTagDialog::SaveData() { if (ref.current_.is_collection_song()) { collection_songs_.insert(ref.current_.id(), ref.current_); } - if (ref.current_ == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(ref.current_); + if (ref.current_ == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(ref.current_); } } @@ -1321,7 +1332,7 @@ void EditTagDialog::SaveData() { void EditTagDialog::SaveDataFinished() { if (!collection_songs_.isEmpty()) { - app_->collection_backend()->AddOrUpdateSongsAsync(collection_songs_.values()); + collection_backend_->AddOrUpdateSongsAsync(collection_songs_.values()); collection_songs_.clear(); } @@ -1483,8 +1494,8 @@ void EditTagDialog::SongSaveTagsComplete(TagReaderReplyPtr reply, const QString } collection_songs_.insert(song.id(), song); } - if (cover_action != UpdateCoverAction::None && song == app_->current_albumcover_loader()->last_song()) { - app_->current_albumcover_loader()->LoadAlbumCover(song); + if (cover_action != UpdateCoverAction::None && song == current_albumcover_loader_->last_song()) { + current_albumcover_loader_->LoadAlbumCover(song); } } else { diff --git a/src/dialogs/edittagdialog.h b/src/dialogs/edittagdialog.h index 9a3a9434e6..c7e41a904c 100644 --- a/src/dialogs/edittagdialog.h +++ b/src/dialogs/edittagdialog.h @@ -51,7 +51,13 @@ class QEvent; class QShowEvent; class QHideEvent; -class Application; +class NetworkAccessManager; +class CollectionBackend; +class AlbumCoverLoader; +class CurrentAlbumCoverLoader; +class CoverProviders; +class LyricsProviders; +class StreamingServices; class AlbumCoverChoiceController; class Ui_EditTagDialog; #ifdef HAVE_MUSICBRAINZ @@ -64,7 +70,16 @@ class EditTagDialog : public QDialog { Q_OBJECT public: - explicit EditTagDialog(Application *app, QWidget *parent = nullptr); + explicit EditTagDialog(const SharedPtr network, + const SharedPtr tagreader_client, + const SharedPtr collection_backend, + const SharedPtr albumcover_loader, + const SharedPtr current_albumcover_loader, + const SharedPtr cover_providers, + const SharedPtr lyrics_providers, + const SharedPtr streaming_services, + QWidget *parent = nullptr); + ~EditTagDialog() override; void SetSongs(const SongList &songs, const PlaylistItemPtrList &items = PlaylistItemPtrList()); @@ -168,7 +183,7 @@ class EditTagDialog : public QDialog { void SetSongListVisibility(bool visible); // Called by QtConcurrentRun - static QList LoadData(const SongList &songs); + QList LoadData(const SongList &songs) const; void SaveData(); static void SetText(QLabel *label, const int value, const QString &suffix, const QString &def = QString()); @@ -180,7 +195,12 @@ class EditTagDialog : public QDialog { Ui_EditTagDialog *ui_; - Application *app_; + const SharedPtr tagreader_client_; + const SharedPtr collection_backend_; + const SharedPtr albumcover_loader_; + const SharedPtr current_albumcover_loader_; + const SharedPtr cover_providers_; + AlbumCoverChoiceController *album_cover_choice_controller_; #ifdef HAVE_MUSICBRAINZ TagFetcher *tag_fetcher_; diff --git a/src/dialogs/lastfmimportdialog.cpp b/src/dialogs/lastfmimportdialog.cpp index a30b64f987..cae401b76f 100644 --- a/src/dialogs/lastfmimportdialog.cpp +++ b/src/dialogs/lastfmimportdialog.cpp @@ -27,7 +27,7 @@ #include "lastfmimportdialog.h" #include "ui_lastfmimportdialog.h" -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/iconloader.h" #include "scrobbler/lastfmimport.h" diff --git a/src/dialogs/lastfmimportdialog.h b/src/dialogs/lastfmimportdialog.h index 94560e6dc4..331c21bccb 100644 --- a/src/dialogs/lastfmimportdialog.h +++ b/src/dialogs/lastfmimportdialog.h @@ -26,9 +26,9 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" -#include "ui_lastfmimportdialog.h" +#include "dialogs/ui_lastfmimportdialog.h" class QCloseEvent; class LastFMImport; diff --git a/src/dialogs/saveplaylistsdialog.cpp b/src/dialogs/saveplaylistsdialog.cpp index 18699cdff2..3fc80d7929 100644 --- a/src/dialogs/saveplaylistsdialog.cpp +++ b/src/dialogs/saveplaylistsdialog.cpp @@ -30,16 +30,16 @@ #include "ui_saveplaylistsdialog.h" #include "core/settings.h" -#include "playlist/playlist.h" +#include "constants/playlistsettings.h" SavePlaylistsDialog::SavePlaylistsDialog(const QStringList &types, const QString &default_extension, QWidget *parent) : QDialog(parent), ui_(new Ui_SavePlaylistsDialog) { ui_->setupUi(this); Settings s; - s.beginGroup(Playlist::kSettingsGroup); - QString last_save_path = s.value("last_save_all_path", QDir::homePath()).toString(); - QString last_save_extension = s.value("last_save_all_extension", default_extension).toString(); + s.beginGroup(PlaylistSettings::kSettingsGroup); + QString last_save_path = s.value(PlaylistSettings::kLastSaveAllPath, QDir::homePath()).toString(); + QString last_save_extension = s.value(PlaylistSettings::kLastSaveAllExtension, default_extension).toString(); s.endGroup(); ui_->lineedit_path->setText(last_save_path); @@ -81,9 +81,9 @@ void SavePlaylistsDialog::accept() { } Settings s; - s.beginGroup(Playlist::kSettingsGroup); - s.setValue("last_save_all_path", path); - s.setValue("last_save_all_extension", ui_->combobox_type->currentText()); + s.beginGroup(PlaylistSettings::kSettingsGroup); + s.setValue(PlaylistSettings::kLastSaveAllPath, path); + s.setValue(PlaylistSettings::kLastSaveAllExtension, ui_->combobox_type->currentText()); s.endGroup(); QDialog::accept(); diff --git a/src/dialogs/saveplaylistsdialog.h b/src/dialogs/saveplaylistsdialog.h index 380257acbe..4584ca6398 100644 --- a/src/dialogs/saveplaylistsdialog.h +++ b/src/dialogs/saveplaylistsdialog.h @@ -25,7 +25,7 @@ #include #include -#include "ui_saveplaylistsdialog.h" +#include "dialogs/ui_saveplaylistsdialog.h" class SavePlaylistsDialog : public QDialog { Q_OBJECT diff --git a/src/dialogs/snapdialog.cpp b/src/dialogs/snapdialog.cpp index ec180cd798..0502b9fb21 100644 --- a/src/dialogs/snapdialog.cpp +++ b/src/dialogs/snapdialog.cpp @@ -17,9 +17,9 @@ * */ +#include "constants/mainwindowsettings.h" #include "core/logging.h" #include "core/iconloader.h" -#include "core/mainwindow.h" #include "utilities/screenutils.h" #include "snapdialog.h" @@ -84,7 +84,7 @@ SnapDialog::SnapDialog(QWidget *parent) : MessageDialog(parent) { ui_->label_text->adjustSize(); adjustSize(); - settings_group_ = QLatin1String(MainWindow::kSettingsGroup); + settings_group_ = QLatin1String(MainWindowSettings::kSettingsGroup); do_not_show_message_again_ = "ignore_snap"_L1; if (parent) { diff --git a/src/dialogs/trackselectiondialog.cpp b/src/dialogs/trackselectiondialog.cpp index 2e29f0dac1..8bf2d9d81c 100644 --- a/src/dialogs/trackselectiondialog.cpp +++ b/src/dialogs/trackselectiondialog.cpp @@ -53,9 +53,10 @@ #include "trackselectiondialog.h" #include "ui_trackselectiondialog.h" -TrackSelectionDialog::TrackSelectionDialog(QWidget *parent) +TrackSelectionDialog::TrackSelectionDialog(const SharedPtr tagreader_client, QWidget *parent) : QDialog(parent), ui_(new Ui_TrackSelectionDialog), + tagreader_client_(tagreader_client), save_on_close_(false) { // Setup dialog window @@ -261,10 +262,10 @@ void TrackSelectionDialog::SetLoading(const QString &message) { } -void TrackSelectionDialog::SaveData(const QList &data) { +void TrackSelectionDialog::SaveData(const QList &_data) const { - for (int i = 0; i < data.count(); ++i) { - const Data &ref = data[i]; + for (int i = 0; i < _data.count(); ++i) { + const Data &ref = _data[i]; if (ref.pending_ || ref.results_.isEmpty() || ref.selected_result_ == -1) { continue; } @@ -278,7 +279,7 @@ void TrackSelectionDialog::SaveData(const QList &data) { copy.set_track(new_metadata.track()); copy.set_year(new_metadata.year()); - const TagReaderResult result = TagReaderClient::Instance()->WriteFileBlocking(copy.url().toLocalFile(), copy, TagReaderClient::SaveOption::Tags, SaveTagCoverData()); + const TagReaderResult result = tagreader_client_->WriteFileBlocking(copy.url().toLocalFile(), copy, TagReaderClient::SaveOption::Tags, SaveTagCoverData()); if (!result.success()) { qLog(Error) << "Failed to write new auto-tags to" << copy.url().toLocalFile() << result.error_string(); } @@ -292,7 +293,7 @@ void TrackSelectionDialog::accept() { SetLoading(tr("Saving tracks") + QStringLiteral("...")); // Save tags in the background - QFuture future = QtConcurrent::run(&TrackSelectionDialog::SaveData, data_); + QFuture future = QtConcurrent::run(&TrackSelectionDialog::SaveData, this, data_); QFutureWatcher *watcher = new QFutureWatcher(this); QObject::connect(watcher, &QFutureWatcher::finished, this, &TrackSelectionDialog::AcceptFinished); watcher->setFuture(future); diff --git a/src/dialogs/trackselectiondialog.h b/src/dialogs/trackselectiondialog.h index 54f40a7c73..3ddb8bfe8d 100644 --- a/src/dialogs/trackselectiondialog.h +++ b/src/dialogs/trackselectiondialog.h @@ -22,24 +22,27 @@ #ifndef TRACKSELECTIONDIALOG_H #define TRACKSELECTIONDIALOG_H +#include "config.h" + #include #include #include #include -#include "config.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QWidget; class QTreeWidget; class QPushButton; class Ui_TrackSelectionDialog; +class TagReaderClient; class TrackSelectionDialog : public QDialog { Q_OBJECT public: - explicit TrackSelectionDialog(QWidget *parent = nullptr); + explicit TrackSelectionDialog(const SharedPtr tagreader_client, QWidget *parent = nullptr); ~TrackSelectionDialog() override; void set_save_on_close(bool save_on_close) { save_on_close_ = save_on_close; } @@ -83,9 +86,11 @@ class TrackSelectionDialog : public QDialog { static void AddSong(const Song &song, int result_index, QTreeWidget *parent); void SetLoading(const QString &message); - static void SaveData(const QList &data); + void SaveData(const QList &data) const; private: + const SharedPtr tagreader_client_; + QList data_; QPushButton *previous_button_; diff --git a/src/edittagdialog/CMakeLists.txt b/src/edittagdialog/CMakeLists.txt new file mode 100644 index 0000000000..78115e29f9 --- /dev/null +++ b/src/edittagdialog/CMakeLists.txt @@ -0,0 +1,44 @@ +set(EDITTAGDIALOG_SOURCES + edittagdialog.cpp + trackselectiondialog.cpp +) + +set(EDITTAGDIALOG_HEADERS + edittagdialog.h + trackselectiondialog.h +) + +set(EDITTAGDIALOG_UI + edittagdialog.ui + trackselectiondialog.ui +) + +qt_wrap_cpp(EDITTAGDIALOG_SOURCES ${EDITTAGDIALOG_HEADERS}) +qt_wrap_ui(EDITTAGDIALOG_SOURCES ${EDITTAGDIALOG_UI}) + +add_library(strawberry_edittagdialog STATIC ${EDITTAGDIALOG_SOURCES}) + +target_include_directories(strawberry_edittagdialog PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_edittagdialog PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_core + strawberry_utilities + strawberry_tagreader + strawberry_covermanager + strawberry_widgets + strawberry_collection + strawberry_lyrics +) diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt new file mode 100644 index 0000000000..7e3e860184 --- /dev/null +++ b/src/engine/CMakeLists.txt @@ -0,0 +1,89 @@ +set(ENGINE_SOURCES + enginebase.cpp + enginedevice.cpp + devicefinders.cpp + devicefinder.cpp + gststartup.cpp + gstengine.cpp + gstenginepipeline.cpp +) + +set(ENGINE_HEADERS + enginebase.h + devicefinders.h + gststartup.h + gstengine.h + gstenginepipeline.h +) + +if(HAVE_ALSA) + list(APPEND ENGINE_SOURCES alsadevicefinder.cpp alsapcmdevicefinder.cpp) +endif() + +if(HAVE_PULSE) + list(APPEND ENGINE_SOURCES pulsedevicefinder.cpp) +endif() + +if(MSVC) + list(APPEND ENGINE_SOURCES uwpdevicefinder.cpp asiodevicefinder.cpp) +endif() + +if(HAVE_SONGFINGERPRINTING OR HAVE_MUSICBRAINZ) + list(APPEND ENGINE_SOURCES chromaprinter.cpp) +endif() + +if(HAVE_EBUR128) + list(APPEND ENGINE_SOURCES ebur128analysis.cpp) +endif() + +if(HAVE_MOODBAR) + list(APPEND ENGINE_SOURCES gstfastspectrumplugin.cpp gstfastspectrum.cpp) +endif() + +if(APPLE) + list(APPEND ENGINE_SOURCES macosdevicefinder.cpp) +endif() + +if(WIN32) + list(APPEND ENGINE_SOURCES directsounddevicefinder.cpp mmdevicefinder.cpp) +endif() + +qt_wrap_cpp(ENGINE_SOURCES ${ENGINE_HEADERS}) + +add_library(strawberry_engine STATIC ${ENGINE_SOURCES}) + +target_include_directories(strawberry_engine PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_engine PRIVATE + PkgConfig::GLIB + PkgConfig::GOBJECT + $<$:ALSA::ALSA> + $<$:PkgConfig::LIBPULSE> + $<$:dsound> + $<$:WindowsApp> + PkgConfig::GSTREAMER + PkgConfig::GSTREAMER_BASE + PkgConfig::GSTREAMER_AUDIO + PkgConfig::GSTREAMER_APP + PkgConfig::GSTREAMER_TAG + PkgConfig::GSTREAMER_PBUTILS + $<$:PkgConfig::CHROMAPRINT> + $<$:PkgConfig::LIBEBUR128> + $<$:PkgConfig::FFTW3> + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Gui + strawberry_core +) + +if(APPLE) + target_link_libraries(strawberry_engine PRIVATE + "-framework CoreAudio" + ) +endif() diff --git a/src/engine/enginebase.cpp b/src/engine/enginebase.cpp index 0481398f40..54bf185974 100644 --- a/src/engine/enginebase.cpp +++ b/src/engine/enginebase.cpp @@ -31,14 +31,15 @@ #include #include "utilities/envutils.h" -#include "utilities/timeconstants.h" -#include "core/networkproxyfactory.h" +#include "constants/timeconstants.h" +#include "core/logging.h" #include "core/settings.h" +#include "core/networkproxyfactory.h" #include "enginebase.h" -#include "settings/backendsettingspage.h" -#include "settings/networkproxysettingspage.h" +#include "constants/backendsettings.h" +#include "constants/networkproxysettings.h" #ifdef HAVE_SPOTIFY -# include "settings/spotifysettingspage.h" +# include "constants/spotifysettings.h" #endif using namespace Qt::Literals::StringLiterals; @@ -61,9 +62,9 @@ EngineBase::EngineBase(QObject *parent) rg_compression_(true), ebur128_loudness_normalization_(false), ebur128_target_level_lufs_(-23.0), - buffer_duration_nanosec_(BackendSettingsPage::kDefaultBufferDuration * kNsecPerMsec), - buffer_low_watermark_(BackendSettingsPage::kDefaultBufferLowWatermark), - buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark), + buffer_duration_nanosec_(BackendSettings::kDefaultBufferDuration * kNsecPerMsec), + buffer_low_watermark_(BackendSettings::kDefaultBufferLowWatermark), + buffer_high_watermark_(BackendSettings::kDefaultBufferHighWatermark), fadeout_enabled_(true), crossfade_enabled_(true), autocrossfade_enabled_(false), @@ -167,59 +168,59 @@ void EngineBase::ReloadSettings() { Settings s; - s.beginGroup(BackendSettingsPage::kSettingsGroup); + s.beginGroup(BackendSettings::kSettingsGroup); - output_ = s.value("output").toString(); - device_ = s.value("device"); + output_ = s.value(BackendSettings::kOutput).toString(); + device_ = s.value(BackendSettings::kDevice); - exclusive_mode_ = s.value("exclusive_mode", false).toBool(); + exclusive_mode_ = s.value(BackendSettings::kExclusiveMode, false).toBool(); - volume_control_ = s.value("volume_control", true).toBool(); + volume_control_ = s.value(BackendSettings::kVolumeControl, true).toBool(); - channels_enabled_ = s.value("channels_enabled", false).toBool(); - channels_ = s.value("channels", 0).toInt(); + channels_enabled_ = s.value(BackendSettings::kChannelsEnabled, false).toBool(); + channels_ = s.value(BackendSettings::kChannels, 0).toInt(); - buffer_duration_nanosec_ = s.value("bufferduration", BackendSettingsPage::kDefaultBufferDuration).toLongLong() * kNsecPerMsec; - buffer_low_watermark_ = s.value("bufferlowwatermark", BackendSettingsPage::kDefaultBufferLowWatermark).toDouble(); - buffer_high_watermark_ = s.value("bufferhighwatermark", BackendSettingsPage::kDefaultBufferHighWatermark).toDouble(); + buffer_duration_nanosec_ = s.value(BackendSettings::kBufferDuration, BackendSettings::kDefaultBufferDuration).toLongLong() * kNsecPerMsec; + buffer_low_watermark_ = s.value(BackendSettings::kBufferLowWatermark, BackendSettings::kDefaultBufferLowWatermark).toDouble(); + buffer_high_watermark_ = s.value(BackendSettings::kBufferHighWatermark, BackendSettings::kDefaultBufferHighWatermark).toDouble(); - rg_enabled_ = s.value("rgenabled", false).toBool(); - rg_mode_ = s.value("rgmode", 0).toInt(); - rg_preamp_ = s.value("rgpreamp", 0.0).toDouble(); - rg_fallbackgain_ = s.value("rgfallbackgain", 0.0).toDouble(); - rg_compression_ = s.value("rgcompression", true).toBool(); + rg_enabled_ = s.value(BackendSettings::kRgEnabled, false).toBool(); + rg_mode_ = s.value(BackendSettings::kRgMode, 0).toInt(); + rg_preamp_ = s.value(BackendSettings::kRgPreamp, 0.0).toDouble(); + rg_fallbackgain_ = s.value(BackendSettings::kRgFallbackGain, 0.0).toDouble(); + rg_compression_ = s.value(BackendSettings::kRgCompression, true).toBool(); - ebur128_loudness_normalization_ = s.value("ebur128_loudness_normalization", false).toBool(); - ebur128_target_level_lufs_ = s.value("ebur128_target_level_lufs", -23.0).toDouble(); + ebur128_loudness_normalization_ = s.value(BackendSettings::kEBUR128LoudnessNormalization, false).toBool(); + ebur128_target_level_lufs_ = s.value(BackendSettings::kEBUR128TargetLevelLUFS, -23.0).toDouble(); - fadeout_enabled_ = s.value("FadeoutEnabled", false).toBool(); - crossfade_enabled_ = s.value("CrossfadeEnabled", false).toBool(); - autocrossfade_enabled_ = s.value("AutoCrossfadeEnabled", false).toBool(); - crossfade_same_album_ = !s.value("NoCrossfadeSameAlbum", true).toBool(); - fadeout_pause_enabled_ = s.value("FadeoutPauseEnabled", false).toBool(); - fadeout_duration_ = s.value("FadeoutDuration", 2000).toLongLong(); + fadeout_enabled_ = s.value(BackendSettings::kFadeoutEnabled, false).toBool(); + crossfade_enabled_ = s.value(BackendSettings::kCrossfadeEnabled, false).toBool(); + autocrossfade_enabled_ = s.value(BackendSettings::kAutoCrossfadeEnabled, false).toBool(); + crossfade_same_album_ = !s.value(BackendSettings::kNoCrossfadeSameAlbum, true).toBool(); + fadeout_pause_enabled_ = s.value(BackendSettings::kFadeoutPauseEnabled, false).toBool(); + fadeout_duration_ = s.value(BackendSettings::kFadeoutDuration, 2000).toLongLong(); fadeout_duration_nanosec_ = (fadeout_duration_ * kNsecPerMsec); - fadeout_pause_duration_ = s.value("FadeoutPauseDuration", 250).toLongLong(); + fadeout_pause_duration_ = s.value(BackendSettings::kFadeoutPauseDuration, 250).toLongLong(); fadeout_pause_duration_nanosec_ = (fadeout_pause_duration_ * kNsecPerMsec); - bs2b_enabled_ = s.value("bs2b", false).toBool(); + bs2b_enabled_ = s.value(BackendSettings::kBS2B, false).toBool(); - bool http2_enabled = s.value("http2", false).toBool(); + bool http2_enabled = s.value(BackendSettings::kHTTP2, false).toBool(); if (http2_enabled != http2_enabled_) { http2_enabled_ = http2_enabled; Utilities::SetEnv("SOUP_FORCE_HTTP1", http2_enabled_ ? ""_L1 : u"1"_s); qLog(Debug) << "SOUP_FORCE_HTTP1:" << (http2_enabled_ ? "OFF" : "ON"); } - strict_ssl_enabled_ = s.value("strict_ssl", false).toBool(); + strict_ssl_enabled_ = s.value(BackendSettings::kStrictSSL, false).toBool(); s.endGroup(); - s.beginGroup(NetworkProxySettingsPage::kSettingsGroup); + s.beginGroup(NetworkProxySettings::kSettingsGroup); const NetworkProxyFactory::Mode proxy_mode = static_cast(s.value("mode", static_cast(NetworkProxyFactory::Mode::System)).toInt()); - if (proxy_mode == NetworkProxyFactory::Mode::Manual && s.contains("engine") && s.value("engine").toBool()) { - QString proxy_host = s.value("hostname").toString(); - int proxy_port = s.value("port").toInt(); + if (proxy_mode == NetworkProxyFactory::Mode::Manual && s.contains(NetworkProxySettings::kEngine) && s.value(NetworkProxySettings::kEngine).toBool()) { + QString proxy_host = s.value(NetworkProxySettings::kHostname).toString(); + int proxy_port = s.value(NetworkProxySettings::kPort).toInt(); if (proxy_host.isEmpty() || proxy_port <= 0) { proxy_address_.clear(); proxy_authentication_ = false; @@ -228,9 +229,9 @@ void EngineBase::ReloadSettings() { } else { proxy_address_ = QStringLiteral("%1:%2").arg(proxy_host).arg(proxy_port); - proxy_authentication_ = s.value("use_authentication").toBool(); - proxy_user_ = s.value("username").toString(); - proxy_pass_ = s.value("password").toString(); + proxy_authentication_ = s.value(NetworkProxySettings::kUseAuthentication).toBool(); + proxy_user_ = s.value(NetworkProxySettings::kUsername).toString(); + proxy_pass_ = s.value(NetworkProxySettings::kPassword).toString(); } } else { @@ -243,8 +244,8 @@ void EngineBase::ReloadSettings() { s.endGroup(); #ifdef HAVE_SPOTIFY - s.beginGroup(SpotifySettingsPage::kSettingsGroup); - spotify_access_token_ = s.value("access_token").toString(); + s.beginGroup(SpotifySettings::kSettingsGroup); + spotify_access_token_ = s.value(SpotifySettings::kAccessToken).toString(); s.endGroup(); #endif diff --git a/src/engine/enginebase.h b/src/engine/enginebase.h index 2940c99f2e..796a1fd60a 100644 --- a/src/engine/enginebase.h +++ b/src/engine/enginebase.h @@ -39,7 +39,7 @@ #include #include "devicefinders.h" -#include "enginemetadata.h" +#include "core/enginemetadata.h" #include "core/song.h" class EngineBase : public QObject { diff --git a/src/engine/gstengine.cpp b/src/engine/gstengine.cpp index dcff4a76a8..a1c3353d5c 100644 --- a/src/engine/gstengine.cpp +++ b/src/engine/gstengine.cpp @@ -50,16 +50,16 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/logging.h" #include "core/taskmanager.h" #include "core/signalchecker.h" -#include "utilities/timeconstants.h" +#include "core/enginemetadata.h" +#include "constants/timeconstants.h" #include "enginebase.h" #include "gstengine.h" #include "gstenginepipeline.h" #include "gstbufferconsumer.h" -#include "enginemetadata.h" using namespace Qt::Literals::StringLiterals; using std::make_shared; diff --git a/src/engine/gstengine.h b/src/engine/gstengine.h index 22291d32ee..da20037737 100644 --- a/src/engine/gstengine.h +++ b/src/engine/gstengine.h @@ -39,7 +39,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "enginebase.h" #include "gststartup.h" #include "gstenginepipeline.h" diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index d4e74977b9..ebc27f2c40 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -61,8 +61,8 @@ #include "core/logging.h" #include "core/signalchecker.h" -#include "utilities/timeconstants.h" -#include "settings/backendsettingspage.h" +#include "constants/timeconstants.h" +#include "constants/backendsettings.h" #include "gstengine.h" #include "gstenginepipeline.h" #include "gstbufferconsumer.h" @@ -103,9 +103,9 @@ GstEnginePipeline::GstEnginePipeline(QObject *parent) volume_enabled_(true), fading_enabled_(false), strict_ssl_enabled_(false), - buffer_duration_nanosec_(BackendSettingsPage::kDefaultBufferDuration * kNsecPerMsec), - buffer_low_watermark_(BackendSettingsPage::kDefaultBufferLowWatermark), - buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark), + buffer_duration_nanosec_(BackendSettings::kDefaultBufferDuration * kNsecPerMsec), + buffer_low_watermark_(BackendSettings::kDefaultBufferLowWatermark), + buffer_high_watermark_(BackendSettings::kDefaultBufferHighWatermark), proxy_authentication_(false), channels_enabled_(false), channels_(0), diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index 9792e526ae..fa11b58055 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -43,9 +43,9 @@ #include #include -#include "core/shared_ptr.h" -#include "core/mutex_protected.h" -#include "enginemetadata.h" +#include "includes/shared_ptr.h" +#include "includes/mutex_protected.h" +#include "core/enginemetadata.h" class QTimer; class QTimerEvent; diff --git a/src/moodbar/gstfastspectrum.cpp b/src/engine/gstfastspectrum.cpp similarity index 100% rename from src/moodbar/gstfastspectrum.cpp rename to src/engine/gstfastspectrum.cpp diff --git a/src/moodbar/gstfastspectrum.h b/src/engine/gstfastspectrum.h similarity index 100% rename from src/moodbar/gstfastspectrum.h rename to src/engine/gstfastspectrum.h diff --git a/src/moodbar/gstfastspectrumplugin.cpp b/src/engine/gstfastspectrumplugin.cpp similarity index 100% rename from src/moodbar/gstfastspectrumplugin.cpp rename to src/engine/gstfastspectrumplugin.cpp diff --git a/src/moodbar/gstfastspectrumplugin.h b/src/engine/gstfastspectrumplugin.h similarity index 100% rename from src/moodbar/gstfastspectrumplugin.h rename to src/engine/gstfastspectrumplugin.h diff --git a/src/engine/gststartup.cpp b/src/engine/gststartup.cpp index 45a8aa59a5..c56702840c 100644 --- a/src/engine/gststartup.cpp +++ b/src/engine/gststartup.cpp @@ -39,7 +39,7 @@ #include "utilities/envutils.h" #ifdef HAVE_MOODBAR -# include "moodbar/gstfastspectrumplugin.h" +# include "gstfastspectrumplugin.h" #endif #include "gststartup.h" diff --git a/src/engine/macosdevicefinder.cpp b/src/engine/macosdevicefinder.cpp index aa6ee0fb4e..a76bdb9dad 100644 --- a/src/engine/macosdevicefinder.cpp +++ b/src/engine/macosdevicefinder.cpp @@ -27,8 +27,8 @@ #include +#include "includes/scoped_cftyperef.h" #include "core/logging.h" -#include "core/scoped_cftyperef.h" #include "macosdevicefinder.h" #include "enginedevice.h" diff --git a/src/equalizer/CMakeLists.txt b/src/equalizer/CMakeLists.txt new file mode 100644 index 0000000000..6faead473c --- /dev/null +++ b/src/equalizer/CMakeLists.txt @@ -0,0 +1,36 @@ +set(EQUALIZER_SOURCES + equalizer.cpp + equalizerslider.cpp +) + +set(EQUALIZER_HEADERS + equalizer.h + equalizerslider.h +) + +set(EQUALIZER_UI + equalizer.ui + equalizerslider.ui +) + +qt_wrap_cpp(EQUALIZER_SOURCES ${EQUALIZER_HEADERS}) +qt_wrap_ui(EQUALIZER_SOURCES ${EQUALIZER_UI}) + +add_library(strawberry_equalizer STATIC ${EQUALIZER_SOURCES}) + +target_include_directories(strawberry_equalizer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_equalizer PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_core + strawberry_widgets +) diff --git a/src/fileview/CMakeLists.txt b/src/fileview/CMakeLists.txt new file mode 100644 index 0000000000..8b44c75419 --- /dev/null +++ b/src/fileview/CMakeLists.txt @@ -0,0 +1,35 @@ +set(FILEVIEW_SOURCES + fileview.cpp + fileviewlist.cpp +) + +set(FILEVIEW_HEADERS + fileview.h + fileviewlist.h +) + +set(FILEVIEW_UI + fileview.ui +) + +qt_wrap_cpp(FILEVIEW_SOURCES ${FILEVIEW_HEADERS}) +qt_wrap_ui(FILEVIEW_SOURCES ${FILEVIEW_UI}) + +add_library(strawberry_fileview STATIC ${FILEVIEW_SOURCES}) + +target_include_directories(strawberry_fileview PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_fileview PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core + strawberry_mimedata + strawberry_dialogs + strawberry_organize +) diff --git a/src/widgets/fileview.cpp b/src/fileview/fileview.cpp similarity index 93% rename from src/widgets/fileview.cpp rename to src/fileview/fileview.cpp index 2cfa1e1fed..9fc98d5f03 100644 --- a/src/widgets/fileview.cpp +++ b/src/fileview/fileview.cpp @@ -36,31 +36,23 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/deletefiles.h" #include "core/filesystemmusicstorage.h" #include "core/iconloader.h" -#include "core/mimedata.h" #include "core/settings.h" +#include "mimedata/mimedata.h" #include "dialogs/deleteconfirmationdialog.h" #include "fileview.h" #include "fileviewlist.h" #include "ui_fileview.h" #include "organize/organizeerrordialog.h" -#include "settings/appearancesettingspage.h" +#include "constants/appearancesettings.h" +#include "constants/filefilterconstants.h" using std::make_unique; using namespace Qt::Literals::StringLiterals; -const char *FileView::kFileFilter = - "*.wav *.flac *.wv *.ogg *.oga *.opus *.spx *.ape *.mpc " - "*.mp2 *.mp3 *.m4a *.mp4 *.aac *.asf *.asx *.wma " - "*.aif *.aiff *.mka *.tta *.dsf *.dsd " - "*.cue *.m3u *.m3u8 *.pls *.xspf *.asxini " - "*.ac3 *.dts " - "*.mod *.s3m *.xm *.it" - "*.spc *.vgm"; - FileView::FileView(QWidget *parent) : QWidget(parent), ui_(new Ui_FileView), @@ -95,7 +87,7 @@ FileView::FileView(QWidget *parent) QObject::connect(ui_->list, &FileViewList::Delete, this, &FileView::Delete); QObject::connect(ui_->list, &FileViewList::EditTags, this, &FileView::EditTags); - QString filter = QLatin1String(FileView::kFileFilter); + QString filter = QLatin1String(kFileFilter); filter_list_ << filter.split(u' '); ReloadSettings(); @@ -109,8 +101,8 @@ FileView::~FileView() { void FileView::ReloadSettings() { Settings s; - s.beginGroup(AppearanceSettingsPage::kSettingsGroup); - int iconsize = s.value(AppearanceSettingsPage::kIconSizeLeftPanelButtons, 22).toInt(); + s.beginGroup(AppearanceSettings::kSettingsGroup); + int iconsize = s.value(AppearanceSettings::kIconSizeLeftPanelButtons, 22).toInt(); s.endGroup(); ui_->back->setIconSize(QSize(iconsize, iconsize)); diff --git a/src/widgets/fileview.h b/src/fileview/fileview.h similarity index 96% rename from src/widgets/fileview.h rename to src/fileview/fileview.h index d9b6c5c404..645286b559 100644 --- a/src/widgets/fileview.h +++ b/src/fileview/fileview.h @@ -30,8 +30,8 @@ #include #include -#include "core/scoped_ptr.h" -#include "core/shared_ptr.h" +#include "includes/scoped_ptr.h" +#include "includes/shared_ptr.h" #include "core/song.h" class QMimeData; @@ -52,8 +52,6 @@ class FileView : public QWidget { explicit FileView(QWidget *parent = nullptr); ~FileView() override; - static const char *kFileFilter; - void ReloadSettings(); void SetPath(const QString &path); diff --git a/src/widgets/fileview.ui b/src/fileview/fileview.ui similarity index 98% rename from src/widgets/fileview.ui rename to src/fileview/fileview.ui index 3be6f3ab65..62dfc3c71b 100644 --- a/src/widgets/fileview.ui +++ b/src/fileview/fileview.ui @@ -125,7 +125,7 @@ FileViewList QListView -
widgets/fileviewlist.h
+
fileview/fileviewlist.h
diff --git a/src/widgets/fileviewlist.cpp b/src/fileview/fileviewlist.cpp similarity index 99% rename from src/widgets/fileviewlist.cpp rename to src/fileview/fileviewlist.cpp index ee7f368b53..17e71fb7b6 100644 --- a/src/widgets/fileviewlist.cpp +++ b/src/fileview/fileviewlist.cpp @@ -32,7 +32,7 @@ #include #include "core/iconloader.h" -#include "core/mimedata.h" +#include "mimedata/mimedata.h" #include "utilities/filemanagerutils.h" #include "fileviewlist.h" diff --git a/src/widgets/fileviewlist.h b/src/fileview/fileviewlist.h similarity index 100% rename from src/widgets/fileviewlist.h rename to src/fileview/fileviewlist.h diff --git a/src/filterparser/CMakeLists.txt b/src/filterparser/CMakeLists.txt new file mode 100644 index 0000000000..971adb6cd3 --- /dev/null +++ b/src/filterparser/CMakeLists.txt @@ -0,0 +1,18 @@ +set(SOURCES + filterparser.cpp + filtertree.cpp +) + +add_library(strawberry_filterparser STATIC ${SOURCES}) + +target_include_directories(strawberry_filterparser PRIVATE + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_filterparser PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui +) diff --git a/src/filterparser/filterparser.cpp b/src/filterparser/filterparser.cpp index 93d890f760..a61608d139 100644 --- a/src/filterparser/filterparser.cpp +++ b/src/filterparser/filterparser.cpp @@ -20,12 +20,15 @@ * */ -#include "config.h" - #include #include "filterparser.h" -#include "filtertree.h" +#include "filtertreenop.h" +#include "filtertreeand.h" +#include "filtertreeor.h" +#include "filtertreenot.h" +#include "filtertreeterm.h" +#include "filtertreecolumnterm.h" #include "filterparsersearchcomparators.h" using namespace Qt::Literals::StringLiterals; @@ -52,9 +55,9 @@ void FilterParser::advance() { FilterTree *FilterParser::parseOrGroup() { advance(); - if (iter_ == end_) return new NopFilter; + if (iter_ == end_) return new FilterTreeNop; - OrFilter *group = new OrFilter; + FilterTreeOr *group = new FilterTreeOr; group->add(parseAndGroup()); advance(); while (checkOr()) { @@ -69,9 +72,9 @@ FilterTree *FilterParser::parseOrGroup() { FilterTree *FilterParser::parseAndGroup() { advance(); - if (iter_ == end_) return new NopFilter; + if (iter_ == end_) return new FilterTreeNop; - AndFilter *group = new AndFilter(); + FilterTreeAnd *group = new FilterTreeAnd(); do { group->add(parseSearchExpression()); advance(); @@ -150,7 +153,7 @@ bool FilterParser::checkOr(const bool step_over) { FilterTree *FilterParser::parseSearchExpression() { advance(); - if (iter_ == end_) return new NopFilter; + if (iter_ == end_) return new FilterTreeNop; if (*iter_ == u'(') { ++iter_; advance(); @@ -166,7 +169,7 @@ FilterTree *FilterParser::parseSearchExpression() { else if (*iter_ == u'-') { ++iter_; FilterTree *tree = parseSearchExpression(); - if (tree->type() != FilterTree::FilterType::Nop) return new NotFilter(tree); + if (tree->type() != FilterTree::FilterType::Nop) return new FilterTreeNot(tree); return tree; } else { @@ -232,7 +235,7 @@ FilterTree *FilterParser::parseSearchTerm() { FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const QString &prefix, const QString &value) const { if (value.isEmpty() && prefix != u'=') { - return new NopFilter; + return new FilterTreeNop; } FilterParserSearchTermComparator *cmp = nullptr; @@ -360,10 +363,10 @@ FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const } if (cmp) { - return new FilterColumnTerm(column, cmp); + return new FilterTreeColumnTerm(column, cmp); } - return new FilterTerm(new FilterParserTextContainsComparator(value)); + return new FilterTreeTerm(new FilterParserTextContainsComparator(value)); } diff --git a/src/filterparser/filterparser.h b/src/filterparser/filterparser.h index 55f0e6b3f1..8b54820b51 100644 --- a/src/filterparser/filterparser.h +++ b/src/filterparser/filterparser.h @@ -23,8 +23,6 @@ #ifndef FILTERPARSER_H #define FILTERPARSER_H -#include "config.h" - #include class FilterTree; diff --git a/src/filterparser/filterparserfloateqcomparator.cpp b/src/filterparser/filterparserfloateqcomparator.cpp new file mode 100644 index 0000000000..690cbeb0bd --- /dev/null +++ b/src/filterparser/filterparserfloateqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserfloateqcomparator.h" + +FilterParserFloatEqComparator::FilterParserFloatEqComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatEqComparator::Matches(const QVariant &value) const { + return value.toFloat() == search_term_; +} diff --git a/src/filterparser/filterparserfloateqcomparator.h b/src/filterparser/filterparserfloateqcomparator.h new file mode 100644 index 0000000000..166264c820 --- /dev/null +++ b/src/filterparser/filterparserfloateqcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERFLOATEQCOMPARATOR_H +#define FILTERPARSERFLOATEQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatEqComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatEqComparator) +}; + +#endif // FILTERPARSERFLOATEQCOMPARATOR_H diff --git a/src/filterparser/filterparserfloatgecomparator.cpp b/src/filterparser/filterparserfloatgecomparator.cpp new file mode 100644 index 0000000000..a14f6878c4 --- /dev/null +++ b/src/filterparser/filterparserfloatgecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserfloatgecomparator.h" + +FilterParserFloatGeComparator::FilterParserFloatGeComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatGeComparator::Matches(const QVariant &value) const { + return value.toFloat() >= search_term_; +} diff --git a/src/filterparser/filterparserfloatgecomparator.h b/src/filterparser/filterparserfloatgecomparator.h new file mode 100644 index 0000000000..8f12116ee6 --- /dev/null +++ b/src/filterparser/filterparserfloatgecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERFLOATGECOMPARATOR_H +#define FILTERPARSERFLOATGECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatGeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatGeComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatGeComparator) +}; + +#endif // FILTERPARSERFLOATGECOMPARATOR_H diff --git a/src/filterparser/filterparserfloatgtcomparator.cpp b/src/filterparser/filterparserfloatgtcomparator.cpp new file mode 100644 index 0000000000..1da2f6f906 --- /dev/null +++ b/src/filterparser/filterparserfloatgtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserfloatgtcomparator.h" + +FilterParserFloatGtComparator::FilterParserFloatGtComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatGtComparator::Matches(const QVariant &value) const { + return value.toFloat() > search_term_; +} diff --git a/src/filterparser/filterparserfloatgtcomparator.h b/src/filterparser/filterparserfloatgtcomparator.h new file mode 100644 index 0000000000..7d28924446 --- /dev/null +++ b/src/filterparser/filterparserfloatgtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERFLOATGTCOMPARATOR_H +#define FILTERPARSERFLOATGTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatGtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatGtComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatGtComparator) +}; + +#endif // FILTERPARSERFLOATGTCOMPARATOR_H diff --git a/src/filterparser/filterparserfloatlecomparator.cpp b/src/filterparser/filterparserfloatlecomparator.cpp new file mode 100644 index 0000000000..be2556fec3 --- /dev/null +++ b/src/filterparser/filterparserfloatlecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserfloatlecomparator.h" + +FilterParserFloatLeComparator::FilterParserFloatLeComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatLeComparator::Matches(const QVariant &value) const { + return value.toFloat() <= search_term_; +} diff --git a/src/filterparser/filterparserfloatlecomparator.h b/src/filterparser/filterparserfloatlecomparator.h new file mode 100644 index 0000000000..f8fe59d4e3 --- /dev/null +++ b/src/filterparser/filterparserfloatlecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERFLOATLECOMPARATOR_H +#define FILTERPARSERFLOATLECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatLeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatLeComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatLeComparator) +}; + +#endif // FILTERPARSERFLOATLECOMPARATOR_H diff --git a/src/filterparser/filterparserfloatltcomparator.cpp b/src/filterparser/filterparserfloatltcomparator.cpp new file mode 100644 index 0000000000..bb41378f9a --- /dev/null +++ b/src/filterparser/filterparserfloatltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserfloatltcomparator.h" + +FilterParserFloatLtComparator::FilterParserFloatLtComparator(const float search_term) : search_term_(search_term) {} + +bool FilterParserFloatLtComparator::Matches(const QVariant &value) const { + return value.toFloat() < search_term_; +} diff --git a/src/filterparser/filterparserfloatltcomparator.h b/src/filterparser/filterparserfloatltcomparator.h new file mode 100644 index 0000000000..c612773723 --- /dev/null +++ b/src/filterparser/filterparserfloatltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERFLOATLTCOMPARATOR_H +#define FILTERPARSERFLOATLTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatLtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatLtComparator(const float search_term); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatLtComparator) +}; + +#endif // FILTERPARSERFLOATLTCOMPARATOR_H diff --git a/src/filterparser/filterparserfloatnecomparator.cpp b/src/filterparser/filterparserfloatnecomparator.cpp new file mode 100644 index 0000000000..8dad959bfe --- /dev/null +++ b/src/filterparser/filterparserfloatnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserfloatnecomparator.h" + +FilterParserFloatNeComparator::FilterParserFloatNeComparator(const float value) : search_term_(value) {} + +bool FilterParserFloatNeComparator::Matches(const QVariant &value) const { + return value.toFloat() != search_term_; +} diff --git a/src/filterparser/filterparserfloatnecomparator.h b/src/filterparser/filterparserfloatnecomparator.h new file mode 100644 index 0000000000..efa55641b2 --- /dev/null +++ b/src/filterparser/filterparserfloatnecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERFLOATNECOMPARATOR_H +#define FILTERPARSERFLOATNECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserFloatNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserFloatNeComparator(const float value); + bool Matches(const QVariant &value) const override; + private: + float search_term_; + Q_DISABLE_COPY(FilterParserFloatNeComparator) +}; + +#endif // FILTERPARSERFLOATNECOMPARATOR_H diff --git a/src/filterparser/filterparserint64eqcomparator.cpp b/src/filterparser/filterparserint64eqcomparator.cpp new file mode 100644 index 0000000000..4a74f240c5 --- /dev/null +++ b/src/filterparser/filterparserint64eqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserint64eqcomparator.h" + +FilterParserInt64EqComparator::FilterParserInt64EqComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64EqComparator::Matches(const QVariant &value) const { + return value.toLongLong() == search_term_; +} diff --git a/src/filterparser/filterparserint64eqcomparator.h b/src/filterparser/filterparserint64eqcomparator.h new file mode 100644 index 0000000000..fc8ca593cf --- /dev/null +++ b/src/filterparser/filterparserint64eqcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINT64EQCOMPARATOR_H +#define FILTERPARSERINT64EQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64EqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64EqComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64EqComparator) +}; + +#endif // FILTERPARSERINT64EQCOMPARATOR_H diff --git a/src/filterparser/filterparserint64gecomparator.cpp b/src/filterparser/filterparserint64gecomparator.cpp new file mode 100644 index 0000000000..bdcd2b30a7 --- /dev/null +++ b/src/filterparser/filterparserint64gecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserint64gecomparator.h" + +FilterParserInt64GeComparator::FilterParserInt64GeComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64GeComparator::Matches(const QVariant &value) const { + return value.toLongLong() >= search_term_; +} diff --git a/src/filterparser/filterparserint64gecomparator.h b/src/filterparser/filterparserint64gecomparator.h new file mode 100644 index 0000000000..27869becd6 --- /dev/null +++ b/src/filterparser/filterparserint64gecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINT64GECOMPARATOR_H +#define FILTERPARSERINT64GECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64GeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64GeComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64GeComparator) +}; + +#endif // FILTERPARSERINT64GECOMPARATOR_H diff --git a/src/filterparser/filterparserint64gtcomparator.cpp b/src/filterparser/filterparserint64gtcomparator.cpp new file mode 100644 index 0000000000..a6d3f6edbd --- /dev/null +++ b/src/filterparser/filterparserint64gtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserint64gtcomparator.h" + +FilterParserInt64GtComparator::FilterParserInt64GtComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64GtComparator::Matches(const QVariant &value) const { + return value.toLongLong() > search_term_; +} diff --git a/src/filterparser/filterparserint64gtcomparator.h b/src/filterparser/filterparserint64gtcomparator.h new file mode 100644 index 0000000000..8aeaac0994 --- /dev/null +++ b/src/filterparser/filterparserint64gtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINT64GTCOMPARATOR_H +#define FILTERPARSERINT64GTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64GtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64GtComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64GtComparator) +}; + +#endif // FILTERPARSERINT64GTCOMPARATOR_H diff --git a/src/filterparser/filterparserint64lecomparator.cpp b/src/filterparser/filterparserint64lecomparator.cpp new file mode 100644 index 0000000000..136e5c2480 --- /dev/null +++ b/src/filterparser/filterparserint64lecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserint64lecomparator.h" + +FilterParserInt64LeComparator::FilterParserInt64LeComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64LeComparator::Matches(const QVariant &value) const { + return value.toLongLong() <= search_term_; +} diff --git a/src/filterparser/filterparserint64lecomparator.h b/src/filterparser/filterparserint64lecomparator.h new file mode 100644 index 0000000000..22792d7a03 --- /dev/null +++ b/src/filterparser/filterparserint64lecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINT64LECOMPARATOR_H +#define FILTERPARSERINT64LECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64LeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64LeComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64LeComparator) +}; + +#endif // FILTERPARSERINT64LECOMPARATOR_H diff --git a/src/filterparser/filterparserint64ltcomparator.cpp b/src/filterparser/filterparserint64ltcomparator.cpp new file mode 100644 index 0000000000..0e47c4fe78 --- /dev/null +++ b/src/filterparser/filterparserint64ltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserint64ltcomparator.h" + +FilterParserInt64LtComparator::FilterParserInt64LtComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64LtComparator::Matches(const QVariant &value) const { + return value.toLongLong() < search_term_; +} diff --git a/src/filterparser/filterparserint64ltcomparator.h b/src/filterparser/filterparserint64ltcomparator.h new file mode 100644 index 0000000000..0fe8c16f4b --- /dev/null +++ b/src/filterparser/filterparserint64ltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINT64LTCOMPARATOR_H +#define FILTERPARSERINT64LTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64LtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64LtComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64LtComparator) +}; + +#endif // FILTERPARSERINT64LTCOMPARATOR_H diff --git a/src/filterparser/filterparserint64necomparator.cpp b/src/filterparser/filterparserint64necomparator.cpp new file mode 100644 index 0000000000..dcefca5bb7 --- /dev/null +++ b/src/filterparser/filterparserint64necomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserint64necomparator.h" + +FilterParserInt64NeComparator::FilterParserInt64NeComparator(const qint64 search_term) : search_term_(search_term) {} + +bool FilterParserInt64NeComparator::Matches(const QVariant &value) const { + return value.toLongLong() != search_term_; +} diff --git a/src/filterparser/filterparserint64necomparator.h b/src/filterparser/filterparserint64necomparator.h new file mode 100644 index 0000000000..3f9d6bebcd --- /dev/null +++ b/src/filterparser/filterparserint64necomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINT64NECOMPARATOR_H +#define FILTERPARSERINT64NECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserInt64NeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserInt64NeComparator(const qint64 search_term); + bool Matches(const QVariant &value) const override; + private: + qint64 search_term_; + Q_DISABLE_COPY(FilterParserInt64NeComparator) +}; + +#endif // FILTERPARSERINT64NECOMPARATOR_H diff --git a/src/filterparser/filterparserinteqcomparator.cpp b/src/filterparser/filterparserinteqcomparator.cpp new file mode 100644 index 0000000000..99d1620cb7 --- /dev/null +++ b/src/filterparser/filterparserinteqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserinteqcomparator.h" + +FilterParserIntEqComparator::FilterParserIntEqComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntEqComparator::Matches(const QVariant &value) const { + return value.toInt() == search_term_; +} diff --git a/src/filterparser/filterparserinteqcomparator.h b/src/filterparser/filterparserinteqcomparator.h new file mode 100644 index 0000000000..4b6494d96c --- /dev/null +++ b/src/filterparser/filterparserinteqcomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINTEQCOMPARATOR_H +#define FILTERPARSERINTEQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntEqComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntEqComparator) +}; + +#endif // FILTERPARSERINTEQCOMPARATOR_H + diff --git a/src/filterparser/filterparserintgecomparator.cpp b/src/filterparser/filterparserintgecomparator.cpp new file mode 100644 index 0000000000..1c254262ff --- /dev/null +++ b/src/filterparser/filterparserintgecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserintgecomparator.h" + +FilterParserIntGeComparator::FilterParserIntGeComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntGeComparator::Matches(const QVariant &value) const { + return value.toInt() >= search_term_; +} diff --git a/src/filterparser/filterparserintgecomparator.h b/src/filterparser/filterparserintgecomparator.h new file mode 100644 index 0000000000..6e6bc56574 --- /dev/null +++ b/src/filterparser/filterparserintgecomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINTGECOMPARATOR_H +#define FILTERPARSERINTGECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntGeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntGeComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntGeComparator) +}; + +#endif // FILTERPARSERINTGECOMPARATOR_H + diff --git a/src/filterparser/filterparserintgtcomparator.cpp b/src/filterparser/filterparserintgtcomparator.cpp new file mode 100644 index 0000000000..e2e350ac20 --- /dev/null +++ b/src/filterparser/filterparserintgtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserintgtcomparator.h" + +FilterParserIntGtComparator::FilterParserIntGtComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntGtComparator::Matches(const QVariant &value) const { + return value.toInt() > search_term_; +} diff --git a/src/filterparser/filterparserintgtcomparator.h b/src/filterparser/filterparserintgtcomparator.h new file mode 100644 index 0000000000..9e993136bc --- /dev/null +++ b/src/filterparser/filterparserintgtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINTGTCOMPARATOR_H +#define FILTERPARSERINTGTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntGtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntGtComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntGtComparator) +}; + +#endif // FILTERPARSERINTGTCOMPARATOR_H diff --git a/src/filterparser/filterparserintlecomparator.cpp b/src/filterparser/filterparserintlecomparator.cpp new file mode 100644 index 0000000000..b127a63f81 --- /dev/null +++ b/src/filterparser/filterparserintlecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserintlecomparator.h" + +FilterParserIntLeComparator::FilterParserIntLeComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntLeComparator::Matches(const QVariant &value) const { + return value.toInt() <= search_term_; +} diff --git a/src/filterparser/filterparserintlecomparator.h b/src/filterparser/filterparserintlecomparator.h new file mode 100644 index 0000000000..d39b1f2abd --- /dev/null +++ b/src/filterparser/filterparserintlecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINTLECOMPARATOR_H +#define FILTERPARSERINTLECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntLeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntLeComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntLeComparator) +}; + +#endif // FILTERPARSERINTLECOMPARATOR_H diff --git a/src/filterparser/filterparserintltcomparator.cpp b/src/filterparser/filterparserintltcomparator.cpp new file mode 100644 index 0000000000..05934d9c0e --- /dev/null +++ b/src/filterparser/filterparserintltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserintltcomparator.h" + +FilterParserIntLtComparator::FilterParserIntLtComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntLtComparator::Matches(const QVariant &value) const { + return value.toInt() < search_term_; +} diff --git a/src/filterparser/filterparserintltcomparator.h b/src/filterparser/filterparserintltcomparator.h new file mode 100644 index 0000000000..f972046e86 --- /dev/null +++ b/src/filterparser/filterparserintltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINTLTCOMPARATOR_H +#define FILTERPARSERINTLTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntLtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntLtComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntLtComparator) +}; + +#endif // FILTERPARSERINTLTCOMPARATOR_H diff --git a/src/filterparser/filterparserintnecomparator.cpp b/src/filterparser/filterparserintnecomparator.cpp new file mode 100644 index 0000000000..d7be5b7b34 --- /dev/null +++ b/src/filterparser/filterparserintnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparserintnecomparator.h" + +FilterParserIntNeComparator::FilterParserIntNeComparator(const int search_term) : search_term_(search_term) {} + +bool FilterParserIntNeComparator::Matches(const QVariant &value) const { + return value.toInt() != search_term_; +} diff --git a/src/filterparser/filterparserintnecomparator.h b/src/filterparser/filterparserintnecomparator.h new file mode 100644 index 0000000000..9e78002103 --- /dev/null +++ b/src/filterparser/filterparserintnecomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERINTNECOMPARATOR_H +#define FILTERPARSERINTNECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserIntNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserIntNeComparator(const int search_term); + bool Matches(const QVariant &value) const override; + private: + int search_term_; + Q_DISABLE_COPY(FilterParserIntNeComparator) +}; + +#endif // FILTERPARSERINTNECOMPARATOR_H + diff --git a/src/filterparser/filterparsersearchcomparators.h b/src/filterparser/filterparsersearchcomparators.h index 3f09f1d2eb..7e4dff511d 100644 --- a/src/filterparser/filterparsersearchcomparators.h +++ b/src/filterparser/filterparsersearchcomparators.h @@ -1,314 +1,28 @@ -/* - * Strawberry Music Player - * This file was part of Clementine. - * Copyright 2012, David Sansome - * Copyright 2018-2024, Jonas Kvinge - * - * Strawberry is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#ifndef FILTERPARSERSEARCHCOMPARATORS_H -#define FILTERPARSERSEARCHCOMPARATORS_H - -#include "config.h" - -#include -#include -#include - -class FilterParserSearchTermComparator { - public: - FilterParserSearchTermComparator() = default; - virtual ~FilterParserSearchTermComparator() = default; - virtual bool Matches(const QVariant &value) const = 0; - private: - Q_DISABLE_COPY(FilterParserSearchTermComparator) -}; - -// "compares" by checking if the field contains the search term -class FilterParserTextContainsComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserTextContainsComparator(const QString &search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.metaType().id() == QMetaType::QString && value.toString().contains(search_term_, Qt::CaseInsensitive); - } - private: - QString search_term_; - - Q_DISABLE_COPY(FilterParserTextContainsComparator) -}; - -class FilterParserTextEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserTextEqComparator(const QString &search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return search_term_.compare(value.toString(), Qt::CaseInsensitive) == 0; - } - private: - QString search_term_; -}; - -class FilterParserTextNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserTextNeComparator(const QString &search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return search_term_.compare(value.toString(), Qt::CaseInsensitive) != 0; - } - private: - QString search_term_; -}; - -class FilterParserIntEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntEqComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() == search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntNeComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() != search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntGtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntGtComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() > search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntGeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntGeComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() >= search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntLtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntLtComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() < search_term_; - } - private: - int search_term_; -}; - -class FilterParserIntLeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserIntLeComparator(const int search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toInt() <= search_term_; - } - private: - int search_term_; -}; - -class FilterParserUIntEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntEqComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() == search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntNeComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() != search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntGtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntGtComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() > search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntGeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntGeComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() >= search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntLtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntLtComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() < search_term_; - } - private: - uint search_term_; -}; - -class FilterParserUIntLeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserUIntLeComparator(const uint search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toUInt() <= search_term_; - } - private: - uint search_term_; -}; - -class FilterParserInt64EqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64EqComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() == search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64NeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64NeComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() != search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64GtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64GtComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() > search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64GeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64GeComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() >= search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64LtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64LtComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() < search_term_; - } - private: - qint64 search_term_; -}; - -class FilterParserInt64LeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserInt64LeComparator(const qint64 search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toLongLong() <= search_term_; - } - private: - qint64 search_term_; -}; - -// Float Comparators are for the rating -class FilterParserFloatEqComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatEqComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() == search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatNeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatNeComparator(const float value) : search_term_(value) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() != search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatGtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatGtComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() > search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatGeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatGeComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() >= search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatLtComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatLtComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() < search_term_; - } - private: - float search_term_; -}; - -class FilterParserFloatLeComparator : public FilterParserSearchTermComparator { - public: - explicit FilterParserFloatLeComparator(const float search_term) : search_term_(search_term) {} - bool Matches(const QVariant &value) const override { - return value.toFloat() <= search_term_; - } - private: - float search_term_; -}; - -#endif // FILTERPARSERSEARCHCOMPARATORS_H +#include "filterparserfloateqcomparator.h" +#include "filterparserfloatgecomparator.h" +#include "filterparserfloatgtcomparator.h" +#include "filterparserfloatlecomparator.h" +#include "filterparserfloatltcomparator.h" +#include "filterparserfloatnecomparator.h" +#include "filterparserint64eqcomparator.h" +#include "filterparserint64gecomparator.h" +#include "filterparserint64gtcomparator.h" +#include "filterparserint64lecomparator.h" +#include "filterparserint64ltcomparator.h" +#include "filterparserint64necomparator.h" +#include "filterparserinteqcomparator.h" +#include "filterparserintgecomparator.h" +#include "filterparserintgtcomparator.h" +#include "filterparserintlecomparator.h" +#include "filterparserintltcomparator.h" +#include "filterparserintnecomparator.h" +#include "filterparsersearchtermcomparator.h" +#include "filterparsertextcontainscomparator.h" +#include "filterparsertexteqcomparator.h" +#include "filterparsertextnecomparator.h" +#include "filterparseruinteqcomparator.h" +#include "filterparseruintgecomparator.h" +#include "filterparseruintgtcomparator.h" +#include "filterparseruintlecomparator.h" +#include "filterparseruintltcomparator.h" +#include "filterparseruintnecomparator.h" diff --git a/src/filterparser/filterparsersearchtermcomparator.cpp b/src/filterparser/filterparsersearchtermcomparator.cpp new file mode 100644 index 0000000000..c7d52ca2c5 --- /dev/null +++ b/src/filterparser/filterparsersearchtermcomparator.cpp @@ -0,0 +1,24 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparsersearchtermcomparator.h" + +FilterParserSearchTermComparator::FilterParserSearchTermComparator() = default; + +FilterParserSearchTermComparator::~FilterParserSearchTermComparator() = default; diff --git a/src/filterparser/filterparsersearchtermcomparator.h b/src/filterparser/filterparsersearchtermcomparator.h new file mode 100644 index 0000000000..72bbf9e4fd --- /dev/null +++ b/src/filterparser/filterparsersearchtermcomparator.h @@ -0,0 +1,34 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERSEARCHTERMCOMPARATOR_H +#define FILTERPARSERSEARCHTERMCOMPARATOR_H + +#include + +class FilterParserSearchTermComparator { + public: + explicit FilterParserSearchTermComparator(); + virtual ~FilterParserSearchTermComparator(); + virtual bool Matches(const QVariant &value) const = 0; + private: + Q_DISABLE_COPY(FilterParserSearchTermComparator) +}; + +#endif // FILTERPARSERSEARCHTERMCOMPARATOR_H diff --git a/src/filterparser/filterparsertextcontainscomparator.cpp b/src/filterparser/filterparsertextcontainscomparator.cpp new file mode 100644 index 0000000000..55822b36a3 --- /dev/null +++ b/src/filterparser/filterparsertextcontainscomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparsertextcontainscomparator.h" + +FilterParserTextContainsComparator::FilterParserTextContainsComparator(const QString &search_term) : search_term_(search_term) {} + +bool FilterParserTextContainsComparator::Matches(const QVariant &value) const { + return value.metaType().id() == QMetaType::QString && value.toString().contains(search_term_, Qt::CaseInsensitive); +} diff --git a/src/filterparser/filterparsertextcontainscomparator.h b/src/filterparser/filterparsertextcontainscomparator.h new file mode 100644 index 0000000000..1a18709f72 --- /dev/null +++ b/src/filterparser/filterparsertextcontainscomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERTEXTCONTAINSCOMPARATOR_H +#define FILTERPARSERTEXTCONTAINSCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserTextContainsComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserTextContainsComparator(const QString &search_term); + bool Matches(const QVariant &value) const override; + private: + QString search_term_; + Q_DISABLE_COPY(FilterParserTextContainsComparator) +}; + +#endif // FILTERPARSERTEXTCONTAINSCOMPARATOR_H diff --git a/src/filterparser/filterparsertexteqcomparator.cpp b/src/filterparser/filterparsertexteqcomparator.cpp new file mode 100644 index 0000000000..16dd3edf6d --- /dev/null +++ b/src/filterparser/filterparsertexteqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparsertexteqcomparator.h" + +FilterParserTextEqComparator::FilterParserTextEqComparator(const QString &search_term) : search_term_(search_term) {} + +bool FilterParserTextEqComparator::Matches(const QVariant &value) const { + return search_term_.compare(value.toString(), Qt::CaseInsensitive) == 0; +} diff --git a/src/filterparser/filterparsertexteqcomparator.h b/src/filterparser/filterparsertexteqcomparator.h new file mode 100644 index 0000000000..07f9eabae7 --- /dev/null +++ b/src/filterparser/filterparsertexteqcomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERTEXTEQCOMPARATOR_H +#define FILTERPARSERTEXTEQCOMPARATOR_H + +#include +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserTextEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserTextEqComparator(const QString &search_term); + bool Matches(const QVariant &value) const override; + private: + QString search_term_; + Q_DISABLE_COPY(FilterParserTextEqComparator) +}; + +#endif // FILTERPARSERTEXTEQCOMPARATOR_H diff --git a/src/filterparser/filterparsertextnecomparator.cpp b/src/filterparser/filterparsertextnecomparator.cpp new file mode 100644 index 0000000000..e7b5e3825d --- /dev/null +++ b/src/filterparser/filterparsertextnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparsertextnecomparator.h" + +FilterParserTextNeComparator::FilterParserTextNeComparator(const QString &search_term) : search_term_(search_term) {} + +bool FilterParserTextNeComparator::Matches(const QVariant &value) const { + return search_term_.compare(value.toString(), Qt::CaseInsensitive) != 0; +} diff --git a/src/filterparser/filterparsertextnecomparator.h b/src/filterparser/filterparsertextnecomparator.h new file mode 100644 index 0000000000..db286c7579 --- /dev/null +++ b/src/filterparser/filterparsertextnecomparator.h @@ -0,0 +1,37 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERTEXTNECOMPARATOR_H +#define FILTERPARSERTEXTNECOMPARATOR_H + +#include +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserTextNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserTextNeComparator(const QString &search_term); + bool Matches(const QVariant &value) const override; + private: + QString search_term_; + Q_DISABLE_COPY(FilterParserTextNeComparator) +}; + +#endif // FILTERPARSERTEXTNECOMPARATOR_H diff --git a/src/filterparser/filterparseruinteqcomparator.cpp b/src/filterparser/filterparseruinteqcomparator.cpp new file mode 100644 index 0000000000..8151cf7b28 --- /dev/null +++ b/src/filterparser/filterparseruinteqcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparseruinteqcomparator.h" + +FilterParserUIntEqComparator::FilterParserUIntEqComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntEqComparator::Matches(const QVariant &value) const { + return value.toUInt() == search_term_; +} diff --git a/src/filterparser/filterparseruinteqcomparator.h b/src/filterparser/filterparseruinteqcomparator.h new file mode 100644 index 0000000000..30a6187016 --- /dev/null +++ b/src/filterparser/filterparseruinteqcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERUINTEQCOMPARATOR_H +#define FILTERPARSERUINTEQCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntEqComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntEqComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntEqComparator) +}; + +#endif // FILTERPARSERUINTEQCOMPARATOR_H diff --git a/src/filterparser/filterparseruintgecomparator.cpp b/src/filterparser/filterparseruintgecomparator.cpp new file mode 100644 index 0000000000..dc20c70081 --- /dev/null +++ b/src/filterparser/filterparseruintgecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparseruintgecomparator.h" + +FilterParserUIntGeComparator::FilterParserUIntGeComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntGeComparator::Matches(const QVariant &value) const { + return value.toUInt() >= search_term_; +} diff --git a/src/filterparser/filterparseruintgecomparator.h b/src/filterparser/filterparseruintgecomparator.h new file mode 100644 index 0000000000..02543b508c --- /dev/null +++ b/src/filterparser/filterparseruintgecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERUINTGECOMPARATOR_H +#define FILTERPARSERUINTGECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntGeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntGeComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntGeComparator) +}; + +#endif // FILTERPARSERUINTGECOMPARATOR_H diff --git a/src/filterparser/filterparseruintgtcomparator.cpp b/src/filterparser/filterparseruintgtcomparator.cpp new file mode 100644 index 0000000000..9b644a27cb --- /dev/null +++ b/src/filterparser/filterparseruintgtcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparseruintgtcomparator.h" + +FilterParserUIntGtComparator::FilterParserUIntGtComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntGtComparator::Matches(const QVariant &value) const { + return value.toUInt() > search_term_; +} diff --git a/src/filterparser/filterparseruintgtcomparator.h b/src/filterparser/filterparseruintgtcomparator.h new file mode 100644 index 0000000000..fe8441d479 --- /dev/null +++ b/src/filterparser/filterparseruintgtcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERUINTGTCOMPARATOR_H +#define FILTERPARSERUINTGTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntGtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntGtComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntGtComparator) +}; + +#endif // FILTERPARSERUINTGTCOMPARATOR_H diff --git a/src/filterparser/filterparseruintlecomparator.cpp b/src/filterparser/filterparseruintlecomparator.cpp new file mode 100644 index 0000000000..9943985b97 --- /dev/null +++ b/src/filterparser/filterparseruintlecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparseruintlecomparator.h" + +FilterParserUIntLeComparator::FilterParserUIntLeComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntLeComparator::Matches(const QVariant &value) const { + return value.toUInt() <= search_term_; +} diff --git a/src/filterparser/filterparseruintlecomparator.h b/src/filterparser/filterparseruintlecomparator.h new file mode 100644 index 0000000000..b6390a5473 --- /dev/null +++ b/src/filterparser/filterparseruintlecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERUINTLECOMPARATOR_H +#define FILTERPARSERUINTLECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntLeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntLeComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntLeComparator) +}; + +#endif // FILTERPARSERUINTLECOMPARATOR_H diff --git a/src/filterparser/filterparseruintltcomparator.cpp b/src/filterparser/filterparseruintltcomparator.cpp new file mode 100644 index 0000000000..57f7866874 --- /dev/null +++ b/src/filterparser/filterparseruintltcomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparseruintltcomparator.h" + +FilterParserUIntLtComparator::FilterParserUIntLtComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntLtComparator::Matches(const QVariant &value) const { + return value.toUInt() < search_term_; +} diff --git a/src/filterparser/filterparseruintltcomparator.h b/src/filterparser/filterparseruintltcomparator.h new file mode 100644 index 0000000000..f31c53632e --- /dev/null +++ b/src/filterparser/filterparseruintltcomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERUINTLTCOMPARATOR_H +#define FILTERPARSERUINTLTCOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntLtComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntLtComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntLtComparator) +}; + +#endif // FILTERPARSERUINTLTCOMPARATOR_H diff --git a/src/filterparser/filterparseruintnecomparator.cpp b/src/filterparser/filterparseruintnecomparator.cpp new file mode 100644 index 0000000000..81c1165048 --- /dev/null +++ b/src/filterparser/filterparseruintnecomparator.cpp @@ -0,0 +1,26 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filterparseruintnecomparator.h" + +FilterParserUIntNeComparator::FilterParserUIntNeComparator(const uint search_term) : search_term_(search_term) {} + +bool FilterParserUIntNeComparator::Matches(const QVariant &value) const { + return value.toUInt() != search_term_; +} diff --git a/src/filterparser/filterparseruintnecomparator.h b/src/filterparser/filterparseruintnecomparator.h new file mode 100644 index 0000000000..a000d040d8 --- /dev/null +++ b/src/filterparser/filterparseruintnecomparator.h @@ -0,0 +1,36 @@ +/* + * Strawberry Music Player + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERPARSERUINTNECOMPARATOR_H +#define FILTERPARSERUINTNECOMPARATOR_H + +#include + +#include "filterparsersearchtermcomparator.h" + +class FilterParserUIntNeComparator : public FilterParserSearchTermComparator { + public: + explicit FilterParserUIntNeComparator(const uint search_term); + bool Matches(const QVariant &value) const override; + private: + uint search_term_; + Q_DISABLE_COPY(FilterParserUIntNeComparator) +}; + +#endif // FILTERPARSERUINTNECOMPARATOR_H diff --git a/src/filterparser/filtertree.cpp b/src/filterparser/filtertree.cpp index a8bbb81c91..50f1bf1c5c 100644 --- a/src/filterparser/filtertree.cpp +++ b/src/filterparser/filtertree.cpp @@ -23,6 +23,8 @@ #include "filtertree.h" +#include "core/song.h" + using namespace Qt::Literals::StringLiterals; FilterTree::FilterTree() = default; diff --git a/src/filterparser/filtertree.h b/src/filterparser/filtertree.h index 7098f1ca20..5e49c78b83 100644 --- a/src/filterparser/filtertree.h +++ b/src/filterparser/filtertree.h @@ -22,15 +22,9 @@ #ifndef FILTERTREE_H #define FILTERTREE_H -#include "config.h" - -#include #include -#include -#include #include "core/song.h" -#include "filterparsersearchcomparators.h" class FilterTree { public: @@ -57,99 +51,4 @@ class FilterTree { Q_DISABLE_COPY(FilterTree) }; -// Trivial filter that accepts *anything* -class NopFilter : public FilterTree { - public: - FilterType type() const override { return FilterType::Nop; } - bool accept(const Song &song) const override { Q_UNUSED(song); return true; } -}; - -// Filter that applies a SearchTermComparator to all fields -class FilterTerm : public FilterTree { - public: - explicit FilterTerm(FilterParserSearchTermComparator *comparator) : cmp_(comparator) {} - - FilterType type() const override { return FilterType::Term; } - - bool accept(const Song &song) const override { - - if (cmp_->Matches(song.PrettyTitle())) return true; - if (cmp_->Matches(song.album())) return true; - if (cmp_->Matches(song.artist())) return true; - if (cmp_->Matches(song.albumartist())) return true; - if (cmp_->Matches(song.composer())) return true; - if (cmp_->Matches(song.performer())) return true; - if (cmp_->Matches(song.grouping())) return true; - if (cmp_->Matches(song.genre())) return true; - if (cmp_->Matches(song.comment())) return true; - - return false; - - } - - private: - QScopedPointer cmp_; -}; - -class FilterColumnTerm : public FilterTree { - public: - explicit FilterColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator) : column_(column), cmp_(comparator) {} - - FilterType type() const override { return FilterType::Column; } - - bool accept(const Song &song) const override { - return cmp_->Matches(DataFromColumn(column_, song)); - } - - private: - const QString column_; - QScopedPointer cmp_; -}; - -class NotFilter : public FilterTree { - public: - explicit NotFilter(const FilterTree *inv) : child_(inv) {} - - FilterType type() const override { return FilterType::Not; } - - bool accept(const Song &song) const override { - return !child_->accept(song); - } - - private: - QScopedPointer child_; -}; - -class OrFilter : public FilterTree { - public: - ~OrFilter() override { qDeleteAll(children_); } - - FilterType type() const override { return FilterType::Or; } - - virtual void add(FilterTree *child) { children_.append(child); } - - bool accept(const Song &song) const override { - return std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return child->accept(song); }); - } - - private: - QList children_; -}; - -class AndFilter : public FilterTree { - public: - ~AndFilter() override { qDeleteAll(children_); } - - FilterType type() const override { return FilterType::And; } - - virtual void add(FilterTree *child) { children_.append(child); } - - bool accept(const Song &song) const override { - return !std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return !child->accept(song); }); - } - - private: - QList children_; -}; - #endif // FILTERTREE_H diff --git a/src/filterparser/filtertreeand.cpp b/src/filterparser/filtertreeand.cpp new file mode 100644 index 0000000000..0672a4abf0 --- /dev/null +++ b/src/filterparser/filtertreeand.cpp @@ -0,0 +1,34 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filtertreeand.h" + +FilterTreeAnd::FilterTreeAnd() = default; + +FilterTreeAnd::~FilterTreeAnd() { + qDeleteAll(children_); +} + +void FilterTreeAnd::add(FilterTree *child) { children_.append(child); } + +bool FilterTreeAnd::accept(const Song &song) const { + return !std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return !child->accept(song); }); +} diff --git a/src/filterparser/filtertreeand.h b/src/filterparser/filtertreeand.h new file mode 100644 index 0000000000..442d8fe841 --- /dev/null +++ b/src/filterparser/filtertreeand.h @@ -0,0 +1,46 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERTREEAND_H +#define FILTERTREEAND_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterTreeAnd : public FilterTree { + public: + explicit FilterTreeAnd(); + ~FilterTreeAnd() override; + + FilterType type() const override { return FilterType::And; } + virtual void add(FilterTree *child); + bool accept(const Song &song) const override; + + private: + QList children_; + + Q_DISABLE_COPY(FilterTreeAnd) +}; + +#endif // FILTERTREEAND_H diff --git a/src/filterparser/filtertreecolumnterm.cpp b/src/filterparser/filtertreecolumnterm.cpp new file mode 100644 index 0000000000..9c1d8f572d --- /dev/null +++ b/src/filterparser/filtertreecolumnterm.cpp @@ -0,0 +1,31 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include + +#include "filtertreecolumnterm.h" +#include "filterparsersearchtermcomparator.h" + +FilterTreeColumnTerm::FilterTreeColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator) : column_(column), cmp_(comparator) {} + +bool FilterTreeColumnTerm::accept(const Song &song) const { + return cmp_->Matches(DataFromColumn(column_, song)); +} diff --git a/src/filterparser/filtertreecolumnterm.h b/src/filterparser/filtertreecolumnterm.h new file mode 100644 index 0000000000..ffaa403763 --- /dev/null +++ b/src/filterparser/filtertreecolumnterm.h @@ -0,0 +1,48 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERTREECOLUMNTERM_H +#define FILTERTREECOLUMNTERM_H + +#include +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterParserSearchTermComparator; + +class FilterTreeColumnTerm : public FilterTree { + public: + explicit FilterTreeColumnTerm(const QString &column, FilterParserSearchTermComparator *comparator); + + FilterType type() const override { return FilterType::Column; } + bool accept(const Song &song) const override; + + private: + const QString column_; + QScopedPointer cmp_; + + Q_DISABLE_COPY(FilterTreeColumnTerm) +}; + +#endif // FILTERTREECOLUMNTERM_H diff --git a/src/filterparser/filtertreenop.cpp b/src/filterparser/filtertreenop.cpp new file mode 100644 index 0000000000..df153ce95b --- /dev/null +++ b/src/filterparser/filtertreenop.cpp @@ -0,0 +1,29 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filtertreenop.h" + +FilterTreeNop::FilterTreeNop() = default; + +bool FilterTreeNop::accept(const Song &song) const { + Q_UNUSED(song); + return true; +} diff --git a/src/filterparser/filtertreenop.h b/src/filterparser/filtertreenop.h new file mode 100644 index 0000000000..b7d6a5ce50 --- /dev/null +++ b/src/filterparser/filtertreenop.h @@ -0,0 +1,38 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERTREENOP_H +#define FILTERTREENOP_H + +#include "filtertree.h" + +#include "core/song.h" + +// Trivial filter that accepts *anything* +class FilterTreeNop : public FilterTree { + public: + explicit FilterTreeNop(); + FilterType type() const override { return FilterType::Nop; } + bool accept(const Song &song) const override; + Q_DISABLE_COPY(FilterTreeNop) +}; + +#endif // FILTERTREENOP_H diff --git a/src/filterparser/filtertreenot.cpp b/src/filterparser/filtertreenot.cpp new file mode 100644 index 0000000000..0289068721 --- /dev/null +++ b/src/filterparser/filtertreenot.cpp @@ -0,0 +1,30 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include + +#include "filtertreenot.h" + +FilterTreeNot::FilterTreeNot(const FilterTree *inv) : child_(inv) {} + +bool FilterTreeNot::accept(const Song &song) const { + return !child_->accept(song); +} diff --git a/src/filterparser/filtertreenot.h b/src/filterparser/filtertreenot.h new file mode 100644 index 0000000000..ede71b6a94 --- /dev/null +++ b/src/filterparser/filtertreenot.h @@ -0,0 +1,44 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERTREENOT_H +#define FILTERTREENOT_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterTreeNot : public FilterTree { + public: + explicit FilterTreeNot(const FilterTree *inv); + + FilterType type() const override { return FilterType::Not; } + bool accept(const Song &song) const override; + + private: + QScopedPointer child_; + + Q_DISABLE_COPY(FilterTreeNot) +}; + +#endif // FILTERTREENOT_H diff --git a/src/filterparser/filtertreeor.cpp b/src/filterparser/filtertreeor.cpp new file mode 100644 index 0000000000..109646dc8b --- /dev/null +++ b/src/filterparser/filtertreeor.cpp @@ -0,0 +1,38 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include + +#include "filtertreeor.h" + +FilterTreeOr::FilterTreeOr() = default; + +FilterTreeOr::~FilterTreeOr() { + qDeleteAll(children_); +} + +void FilterTreeOr::add(FilterTree *child) { + children_.append(child); +} + +bool FilterTreeOr::accept(const Song &song) const { + return std::any_of(children_.begin(), children_.end(), [song](FilterTree *child) { return child->accept(song); }); +} diff --git a/src/filterparser/filtertreeor.h b/src/filterparser/filtertreeor.h new file mode 100644 index 0000000000..bd570d31af --- /dev/null +++ b/src/filterparser/filtertreeor.h @@ -0,0 +1,46 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERTREEOR_H +#define FILTERTREEOR_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterTreeOr : public FilterTree { + public: + explicit FilterTreeOr(); + ~FilterTreeOr() override; + + FilterType type() const override { return FilterType::Or; } + virtual void add(FilterTree *child); + bool accept(const Song &song) const override; + + private: + QList children_; + + Q_DISABLE_COPY(FilterTreeOr) +}; + +#endif // FILTERTREEOR_H diff --git a/src/filterparser/filtertreeterm.cpp b/src/filterparser/filtertreeterm.cpp new file mode 100644 index 0000000000..5b212cde05 --- /dev/null +++ b/src/filterparser/filtertreeterm.cpp @@ -0,0 +1,41 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "filtertreeterm.h" +#include "filterparsersearchtermcomparator.h" + +FilterTreeTerm::FilterTreeTerm(FilterParserSearchTermComparator *comparator) : cmp_(comparator) {} + +bool FilterTreeTerm::accept(const Song &song) const { + + if (cmp_->Matches(song.PrettyTitle())) return true; + if (cmp_->Matches(song.album())) return true; + if (cmp_->Matches(song.artist())) return true; + if (cmp_->Matches(song.albumartist())) return true; + if (cmp_->Matches(song.composer())) return true; + if (cmp_->Matches(song.performer())) return true; + if (cmp_->Matches(song.grouping())) return true; + if (cmp_->Matches(song.genre())) return true; + if (cmp_->Matches(song.comment())) return true; + + return false; + +} diff --git a/src/filterparser/filtertreeterm.h b/src/filterparser/filtertreeterm.h new file mode 100644 index 0000000000..1cf68da24a --- /dev/null +++ b/src/filterparser/filtertreeterm.h @@ -0,0 +1,47 @@ +/* + * Strawberry Music Player + * This file was part of Clementine. + * Copyright 2012, David Sansome + * Copyright 2018-2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef FILTERTREETERM_H +#define FILTERTREETERM_H + +#include + +#include "filtertree.h" + +#include "core/song.h" + +class FilterParserSearchTermComparator; + +// Filter that applies a SearchTermComparator to all fields +class FilterTreeTerm : public FilterTree { + public: + explicit FilterTreeTerm(FilterParserSearchTermComparator *comparator); + + FilterType type() const override { return FilterType::Term; } + bool accept(const Song &song) const override; + + private: + QScopedPointer cmp_; + + Q_DISABLE_COPY(FilterTreeTerm) +}; + +#endif // FILTERTREETERM_H diff --git a/src/globalshortcuts/CMakeLists.txt b/src/globalshortcuts/CMakeLists.txt new file mode 100644 index 0000000000..474c33190d --- /dev/null +++ b/src/globalshortcuts/CMakeLists.txt @@ -0,0 +1,64 @@ +set(GLOBALSHORTCUTS_SOURCES globalshortcutsmanager.cpp globalshortcutsbackend.cpp globalshortcutgrabber.cpp) +set(GLOBALSHORTCUTS_HEADERS globalshortcutsmanager.h globalshortcutsbackend.h globalshortcutgrabber.h) +set(GLOBALSHORTCUTS_UI globalshortcutgrabber.ui) + +if(HAVE_KDE_GLOBALSHORTCUTS) + list(APPEND GLOBALSHORTCUTS_SOURCES globalshortcutsbackend-kde.cpp globalshortcutsbackend-gnome.cpp globalshortcutsbackend-mate.cpp) + list(APPEND GLOBALSHORTCUTS_HEADERS globalshortcutsbackend-kde.h globalshortcutsbackend-gnome.h globalshortcutsbackend-mate.h) +endif() + +if(HAVE_X11_GLOBALSHORTCUTS) + list(APPEND GLOBALSHORTCUTS_SOURCES globalshortcutsbackend-x11.cpp globalshortcut.cpp globalshortcut-x11.cpp) + list(APPEND GLOBALSHORTCUTS_HEADERS globalshortcutsbackend-x11.h globalshortcut.h) +endif() + +if(APPLE) + list(APPEND GLOBALSHORTCUTS_SOURCES globalshortcutsbackend-macos.mm globalshortcutgrabber.mm) + list(APPEND GLOBALSHORTCUTS_HEADERS globalshortcutsbackend-macos.h globalshortcutgrabber.h) +endif() + +if(WIN32) + list(APPEND GLOBALSHORTCUTS_SOURCES globalshortcutsbackend-win.cpp globalshortcut.cpp globalshortcut-win.cpp) + list(APPEND GLOBALSHORTCUTS_HEADERS globalshortcutsbackend-win.h globalshortcut.h) +endif() + +if(HAVE_KDE_GLOBALSHORTCUTS) + qt_add_dbus_interface(GLOBALSHORTCUTS_SOURCES org.kde.KGlobalAccel.xml kglobalaccel) + qt_add_dbus_interface(GLOBALSHORTCUTS_SOURCES org.kde.KGlobalAccel.Component.xml kglobalaccelcomponent) +endif() + +if(HAVE_GNOME_GLOBALSHORTCUTS) + qt_add_dbus_interface(GLOBALSHORTCUTS_SOURCES org.gnome.SettingsDaemon.MediaKeys.xml gnomesettingsdaemon) +endif() + +if(HAVE_MATE_GLOBALSHORTCUTS) + qt_add_dbus_interface(GLOBALSHORTCUTS_SOURCES org.mate.SettingsDaemon.MediaKeys.xml matesettingsdaemon) +endif() + +qt_wrap_cpp(GLOBALSHORTCUTS_SOURCES ${GLOBALSHORTCUTS_HEADERS}) +qt_wrap_ui(GLOBALSHORTCUTS_SOURCES ${GLOBALSHORTCUTS_UI}) + +add_library(strawberry_globalshortcuts STATIC ${GLOBALSHORTCUTS_SOURCES}) + +target_include_directories(strawberry_globalshortcuts PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_globalshortcuts PRIVATE + $<$:X11::X11_xcb> + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + $<$:Qt${QT_VERSION_MAJOR}::DBus> + strawberry_core +) + +if(APPLE) + target_link_libraries(strawberry_globalshortcuts PRIVATE + "-framework ScriptingBridge" + strawberry_macstartup + ) +endif() diff --git a/src/globalshortcuts/globalshortcut-x11.cpp b/src/globalshortcuts/globalshortcut-x11.cpp index abdc8d47f5..a4cc24cca2 100644 --- a/src/globalshortcuts/globalshortcut-x11.cpp +++ b/src/globalshortcuts/globalshortcut-x11.cpp @@ -91,8 +91,8 @@ int GlobalShortcut::nativeKeycode(const Qt::Key qt_keycode) { } -int GlobalShortcut::nativeKeycode2(const Qt::Key key) { - Q_UNUSED(key) +int GlobalShortcut::nativeKeycode2(const Qt::Key qt_keycode) { + Q_UNUSED(qt_keycode) return 0; } diff --git a/src/globalshortcuts/globalshortcutgrabber.cpp b/src/globalshortcuts/globalshortcutgrabber.cpp index 2e1919bb60..7d96e9474e 100644 --- a/src/globalshortcuts/globalshortcutgrabber.cpp +++ b/src/globalshortcuts/globalshortcutgrabber.cpp @@ -32,7 +32,7 @@ #include #include "globalshortcutgrabber.h" -#include "ui_globalshortcutgrabber.h" +#include "globalshortcuts/ui_globalshortcutgrabber.h" using namespace Qt::Literals::StringLiterals; diff --git a/src/globalshortcuts/globalshortcutgrabber.mm b/src/globalshortcuts/globalshortcutgrabber.mm index 06cf3230fb..97c9f62a17 100644 --- a/src/globalshortcuts/globalshortcutgrabber.mm +++ b/src/globalshortcuts/globalshortcutgrabber.mm @@ -29,7 +29,7 @@ #include -#import "core/mac_startup.h" +#import "macstartup/mac_startup.h" class MacMonitorWrapper { public: diff --git a/src/globalshortcuts/globalshortcutsbackend-gnome.cpp b/src/globalshortcuts/globalshortcutsbackend-gnome.cpp index b12028ae9d..4613305ec7 100644 --- a/src/globalshortcuts/globalshortcutsbackend-gnome.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-gnome.cpp @@ -35,7 +35,7 @@ #include "globalshortcutsbackend.h" #include "globalshortcutsbackend-gnome.h" -#include "gnomesettingsdaemon.h" +#include "globalshortcuts/gnomesettingsdaemon.h" using namespace Qt::Literals::StringLiterals; diff --git a/src/globalshortcuts/globalshortcutsbackend-kde.cpp b/src/globalshortcuts/globalshortcutsbackend-kde.cpp index 664c19d5cc..d6a50dbb7f 100644 --- a/src/globalshortcuts/globalshortcutsbackend-kde.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-kde.cpp @@ -35,8 +35,8 @@ #include "globalshortcutsbackend-kde.h" -#include "kglobalaccel.h" -#include "kglobalaccelcomponent.h" +#include "globalshortcuts/kglobalaccel.h" +#include "globalshortcuts/kglobalaccelcomponent.h" using namespace Qt::Literals::StringLiterals; diff --git a/src/globalshortcuts/globalshortcutsbackend-macos.h b/src/globalshortcuts/globalshortcutsbackend-macos.h index 4abd125127..209ddfbdab 100644 --- a/src/globalshortcuts/globalshortcutsbackend-macos.h +++ b/src/globalshortcuts/globalshortcutsbackend-macos.h @@ -31,7 +31,7 @@ #include #include -#include "core/scoped_ptr.h" +#include "includes/scoped_ptr.h" class GlobalShortcutsBackendMacOSPrivate; diff --git a/src/globalshortcuts/globalshortcutsbackend-macos.mm b/src/globalshortcuts/globalshortcutsbackend-macos.mm index 99234509d3..6ac3d17a39 100644 --- a/src/globalshortcuts/globalshortcutsbackend-macos.mm +++ b/src/globalshortcuts/globalshortcutsbackend-macos.mm @@ -36,12 +36,11 @@ #include #include -#include "config.h" #include "globalshortcutsmanager.h" #include "core/logging.h" -#include "core/mac_startup.h" +#include "macstartup/mac_startup.h" -#import "core/SBSystemPreferences.h" +#import "includes/SBSystemPreferences.h" class GlobalShortcutsBackendMacOSPrivate { public: diff --git a/src/globalshortcuts/globalshortcutsbackend-mate.cpp b/src/globalshortcuts/globalshortcutsbackend-mate.cpp index 013bd37c16..edeb03b4f2 100644 --- a/src/globalshortcuts/globalshortcutsbackend-mate.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-mate.cpp @@ -33,7 +33,7 @@ #include "globalshortcutsbackend.h" #include "globalshortcutsbackend-mate.h" -#include "matesettingsdaemon.h" +#include "globalshortcuts/matesettingsdaemon.h" using namespace Qt::Literals::StringLiterals; diff --git a/src/globalshortcuts/globalshortcutsmanager.cpp b/src/globalshortcuts/globalshortcutsmanager.cpp index b16022d2fe..545c7819b1 100644 --- a/src/globalshortcuts/globalshortcutsmanager.cpp +++ b/src/globalshortcuts/globalshortcutsmanager.cpp @@ -31,6 +31,8 @@ #include #include +#include "core/logging.h" + #include "globalshortcutsmanager.h" #include "globalshortcutsbackend.h" @@ -58,13 +60,13 @@ # include "globalshortcutsbackend-macos.h" #endif -#include "settings/globalshortcutssettingspage.h" +#include "constants/globalshortcutssettings.h" using namespace Qt::Literals::StringLiterals; GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) : QWidget(parent) { - settings_.beginGroup(GlobalShortcutsSettingsPage::kSettingsGroup); + settings_.beginGroup(GlobalShortcutsSettings::kSettingsGroup); // Create actions AddShortcut(u"play"_s, tr("Play"), std::bind(&GlobalShortcutsManager::Play, this)); @@ -131,25 +133,25 @@ void GlobalShortcutsManager::ReloadSettings() { #endif #ifdef HAVE_KDE_GLOBALSHORTCUTS - if (settings_.value("use_kde", true).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseKDE, true).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::KDE; } #endif #ifdef HAVE_GNOME_GLOBALSHORTCUTS - if (settings_.value("use_gnome", true).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseGnome, true).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::Gnome; } #endif #ifdef HAVE_MATE_GLOBALSHORTCUTS - if (settings_.value("use_mate", true).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseMate, true).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::Mate; } #endif #ifdef HAVE_X11_GLOBALSHORTCUTS - if (settings_.value("use_x11", false).toBool()) { + if (settings_.value(GlobalShortcutsSettings::kUseX11, false).toBool()) { backends_enabled_ << GlobalShortcutsBackend::Type::X11; } #endif diff --git a/src/core/SBSystemPreferences.h b/src/includes/SBSystemPreferences.h similarity index 100% rename from src/core/SBSystemPreferences.h rename to src/includes/SBSystemPreferences.h diff --git a/src/core/arraysize.h b/src/includes/arraysize.h similarity index 100% rename from src/core/arraysize.h rename to src/includes/arraysize.h diff --git a/src/core/dbus_metatypes.h b/src/includes/dbus_metatypes.h similarity index 100% rename from src/core/dbus_metatypes.h rename to src/includes/dbus_metatypes.h diff --git a/src/core/iconmapper.h b/src/includes/iconmapper.h similarity index 100% rename from src/core/iconmapper.h rename to src/includes/iconmapper.h diff --git a/src/core/lazy.h b/src/includes/lazy.h similarity index 100% rename from src/core/lazy.h rename to src/includes/lazy.h diff --git a/src/core/mac_delegate.h b/src/includes/mac_delegate.h similarity index 100% rename from src/core/mac_delegate.h rename to src/includes/mac_delegate.h diff --git a/src/core/mutex_protected.h b/src/includes/mutex_protected.h similarity index 100% rename from src/core/mutex_protected.h rename to src/includes/mutex_protected.h diff --git a/src/core/qt_blurimage.h b/src/includes/qt_blurimage.h similarity index 100% rename from src/core/qt_blurimage.h rename to src/includes/qt_blurimage.h diff --git a/src/core/scoped_cftyperef.h b/src/includes/scoped_cftyperef.h similarity index 100% rename from src/core/scoped_cftyperef.h rename to src/includes/scoped_cftyperef.h diff --git a/src/core/scoped_nsobject.h b/src/includes/scoped_nsobject.h similarity index 100% rename from src/core/scoped_nsobject.h rename to src/includes/scoped_nsobject.h diff --git a/src/core/scoped_ptr.h b/src/includes/scoped_ptr.h similarity index 100% rename from src/core/scoped_ptr.h rename to src/includes/scoped_ptr.h diff --git a/src/core/scopedgobject.h b/src/includes/scopedgobject.h similarity index 100% rename from src/core/scopedgobject.h rename to src/includes/scopedgobject.h diff --git a/src/core/shared_ptr.h b/src/includes/shared_ptr.h similarity index 100% rename from src/core/shared_ptr.h rename to src/includes/shared_ptr.h diff --git a/src/lyrics/CMakeLists.txt b/src/lyrics/CMakeLists.txt new file mode 100644 index 0000000000..8d1fe0a513 --- /dev/null +++ b/src/lyrics/CMakeLists.txt @@ -0,0 +1,60 @@ +set(LYRICS_SOURCES + lyricsproviders.cpp + lyricsprovider.cpp + lyricssearchrequest.h + lyricssearchresult.h + lyricsfetcher.cpp + lyricsfetchersearch.cpp + jsonlyricsprovider.cpp + htmllyricsprovider.cpp + ovhlyricsprovider.cpp + lololyricsprovider.cpp + geniuslyricsprovider.cpp + musixmatchlyricsprovider.cpp + chartlyricsprovider.cpp + songlyricscomlyricsprovider.cpp + azlyricscomlyricsprovider.cpp + elyricsnetlyricsprovider.cpp + letraslyricsprovider.cpp + lyricfindlyricsprovider.cpp +) + +set(LYRICS_HEADERS + lyricsproviders.h + lyricsprovider.h + lyricsfetcher.h + lyricsfetchersearch.h + jsonlyricsprovider.h + htmllyricsprovider.h + ovhlyricsprovider.h + lololyricsprovider.h + geniuslyricsprovider.h + musixmatchlyricsprovider.h + chartlyricsprovider.h + songlyricscomlyricsprovider.h + azlyricscomlyricsprovider.h + elyricsnetlyricsprovider.h + letraslyricsprovider.h + lyricfindlyricsprovider.h +) + +qt_wrap_cpp(LYRICS_SOURCES ${LYRICS_HEADERS}) + +add_library(strawberry_lyrics STATIC ${LYRICS_SOURCES}) + +target_include_directories(strawberry_lyrics PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(strawberry_lyrics PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + strawberry_utilities + strawberry_core + strawberry_providers +) diff --git a/src/lyrics/azlyricscomlyricsprovider.cpp b/src/lyrics/azlyricscomlyricsprovider.cpp index 3046725805..1dd5971bf6 100644 --- a/src/lyrics/azlyricscomlyricsprovider.cpp +++ b/src/lyrics/azlyricscomlyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/transliterate.h" #include "lyricssearchrequest.h" @@ -38,7 +38,7 @@ constexpr char kEndTag[] = ""; constexpr char kLyricsStart[] = ""; } // namespace -AzLyricsComLyricsProvider::AzLyricsComLyricsProvider(SharedPtr network, QObject *parent) +AzLyricsComLyricsProvider::AzLyricsComLyricsProvider(const SharedPtr network, QObject *parent) : HtmlLyricsProvider(u"azlyrics.com"_s, true, QLatin1String(kStartTag), QLatin1String(kEndTag), QLatin1String(kLyricsStart), false, network, parent) {} QUrl AzLyricsComLyricsProvider::Url(const LyricsSearchRequest &request) { diff --git a/src/lyrics/azlyricscomlyricsprovider.h b/src/lyrics/azlyricscomlyricsprovider.h index 88a41bb42b..20d01b1627 100644 --- a/src/lyrics/azlyricscomlyricsprovider.h +++ b/src/lyrics/azlyricscomlyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" @@ -34,7 +34,7 @@ class AzLyricsComLyricsProvider : public HtmlLyricsProvider { Q_OBJECT public: - explicit AzLyricsComLyricsProvider(SharedPtr network, QObject *parent = nullptr); + explicit AzLyricsComLyricsProvider(const SharedPtr network, QObject *parent = nullptr); protected: QUrl Url(const LyricsSearchRequest &request) override; diff --git a/src/lyrics/chartlyricsprovider.cpp b/src/lyrics/chartlyricsprovider.cpp index 9b48e9bf09..bb1a15a1ff 100644 --- a/src/lyrics/chartlyricsprovider.cpp +++ b/src/lyrics/chartlyricsprovider.cpp @@ -30,8 +30,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "lyricssearchrequest.h" @@ -44,7 +44,7 @@ namespace { constexpr char kUrlSearch[] = "http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect"; } -ChartLyricsProvider::ChartLyricsProvider(SharedPtr network, QObject *parent) : LyricsProvider(u"ChartLyrics"_s, false, false, network, parent) {} +ChartLyricsProvider::ChartLyricsProvider(const SharedPtr network, QObject *parent) : LyricsProvider(u"ChartLyrics"_s, false, false, network, parent) {} ChartLyricsProvider::~ChartLyricsProvider() { diff --git a/src/lyrics/chartlyricsprovider.h b/src/lyrics/chartlyricsprovider.h index 1df3564b01..64b016cdc5 100644 --- a/src/lyrics/chartlyricsprovider.h +++ b/src/lyrics/chartlyricsprovider.h @@ -27,7 +27,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsprovider.h" #include "lyricsfetcher.h" @@ -38,7 +38,7 @@ class ChartLyricsProvider : public LyricsProvider { Q_OBJECT public: - explicit ChartLyricsProvider(SharedPtr network, QObject *parent = nullptr); + explicit ChartLyricsProvider(const SharedPtr network, QObject *parent = nullptr); ~ChartLyricsProvider() override; private: diff --git a/src/lyrics/elyricsnetlyricsprovider.cpp b/src/lyrics/elyricsnetlyricsprovider.cpp index 473064b400..1670b17621 100644 --- a/src/lyrics/elyricsnetlyricsprovider.cpp +++ b/src/lyrics/elyricsnetlyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/transliterate.h" #include "lyricssearchrequest.h" @@ -38,7 +38,7 @@ constexpr char kEndTag[] = "<\\/div>"; constexpr char kLyricsStart[] = "
"; } // namespace -ElyricsNetLyricsProvider::ElyricsNetLyricsProvider(SharedPtr network, QObject *parent) +ElyricsNetLyricsProvider::ElyricsNetLyricsProvider(const SharedPtr network, QObject *parent) : HtmlLyricsProvider(u"elyrics.net"_s, true, QLatin1String(kStartTag), QLatin1String(kEndTag), QLatin1String(kLyricsStart), false, network, parent) {} QUrl ElyricsNetLyricsProvider::Url(const LyricsSearchRequest &request) { diff --git a/src/lyrics/elyricsnetlyricsprovider.h b/src/lyrics/elyricsnetlyricsprovider.h index f1341f2ce7..ac56fd8cd3 100644 --- a/src/lyrics/elyricsnetlyricsprovider.h +++ b/src/lyrics/elyricsnetlyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" @@ -34,7 +34,7 @@ class ElyricsNetLyricsProvider : public HtmlLyricsProvider { Q_OBJECT public: - explicit ElyricsNetLyricsProvider(SharedPtr network, QObject *parent = nullptr); + explicit ElyricsNetLyricsProvider(const SharedPtr network, QObject *parent = nullptr); protected: QUrl Url(const LyricsSearchRequest &request) override; diff --git a/src/lyrics/geniuslyricsprovider.cpp b/src/lyrics/geniuslyricsprovider.cpp index 371497cfa3..223321fdac 100644 --- a/src/lyrics/geniuslyricsprovider.cpp +++ b/src/lyrics/geniuslyricsprovider.cpp @@ -45,8 +45,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/settings.h" #include "core/localredirectserver.h" @@ -68,7 +68,7 @@ constexpr char kClientIDB64[] = "RUNTNXU4U1VyMU1KUU5hdTZySEZteUxXY2hkanFiY3lfc2J constexpr char kClientSecretB64[] = "VE9pMU9vUjNtTXZ3eFR3YVN0QVRyUjVoUlhVWDI1Ylp5X240eEt1M0ZkYlNwRG5JUnd0LXFFbHdGZkZkRWY2VzJ1S011UnQzM3c2Y3hqY0tVZ3NGN2c="; } // namespace -GeniusLyricsProvider::GeniusLyricsProvider(SharedPtr network, QObject *parent) : JsonLyricsProvider(u"Genius"_s, true, true, network, parent), server_(nullptr) { +GeniusLyricsProvider::GeniusLyricsProvider(const SharedPtr network, QObject *parent) : JsonLyricsProvider(u"Genius"_s, true, true, network, parent), server_(nullptr) { Settings s; s.beginGroup(kSettingsGroup); diff --git a/src/lyrics/geniuslyricsprovider.h b/src/lyrics/geniuslyricsprovider.h index 56dcf9f925..9b34dc3741 100644 --- a/src/lyrics/geniuslyricsprovider.h +++ b/src/lyrics/geniuslyricsprovider.h @@ -34,7 +34,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "jsonlyricsprovider.h" #include "lyricssearchrequest.h" #include "lyricssearchresult.h" @@ -47,7 +47,7 @@ class GeniusLyricsProvider : public JsonLyricsProvider { Q_OBJECT public: - explicit GeniusLyricsProvider(SharedPtr network, QObject *parent = nullptr); + explicit GeniusLyricsProvider(const SharedPtr network, QObject *parent = nullptr); ~GeniusLyricsProvider() override; bool IsAuthenticated() const override { return !access_token().isEmpty(); } diff --git a/src/lyrics/htmllyricsprovider.cpp b/src/lyrics/htmllyricsprovider.cpp index 71edb3d915..db67ea0886 100644 --- a/src/lyrics/htmllyricsprovider.cpp +++ b/src/lyrics/htmllyricsprovider.cpp @@ -29,8 +29,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "htmllyricsprovider.h" @@ -38,7 +38,7 @@ using namespace Qt::Literals::StringLiterals; -HtmlLyricsProvider::HtmlLyricsProvider(const QString &name, const bool enabled, const QString &start_tag, const QString &end_tag, const QString &lyrics_start, const bool multiple, SharedPtr network, QObject *parent) +HtmlLyricsProvider::HtmlLyricsProvider(const QString &name, const bool enabled, const QString &start_tag, const QString &end_tag, const QString &lyrics_start, const bool multiple, const SharedPtr network, QObject *parent) : LyricsProvider(name, enabled, false, network, parent), start_tag_(start_tag), end_tag_(end_tag), lyrics_start_(lyrics_start), multiple_(multiple) {} HtmlLyricsProvider::~HtmlLyricsProvider() { diff --git a/src/lyrics/htmllyricsprovider.h b/src/lyrics/htmllyricsprovider.h index 4f77df6bc0..4595e820e1 100644 --- a/src/lyrics/htmllyricsprovider.h +++ b/src/lyrics/htmllyricsprovider.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "lyricsprovider.h" #include "lyricssearchrequest.h" @@ -40,7 +40,7 @@ class HtmlLyricsProvider : public LyricsProvider { Q_OBJECT public: - explicit HtmlLyricsProvider(const QString &name, const bool enabled, const QString &start_tag, const QString &end_tag, const QString &lyrics_start, const bool multiple, SharedPtr network, QObject *parent); + explicit HtmlLyricsProvider(const QString &name, const bool enabled, const QString &start_tag, const QString &end_tag, const QString &lyrics_start, const bool multiple, const SharedPtr network, QObject *parent); ~HtmlLyricsProvider(); virtual bool StartSearchAsync(const int id, const LyricsSearchRequest &request) override; diff --git a/src/lyrics/jsonlyricsprovider.cpp b/src/lyrics/jsonlyricsprovider.cpp index afd7f81ae6..f770f907ad 100644 --- a/src/lyrics/jsonlyricsprovider.cpp +++ b/src/lyrics/jsonlyricsprovider.cpp @@ -26,11 +26,11 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "jsonlyricsprovider.h" -JsonLyricsProvider::JsonLyricsProvider(const QString &name, const bool enabled, const bool authentication_required, SharedPtr network, QObject *parent) : LyricsProvider(name, enabled, authentication_required, network, parent) {} +JsonLyricsProvider::JsonLyricsProvider(const QString &name, const bool enabled, const bool authentication_required, const SharedPtr network, QObject *parent) : LyricsProvider(name, enabled, authentication_required, network, parent) {} QByteArray JsonLyricsProvider::ExtractData(QNetworkReply *reply) { diff --git a/src/lyrics/jsonlyricsprovider.h b/src/lyrics/jsonlyricsprovider.h index 58135424e5..2624c6612e 100644 --- a/src/lyrics/jsonlyricsprovider.h +++ b/src/lyrics/jsonlyricsprovider.h @@ -29,7 +29,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsprovider.h" class NetworkAccessManager; @@ -39,7 +39,7 @@ class JsonLyricsProvider : public LyricsProvider { Q_OBJECT public: - explicit JsonLyricsProvider(const QString &name, const bool enabled, const bool authentication_required, SharedPtr network, QObject *parent = nullptr); + explicit JsonLyricsProvider(const QString &name, const bool enabled, const bool authentication_required, const SharedPtr network, QObject *parent = nullptr); protected: QByteArray ExtractData(QNetworkReply *reply); diff --git a/src/lyrics/letraslyricsprovider.cpp b/src/lyrics/letraslyricsprovider.cpp index f62bd497c6..3815f1a30f 100644 --- a/src/lyrics/letraslyricsprovider.cpp +++ b/src/lyrics/letraslyricsprovider.cpp @@ -23,7 +23,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "core/logging.h" #include "utilities/transliterate.h" @@ -39,7 +39,7 @@ constexpr char kEndTag[] = "<\\/div>"; constexpr char kLyricsStart[] = "
"; } // namespace -LetrasLyricsProvider::LetrasLyricsProvider(SharedPtr network, QObject *parent) +LetrasLyricsProvider::LetrasLyricsProvider(const SharedPtr network, QObject *parent) : HtmlLyricsProvider(u"letras.mus.br"_s, true, QLatin1String(kStartTag), QLatin1String(kEndTag), QLatin1String(kLyricsStart), false, network, parent) {} QUrl LetrasLyricsProvider::Url(const LyricsSearchRequest &request) { diff --git a/src/lyrics/letraslyricsprovider.h b/src/lyrics/letraslyricsprovider.h index 0f57a30072..16b9186ea0 100644 --- a/src/lyrics/letraslyricsprovider.h +++ b/src/lyrics/letraslyricsprovider.h @@ -25,7 +25,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "core/networkaccessmanager.h" #include "htmllyricsprovider.h" #include "lyricssearchrequest.h" @@ -34,7 +34,7 @@ class LetrasLyricsProvider : public HtmlLyricsProvider { Q_OBJECT public: - explicit LetrasLyricsProvider(SharedPtr network, QObject *parent = nullptr); + explicit LetrasLyricsProvider(const SharedPtr network, QObject *parent = nullptr); protected: QUrl Url(const LyricsSearchRequest &request) override; diff --git a/src/lyrics/lololyricsprovider.cpp b/src/lyrics/lololyricsprovider.cpp index 01ac5b499c..8841a7fcb7 100644 --- a/src/lyrics/lololyricsprovider.cpp +++ b/src/lyrics/lololyricsprovider.cpp @@ -30,8 +30,8 @@ #include #include +#include "includes/shared_ptr.h" #include "core/logging.h" -#include "core/shared_ptr.h" #include "core/networkaccessmanager.h" #include "utilities/strutils.h" #include "lyricssearchrequest.h" @@ -44,7 +44,7 @@ namespace { constexpr char kUrlSearch[] = "http://api.lololyrics.com/0.5/getLyric"; } -LoloLyricsProvider::LoloLyricsProvider(SharedPtr network, QObject *parent) : LyricsProvider(u"LoloLyrics"_s, true, false, network, parent) {} +LoloLyricsProvider::LoloLyricsProvider(const SharedPtr network, QObject *parent) : LyricsProvider(u"LoloLyrics"_s, true, false, network, parent) {} LoloLyricsProvider::~LoloLyricsProvider() { diff --git a/src/lyrics/lololyricsprovider.h b/src/lyrics/lololyricsprovider.h index fdbcd825f4..fe5a44e72b 100644 --- a/src/lyrics/lololyricsprovider.h +++ b/src/lyrics/lololyricsprovider.h @@ -28,7 +28,7 @@ #include #include -#include "core/shared_ptr.h" +#include "includes/shared_ptr.h" #include "lyricsprovider.h" #include "lyricssearchrequest.h" @@ -39,7 +39,7 @@ class LoloLyricsProvider : public LyricsProvider { Q_OBJECT public: - explicit LoloLyricsProvider(SharedPtr network, QObject *parent = nullptr); + explicit LoloLyricsProvider(const SharedPtr network, QObject *parent = nullptr); ~LoloLyricsProvider() override; private: diff --git a/src/lyrics/lyricfindlyricsprovider.cpp b/src/lyrics/lyricfindlyricsprovider.cpp index 42af108b25..f6985d1fa8 100644 --- a/src/lyrics/lyricfindlyricsprovider.cpp +++ b/src/lyrics/lyricfindlyricsprovider.cpp @@ -45,7 +45,7 @@ constexpr char kLyricsStart[] = "