Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e35fbe532 | ||
|
|
b1fdccde6e | ||
|
|
6741f100a1 | ||
|
|
e05e9ea1b2 | ||
|
|
197341de5e | ||
|
|
2933482be3 | ||
|
|
c7ce23239f | ||
|
|
79115f7439 | ||
|
|
4457103672 | ||
|
|
d204875f72 | ||
|
|
c690e73b1a | ||
|
|
b5d39c5f21 | ||
|
|
7f8834cb04 | ||
|
|
0dab7e293c | ||
|
|
8f016880af | ||
|
|
f471462a84 | ||
|
|
58eec8df1e | ||
|
|
2655b8b43a | ||
|
|
ea86c043a4 | ||
|
|
c1faa616bc | ||
|
|
a68bf5a30d | ||
|
|
9568b8e0e5 | ||
|
|
b34321ef87 | ||
|
|
4971f1c5bf | ||
|
|
962b52bd5b | ||
|
|
9449bfa414 | ||
|
|
5b8e9066c6 | ||
|
|
8690be7fd2 | ||
|
|
497267016b |
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
@@ -7,7 +7,8 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
For technical issues, questions and feature suggestions/requests please use the forum on https://forum.strawberrymusicplayer.org/
|
||||
For technical issues, questions and discussion please use the forum on https://forum.strawberrymusicplayer.org/
|
||||
Any issues related to feature requests will be closed. See the README for more details.
|
||||
|
||||
Check the Changelog to see if the issue is already fixed:
|
||||
https://github.com/strawberrymusicplayer/strawberry/blob/master/Changelog
|
||||
|
||||
3
.github/workflows/ccpp.yml
vendored
3
.github/workflows/ccpp.yml
vendored
@@ -1525,6 +1525,7 @@ jobs:
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgstfdkaac.dll
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgstflac.dll
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgstgio.dll
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgsthls.dll
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgsticydemux.dll
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgstid3demux.dll
|
||||
/usr/src/strawberry-mxe/usr/x86_64-w64-mingw32.shared/bin/gstreamer-1.0/libgstisomp4.dll
|
||||
@@ -1769,6 +1770,7 @@ jobs:
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstfdkaac.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstflac.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstgio.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gsthls.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gsticydemux.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstid3demux.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstisomp4.dll .\gstreamer-plugins\
|
||||
@@ -2022,6 +2024,7 @@ jobs:
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstfdkaac.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstflac.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstgio.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gsthls.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gsticydemux.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstid3demux.dll .\gstreamer-plugins\
|
||||
copy c:\msvc_x86_64\lib\gstreamer-1.0\gstisomp4.dll .\gstreamer-plugins\
|
||||
|
||||
15
Changelog
15
Changelog
@@ -2,6 +2,21 @@ Strawberry Music Player
|
||||
=======================
|
||||
ChangeLog
|
||||
|
||||
Version 1.0.4 (2022.04.10)
|
||||
|
||||
Bugfixes:
|
||||
* Fixed use-after-free memory in ALSA PCM device finder.
|
||||
* Translate global shortcuts.
|
||||
* (Windows) Fixed registering 0-9 numpad keys in global shortcuts.
|
||||
|
||||
Enhancements
|
||||
* Added save all playlists action.
|
||||
* (Windows) Made updater support both MSVC and MinGW.
|
||||
* (Windows) Added HLS support.
|
||||
|
||||
Other:
|
||||
* Removed use of custom font in context.
|
||||
|
||||
Version 1.0.3 (2022.03.24)
|
||||
|
||||
Bugfixes:
|
||||
|
||||
@@ -23,7 +23,8 @@ Resources:
|
||||
### :bangbang: Opening an issue:
|
||||
|
||||
* Search for the issue to see if it is already solved, or if there is an open issue for it already. If there is an open issue already, you can comment on it if you have additional information that could be useful to us.
|
||||
* For technical problems, questions and feature requests please use our forum on https://forum.strawberrymusicplayer.org/ that is better suited for discussion. It also better allows answers from the community instead of just the developers on GitHub.
|
||||
* For technical problems, discussion, questions and feature suggestions use the forum (https://forum.strawberrymusicplayer.org/) instead. The forum is better suited for discussion.
|
||||
* We do not take feature requests from users on GitHub. Any issues related to feature requests will be closed. This does not necessarily mean that we won't add new features, but we don't have time to take feature requests or answer questions about new features from users. It is still possible to suggest or discuss new features on the forum (https://forum.strawberrymusicplayer.org/).
|
||||
|
||||
### :moneybag: Sponsoring:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(STRAWBERRY_VERSION_MAJOR 1)
|
||||
set(STRAWBERRY_VERSION_MINOR 0)
|
||||
set(STRAWBERRY_VERSION_PATCH 3)
|
||||
set(STRAWBERRY_VERSION_PATCH 4)
|
||||
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
||||
|
||||
set(INCLUDE_GIT_REVISION OFF)
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
<file>pictures/rainbowdash.png</file>
|
||||
<file>pictures/star-on.png</file>
|
||||
<file>pictures/star-off.png</file>
|
||||
<file>fonts/HumongousofEternitySt.ttf</file>
|
||||
<file>mood/sample.mood</file>
|
||||
<file>text/ghosts.txt</file>
|
||||
</qresource>
|
||||
|
||||
Binary file not shown.
@@ -24,6 +24,7 @@
|
||||
<file>icons/128x128/document-open-folder.png</file>
|
||||
<file>icons/128x128/document-open.png</file>
|
||||
<file>icons/128x128/document-save.png</file>
|
||||
<file>icons/128x128/document-save-all.png</file>
|
||||
<file>icons/128x128/document-search.png</file>
|
||||
<file>icons/128x128/download.png</file>
|
||||
<file>icons/128x128/edit-clear-list.png</file>
|
||||
@@ -120,6 +121,7 @@
|
||||
<file>icons/64x64/document-open-folder.png</file>
|
||||
<file>icons/64x64/document-open.png</file>
|
||||
<file>icons/64x64/document-save.png</file>
|
||||
<file>icons/64x64/document-save-all.png</file>
|
||||
<file>icons/64x64/document-search.png</file>
|
||||
<file>icons/64x64/download.png</file>
|
||||
<file>icons/64x64/edit-clear-list.png</file>
|
||||
@@ -218,6 +220,7 @@
|
||||
<file>icons/48x48/document-open-remote.png</file>
|
||||
<file>icons/48x48/document-open.png</file>
|
||||
<file>icons/48x48/document-save.png</file>
|
||||
<file>icons/48x48/document-save-all.png</file>
|
||||
<file>icons/48x48/document-search.png</file>
|
||||
<file>icons/48x48/download.png</file>
|
||||
<file>icons/48x48/edit-clear-list.png</file>
|
||||
@@ -319,6 +322,7 @@
|
||||
<file>icons/32x32/document-open-remote.png</file>
|
||||
<file>icons/32x32/document-open.png</file>
|
||||
<file>icons/32x32/document-save.png</file>
|
||||
<file>icons/32x32/document-save-all.png</file>
|
||||
<file>icons/32x32/document-search.png</file>
|
||||
<file>icons/32x32/download.png</file>
|
||||
<file>icons/32x32/edit-clear-list.png</file>
|
||||
@@ -420,6 +424,7 @@
|
||||
<file>icons/22x22/document-open-remote.png</file>
|
||||
<file>icons/22x22/document-open.png</file>
|
||||
<file>icons/22x22/document-save.png</file>
|
||||
<file>icons/22x22/document-save-all.png</file>
|
||||
<file>icons/22x22/document-search.png</file>
|
||||
<file>icons/22x22/download.png</file>
|
||||
<file>icons/22x22/edit-clear-list.png</file>
|
||||
|
||||
BIN
data/icons/128x128/document-save-all.png
Normal file
BIN
data/icons/128x128/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
BIN
data/icons/22x22/document-save-all.png
Normal file
BIN
data/icons/22x22/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 921 B |
BIN
data/icons/32x32/document-save-all.png
Normal file
BIN
data/icons/32x32/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
data/icons/48x48/document-save-all.png
Normal file
BIN
data/icons/48x48/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
data/icons/64x64/document-save-all.png
Normal file
BIN
data/icons/64x64/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
data/icons/full/document-save-all.png
Normal file
BIN
data/icons/full/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
145
debian/copyright
vendored
145
debian/copyright
vendored
@@ -1,10 +1,11 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: strawberry
|
||||
Upstream-Contact: Jonas Kvinge <jonas@jkvinge.net>
|
||||
Source: https://www.strawberrymusicplayer.org/
|
||||
Source: https://github.com/strawberrymusicplayer/strawberry
|
||||
|
||||
Files: *
|
||||
Copyright: 2010-2015, David Sansome <me@davidsansome.com>
|
||||
2012-2014, 2017-2022 Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/timeconstants.h
|
||||
@@ -13,14 +14,13 @@ Files: src/core/timeconstants.h
|
||||
ext/libstrawberry-common/core/messagehandler.cpp
|
||||
ext/libstrawberry-common/core/messagehandler.h
|
||||
Copyright: 2011, 2012, David Sansome <me@davidsansome.com>
|
||||
2018-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: Apache-2.0
|
||||
|
||||
Files: src/core/main.h
|
||||
src/core/iconloader.cpp
|
||||
src/core/iconloader.h
|
||||
src/core/iconmapper.h
|
||||
src/config.h.in
|
||||
src/version.h.in
|
||||
src/context/contextview.cpp
|
||||
src/context/contextview.h
|
||||
src/context/contextalbum.cpp
|
||||
@@ -29,6 +29,8 @@ Files: src/core/main.h
|
||||
src/engine/enginetype.h
|
||||
src/engine/alsadevicefinder.cpp
|
||||
src/engine/alsadevicefinder.h
|
||||
src/engine/alsapcmdevicefinder.cpp
|
||||
src/engine/alsapcmdevicefinder.h
|
||||
src/engine/mmdevicefinder.cpp
|
||||
src/engine/mmdevicefinder.h
|
||||
src/engine/devicefinder.cpp
|
||||
@@ -69,8 +71,14 @@ Files: src/core/main.h
|
||||
src/covermanager/spotifycoverprovider.h
|
||||
src/covermanager/musixmatchcoverprovider.cpp
|
||||
src/covermanager/musixmatchcoverprovider.h
|
||||
src/globalshortcuts/globalshortcutsbackend-system.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-system.h
|
||||
src/globalshortcuts/globalshortcutsbackend-kde.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-kde.h
|
||||
src/globalshortcuts/globalshortcutsbackend-mate.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-mate.h
|
||||
src/globalshortcuts/globalshortcutsbackend-x11.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-x11.h
|
||||
src/globalshortcuts/globalshortcutsbackend-win.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-win.h
|
||||
src/globalshortcuts/globalshortcut.cpp
|
||||
src/globalshortcuts/globalshortcut.h
|
||||
src/globalshortcuts/globalshortcut-X11.cpp
|
||||
@@ -81,127 +89,14 @@ Files: src/core/main.h
|
||||
src/scrobbler/*
|
||||
src/subsonic/*
|
||||
src/tidal/*
|
||||
src/qobuz/*
|
||||
src/radios/*
|
||||
src/transcoder/transcoderoptionswavpack.cpp
|
||||
src/transcoder/transcoderoptionswavpack.h
|
||||
Copyright: 2012-2014, 2017-2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/main.cpp
|
||||
src/core/mainwindow.cpp
|
||||
src/core/mainwindow.h
|
||||
src/core/player.cpp
|
||||
src/core/player.h
|
||||
src/core/song.cpp
|
||||
src/core/song.h
|
||||
src/core/songloader.cpp
|
||||
src/core/songloader.h
|
||||
src/core/urlhandler.cpp
|
||||
src/core/urlhandler.h
|
||||
src/core/utilities.cpp
|
||||
src/core/utilities.h
|
||||
src/core/networkaccessmanager.cpp
|
||||
src/core/networkaccessmanager.h
|
||||
src/core/threadsafenetworkdiskcache.cpp
|
||||
src/core/threadsafenetworkdiskcache.h
|
||||
src/core/filesystemmusicstorage.cpp
|
||||
src/core/filesystemmusicstorage.h
|
||||
src/core/stylesheetloader.cpp
|
||||
src/core/stylesheetloader.h
|
||||
src/engine/gstenginepipeline.cpp
|
||||
src/engine/gstenginepipeline.h
|
||||
src/engine/vlcengine.cpp
|
||||
src/engine/vlcengine.h
|
||||
src/collection/collectionwatcher.cpp
|
||||
src/collection/collectionwatcher.h
|
||||
src/collection/collectionbackend.cpp
|
||||
src/collection/collectionbackend.h
|
||||
src/collection/collectionmodel.cpp
|
||||
src/collection/collectionmodel.h
|
||||
src/context/contextalbumsmodel.cpp
|
||||
src/context/contextalbumsview.cpp
|
||||
src/context/contextalbumsmodel.h
|
||||
src/context/contextalbumsview.h
|
||||
src/widgets/playingwidget.cpp
|
||||
src/widgets/playingwidget.h
|
||||
src/osd/osdbase.cpp
|
||||
src/osd/osdbase.h
|
||||
src/osd/osdpretty.cpp
|
||||
src/osd/osdpretty.h
|
||||
src/osd/osddbus.cpp
|
||||
src/osd/osddbus.h
|
||||
src/osd/osdmac.cpp
|
||||
src/osd/osdmac.h
|
||||
src/dialogs/about.cpp
|
||||
src/dialogs/about.h
|
||||
src/playlist/playlist.cpp
|
||||
src/playlist/playlist.h
|
||||
src/playlist/playlistitem.cpp
|
||||
src/playlist/playlistitem.h
|
||||
src/playlist/playlistdelegates.cpp
|
||||
src/playlist/playlistdelegates.h
|
||||
src/playlist/playlistbackend.cpp
|
||||
src/playlist/playlistbackend.h
|
||||
src/playlist/playlistview.cpp
|
||||
src/playlist/playlistview.h
|
||||
src/playlist/songplaylistitem.cpp
|
||||
src/playlist/songplaylistitem.h
|
||||
src/internet/internetplaylistitem.cpp
|
||||
src/internet/internetsearch.cpp
|
||||
src/internet/internetsearch.h
|
||||
src/internet/internetsearchview.cpp
|
||||
src/internet/internetsearchview.h
|
||||
src/internet/internetservices.cpp
|
||||
src/internet/internetservices.h
|
||||
src/internet/internetsongsview.cpp
|
||||
src/internet/internetsongsview.h
|
||||
src/internet/internetcollectionview.cpp
|
||||
src/internet/internetcollectionview.h
|
||||
ext/libstrawberry-tagreader/tagreader.cpp
|
||||
ext/libstrawberry-tagreader/tagreader.h
|
||||
src/device/devicemanager.cpp
|
||||
src/device/devicemanager.h
|
||||
src/device/deviceinfo.cpp
|
||||
src/device/deviceinfo.h
|
||||
src/device/deviceproperties.cpp
|
||||
src/device/deviceproperties.h
|
||||
src/device/deviceview.cpp
|
||||
src/device/deviceview.h
|
||||
src/device/connecteddevice.cpp
|
||||
src/device/connecteddevice.h
|
||||
src/device/mtpconnection.cpp
|
||||
src/device/mtpconnection.h
|
||||
src/device/mtpdevice.cpp
|
||||
src/device/mtpdevice.h
|
||||
src/globalshortcuts/globalshortcutsmanager.cpp
|
||||
src/globalshortcuts/globalshortcutsmanager.h
|
||||
src/settings/shortcutssettingspage.cpp
|
||||
src/settings/shortcutssettingspage.h
|
||||
src/settings/appearancesettingspage.cpp
|
||||
src/settings/appearancesettingspage.h
|
||||
src/organize/organize.cpp
|
||||
src/organize/organize.h
|
||||
src/organize/organizedialog.cpp
|
||||
src/organize/organizedialog.h
|
||||
src/organize/organizeerrordialog.cpp
|
||||
src/organize/organizeerrordialog.h
|
||||
src/transcoder/transcoder.cpp
|
||||
src/transcoder/transcoder.h
|
||||
src/musicbrainz/musicbrainzclient.cpp
|
||||
src/musicbrainz/musicbrainzclient.h
|
||||
src/covermanager/albumcoverloader.cpp
|
||||
src/covermanager/albumcoverloader.h
|
||||
src/covermanager/currentalbumcoverloader.cpp
|
||||
src/covermanager/currentalbumcoverloader.h
|
||||
src/covermanager/albumcoverchoicecontroller.cpp
|
||||
src/covermanager/albumcoverchoicecontroller.h
|
||||
src/covermanager/albumcoverfetchersearch.cpp
|
||||
src/covermanager/albumcoverfetchersearch.h
|
||||
src/covermanager/coverproviders.cpp
|
||||
src/covermanager/coverproviders.h
|
||||
src/covermanager/coverprovider.cpp
|
||||
src/covermanager/coverprovider.h
|
||||
Copyright: 2010, 2012-2014 David Sansome <me@davidsansome.com>
|
||||
2012-2014, 2017-2020 Jonas Kvinge <jonas@jkvinge.net>
|
||||
ext/libstrawberry-tagreader/tagreadertagparser.cpp
|
||||
ext/libstrawberry-tagreader/tagreadertagparser.h
|
||||
ext/macdeploycheck/*
|
||||
Copyright: 2012-2014, 2017-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/engine/enginebase.cpp
|
||||
@@ -367,7 +262,7 @@ Copyright: 2010, Spotify AB
|
||||
License: BSD-3-clause
|
||||
|
||||
Files: 3rdparty/singleapplication/*
|
||||
Copyright: 2015-2018, Itay Grudev
|
||||
Copyright: 2015-2022, Itay Grudev
|
||||
License: MIT
|
||||
|
||||
|
||||
|
||||
6
debian/copyright-scan-patterns.yml
vendored
6
debian/copyright-scan-patterns.yml
vendored
@@ -4,14 +4,14 @@ ignore:
|
||||
- Changelog
|
||||
- COPYING
|
||||
- CMakeLists.txt
|
||||
- Dockerfile
|
||||
- cmake_uninstall.cmake.in
|
||||
- .clang-format
|
||||
- .gitignore
|
||||
- .travis.yml
|
||||
- .github
|
||||
- /debian/
|
||||
- /cmake/
|
||||
- /data/
|
||||
- /dist/
|
||||
- /snap/
|
||||
|
||||
suffixes:
|
||||
- jpg
|
||||
|
||||
14
dist/windows/strawberry.nsi.in
vendored
14
dist/windows/strawberry.nsi.in
vendored
@@ -281,7 +281,7 @@ Section "Strawberry" Strawberry
|
||||
File "libpcre-1.dll"
|
||||
File "libpcre2-16-0.dll"
|
||||
File "libpng16-16.dll"
|
||||
File "libprotobuf-30.dll"
|
||||
File "libprotobuf-31.dll"
|
||||
File "libpsl-5.dll"
|
||||
File "libqtsparkle-qt6.dll"
|
||||
File "libsoup-2.4-1.dll"
|
||||
@@ -385,12 +385,14 @@ Section "Strawberry" Strawberry
|
||||
File "libpng16.dll"
|
||||
File "libprotobuf.dll"
|
||||
File "libxml2.dll"
|
||||
File "pcre2-16.dll"
|
||||
File "zlib.dll"
|
||||
!endif
|
||||
!ifdef debug
|
||||
File "libpng16d.dll"
|
||||
File "libprotobufd.dll"
|
||||
File "libxml2d.dll"
|
||||
File "pcre2-16d.dll"
|
||||
File "zlibd.dll"
|
||||
!endif
|
||||
|
||||
@@ -536,6 +538,7 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=libgstfdkaac.dll" "gstreamer-plugins\libgstfdkaac.dll"
|
||||
File "/oname=libgstflac.dll" "gstreamer-plugins\libgstflac.dll"
|
||||
File "/oname=libgstgio.dll" "gstreamer-plugins\libgstgio.dll"
|
||||
File "/oname=libgsthls.dll" "gstreamer-plugins\libgsthls.dll"
|
||||
File "/oname=libgsticydemux.dll" "gstreamer-plugins\libgsticydemux.dll"
|
||||
File "/oname=libgstid3demux.dll" "gstreamer-plugins\libgstid3demux.dll"
|
||||
File "/oname=libgstisomp4.dll" "gstreamer-plugins\libgstisomp4.dll"
|
||||
@@ -591,6 +594,7 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=gstfdkaac.dll" "gstreamer-plugins\gstfdkaac.dll"
|
||||
File "/oname=gstflac.dll" "gstreamer-plugins\gstflac.dll"
|
||||
File "/oname=gstgio.dll" "gstreamer-plugins\gstgio.dll"
|
||||
File "/oname=gsthls.dll" "gstreamer-plugins\gsthls.dll"
|
||||
File "/oname=gsticydemux.dll" "gstreamer-plugins\gsticydemux.dll"
|
||||
File "/oname=gstid3demux.dll" "gstreamer-plugins\gstid3demux.dll"
|
||||
File "/oname=gstisomp4.dll" "gstreamer-plugins\gstisomp4.dll"
|
||||
@@ -614,7 +618,7 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=gstvolume.dll" "gstreamer-plugins\gstvolume.dll"
|
||||
File "/oname=gstvorbis.dll" "gstreamer-plugins\gstvorbis.dll"
|
||||
File "/oname=gstwasapi.dll" "gstreamer-plugins\gstwasapi.dll"
|
||||
File "/oname=gstwasapi2.dll" "gstreamer-plugins\gstwasapi2.dll"
|
||||
;File "/oname=gstwasapi2.dll" "gstreamer-plugins\gstwasapi2.dll"
|
||||
File "/oname=gstwavpack.dll" "gstreamer-plugins\gstwavpack.dll"
|
||||
File "/oname=gstwavparse.dll" "gstreamer-plugins\gstwavparse.dll"
|
||||
File "/oname=gstxingmux.dll" "gstreamer-plugins\gstxingmux.dll"
|
||||
@@ -741,7 +745,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\libpcre-1.dll"
|
||||
Delete "$INSTDIR\libpcre2-16-0.dll"
|
||||
Delete "$INSTDIR\libpng16-16.dll"
|
||||
Delete "$INSTDIR\libprotobuf-30.dll"
|
||||
Delete "$INSTDIR\libprotobuf-31.dll"
|
||||
Delete "$INSTDIR\libpsl-5.dll"
|
||||
Delete "$INSTDIR\libqtsparkle-qt6.dll"
|
||||
Delete "$INSTDIR\libsoup-2.4-1.dll"
|
||||
@@ -846,12 +850,14 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\libpng16.dll"
|
||||
Delete "$INSTDIR\libprotobuf.dll"
|
||||
Delete "$INSTDIR\libxml2.dll"
|
||||
Delete "$INSTDIR\pcre2-16.dll"
|
||||
Delete "$INSTDIR\zlib.dll"
|
||||
!endif
|
||||
!ifdef debug
|
||||
Delete "$INSTDIR\libpng16d.dll"
|
||||
Delete "$INSTDIR\libprotobufd.dll"
|
||||
Delete "$INSTDIR\libxml2d.dll"
|
||||
Delete "$INSTDIR\pcre2-16d.dll"
|
||||
Delete "$INSTDIR\zlibd.dll"
|
||||
!endif
|
||||
|
||||
@@ -930,6 +936,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstfdkaac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstflac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstgio.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsthls.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsticydemux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstid3demux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstisomp4.dll"
|
||||
@@ -987,6 +994,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstfdkaac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstflac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstgio.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsthls.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsticydemux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstid3demux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstisomp4.dll"
|
||||
|
||||
@@ -997,7 +997,7 @@ bool TagReaderTagLib::SaveEmbeddedArt(const QString &filename, const QByteArray
|
||||
frontcover = new TagLib::ID3v2::AttachedPictureFrame("APIC");
|
||||
frontcover->setType(TagLib::ID3v2::AttachedPictureFrame::FrontCover);
|
||||
frontcover->setMimeType("image/jpeg");
|
||||
frontcover->setPicture(TagLib::ByteVector(data.constData(), data.count()));
|
||||
frontcover->setPicture(TagLib::ByteVector(data.constData(), data.size()));
|
||||
tag->addFrame(frontcover);
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1011,7 @@ bool TagReaderTagLib::SaveEmbeddedArt(const QString &filename, const QByteArray
|
||||
if (tag->contains("covr")) tag->removeItem("covr");
|
||||
}
|
||||
else {
|
||||
covers.append(TagLib::MP4::CoverArt(TagLib::MP4::CoverArt::JPEG, TagLib::ByteVector(data.constData(), data.count())));
|
||||
covers.append(TagLib::MP4::CoverArt(TagLib::MP4::CoverArt::JPEG, TagLib::ByteVector(data.constData(), data.size())));
|
||||
tag->setItem("covr", covers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
#include <QVector>
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
#include <QBasicTimer>
|
||||
#include <QShowEvent>
|
||||
#include <QHideEvent>
|
||||
#include <QTimerEvent>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "core/logging.h"
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
// INSTRUCTIONS Base2D
|
||||
@@ -51,16 +52,34 @@
|
||||
|
||||
Analyzer::Base::Base(QWidget *parent, const uint scopeSize)
|
||||
: QWidget(parent),
|
||||
timeout_(40),
|
||||
fht_(new FHT(scopeSize)),
|
||||
engine_(nullptr),
|
||||
lastscope_(512),
|
||||
new_frame_(false),
|
||||
is_playing_(false) {}
|
||||
is_playing_(false),
|
||||
timeout_(40) {}
|
||||
|
||||
void Analyzer::Base::hideEvent(QHideEvent*) { timer_.stop(); }
|
||||
Analyzer::Base::~Base() {
|
||||
delete fht_;
|
||||
}
|
||||
|
||||
void Analyzer::Base::showEvent(QShowEvent*) { timer_.start(timeout(), this); }
|
||||
void Analyzer::Base::showEvent(QShowEvent*) {
|
||||
timer_.start(timeout(), this);
|
||||
}
|
||||
|
||||
void Analyzer::Base::hideEvent(QHideEvent*) {
|
||||
timer_.stop();
|
||||
}
|
||||
|
||||
void Analyzer::Base::ChangeTimeout(const int timeout) {
|
||||
|
||||
timeout_ = timeout;
|
||||
if (timer_.isActive()) {
|
||||
timer_.stop();
|
||||
timer_.start(timeout_, this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Analyzer::Base::transform(Scope &scope) {
|
||||
|
||||
@@ -186,10 +205,6 @@ void Analyzer::Base::demo(QPainter &p) {
|
||||
|
||||
}
|
||||
|
||||
void Analyzer::Base::polishEvent() {
|
||||
init();
|
||||
}
|
||||
|
||||
void Analyzer::interpolate(const Scope &inVec, Scope &outVec) {
|
||||
|
||||
double pos = 0.0;
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
|
||||
class QHideEvent;
|
||||
class QShowEvent;
|
||||
class QTimerEvent;
|
||||
class QPaintEvent;
|
||||
class QTimerEvent;
|
||||
|
||||
namespace Analyzer {
|
||||
|
||||
@@ -55,19 +55,13 @@ class Base : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~Base() override { delete fht_; }
|
||||
~Base() override;
|
||||
|
||||
int timeout() const { return timeout_; }
|
||||
|
||||
void set_engine(EngineBase *engine) { engine_ = engine; }
|
||||
|
||||
void changeTimeout(int newTimeout) {
|
||||
timeout_ = newTimeout;
|
||||
if (timer_.isActive()) {
|
||||
timer_.stop();
|
||||
timer_.start(timeout_, this);
|
||||
}
|
||||
}
|
||||
void ChangeTimeout(const int timeout);
|
||||
|
||||
virtual void framerateChanged() {}
|
||||
|
||||
@@ -76,10 +70,8 @@ class Base : public QWidget {
|
||||
|
||||
void hideEvent(QHideEvent*) override;
|
||||
void showEvent(QShowEvent*) override;
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
void timerEvent(QTimerEvent*) override;
|
||||
|
||||
void polishEvent();
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
|
||||
int resizeExponent(int);
|
||||
int resizeForBands(const int);
|
||||
@@ -90,13 +82,13 @@ class Base : public QWidget {
|
||||
|
||||
protected:
|
||||
QBasicTimer timer_;
|
||||
int timeout_;
|
||||
FHT *fht_;
|
||||
EngineBase *engine_;
|
||||
Scope lastscope_;
|
||||
|
||||
bool new_frame_;
|
||||
bool is_playing_;
|
||||
int timeout_;
|
||||
};
|
||||
|
||||
void interpolate(const Scope&, Scope&);
|
||||
|
||||
@@ -153,7 +153,7 @@ void AnalyzerContainer::ChangeAnalyzer(const int id) {
|
||||
current_analyzer_->set_engine(engine_);
|
||||
// Even if it is not supposed to happen, I don't want to get a dbz error
|
||||
current_framerate_ = current_framerate_ == 0 ? kMediumFramerate : current_framerate_;
|
||||
current_analyzer_->changeTimeout(1000 / current_framerate_);
|
||||
current_analyzer_->ChangeTimeout(1000 / current_framerate_);
|
||||
|
||||
layout()->addWidget(current_analyzer_);
|
||||
|
||||
@@ -166,7 +166,7 @@ void AnalyzerContainer::ChangeFramerate(int new_framerate) {
|
||||
if (current_analyzer_) {
|
||||
// Even if it is not supposed to happen, I don't want to get a dbz error
|
||||
new_framerate = new_framerate == 0 ? kMediumFramerate : new_framerate;
|
||||
current_analyzer_->changeTimeout(1000 / new_framerate);
|
||||
current_analyzer_->ChangeTimeout(1000 / new_framerate);
|
||||
|
||||
// notify the current analyzer that the framerate has changed
|
||||
current_analyzer_->framerateChanged();
|
||||
|
||||
@@ -286,8 +286,6 @@ ContextView::ContextView(QWidget *parent)
|
||||
|
||||
labels_play_all_ = labels_play_ << labels_play_data_;
|
||||
|
||||
QFontDatabase::addApplicationFont(":/fonts/HumongousofEternitySt.ttf");
|
||||
|
||||
QObject::connect(widget_album_, &ContextAlbum::FadeStopFinished, this, &ContextView::FadeStopFinished);
|
||||
|
||||
}
|
||||
@@ -458,7 +456,7 @@ void ContextView::NoSong() {
|
||||
widget_album_->show();
|
||||
}
|
||||
|
||||
label_top_->setStyleSheet("font: 20pt \"Humongous of Eternity St\"; font-weight: Regular;");
|
||||
label_top_->setStyleSheet("font: 20pt 'Open Sans', 'FreeSans', 'FreeSerif', 'Liberation Serif'; font-weight: Regular;");
|
||||
|
||||
label_top_->setText(tr("No song playing"));
|
||||
|
||||
|
||||
@@ -221,6 +221,18 @@ const int kTrackSliderUpdateTimeMs = 200;
|
||||
const int kTrackPositionUpdateTimeMs = 1000;
|
||||
} // namespace
|
||||
|
||||
#ifdef HAVE_QTSPARKLE
|
||||
# ifdef _MSC_VER
|
||||
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-msvc-x64";
|
||||
# else
|
||||
# ifdef __x86_64__
|
||||
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x64";
|
||||
# else
|
||||
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x86";
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_icon, OSDBase *osd, const CommandlineOptions &options, QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
ui_(new Ui_MainWindow),
|
||||
@@ -446,6 +458,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
ui_->action_remove_duplicates->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_remove_unavailable->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_remove_from_playlist->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_save_all_playlists->setIcon(IconLoader::Load("document-save-all"));
|
||||
|
||||
// Configure
|
||||
|
||||
@@ -551,8 +564,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
ui_->button_scrobble->setDefaultAction(ui_->action_toggle_scrobbling);
|
||||
ui_->button_love->setDefaultAction(ui_->action_love);
|
||||
|
||||
ui_->playlist->SetActions(ui_->action_new_playlist, ui_->action_load_playlist, ui_->action_save_playlist, ui_->action_clear_playlist, ui_->action_next_playlist, /* These two actions aren't associated */ ui_->action_previous_playlist /* to a button but to the main window */ );
|
||||
|
||||
ui_->playlist->SetActions(ui_->action_new_playlist, ui_->action_load_playlist, ui_->action_save_playlist, ui_->action_clear_playlist, ui_->action_next_playlist, /* These two actions aren't associated */ ui_->action_previous_playlist /* to a button but to the main window */, ui_->action_save_all_playlists);
|
||||
// Add the shuffle and repeat action groups to the menu
|
||||
ui_->action_shuffle_mode->setMenu(ui_->playlist_sequence->shuffle_menu());
|
||||
ui_->action_repeat_mode->setMenu(ui_->playlist_sequence->repeat_menu());
|
||||
@@ -1000,12 +1012,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
}
|
||||
|
||||
#ifdef HAVE_QTSPARKLE
|
||||
QUrl sparkle_url;
|
||||
# if defined(Q_OS_MACOS)
|
||||
sparkle_url.setUrl("https://www.strawberrymusicplayer.org/sparkle-macos");
|
||||
# elif defined(Q_OS_WIN)
|
||||
sparkle_url.setUrl("https://www.strawberrymusicplayer.org/sparkle-windows");
|
||||
# endif
|
||||
QUrl sparkle_url(QTSPARKLE_URL);
|
||||
if (!sparkle_url.isEmpty()) {
|
||||
qLog(Debug) << "Creating Qt Sparkle updater";
|
||||
qtsparkle::Updater *updater = new qtsparkle::Updater(sparkle_url, this);
|
||||
|
||||
@@ -483,6 +483,7 @@
|
||||
<addaction name="action_new_playlist"/>
|
||||
<addaction name="action_save_playlist"/>
|
||||
<addaction name="action_load_playlist"/>
|
||||
<addaction name="action_save_all_playlists"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_jump"/>
|
||||
<addaction name="action_clear_playlist"/>
|
||||
@@ -747,6 +748,11 @@
|
||||
<string>Ctrl+Shift+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_save_all_playlists">
|
||||
<property name="text">
|
||||
<string>&Save all playlists</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_next_playlist">
|
||||
<property name="text">
|
||||
<string>Go to next playlist tab</string>
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
// Use these to convert between time units
|
||||
const qint64 kMsecPerSec = 1000ll;
|
||||
const qint64 kUsecPerMsec = 1000ll;
|
||||
const qint64 kUsecPerSec = 1000000ll;
|
||||
const qint64 kNsecPerUsec = 1000ll;
|
||||
const qint64 kNsecPerMsec = 1000000ll;
|
||||
const qint64 kNsecPerSec = 1000000000ll;
|
||||
constexpr qint64 kMsecPerSec = 1000ll;
|
||||
constexpr qint64 kUsecPerMsec = 1000ll;
|
||||
constexpr qint64 kUsecPerSec = 1000000ll;
|
||||
constexpr qint64 kNsecPerUsec = 1000ll;
|
||||
constexpr qint64 kNsecPerMsec = 1000000ll;
|
||||
constexpr qint64 kNsecPerSec = 1000000000ll;
|
||||
|
||||
const qint64 kSecsPerDay = 24 * 60 * 60;
|
||||
constexpr qint64 kSecsPerDay = 24 * 60 * 60;
|
||||
|
||||
#endif // TIMECONSTANTS_H
|
||||
|
||||
@@ -45,14 +45,16 @@ QList<DeviceFinder::Device> AlsaPCMDeviceFinder::ListDevices() {
|
||||
}
|
||||
|
||||
for (void **n = hints; *n; ++n) {
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *desc = snd_device_name_get_hint(*n, "DESC");
|
||||
if (io && name && desc && strcmp(io, "Output") == 0) {
|
||||
char *hint_io = snd_device_name_get_hint(*n, "IOID");
|
||||
char *hint_name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *hint_desc = snd_device_name_get_hint(*n, "DESC");
|
||||
if (hint_io && hint_name && hint_desc && strcmp(hint_io, "Output") == 0) {
|
||||
|
||||
char *desc_last = desc;
|
||||
QString name(hint_name);
|
||||
|
||||
char *desc_last = hint_desc;
|
||||
QString description;
|
||||
for (char *desc_i = desc; desc_i && *desc_i != '\0'; ++desc_i) {
|
||||
for (char *desc_i = hint_desc; desc_i && *desc_i != '\0'; ++desc_i) {
|
||||
if (*desc_i == '\n') {
|
||||
*desc_i = '\0';
|
||||
if (!description.isEmpty()) description.append(' ');
|
||||
@@ -72,9 +74,9 @@ QList<DeviceFinder::Device> AlsaPCMDeviceFinder::ListDevices() {
|
||||
device.iconname = GuessIconName(device.description);
|
||||
ret << device; // clazy:exclude=reserve-candidates
|
||||
}
|
||||
if (io) free(io);
|
||||
if (name) free(name);
|
||||
if (desc) free(desc);
|
||||
if (hint_io) free(hint_io);
|
||||
if (hint_name) free(hint_name);
|
||||
if (hint_desc) free(hint_desc);
|
||||
}
|
||||
|
||||
snd_device_name_free_hint(hints);
|
||||
|
||||
@@ -698,6 +698,9 @@ GstEngine::PluginDetailsList GstEngine::GetPluginList(const QString &classname)
|
||||
PluginDetails details;
|
||||
details.name = QString::fromUtf8(gst_plugin_feature_get_name(p->data));
|
||||
details.description = QString::fromUtf8(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_DESCRIPTION));
|
||||
if (details.name == "wasapi2sink" && details.description == "Stream audio to an audio capture device through WASAPI") {
|
||||
details.description += " 2";
|
||||
}
|
||||
ret << details;
|
||||
//qLog(Debug) << details.name << details.description;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
#include "globalshortcut.h"
|
||||
#include "keymapper_win.h"
|
||||
|
||||
int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
|
||||
#include "core/logging.h"
|
||||
|
||||
int GlobalShortcut::nativeModifiers(const Qt::KeyboardModifiers qt_mods) {
|
||||
|
||||
int native_mods = 0;
|
||||
if (qt_mods & Qt::ShiftModifier) native_mods |= MOD_SHIFT;
|
||||
@@ -36,22 +38,57 @@ int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
|
||||
|
||||
}
|
||||
|
||||
int GlobalShortcut::nativeKeycode(Qt::Key qt_key) {
|
||||
int GlobalShortcut::nativeKeycode(const Qt::Key qt_keycode) {
|
||||
|
||||
int key_code = 0;
|
||||
if (KeyMapperWin::keymapper_win_.contains(qt_key)) {
|
||||
key_code = KeyMapperWin::keymapper_win_.value(qt_key);
|
||||
if (KeyMapperWin::keymapper_win_.contains(qt_keycode)) {
|
||||
key_code = KeyMapperWin::keymapper_win_.value(qt_keycode);
|
||||
}
|
||||
return key_code;
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcut::registerShortcut(int native_key, int native_mods) {
|
||||
return RegisterHotKey(0, native_mods ^ native_key, native_mods, native_key);
|
||||
int GlobalShortcut::nativeKeycode2(const Qt::Key qt_keycode) {
|
||||
|
||||
switch (qt_keycode) {
|
||||
case Qt::Key_0:
|
||||
return VK_NUMPAD0;
|
||||
case Qt::Key_1:
|
||||
return VK_NUMPAD1;
|
||||
case Qt::Key_2:
|
||||
return VK_NUMPAD2;
|
||||
case Qt::Key_3:
|
||||
return VK_NUMPAD3;
|
||||
case Qt::Key_4:
|
||||
return VK_NUMPAD4;
|
||||
case Qt::Key_5:
|
||||
return VK_NUMPAD5;
|
||||
case Qt::Key_6:
|
||||
return VK_NUMPAD6;
|
||||
case Qt::Key_7:
|
||||
return VK_NUMPAD7;
|
||||
case Qt::Key_8:
|
||||
return VK_NUMPAD8;
|
||||
case Qt::Key_9:
|
||||
return VK_NUMPAD9;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcut::unregisterShortcut(int native_key, int native_mods) {
|
||||
bool GlobalShortcut::registerShortcut(const int native_key, const int native_mods) {
|
||||
|
||||
return RegisterHotKey(0, native_mods ^ native_key, native_mods, native_key);
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcut::unregisterShortcut(const int native_key, const int native_mods) {
|
||||
|
||||
return UnregisterHotKey(0, native_mods ^ native_key);
|
||||
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
@@ -69,6 +106,7 @@ bool GlobalShortcut::nativeEventFilter(const QByteArray &eventtype, void *messag
|
||||
quint32 key_code = HIWORD(msg->lParam);
|
||||
quint32 modifiers = LOWORD(msg->lParam);
|
||||
activateShortcut(key_code, modifiers);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ quint32 AppRootWindow() {
|
||||
|
||||
} // namespace
|
||||
|
||||
int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
|
||||
int GlobalShortcut::nativeModifiers(const Qt::KeyboardModifiers qt_mods) {
|
||||
|
||||
int native_mods = 0;
|
||||
if (qt_mods & Qt::ShiftModifier) native_mods |= ShiftMask;
|
||||
@@ -130,41 +130,43 @@ int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
|
||||
|
||||
}
|
||||
|
||||
int GlobalShortcut::nativeKeycode(Qt::Key qt_key) {
|
||||
int GlobalShortcut::nativeKeycode(const Qt::Key qt_keycode) {
|
||||
|
||||
Display *disp = X11Display();
|
||||
if (!disp) return false;
|
||||
|
||||
quint32 keysym = 0;
|
||||
if (KeyMapperX11::keymapper_x11_.contains(qt_key)) {
|
||||
keysym = KeyMapperX11::keymapper_x11_.value(qt_key);
|
||||
if (KeyMapperX11::keymapper_x11_.contains(qt_keycode)) {
|
||||
keysym = KeyMapperX11::keymapper_x11_.value(qt_keycode);
|
||||
}
|
||||
else {
|
||||
keysym = XStringToKeysym(QKeySequence(qt_key).toString().toLatin1().data());
|
||||
keysym = XStringToKeysym(QKeySequence(qt_keycode).toString().toLatin1().data());
|
||||
if (keysym == NoSymbol) return 0;
|
||||
}
|
||||
return XKeysymToKeycode(disp, keysym);
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcut::registerShortcut(int native_key, int native_mods) {
|
||||
int GlobalShortcut::nativeKeycode2(const Qt::Key) { return 0; }
|
||||
|
||||
bool GlobalShortcut::registerShortcut(const int native_key, const int native_mods) {
|
||||
|
||||
Display *disp = X11Display();
|
||||
if (!disp) return false;
|
||||
|
||||
for (quint32 mask_mods : mask_modifiers_) {
|
||||
for (const quint32 mask_mods : mask_modifiers_) {
|
||||
XGrabKey(disp, native_key, (native_mods | mask_mods), AppRootWindow(), True, GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcut::unregisterShortcut(int native_key, int native_mods) {
|
||||
bool GlobalShortcut::unregisterShortcut(const int native_key, const int native_mods) {
|
||||
|
||||
Display *disp = X11Display();
|
||||
if (!disp) return false;
|
||||
|
||||
for (quint32 mask_mods : mask_modifiers_) {
|
||||
for (const quint32 mask_mods : mask_modifiers_) {
|
||||
XUngrabKey(disp, native_key, native_mods | mask_mods, AppRootWindow());
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -44,6 +44,7 @@ GlobalShortcut::GlobalShortcut(QObject *parent)
|
||||
qt_key_(Qt::Key(0)),
|
||||
qt_mods_(Qt::NoModifier),
|
||||
native_key_(0),
|
||||
native_key2_(0),
|
||||
native_mods_(0) {
|
||||
|
||||
Q_ASSERT(!initialized_);
|
||||
@@ -60,6 +61,7 @@ GlobalShortcut::GlobalShortcut(const QKeySequence &shortcut, GlobalShortcutsBack
|
||||
qt_key_(Qt::Key(0)),
|
||||
qt_mods_(Qt::NoModifier),
|
||||
native_key_(0),
|
||||
native_key2_(0),
|
||||
native_mods_(0) {
|
||||
|
||||
Q_ASSERT(initialized_);
|
||||
@@ -100,16 +102,20 @@ bool GlobalShortcut::setShortcut(const QKeySequence &shortcut) {
|
||||
if (native_key_ == 0) return false;
|
||||
native_mods_ = nativeModifiers(qt_mods_);
|
||||
|
||||
bool result = registerShortcut(native_key_, native_mods_);
|
||||
if (result) {
|
||||
bool success = registerShortcut(native_key_, native_mods_);
|
||||
if (success) {
|
||||
internal_shortcuts_.insert(qMakePair(native_key_, native_mods_), this);
|
||||
qLog(Info) << "Registered shortcut" << shortcut_.toString();
|
||||
native_key2_ = nativeKeycode2(qt_key_);
|
||||
if (native_key2_ > 0 && registerShortcut(native_key2_, native_mods_)) {
|
||||
internal_shortcuts_.insert(qMakePair(native_key2_, native_mods_), this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qLog(Error) << "Failed to register shortcut" << shortcut_.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
@@ -123,12 +129,22 @@ bool GlobalShortcut::unsetShortcut() {
|
||||
if (gshortcut != this) return false;
|
||||
}
|
||||
|
||||
bool result = unregisterShortcut(native_key_, native_mods_);
|
||||
if (result) {
|
||||
bool success = unregisterShortcut(native_key_, native_mods_);
|
||||
if (success) {
|
||||
if (internal_shortcuts_.contains(hash)) {
|
||||
internal_shortcuts_.remove(hash);
|
||||
}
|
||||
qLog(Info) << "Unregister shortcut" << shortcut_.toString();
|
||||
if (native_key2_ > 0) {
|
||||
QPair<quint32, quint32> hash2 = qMakePair(native_key2_, native_mods_);
|
||||
if (internal_shortcuts_.contains(hash2)) {
|
||||
GlobalShortcut *gshortcut2 = internal_shortcuts_.value(hash);
|
||||
if (gshortcut2 == this) {
|
||||
unregisterShortcut(native_key2_, native_mods_);
|
||||
internal_shortcuts_.remove(hash2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
qLog(Error) << "Failed to unregister shortcut" << shortcut_.toString();
|
||||
@@ -139,11 +155,11 @@ bool GlobalShortcut::unsetShortcut() {
|
||||
native_key_ = 0;
|
||||
native_mods_ = 0;
|
||||
|
||||
return result;
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
void GlobalShortcut::activateShortcut(quint32 native_key, quint32 native_mod) {
|
||||
void GlobalShortcut::activateShortcut(const quint32 native_key, const quint32 native_mod) {
|
||||
|
||||
Q_ASSERT(initialized_);
|
||||
|
||||
|
||||
@@ -53,13 +53,14 @@ class GlobalShortcut : public QObject, QAbstractNativeEventFilter {
|
||||
|
||||
private:
|
||||
|
||||
static void activateShortcut(quint32 native_key, quint32 native_mods);
|
||||
static void activateShortcut(const quint32 native_key, const quint32 native_mods);
|
||||
|
||||
static int nativeModifiers(Qt::KeyboardModifiers qt_mods);
|
||||
static int nativeKeycode(Qt::Key qt_keycode);
|
||||
static int nativeModifiers(const Qt::KeyboardModifiers qt_mods);
|
||||
static int nativeKeycode(const Qt::Key qt_keycode);
|
||||
static int nativeKeycode2(const Qt::Key qt_keycode);
|
||||
|
||||
static bool registerShortcut(int native_key, int native_mods);
|
||||
static bool unregisterShortcut(int native_key, int native_mods);
|
||||
static bool registerShortcut(const int native_key, const int native_mods);
|
||||
static bool unregisterShortcut(const int native_key, const int native_mods);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEventFilter(const QByteArray &eventtype, void *message, qintptr *result) override;
|
||||
@@ -76,6 +77,7 @@ class GlobalShortcut : public QObject, QAbstractNativeEventFilter {
|
||||
Qt::Key qt_key_;
|
||||
Qt::KeyboardModifiers qt_mods_;
|
||||
int native_key_;
|
||||
int native_key2_;
|
||||
int native_mods_;
|
||||
|
||||
};
|
||||
|
||||
@@ -60,25 +60,25 @@ GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) : QWidget(parent
|
||||
settings_.beginGroup(GlobalShortcutsSettingsPage::kSettingsGroup);
|
||||
|
||||
// Create actions
|
||||
AddShortcut("play", "Play", std::bind(&GlobalShortcutsManager::Play, this));
|
||||
AddShortcut("pause", "Pause", std::bind(&GlobalShortcutsManager::Pause, this));
|
||||
AddShortcut("play_pause", "Play/Pause", std::bind(&GlobalShortcutsManager::PlayPause, this), QKeySequence(Qt::Key_MediaPlay));
|
||||
AddShortcut("stop", "Stop", std::bind(&GlobalShortcutsManager::Stop, this), QKeySequence(Qt::Key_MediaStop));
|
||||
AddShortcut("stop_after", "Stop playing after current track", std::bind(&GlobalShortcutsManager::StopAfter, this));
|
||||
AddShortcut("next_track", "Next track", std::bind(&GlobalShortcutsManager::Next, this), QKeySequence(Qt::Key_MediaNext));
|
||||
AddShortcut("prev_track", "Previous track", std::bind(&GlobalShortcutsManager::Previous, this), QKeySequence(Qt::Key_MediaPrevious));
|
||||
AddShortcut("inc_volume", "Increase volume", std::bind(&GlobalShortcutsManager::IncVolume, this));
|
||||
AddShortcut("dec_volume", "Decrease volume", std::bind(&GlobalShortcutsManager::DecVolume, this));
|
||||
AddShortcut("play", tr("Play"), std::bind(&GlobalShortcutsManager::Play, this));
|
||||
AddShortcut("pause", tr("Pause"), std::bind(&GlobalShortcutsManager::Pause, this));
|
||||
AddShortcut("play_pause", tr("Play/Pause"), std::bind(&GlobalShortcutsManager::PlayPause, this), QKeySequence(Qt::Key_MediaPlay));
|
||||
AddShortcut("stop", tr("Stop"), std::bind(&GlobalShortcutsManager::Stop, this), QKeySequence(Qt::Key_MediaStop));
|
||||
AddShortcut("stop_after", tr("Stop playing after current track"), std::bind(&GlobalShortcutsManager::StopAfter, this));
|
||||
AddShortcut("next_track", tr("Next track"), std::bind(&GlobalShortcutsManager::Next, this), QKeySequence(Qt::Key_MediaNext));
|
||||
AddShortcut("prev_track", tr("Previous track"), std::bind(&GlobalShortcutsManager::Previous, this), QKeySequence(Qt::Key_MediaPrevious));
|
||||
AddShortcut("inc_volume", tr("Increase volume"), std::bind(&GlobalShortcutsManager::IncVolume, this));
|
||||
AddShortcut("dec_volume", tr("Decrease volume"), std::bind(&GlobalShortcutsManager::DecVolume, this));
|
||||
AddShortcut("mute", tr("Mute"), std::bind(&GlobalShortcutsManager::Mute, this));
|
||||
AddShortcut("seek_forward", "Seek forward", std::bind(&GlobalShortcutsManager::SeekForward, this));
|
||||
AddShortcut("seek_backward", "Seek backward", std::bind(&GlobalShortcutsManager::SeekBackward, this));
|
||||
AddShortcut("show_hide", "Show/Hide", std::bind(&GlobalShortcutsManager::ShowHide, this));
|
||||
AddShortcut("show_osd", "Show OSD", std::bind(&GlobalShortcutsManager::ShowOSD, this));
|
||||
AddShortcut("toggle_pretty_osd", "Toggle Pretty OSD", std::bind(&GlobalShortcutsManager::TogglePrettyOSD, this)); // Toggling possible only for pretty OSD
|
||||
AddShortcut("shuffle_mode", "Change shuffle mode", std::bind(&GlobalShortcutsManager::CycleShuffleMode, this));
|
||||
AddShortcut("repeat_mode", "Change repeat mode", std::bind(&GlobalShortcutsManager::CycleRepeatMode, this));
|
||||
AddShortcut("toggle_scrobbling", "Enable/disable scrobbling", std::bind(&GlobalShortcutsManager::ToggleScrobbling, this));
|
||||
AddShortcut("love", "Love", std::bind(&GlobalShortcutsManager::Love, this));
|
||||
AddShortcut("seek_forward", tr("Seek forward"), std::bind(&GlobalShortcutsManager::SeekForward, this));
|
||||
AddShortcut("seek_backward", tr("Seek backward"), std::bind(&GlobalShortcutsManager::SeekBackward, this));
|
||||
AddShortcut("show_hide", tr("Show/Hide"), std::bind(&GlobalShortcutsManager::ShowHide, this));
|
||||
AddShortcut("show_osd", tr("Show OSD"), std::bind(&GlobalShortcutsManager::ShowOSD, this));
|
||||
AddShortcut("toggle_pretty_osd", tr("Toggle Pretty OSD"), std::bind(&GlobalShortcutsManager::TogglePrettyOSD, this)); // Toggling possible only for pretty OSD
|
||||
AddShortcut("shuffle_mode", tr("Change shuffle mode"), std::bind(&GlobalShortcutsManager::CycleShuffleMode, this));
|
||||
AddShortcut("repeat_mode", tr("Change repeat mode"), std::bind(&GlobalShortcutsManager::CycleRepeatMode, this));
|
||||
AddShortcut("toggle_scrobbling", tr("Enable/disable scrobbling"), std::bind(&GlobalShortcutsManager::ToggleScrobbling, this));
|
||||
AddShortcut("love", tr("Love"), std::bind(&GlobalShortcutsManager::Love, this));
|
||||
|
||||
// Create backends - these do the actual shortcut registration
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ PlaylistContainer::~PlaylistContainer() { delete ui_; }
|
||||
|
||||
PlaylistView *PlaylistContainer::view() const { return ui_->playlist; }
|
||||
|
||||
void PlaylistContainer::SetActions(QAction *new_playlist, QAction *load_playlist, QAction *save_playlist, QAction *clear_playlist, QAction *next_playlist, QAction *previous_playlist) {
|
||||
void PlaylistContainer::SetActions(QAction *new_playlist, QAction *load_playlist, QAction *save_playlist, QAction *clear_playlist, QAction *next_playlist, QAction *previous_playlist, QAction *save_all_playlists) {
|
||||
|
||||
ui_->create_new->setDefaultAction(new_playlist);
|
||||
ui_->load->setDefaultAction(load_playlist);
|
||||
@@ -148,6 +148,7 @@ void PlaylistContainer::SetActions(QAction *new_playlist, QAction *load_playlist
|
||||
QObject::connect(next_playlist, &QAction::triggered, this, &PlaylistContainer::GoToNextPlaylistTab);
|
||||
QObject::connect(previous_playlist, &QAction::triggered, this, &PlaylistContainer::GoToPreviousPlaylistTab);
|
||||
QObject::connect(clear_playlist, &QAction::triggered, this, &PlaylistContainer::ClearPlaylist);
|
||||
QObject::connect(save_all_playlists, &QAction::triggered, manager_, &PlaylistManager::SaveAllPlaylists);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class PlaylistContainer : public QWidget {
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
|
||||
void SetActions(QAction *new_playlist, QAction *load_playlist, QAction *save_playlist, QAction *clear_playlist, QAction *next_playlist, QAction *previous_playlist);
|
||||
void SetActions(QAction *new_playlist, QAction *load_playlist, QAction *save_playlist, QAction *clear_playlist, QAction *next_playlist, QAction *previous_playlist, QAction *save_all_playlists);
|
||||
void SetManager(PlaylistManager *manager);
|
||||
void ReloadSettings();
|
||||
|
||||
|
||||
@@ -650,3 +650,15 @@ void PlaylistManager::RateCurrentSong(const float rating) {
|
||||
void PlaylistManager::RateCurrentSong2(const int rating) {
|
||||
RateCurrentSong(static_cast<float>(rating) / 5.0F);
|
||||
}
|
||||
|
||||
void PlaylistManager::SaveAllPlaylists() {
|
||||
|
||||
const QString path = QFileDialog::getExistingDirectory(nullptr, tr("Select directory for the playlists"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
for (QMap<int, Data>::const_iterator it = playlists_.constBegin(); it != playlists_.constEnd(); ++it) {
|
||||
const Data &data = *it;
|
||||
const QString filepath = path + "/" + data.name + ".m3u";
|
||||
Save(it.key(), filepath, Playlist::Path_Absolute);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -222,6 +222,8 @@ class PlaylistManager : public PlaylistManagerInterface {
|
||||
// Rate current song using 0 - 5 scale.
|
||||
void RateCurrentSong2(const int rating) override;
|
||||
|
||||
void SaveAllPlaylists();
|
||||
|
||||
private slots:
|
||||
void SetActivePlaying() override;
|
||||
void SetActivePaused() override;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user