Compare commits

..

45 Commits

Author SHA1 Message Date
Jonas Kvinge
38d49ceb64 Split into separate libraries 2025-01-22 18:34:04 +01:00
Jonas Kvinge
58fc8c82bb MainWindow: Maximize error dialog when window is shown 2025-01-22 17:51:16 +01:00
Jonas Kvinge
02bb875bb3 ErrorDialog: Only raise window if parent is maximized
Fixes #1627
2025-01-22 17:50:41 +01:00
Jonas Kvinge
5db01482eb Lazy: Fix bool 2025-01-22 17:49:52 +01:00
Jonas Kvinge
719fa6ffb3 MainWindow: Only hide window when system tray and keep running is enabled 2025-01-22 17:26:08 +01:00
Jonas Kvinge
159be5d79e MainWindow: Change close() to hide() in SetHiddenInTray
Otherwise close event is triggered causing Strawberry to quit.
2025-01-19 09:45:13 +01:00
Jonas Kvinge
911237e281 AnalyzerBase: Add missing parameter names 2025-01-19 09:42:00 +01:00
Jonas Kvinge
ae89ca8123 Turn on git revision 2025-01-17 12:34:43 +01:00
Jonas Kvinge
b832675893 Release 1.2.6 2025-01-17 10:27:48 +01:00
Jonas Kvinge
b4cfe636c9 TranscodeDialog: Fix mismatched definition 2025-01-17 09:15:55 +01:00
Jonas Kvinge
e6a0945dfa Call QObject::metaObject 2025-01-17 09:08:59 +01:00
Jonas Kvinge
726c105ed6 MoodbarItemDelegate: Remove delete of data
Memory is deleted in QCache::insert
2025-01-17 08:29:17 +01:00
Jonas Kvinge
d73cbc3a1d EngineBase: Fix mismatched definition 2025-01-17 08:26:11 +01:00
Jonas Kvinge
121f45d3b6 Playlist: Use sizeof playlist pointer to pointer 2025-01-17 07:22:49 +01:00
Jonas Kvinge
3a9ea81929 Queue: Fix sizeof, should be the pointer not the class 2025-01-17 07:12:25 +01:00
Jonas Kvinge
b919472241 Playlist: Correct sizeof 2025-01-17 06:56:08 +01:00
Jonas Kvinge
e8c8b39410 Turn on git revision 2025-01-17 04:29:05 +01:00
Jonas Kvinge
6904efef47 Release 1.2.5 2025-01-17 01:40:38 +01:00
Jonas Kvinge
fafa89baff CI: Disable GIO on Windows 2025-01-16 07:18:31 +01:00
Strawberry Bot
d9062446f5 New translations 2025-01-16 06:39:23 +01:00
Jonas Kvinge
9256b92d8f Update Changelog 2025-01-16 06:32:35 +01:00
Jonas Kvinge
f66459f3cb Make optional feature required unless disabled, add QtSparkle for macOS 2025-01-16 06:22:13 +01:00
Jonas Kvinge
f8ea9631ca Add sparkle 2025-01-15 23:03:40 +01:00
Jonas Kvinge
ab558f87b5 GstEnginePipeline: Use SetStateAsync in finish if needed 2025-01-15 07:01:43 +01:00
Jonas Kvinge
ab73eda2be Add mutex_protected_test 2025-01-15 07:00:28 +01:00
Jonas Kvinge
92f34ff36e mutex_protected: Add more operators 2025-01-15 07:00:16 +01:00
Strawberry Bot
d0bf2d7a9c New translations 2025-01-14 07:10:07 +01:00
Jonas Kvinge
b2cd3afe55 TagReaderClient: Add [[nodiscard]] 2025-01-14 06:36:15 +01:00
Jonas Kvinge
decd0a1dc6 TagReaderClient: Connect TagReaderReplyPtr
Makes sure TagReaderReplyPtr is not deleted too early.

Partial fix for #1633
2025-01-14 06:35:51 +01:00
Jonas Kvinge
3e0a9fa388 SettingsProvider: Use Settings
Fixes #1649
2025-01-13 12:22:31 +01:00
Jonas Kvinge
e5b6c5959f CMake: Use find_package for qtsparkle 2025-01-12 04:16:17 +01:00
Jonas Kvinge
8a9db5440d rpm: Enable unit tests on Fedora 2025-01-11 01:39:26 +01:00
Jonas Kvinge
28a25c5763 CMake: Fix add_test 2025-01-11 01:37:06 +01:00
dependabot[bot]
ea49fbcbee Bump vmactions/openbsd-vm from 1.1.5 to 1.1.6
Bumps [vmactions/openbsd-vm](https://github.com/vmactions/openbsd-vm) from 1.1.5 to 1.1.6.
- [Release notes](https://github.com/vmactions/openbsd-vm/releases)
- [Commits](https://github.com/vmactions/openbsd-vm/compare/v1.1.5...v1.1.6)

---
updated-dependencies:
- dependency-name: vmactions/openbsd-vm
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-11 00:37:52 +01:00
Jonas Kvinge
d9807b358e GioLister: Fix use of deprecated functions 2025-01-11 00:35:24 +01:00
Jonas Kvinge
3e53d2b237 CI: Add -Wno-maybe-uninitialized for Fedora 2025-01-11 00:35:24 +01:00
Jonas Kvinge
9122881f74 CI: Bump GCC on openSUSE Leap 2025-01-11 00:35:24 +01:00
Jonas Kvinge
9c36d7fd43 rpm: Add BUILD_WERROR 2025-01-11 00:35:24 +01:00
Jonas Kvinge
a4a365cbee CI: Set RPM_BUILD_NCPUS to 4 2025-01-11 00:35:24 +01:00
Jonas Kvinge
00f06b22b8 CMake: Check for gmock 2025-01-11 00:35:24 +01:00
Jonas Kvinge
e2d8838fca rpm: Run unit tests 2025-01-11 00:35:24 +01:00
Jonas Kvinge
9427691f39 CI: Install gtest and gmock for openSUSE, Fedora and Mageia 2025-01-11 00:35:24 +01:00
Jonas Kvinge
bebdcc4e7f CollectionModel: Simply data function 2025-01-10 17:47:30 +01:00
Jonas Kvinge
041f761921 test_utils: Fix Q_ASSERT 2025-01-10 15:35:15 +01:00
Jonas Kvinge
1435ae6dc0 Turn on git revision 2025-01-10 15:08:04 +01:00
178 changed files with 3882 additions and 2000 deletions

View File

@@ -21,18 +21,18 @@ jobs:
steps: steps:
- name: Refresh repositories - name: Refresh repositories
run: zypper -n --gpg-auto-import-keys ref run: zypper -n --gpg-auto-import-keys ref
- name: Upgrade packages - name: Upgrade packages (Tumbleweed)
if: matrix.opensuse_version == 'tumbleweed' if: matrix.opensuse_version == 'tumbleweed'
run: zypper -n --gpg-auto-import-keys dup run: zypper -n --gpg-auto-import-keys dup
- name: Upgrade packages - name: Upgrade packages (Leap)
if: matrix.opensuse_version != 'tumbleweed' if: matrix.opensuse_version != 'tumbleweed'
run: zypper -n --gpg-auto-import-keys up run: zypper -n --gpg-auto-import-keys up
- name: Install gcc - name: Install gcc (Tumbleweed)
if: matrix.opensuse_version == 'tumbleweed' if: matrix.opensuse_version == 'tumbleweed'
run: zypper -n --gpg-auto-import-keys in gcc gcc-c++ run: zypper -n --gpg-auto-import-keys in gcc gcc-c++
- name: Install gcc 13 - name: Install gcc (Leap)
if: matrix.opensuse_version != 'tumbleweed' if: matrix.opensuse_version != 'tumbleweed'
run: zypper -n --gpg-auto-import-keys in gcc13 gcc13-c++ run: zypper -n --gpg-auto-import-keys in gcc14 gcc14-c++
- name: Install packages - name: Install packages
run: > run: >
zypper -n --gpg-auto-import-keys in zypper -n --gpg-auto-import-keys in
@@ -77,6 +77,8 @@ jobs:
qt6-base-common-devel qt6-base-common-devel
qt6-sql-sqlite qt6-sql-sqlite
qt6-linguist-devel qt6-linguist-devel
gtest
gmock
- name: Install kdsingleapplication-qt6-devel - name: Install kdsingleapplication-qt6-devel
if: matrix.opensuse_version == 'tumbleweed' if: matrix.opensuse_version == 'tumbleweed'
run: zypper -n --gpg-auto-import-keys in kdsingleapplication-qt6-devel run: zypper -n --gpg-auto-import-keys in kdsingleapplication-qt6-devel
@@ -101,14 +103,17 @@ jobs:
run: cp strawberry-*.tar.xz /usr/src/packages/SOURCES/ run: cp strawberry-*.tar.xz /usr/src/packages/SOURCES/
- name: Build RPM (Tumbleweed) - name: Build RPM (Tumbleweed)
if: matrix.opensuse_version == 'tumbleweed' if: matrix.opensuse_version == 'tumbleweed'
env:
RPM_BUILD_NCPUS: 4
working-directory: build working-directory: build
run: rpmbuild -ba strawberry.spec run: rpmbuild -ba strawberry.spec
- name: Build RPM (Leap) - name: Build RPM (Leap)
if: matrix.opensuse_version != 'tumbleweed' if: matrix.opensuse_version != 'tumbleweed'
working-directory: build
env: env:
CC: gcc-13 RPM_BUILD_NCPUS: 4
CXX: g++-13 CC: gcc-14
CXX: g++-14
working-directory: build
run: rpmbuild -ba strawberry.spec run: rpmbuild -ba strawberry.spec
- name: Set subdir - name: Set subdir
id: set-subdir id: set-subdir
@@ -185,6 +190,8 @@ jobs:
libappstream-glib libappstream-glib
hicolor-icon-theme hicolor-icon-theme
kdsingleapplication-qt6-devel kdsingleapplication-qt6-devel
gtest-devel
gmock-devel
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@@ -207,7 +214,7 @@ jobs:
run: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/ run: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/
- name: Build RPM - name: Build RPM
env: env:
RPM_BUILD_NCPUS: "2" RPM_BUILD_NCPUS: 4
working-directory: build working-directory: build
run: rpmbuild -ba strawberry.spec run: rpmbuild -ba strawberry.spec
- name: Upload artifacts - name: Upload artifacts
@@ -300,7 +307,7 @@ jobs:
run: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/ run: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/
- name: Build RPM - name: Build RPM
env: env:
RPM_BUILD_NCPUS: "2" RPM_BUILD_NCPUS: 4
working-directory: build working-directory: build
run: rpmbuild -ba strawberry.spec run: rpmbuild -ba strawberry.spec
- name: Upload artifacts - name: Upload artifacts
@@ -374,6 +381,7 @@ jobs:
desktop-file-utils desktop-file-utils
appstream-util appstream-util
hicolor-icon-theme hicolor-icon-theme
gtest
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@@ -396,7 +404,7 @@ jobs:
run: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/ run: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/
- name: Build RPM - name: Build RPM
env: env:
RPM_BUILD_NCPUS: "2" RPM_BUILD_NCPUS: 4
working-directory: build working-directory: build
run: rpmbuild -ba strawberry.spec run: rpmbuild -ba strawberry.spec
- name: Upload artifacts - name: Upload artifacts
@@ -693,7 +701,7 @@ jobs:
submodules: recursive submodules: recursive
- name: Build OpenBSD - name: Build OpenBSD
id: build-openbsd id: build-openbsd
uses: vmactions/openbsd-vm@v1.1.5 uses: vmactions/openbsd-vm@v1.1.6
with: with:
usesh: true usesh: true
mem: 4096 mem: 4096
@@ -703,7 +711,7 @@ jobs:
export LDFLAGS="-L/usr/local/lib" export LDFLAGS="-L/usr/local/lib"
git config --global --add safe.directory ${GITHUB_WORKSPACE} git config --global --add safe.directory ${GITHUB_WORKSPACE}
cmake -E make_directory build cmake -E make_directory build
cmake -S . -B build -DCMAKE_BUILD_TYPE="Debug" cmake -S . -B build -DCMAKE_BUILD_TYPE="Debug" -DENABLE_ALSA=OFF
cmake --build build --config Debug --parallel 4 cmake --build build --config Debug --parallel 4
@@ -793,10 +801,12 @@ jobs:
-DCMAKE_PREFIX_PATH="${{env.prefix_path}}/lib/cmake" -DCMAKE_PREFIX_PATH="${{env.prefix_path}}/lib/cmake"
-DBUILD_WERROR=ON -DBUILD_WERROR=ON
-DUSE_BUNDLE=ON -DUSE_BUNDLE=ON
-DENABLE_DBUS=OFF
-DICU_ROOT="${{env.prefix_path}}" -DICU_ROOT="${{env.prefix_path}}"
-DAPPLE_DEVELOPER_ID=$(test '${{github.repository}}' = 'strawberrymusicplayer/strawberry' && test '${{github.event.pull_request.base.repo.full_name}}' = '${{github.event.pull_request.head.repo.full_name}}' && echo "383J84DVB6" || echo "") -DAPPLE_DEVELOPER_ID=$(test '${{github.repository}}' = 'strawberrymusicplayer/strawberry' && test '${{github.event.pull_request.base.repo.full_name}}' = '${{github.event.pull_request.head.repo.full_name}}' && echo "383J84DVB6" || echo "")
-DARCH="${{env.arch}}"
-DENABLE_SPOTIFY=$(test -f "${{env.prefix_path}}/lib/gstreamer-1.0/libgstspotify.dylib" && echo "ON" || echo "OFF") -DENABLE_SPOTIFY=$(test -f "${{env.prefix_path}}/lib/gstreamer-1.0/libgstspotify.dylib" && echo "ON" || echo "OFF")
-DENABLE_SPARKLE=ON
-DENABLE_QTSPARKLE=OFF
- name: Build - name: Build
run: cmake --build build --config Release --parallel 4 run: cmake --build build --config Release --parallel 4
@@ -932,10 +942,12 @@ jobs:
-DCMAKE_PREFIX_PATH="${{env.prefix_path}}/lib/cmake" -DCMAKE_PREFIX_PATH="${{env.prefix_path}}/lib/cmake"
-DBUILD_WERROR=ON -DBUILD_WERROR=ON
-DUSE_BUNDLE=ON -DUSE_BUNDLE=ON
-DENABLE_DBUS=OFF
-DICU_ROOT="${{env.prefix_path}}" -DICU_ROOT="${{env.prefix_path}}"
-DAPPLE_DEVELOPER_ID="383J84DVB6" -DAPPLE_DEVELOPER_ID="383J84DVB6"
-DARCH="${{env.arch}}"
-DENABLE_SPOTIFY=$(test -f "${{env.prefix_path}}/lib/gstreamer-1.0/libgstspotify.dylib" && echo "ON" || echo "OFF") -DENABLE_SPOTIFY=$(test -f "${{env.prefix_path}}/lib/gstreamer-1.0/libgstspotify.dylib" && echo "ON" || echo "OFF")
-DENABLE_SPARKLE=ON
-DENABLE_QTSPARKLE=OFF
- name: Build - name: Build
run: cmake --build build --config Release --parallel 4 run: cmake --build build --config Release --parallel 4
@@ -1030,7 +1042,7 @@ jobs:
-DBUILD_WERROR=ON -DBUILD_WERROR=ON
-DARCH="${{matrix.arch}}" -DARCH="${{matrix.arch}}"
-DENABLE_WIN32_CONSOLE=$(test "${{matrix.buildtype}}" = "debug" && echo "ON" || echo "OFF") -DENABLE_WIN32_CONSOLE=$(test "${{matrix.buildtype}}" = "debug" && echo "ON" || echo "OFF")
-DENABLE_DBUS=OFF -DENABLE_GIO=OFF
-DENABLE_AUDIOCD=OFF -DENABLE_AUDIOCD=OFF
-DENABLE_MTP=OFF -DENABLE_MTP=OFF
-DENABLE_GPOD=OFF -DENABLE_GPOD=OFF
@@ -1318,6 +1330,10 @@ jobs:
-DENABLE_WIN32_CONSOLE=${{env.win32_console}} -DENABLE_WIN32_CONSOLE=${{env.win32_console}}
-DPKG_CONFIG_EXECUTABLE="${{env.prefix_path_forwardslash}}/bin/pkg-config.exe" -DPKG_CONFIG_EXECUTABLE="${{env.prefix_path_forwardslash}}/bin/pkg-config.exe"
-DICU_ROOT="${{env.prefix_path_forwardslash}}" -DICU_ROOT="${{env.prefix_path_forwardslash}}"
-DENABLE_GIO=OFF
-DENABLE_AUDIOCD=OFF
-DENABLE_MTP=OFF
-DENABLE_GPOD=OFF
-DENABLE_SPOTIFY=ON -DENABLE_SPOTIFY=ON
- name: Run Make - name: Run Make

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,22 @@ Strawberry Music Player
======================= =======================
ChangeLog ChangeLog
Version 1.2.6 (2025.01.17):
Bugfixes:
* Fixed dragging songs from playlist to queue.
Version 1.2.5 (2025.01.17):
Bugfixes:
* Fixed crash when saving playcount or rating to file (#1633).
* Fixed QFile::open failing in unit tests.
* Fixed playlist sequence settings saved to wrong configuration file (#1649).
Enhancements:
* Fixed use of deprecated GIO functions with GLib 2.84 and newer.
* (macOS) Added back Sparkle updater to check for new releases.
Version 1.2.4 (2025.01.10): Version 1.2.4 (2025.01.10):
Bugfixes: Bugfixes:

View File

@@ -1,15 +1,15 @@
set(summary_willbuild "") set(summary_willbuild "")
set(summary_willnotbuild "") set(summary_willnotbuild "")
macro(summary_add name test) macro(optional_component_summary_add name test)
if (${test}) if (${test})
list(APPEND summary_willbuild ${name}) list(APPEND summary_willbuild ${name})
else (${test}) else (${test})
list(APPEND summary_willnotbuild "${name}") list(APPEND summary_willnotbuild "${name}")
endif (${test}) endif (${test})
endmacro(summary_add) endmacro(optional_component_summary_add)
macro(summary_show_part variable title) macro(optional_component_summary_show_part variable title)
list(LENGTH ${variable} _len) list(LENGTH ${variable} _len)
if (_len) if (_len)
message("") message("")
@@ -18,19 +18,20 @@ macro(summary_show_part variable title)
message(" ${_item}") message(" ${_item}")
endforeach (_item) endforeach (_item)
endif (_len) endif (_len)
endmacro(summary_show_part) endmacro(optional_component_summary_show_part)
macro(summary_show) macro(optional_component_summary_show)
list(SORT summary_willbuild) list(SORT summary_willbuild)
list(SORT summary_willnotbuild) list(SORT summary_willnotbuild)
message("") message("")
message("Building strawberry version: ${STRAWBERRY_VERSION_DISPLAY}, Qt version ${Qt${QT_VERSION_MAJOR}Core_VERSION}") message("Building strawberry version: ${STRAWBERRY_VERSION_DISPLAY}, Qt version ${Qt${QT_VERSION_MAJOR}Core_VERSION}")
summary_show_part(summary_willbuild "The following components will be built:") optional_component_summary_show_part(summary_willbuild "The following components will be built:")
summary_show_part(summary_willnotbuild "The following components WILL NOT be built:") optional_component_summary_show_part(summary_willnotbuild "The following components WILL NOT be built:")
message("") message("")
endmacro(summary_show) endmacro(optional_component_summary_show)
function(optional_component name default description) function(optional_component name default description)
set(option_variable "ENABLE_${name}") set(option_variable "ENABLE_${name}")
set(have_variable "HAVE_${name}") set(have_variable "HAVE_${name}")
set(${have_variable} OFF) set(${have_variable} OFF)
@@ -79,6 +80,9 @@ function(optional_component name default description)
set(text "${description} (missing ${deplist_text})") set(text "${description} (missing ${deplist_text})")
set(summary_willnotbuild "${summary_willnotbuild};${text}" PARENT_SCOPE) set(summary_willnotbuild "${summary_willnotbuild};${text}" PARENT_SCOPE)
message(FATAL_ERROR "${text}, to disable this optional feature, pass -D${option_variable}=OFF to CMake")
else() else()
set(${have_variable} ON PARENT_SCOPE) set(${have_variable} ON PARENT_SCOPE)
set(summary_willbuild "${summary_willbuild};${description}" PARENT_SCOPE) set(summary_willbuild "${summary_willbuild};${description}" PARENT_SCOPE)

View File

@@ -1,9 +1,9 @@
set(STRAWBERRY_VERSION_MAJOR 1) set(STRAWBERRY_VERSION_MAJOR 1)
set(STRAWBERRY_VERSION_MINOR 2) set(STRAWBERRY_VERSION_MINOR 2)
set(STRAWBERRY_VERSION_PATCH 4) set(STRAWBERRY_VERSION_PATCH 6)
#set(STRAWBERRY_VERSION_PRERELEASE rc1) #set(STRAWBERRY_VERSION_PRERELEASE rc1)
set(INCLUDE_GIT_REVISION OFF) set(INCLUDE_GIT_REVISION ON)
set(majorminorpatch "${STRAWBERRY_VERSION_MAJOR}.${STRAWBERRY_VERSION_MINOR}.${STRAWBERRY_VERSION_PATCH}") set(majorminorpatch "${STRAWBERRY_VERSION_MAJOR}.${STRAWBERRY_VERSION_MINOR}.${STRAWBERRY_VERSION_PATCH}")

View File

@@ -35,9 +35,9 @@
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>@LSMinimumSystemVersion@</string> <string>@LSMinimumSystemVersion@</string>
<key>SUFeedURL</key> <key>SUFeedURL</key>
<string>https://www.strawberrymusicplayer.org/sparkle-macos</string> <string>https://www.strawberrymusicplayer.org/sparkle-macos-@ARCH@</string>
<key>SUPublicEDKey</key> <key>SUPublicEDKey</key>
<string>3IRScV8YtNVnx7zoeJAXvg28Kh1gN/Pyl2iPM467pG8=</string> <string>/OydhYVfypuO2Mf7G6DUqVZWW9G19eFV74qaDCBTOUk=</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
<array> <array>
<dict> <dict>

View File

@@ -51,6 +51,8 @@
</screenshots> </screenshots>
<update_contact>eclipseo@fedoraproject.org</update_contact> <update_contact>eclipseo@fedoraproject.org</update_contact>
<releases> <releases>
<release version="1.2.6" date="2025-01-17"/>
<release version="1.2.5" date="2025-01-17"/>
<release version="1.2.4" date="2025-01-10"/> <release version="1.2.4" date="2025-01-10"/>
<release version="1.2.3" date="2024-12-08"/> <release version="1.2.3" date="2024-12-08"/>
<release version="1.2.2" date="2024-11-23"/> <release version="1.2.2" date="2024-11-23"/>

View File

@@ -63,6 +63,8 @@ BuildRequires: pkgconfig(libcdio)
BuildRequires: pkgconfig(libebur128) BuildRequires: pkgconfig(libebur128)
BuildRequires: pkgconfig(libgpod-1.0) BuildRequires: pkgconfig(libgpod-1.0)
BuildRequires: pkgconfig(libmtp) BuildRequires: pkgconfig(libmtp)
BuildRequires: cmake(GTest)
BuildRequires: pkgconfig(gmock)
%if 0%{?suse_version} %if 0%{?suse_version}
Requires: qt6-sql-sqlite Requires: qt6-sql-sqlite
@@ -103,13 +105,13 @@ Features:
%build %build
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos} %if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos}
export CXXFLAGS="-fPIC $RPM_OPT_FLAGS" export CXXFLAGS="-fPIC -Wno-maybe-uninitialized $RPM_OPT_FLAGS"
%endif %endif
%if "%{?_vendor}" == "openmandriva" %if "%{?_vendor}" == "openmandriva"
%{cmake} -DQT_VERSION_MAJOR=@QT_VERSION_MAJOR@ -DENABLE_TRANSLATIONS=OFF %{cmake} -DBUILD_WERROR=ON
%make_build %make_build
%else %else
%{cmake} -DQT_VERSION_MAJOR=@QT_VERSION_MAJOR@ %{cmake} -DBUILD_WERROR=ON
%cmake_build %cmake_build
%endif %endif
@@ -120,11 +122,13 @@ Features:
%cmake_install %cmake_install
%endif %endif
%if 0%{?suse_version}
%suse_update_desktop_file org.strawberrymusicplayer.strawberry Qt AudioVideo Audio Player
%endif
%check %check
export QT_QPA_PLATFORM="offscreen"
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos}
%{cmake_build} -t strawberry_tests
%else
%{make_build} -j $(nproc) -C build strawberry_tests
%endif
desktop-file-validate %{buildroot}%{_datadir}/applications/org.strawberrymusicplayer.strawberry.desktop desktop-file-validate %{buildroot}%{_datadir}/applications/org.strawberrymusicplayer.strawberry.desktop
%if 0%{?suse_version} %if 0%{?suse_version}
appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/org.strawberrymusicplayer.strawberry.appdata.xml appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/org.strawberrymusicplayer.strawberry.appdata.xml

View File

@@ -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}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.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()

View File

@@ -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
)

View File

@@ -50,9 +50,9 @@
// Make an INSTRUCTIONS file // Make an INSTRUCTIONS file
// can't mod scope in analyze you have to use transform for 2D use setErasePixmap Qt function insetead of m_background // can't mod scope in analyze you have to use transform for 2D use setErasePixmap Qt function insetead of m_background
AnalyzerBase::AnalyzerBase(QWidget *parent, const uint scopeSize) AnalyzerBase::AnalyzerBase(QWidget *parent, const uint scope_size)
: QWidget(parent), : QWidget(parent),
fht_(new FHT(scopeSize)), fht_(new FHT(scope_size)),
engine_(nullptr), engine_(nullptr),
lastscope_(512), lastscope_(512),
new_frame_(false), new_frame_(false),
@@ -211,28 +211,28 @@ void AnalyzerBase::demo(QPainter &p) {
} }
void AnalyzerBase::interpolate(const Scope &inVec, Scope &outVec) { void AnalyzerBase::interpolate(const Scope &in_scope, Scope &out_scope) {
double pos = 0.0; double pos = 0.0;
const double step = static_cast<double>(inVec.size()) / static_cast<double>(outVec.size()); const double step = static_cast<double>(in_scope.size()) / static_cast<double>(out_scope.size());
for (uint i = 0; i < outVec.size(); ++i, pos += step) { for (uint i = 0; i < out_scope.size(); ++i, pos += step) {
const double error = pos - std::floor(pos); const double error = pos - std::floor(pos);
const uint64_t offset = static_cast<uint64_t>(pos); const uint64_t offset = static_cast<uint64_t>(pos);
uint64_t indexLeft = offset + 0; uint64_t indexLeft = offset + 0;
if (indexLeft >= inVec.size()) { if (indexLeft >= in_scope.size()) {
indexLeft = inVec.size() - 1; indexLeft = in_scope.size() - 1;
} }
uint64_t indexRight = offset + 1; uint64_t indexRight = offset + 1;
if (indexRight >= inVec.size()) { if (indexRight >= in_scope.size()) {
indexRight = inVec.size() - 1; indexRight = in_scope.size() - 1;
} }
outVec[i] = inVec[indexLeft] * (1.0F - static_cast<float>(error)) + inVec[indexRight] * static_cast<float>(error); out_scope[i] = in_scope[indexLeft] * (1.0F - static_cast<float>(error)) + in_scope[indexRight] * static_cast<float>(error);
} }
} }

View File

@@ -61,7 +61,7 @@ class AnalyzerBase : public QWidget {
protected: protected:
using Scope = std::vector<float>; using Scope = std::vector<float>;
explicit AnalyzerBase(QWidget*, const uint scopeSize = 7); explicit AnalyzerBase(QWidget *parent, const uint scope_size = 7);
void hideEvent(QHideEvent *e) override; void hideEvent(QHideEvent *e) override;
void showEvent(QShowEvent *e) override; void showEvent(QShowEvent *e) override;
@@ -71,12 +71,12 @@ class AnalyzerBase : public QWidget {
int resizeExponent(int exp); int resizeExponent(int exp);
int resizeForBands(const int bands); int resizeForBands(const int bands);
virtual void init() {} virtual void init() {}
virtual void transform(Scope&); virtual void transform(Scope &scope);
virtual void analyze(QPainter &p, const Scope&, const bool new_frame) = 0; virtual void analyze(QPainter &p, const Scope &s, const bool new_frame) = 0;
virtual void demo(QPainter &p); virtual void demo(QPainter &p);
void interpolate(const Scope&, Scope&); void interpolate(const Scope &in_scope, Scope &out_scope);
void initSin(Scope&, const uint = 6000); void initSin(Scope &v, const uint size = 6000);
protected: protected:
QBasicTimer timer_; QBasicTimer timer_;

View File

@@ -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
)

View File

@@ -78,7 +78,7 @@ CollectionBackend::~CollectionBackend() {
void CollectionBackend::Init(SharedPtr<Database> db, SharedPtr<TaskManager> task_manager, const Song::Source source, const QString &songs_table, const QString &dirs_table, const QString &subdirs_table) { void CollectionBackend::Init(SharedPtr<Database> db, SharedPtr<TaskManager> task_manager, const Song::Source source, const QString &songs_table, const QString &dirs_table, const QString &subdirs_table) {
setObjectName(source == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(source), QLatin1String(metaObject()->className()))); setObjectName(source == Song::Source::Collection ? QLatin1String(QObject::metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(source), QLatin1String(QObject::metaObject()->className())));
db_ = db; db_ = db;
task_manager_ = task_manager; task_manager_ = task_manager;

View File

@@ -28,7 +28,7 @@
#include <QUrl> #include <QUrl>
#include "core/song.h" #include "core/song.h"
#include "core/songmimedata.h" #include "mimedata/songmimedata.h"
#include "filterparser/filterparser.h" #include "filterparser/filterparser.h"
#include "filterparser/filtertree.h" #include "filterparser/filtertree.h"
#include "collectionbackend.h" #include "collectionbackend.h"

View File

@@ -53,7 +53,7 @@
#include "savedgroupingmanager.h" #include "savedgroupingmanager.h"
#include "collectionfilterwidget.h" #include "collectionfilterwidget.h"
#include "groupbydialog.h" #include "groupbydialog.h"
#include "ui_collectionfilterwidget.h" #include "collection/ui_collectionfilterwidget.h"
#include "widgets/searchfield.h" #include "widgets/searchfield.h"
#include "constants/collectionsettings.h" #include "constants/collectionsettings.h"
#include "constants/appearancesettings.h" #include "constants/appearancesettings.h"

View File

@@ -66,7 +66,7 @@ CollectionLibrary::CollectionLibrary(const SharedPtr<Database> database,
save_playcounts_to_files_(false), save_playcounts_to_files_(false),
save_ratings_to_files_(false) { save_ratings_to_files_(false) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
original_thread_ = thread(); original_thread_ = thread();

View File

@@ -59,7 +59,7 @@
#include "core/database.h" #include "core/database.h"
#include "core/iconloader.h" #include "core/iconloader.h"
#include "core/settings.h" #include "core/settings.h"
#include "core/songmimedata.h" #include "mimedata/songmimedata.h"
#include "collectionfilteroptions.h" #include "collectionfilteroptions.h"
#include "collectionquery.h" #include "collectionquery.h"
#include "collectionbackend.h" #include "collectionbackend.h"
@@ -98,7 +98,7 @@ CollectionModel::CollectionModel(const SharedPtr<CollectionBackend> backend, con
loading_(false), loading_(false),
icon_disk_cache_(new QNetworkDiskCache(this)) { icon_disk_cache_(new QNetworkDiskCache(this)) {
setObjectName(backend_->source() == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(backend_->source()), QLatin1String(metaObject()->className()))); setObjectName(backend_->source() == Song::Source::Collection ? QLatin1String(QObject::metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(backend_->source()), QLatin1String(QObject::metaObject()->className())));
filter_->setSourceModel(this); filter_->setSourceModel(this);
filter_->setSortRole(Role_SortText); filter_->setSortRole(Role_SortText);
@@ -288,29 +288,11 @@ void CollectionModel::SetFilterMaxAge(const int filter_max_age) {
QVariant CollectionModel::data(const QModelIndex &idx, const int role) const { QVariant CollectionModel::data(const QModelIndex &idx, const int role) const {
const CollectionItem *item = IndexToItem(idx); return data(IndexToItem(idx), role);
// Handle a special case for returning album artwork instead of a generic CD icon.
// this is here instead of in the other data() function to let us use the
// QModelIndex& version of GetChildSongs, which satisfies const-ness, instead
// of the CollectionItem *version, which doesn't.
if (options_active_.show_pretty_covers) {
bool is_album_node = false;
if (role == Qt::DecorationRole && item->type == CollectionItem::Type::Container) {
GroupBy container_group_by = options_active_.group_by[item->container_level];
is_album_node = IsAlbumGroupBy(container_group_by);
}
if (is_album_node) {
// It has const behaviour some of the time - that's ok right?
return const_cast<CollectionModel*>(this)->AlbumIcon(idx);
}
}
return data(item, role);
} }
QVariant CollectionModel::data(const CollectionItem *item, const int role) const { QVariant CollectionModel::data(CollectionItem *item, const int role) const {
GroupBy container_group_by = item->type == CollectionItem::Type::Container ? options_active_.group_by[item->container_level] : GroupBy::None; GroupBy container_group_by = item->type == CollectionItem::Type::Container ? options_active_.group_by[item->container_level] : GroupBy::None;
@@ -329,7 +311,7 @@ QVariant CollectionModel::data(const CollectionItem *item, const int role) const
case GroupBy::YearAlbumDisc: case GroupBy::YearAlbumDisc:
case GroupBy::OriginalYearAlbum: case GroupBy::OriginalYearAlbum:
case GroupBy::OriginalYearAlbumDisc: case GroupBy::OriginalYearAlbumDisc:
return QVariant(); return options_active_.show_pretty_covers ? const_cast<CollectionModel*>(this)->AlbumIcon(item) : QVariant();
case GroupBy::Artist: case GroupBy::Artist:
case GroupBy::AlbumArtist: case GroupBy::AlbumArtist:
return icon_artist_; return icon_artist_;
@@ -408,17 +390,17 @@ QMimeData *CollectionModel::mimeData(const QModelIndexList &indexes) const {
if (indexes.isEmpty()) return nullptr; if (indexes.isEmpty()) return nullptr;
SongMimeData *data = new SongMimeData; SongList songs;
QList<QUrl> urls;
QSet<int> song_ids; QSet<int> song_ids;
QList<QUrl> urls;
data->backend = backend_;
for (const QModelIndex &idx : indexes) { for (const QModelIndex &idx : indexes) {
GetChildSongs(IndexToItem(idx), &urls, &data->songs, &song_ids); GetChildSongs(IndexToItem(idx), songs, song_ids, urls);
} }
SongMimeData *data = new SongMimeData;
data->setUrls(urls); data->setUrls(urls);
data->backend = backend_;
data->songs = songs;
data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs); data->name_for_new_playlist_ = Song::GetNameForNewPlaylist(data->songs);
return data; return data;
@@ -854,9 +836,9 @@ void CollectionModel::LoadSongsFromSqlAsyncFinished() {
} }
QString CollectionModel::AlbumIconPixmapCacheKey(const QModelIndex &idx) const { QString CollectionModel::AlbumIconPixmapCacheKey(const CollectionItem *item) const {
return Song::TextForSource(backend_->source()) + QLatin1Char('/') + idx.data(Role_ContainerKey).toString(); return Song::TextForSource(backend_->source()) + QLatin1Char('/') + item->container_key;
} }
@@ -869,7 +851,7 @@ QUrl CollectionModel::AlbumIconPixmapDiskCacheKey(const QString &cache_key) {
void CollectionModel::ClearItemPixmapCache(CollectionItem *item) { void CollectionModel::ClearItemPixmapCache(CollectionItem *item) {
// Remove from pixmap cache // Remove from pixmap cache
const QString cache_key = AlbumIconPixmapCacheKey(ItemToIndex(item)); const QString cache_key = AlbumIconPixmapCacheKey(item);
QPixmapCache::remove(cache_key); QPixmapCache::remove(cache_key);
if (use_disk_cache_ && icon_disk_cache_) icon_disk_cache_->remove(AlbumIconPixmapDiskCacheKey(cache_key)); if (use_disk_cache_ && icon_disk_cache_) icon_disk_cache_->remove(AlbumIconPixmapDiskCacheKey(cache_key));
if (pending_cache_keys_.contains(cache_key)) { if (pending_cache_keys_.contains(cache_key)) {
@@ -888,13 +870,12 @@ void CollectionModel::ClearItemPixmapCache(CollectionItem *item) {
} }
QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) { QVariant CollectionModel::AlbumIcon(CollectionItem *item) {
CollectionItem *item = IndexToItem(idx);
if (!item) return pixmap_no_cover_; if (!item) return pixmap_no_cover_;
// Check the cache for a pixmap we already loaded. // Check the cache for a pixmap we already loaded.
const QString cache_key = AlbumIconPixmapCacheKey(idx); const QString cache_key = AlbumIconPixmapCacheKey(item);
QPixmap cached_pixmap; QPixmap cached_pixmap;
if (QPixmapCache::find(cache_key, &cached_pixmap)) { if (QPixmapCache::find(cache_key, &cached_pixmap)) {
@@ -919,7 +900,7 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) {
} }
// No art is cached and we're not loading it already. Load art for the first song in the album. // No art is cached and we're not loading it already. Load art for the first song in the album.
SongList songs = GetChildSongs(idx); const SongList songs = GetChildSongs(item);
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
AlbumCoverLoaderOptions cover_loader_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage); AlbumCoverLoaderOptions cover_loader_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage);
cover_loader_options.desired_scaled_size = QSize(kPrettyCoverSize, kPrettyCoverSize); cover_loader_options.desired_scaled_size = QSize(kPrettyCoverSize, kPrettyCoverSize);
@@ -1412,7 +1393,7 @@ QString CollectionModel::DividerDisplayText(const GroupBy group_by, const QStrin
} }
bool CollectionModel::CompareItems(const CollectionItem *a, const CollectionItem *b) const { bool CollectionModel::CompareItems(CollectionItem *a, CollectionItem *b) const {
QVariant left = data(a, CollectionModel::Role_SortText); QVariant left = data(a, CollectionModel::Role_SortText);
QVariant right = data(b, CollectionModel::Role_SortText); QVariant right = data(b, CollectionModel::Role_SortText);
@@ -1453,24 +1434,23 @@ qint64 CollectionModel::MaximumCacheSize(Settings *s, const char *size_id, const
} }
void CollectionModel::GetChildSongs(CollectionItem *item, QList<QUrl> *urls, SongList *songs, QSet<int> *song_ids) const { void CollectionModel::GetChildSongs(CollectionItem *item, SongList &songs, QSet<int> &song_ids, QList<QUrl> &urls) const {
switch (item->type) { switch (item->type) {
case CollectionItem::Type::Container: { case CollectionItem::Type::Container: {
QList<CollectionItem*> children = item->children; QList<CollectionItem*> children = item->children;
std::sort(children.begin(), children.end(), std::bind(&CollectionModel::CompareItems, this, std::placeholders::_1, std::placeholders::_2)); std::sort(children.begin(), children.end(), std::bind(&CollectionModel::CompareItems, this, std::placeholders::_1, std::placeholders::_2));
for (CollectionItem *child : children) { for (CollectionItem *child : children) {
GetChildSongs(child, urls, songs, song_ids); GetChildSongs(child, songs, song_ids, urls);
} }
break; break;
} }
case CollectionItem::Type::Song: case CollectionItem::Type::Song:
urls->append(item->metadata.url()); urls << item->metadata.url();
if (!song_ids->contains(item->metadata.id())) { if (!song_ids.contains(item->metadata.id())) {
songs->append(item->metadata); songs << item->metadata;
song_ids->insert(item->metadata.id()); song_ids << item->metadata.id();
} }
break; break;
@@ -1480,16 +1460,33 @@ void CollectionModel::GetChildSongs(CollectionItem *item, QList<QUrl> *urls, Son
} }
SongList CollectionModel::GetChildSongs(const QList<CollectionItem*> items) const {
SongList songs;
QSet<int> song_ids;
QList<QUrl> urls;
for (CollectionItem *item : items) {
GetChildSongs(item, songs, song_ids, urls);
}
return songs;
}
SongList CollectionModel::GetChildSongs(CollectionItem *item) const {
return GetChildSongs(QList<CollectionItem*>() << item);
}
SongList CollectionModel::GetChildSongs(const QModelIndexList &indexes) const { SongList CollectionModel::GetChildSongs(const QModelIndexList &indexes) const {
QList<QUrl> dontcare; SongList songs;
SongList ret;
QSet<int> song_ids; QSet<int> song_ids;
QList<QUrl> urls;
for (const QModelIndex &idx : indexes) { for (const QModelIndex &idx : indexes) {
GetChildSongs(IndexToItem(idx), &dontcare, &ret, &song_ids); GetChildSongs(IndexToItem(idx), songs, song_ids, urls);
} }
return ret;
return songs;
} }

View File

@@ -194,11 +194,13 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
QString ContainerKey(const GroupBy group_by, const Song &song, bool &has_unique_album_identifier) const; QString ContainerKey(const GroupBy group_by, const Song &song, bool &has_unique_album_identifier) const;
// Get information about the collection // Get information about the collection
void GetChildSongs(CollectionItem *item, QList<QUrl> *urls, SongList *songs, QSet<int> *song_ids) const; void GetChildSongs(CollectionItem *item, SongList &songs, QSet<int> &song_ids, QList<QUrl> &urls) const;
SongList GetChildSongs(const QList<CollectionItem*> items) const;
SongList GetChildSongs(CollectionItem *item) const;
SongList GetChildSongs(const QModelIndex &idx) const; SongList GetChildSongs(const QModelIndex &idx) const;
SongList GetChildSongs(const QModelIndexList &indexes) const; SongList GetChildSongs(const QModelIndexList &indexes) const;
bool CompareItems(const CollectionItem *a, const CollectionItem *b) const; bool CompareItems(CollectionItem *a, CollectionItem *b) const;
bool HasParentAlbumGroupBy(CollectionItem *item) const; bool HasParentAlbumGroupBy(CollectionItem *item) const;
@@ -224,7 +226,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
void BeginReset(); void BeginReset();
void EndReset(); void EndReset();
QVariant data(const CollectionItem *item, const int role) const; QVariant data(CollectionItem *item, const int role) const;
void ScheduleUpdate(const CollectionModelUpdate::Type type, const SongList &songs); void ScheduleUpdate(const CollectionModelUpdate::Type type, const SongList &songs);
void ScheduleAddSongs(const SongList &songs); void ScheduleAddSongs(const SongList &songs);
@@ -250,9 +252,9 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
// Helpers // Helpers
static bool IsCompilationArtistNode(const CollectionItem *node) { return node == node->parent->compilation_artist_node_; } static bool IsCompilationArtistNode(const CollectionItem *node) { return node == node->parent->compilation_artist_node_; }
QString AlbumIconPixmapCacheKey(const QModelIndex &idx) const; QString AlbumIconPixmapCacheKey(const CollectionItem *item) const;
static QUrl AlbumIconPixmapDiskCacheKey(const QString &cache_key); static QUrl AlbumIconPixmapDiskCacheKey(const QString &cache_key);
QVariant AlbumIcon(const QModelIndex &idx); QVariant AlbumIcon(CollectionItem *item);
void ClearItemPixmapCache(CollectionItem *item); void ClearItemPixmapCache(CollectionItem *item);
static qint64 MaximumCacheSize(Settings *s, const char *size_id, const char *size_unit_id, const qint64 cache_size_default); static qint64 MaximumCacheSize(Settings *s, const char *size_id, const char *size_unit_id, const qint64 cache_size_default);

View File

@@ -51,7 +51,7 @@
#include <QContextMenuEvent> #include <QContextMenuEvent>
#include "core/iconloader.h" #include "core/iconloader.h"
#include "core/mimedata.h" #include "mimedata/mimedata.h"
#include "core/musicstorage.h" #include "core/musicstorage.h"
#include "core/deletefiles.h" #include "core/deletefiles.h"
#include "core/settings.h" #include "core/settings.h"
@@ -69,7 +69,7 @@
# include "device/devicemanager.h" # include "device/devicemanager.h"
# include "device/devicestatefiltermodel.h" # include "device/devicestatefiltermodel.h"
#endif #endif
#include "dialogs/edittagdialog.h" #include "edittagdialog/edittagdialog.h"
#include "dialogs/deleteconfirmationdialog.h" #include "dialogs/deleteconfirmationdialog.h"
#include "organize/organizedialog.h" #include "organize/organizedialog.h"
#include "organize/organizeerrordialog.h" #include "organize/organizeerrordialog.h"
@@ -108,7 +108,7 @@ CollectionView::CollectionView(QWidget *parent)
is_in_keyboard_search_(false), is_in_keyboard_search_(false),
delete_files_(false) { delete_files_(false) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
setItemDelegate(new CollectionItemDelegate(this)); setItemDelegate(new CollectionItemDelegate(this));
setAttribute(Qt::WA_MacShowFocusRect, false); setAttribute(Qt::WA_MacShowFocusRect, false);

View File

@@ -26,7 +26,7 @@
#include "collectionfilterwidget.h" #include "collectionfilterwidget.h"
#include "collectionview.h" #include "collectionview.h"
#include "collectionviewcontainer.h" #include "collectionviewcontainer.h"
#include "ui_collectionviewcontainer.h" #include "collection/ui_collectionviewcontainer.h"
CollectionViewContainer::CollectionViewContainer(QWidget *parent) : QWidget(parent), ui_(new Ui_CollectionViewContainer) { CollectionViewContainer::CollectionViewContainer(QWidget *parent) : QWidget(parent), ui_(new Ui_CollectionViewContainer) {

View File

@@ -106,7 +106,7 @@ CollectionWatcher::CollectionWatcher(const Song::Source source,
cue_parser_(new CueParser(tagreader_client, backend, this)), cue_parser_(new CueParser(tagreader_client, backend, this)),
last_scan_time_(0) { last_scan_time_(0) {
setObjectName(source_ == Song::Source::Collection ? QLatin1String(metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(source_), QLatin1String(metaObject()->className()))); setObjectName(source_ == Song::Source::Collection ? QLatin1String(QObject::metaObject()->className()) : QStringLiteral("%1%2").arg(Song::DescriptionForSource(source_), QLatin1String(QObject::metaObject()->className())));
original_thread_ = thread(); original_thread_ = thread();

View File

@@ -18,6 +18,7 @@
#cmakedefine HAVE_AUDIOCD #cmakedefine HAVE_AUDIOCD
#cmakedefine HAVE_MTP #cmakedefine HAVE_MTP
#cmakedefine HAVE_GPOD #cmakedefine HAVE_GPOD
#cmakedefine HAVE_SPARKLE
#cmakedefine HAVE_QTSPARKLE #cmakedefine HAVE_QTSPARKLE
#cmakedefine HAVE_SONGFINGERPRINTING #cmakedefine HAVE_SONGFINGERPRINTING
#cmakedefine HAVE_MUSICBRAINZ #cmakedefine HAVE_MUSICBRAINZ

View File

@@ -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
)

95
src/core/CMakeLists.txt Normal file
View File

@@ -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
$<$<BOOL:${HAVE_DBUS}>:Qt${QT_VERSION_MAJOR}::DBus>
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
$<$<BOOL:${HAVE_GPOD}>:PkgConfig::LIBGPOD PkgConfig::GDK_PIXBUF>
$<$<BOOL:${WIN32}>:getopt-win::getopt>
strawberry_utilities
)

View File

@@ -69,7 +69,7 @@ Database::Database(SharedPtr<TaskManager> task_manager, QObject *parent, const Q
startup_schema_version_(-1), startup_schema_version_(-1),
original_thread_(nullptr) { original_thread_(nullptr) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
original_thread_ = thread(); original_thread_ = thread();

View File

@@ -26,7 +26,8 @@
#include <QVariant> #include <QVariant>
#include <QString> #include <QString>
#include <QSettings>
#include "core/settings.h"
class SettingsProvider { class SettingsProvider {
public: public:
@@ -60,7 +61,7 @@ class DefaultSettingsProvider : public SettingsProvider {
void endArray() override; void endArray() override;
private: private:
QSettings backend_; Settings backend_;
Q_DISABLE_COPY(DefaultSettingsProvider) Q_DISABLE_COPY(DefaultSettingsProvider)
}; };

48
src/core/sparkleupdater.h Normal file
View File

@@ -0,0 +1,48 @@
/*
* Strawberry Music Player
* Copyright 2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef SPARKLEUPDATER_H
#define SPARKLEUPDATER_H
#include <QObject>
class QAction;
#ifdef __OBJC__
@class AppUpdaterDelegate;
#endif
class SparkleUpdater : public QObject {
Q_OBJECT
public:
explicit SparkleUpdater(QAction *action_check_updates, QObject *parent = nullptr);
public Q_SLOTS:
void CheckForUpdates();
private:
#ifdef __OBJC__
AppUpdaterDelegate *updater_delegate_;
#else
void *updater_delegate_;
#endif
};
#endif // SPARKLEUPDATER_H

View File

@@ -0,0 +1,79 @@
/*
* Strawberry Music Player
* Copyright 2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#import <Sparkle/Sparkle.h>
#include <QObject>
#include <QAction>
#include "sparkleupdater.h"
@interface AppUpdaterDelegate : NSObject <SPUUpdaterDelegate>
@property(nonatomic, assign) SPUStandardUpdaterController *updater_controller;
@end
@implementation AppUpdaterDelegate
- (void)observeCanCheckForUpdatesWithAction:(QAction*)action_check_updates {
[_updater_controller.updater addObserver:self forKeyPath:NSStringFromSelector(@selector(canCheckForUpdates)) options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:(void*)action_check_updates];
}
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey, id>*)change context:(void*)context {
if ([keyPath isEqualToString:NSStringFromSelector(@selector(canCheckForUpdates))]) {
QAction *action = reinterpret_cast<QAction*>(context);
action->setEnabled(_updater_controller.updater.canCheckForUpdates);
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc {
@autoreleasepool {
[_updater_controller.updater removeObserver:self forKeyPath:NSStringFromSelector(@selector(canCheckForUpdates))];
}
[super dealloc];
}
@end
SparkleUpdater::SparkleUpdater(QAction *action_check_updates, QObject *parent) : QObject(parent) {
@autoreleasepool {
updater_delegate_ = [[AppUpdaterDelegate alloc] init];
updater_delegate_.updater_controller = [[SPUStandardUpdaterController alloc] initWithStartingUpdater:YES updaterDelegate:updater_delegate_ userDriverDelegate:nil];
[updater_delegate_ observeCanCheckForUpdatesWithAction:action_check_updates];
}
}
void SparkleUpdater::CheckForUpdates() {
@autoreleasepool {
[updater_delegate_.updater_controller checkForUpdates:nil];
}
}

View File

@@ -34,7 +34,7 @@ using namespace Qt::Literals::StringLiterals;
TaskManager::TaskManager(QObject *parent) : QObject(parent), next_task_id_(1) { TaskManager::TaskManager(QObject *parent) : QObject(parent), next_task_id_(1) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
} }

View File

@@ -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()

View File

@@ -64,7 +64,7 @@ AlbumCoverLoader::AlbumCoverLoader(const SharedPtr<TagReaderClient> tagreader_cl
load_image_async_id_(1), load_image_async_id_(1),
original_thread_(nullptr) { original_thread_(nullptr) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
original_thread_ = thread(); original_thread_ = thread();

View File

@@ -69,7 +69,7 @@
#include "core/settings.h" #include "core/settings.h"
#include "core/database.h" #include "core/database.h"
#include "core/networkaccessmanager.h" #include "core/networkaccessmanager.h"
#include "core/songmimedata.h" #include "mimedata/songmimedata.h"
#include "utilities/strutils.h" #include "utilities/strutils.h"
#include "utilities/fileutils.h" #include "utilities/fileutils.h"
#include "utilities/imageutils.h" #include "utilities/imageutils.h"

View File

@@ -35,7 +35,7 @@
#include "includes/scoped_ptr.h" #include "includes/scoped_ptr.h"
#include "core/song.h" #include "core/song.h"
#include "core/songmimedata.h" #include "mimedata/songmimedata.h"
#include "collection/collectionbackend.h" #include "collection/collectionbackend.h"
#include "albumcovermanager.h" #include "albumcovermanager.h"
#include "albumcovermanagerlist.h" #include "albumcovermanagerlist.h"

View File

@@ -45,7 +45,7 @@ CurrentAlbumCoverLoader::CurrentAlbumCoverLoader(const SharedPtr<AlbumCoverLoade
temp_file_pattern_(StandardPaths::WritableLocation(StandardPaths::StandardLocation::TempLocation) + u"/strawberry-cover-XXXXXX.jpg"_s), temp_file_pattern_(StandardPaths::WritableLocation(StandardPaths::StandardLocation::TempLocation) + u"/strawberry-cover-XXXXXX.jpg"_s),
id_(0) { id_(0) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
options_.options = AlbumCoverLoaderOptions::Option::RawImageData | AlbumCoverLoaderOptions::Option::OriginalImage | AlbumCoverLoaderOptions::Option::ScaledImage; options_.options = AlbumCoverLoaderOptions::Option::RawImageData | AlbumCoverLoaderOptions::Option::OriginalImage | AlbumCoverLoaderOptions::Option::ScaledImage;
options_.desired_scaled_size = QSize(120, 120); options_.desired_scaled_size = QSize(120, 120);

115
src/device/CMakeLists.txt Normal file
View File

@@ -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
$<$<BOOL:${HAVE_GIO}>:PkgConfig::GIO>
$<$<BOOL:${HAVE_GIO_UNIX}>:PkgConfig::GIO_UNIX>
$<$<BOOL:${HAVE_AUDIOCD}>:PkgConfig::LIBCDIO>
$<$<BOOL:${HAVE_MTP}>:PkgConfig::LIBMTP>
$<$<BOOL:${HAVE_GPOD}>: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
$<$<BOOL:${HAVE_DBUS}>: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()

View File

@@ -49,7 +49,7 @@ DeviceDatabaseBackend::DeviceDatabaseBackend(QObject *parent)
db_(nullptr), db_(nullptr),
original_thread_(nullptr) { original_thread_(nullptr) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
original_thread_ = thread(); original_thread_ = thread();

View File

@@ -45,7 +45,7 @@ DeviceLister::DeviceLister(QObject *parent)
original_thread_(nullptr), original_thread_(nullptr),
next_mount_request_id_(0) { next_mount_request_id_(0) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
original_thread_ = thread(); original_thread_ = thread();

View File

@@ -99,7 +99,7 @@ DeviceManager::DeviceManager(const SharedPtr<TaskManager> task_manager,
albumcover_loader_(albumcover_loader), albumcover_loader_(albumcover_loader),
not_connected_overlay_(IconLoader::Load(u"edit-delete"_s)) { not_connected_overlay_(IconLoader::Load(u"edit-delete"_s)) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
thread_pool_.setMaxThreadCount(1); thread_pool_.setMaxThreadCount(1);
QObject::connect(&*task_manager, &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged); QObject::connect(&*task_manager, &TaskManager::TasksChanged, this, &DeviceManager::TasksChanged);

View File

@@ -53,7 +53,7 @@
#include "core/iconloader.h" #include "core/iconloader.h"
#include "core/deletefiles.h" #include "core/deletefiles.h"
#include "core/mergedproxymodel.h" #include "core/mergedproxymodel.h"
#include "core/mimedata.h" #include "mimedata/mimedata.h"
#include "core/musicstorage.h" #include "core/musicstorage.h"
#include "utilities/colorutils.h" #include "utilities/colorutils.h"
#include "organize/organizedialog.h" #include "organize/organizedialog.h"

View File

@@ -484,16 +484,22 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) {
} }
#ifdef HAVE_GIO_UNIX #ifdef HAVE_GIO_UNIX
#ifdef GLIB_VERSION_2_84
GUnixMountEntry *unix_mount = g_unix_mount_entry_for(g_file_get_path(root), nullptr);
#else
GUnixMountEntry *unix_mount = g_unix_mount_for(g_file_get_path(root), nullptr); GUnixMountEntry *unix_mount = g_unix_mount_for(g_file_get_path(root), nullptr);
#endif
if (unix_mount) { if (unix_mount) {
// the GIO's definition of system internal mounts include filesystems like // The GIO's definition of system internal mounts include filesystems like autofs, tmpfs, sysfs, etc,
// autofs, tmpfs, sysfs, etc, and various system directories, including the root, // and various system directories, including the root, /boot, /var, /home, etc.
// /boot, /var, /home, etc. #ifdef GLIB_VERSION_2_84
is_system_internal = g_unix_mount_entry_is_system_internal(unix_mount);
g_unix_mount_entry_free(unix_mount);
#else
is_system_internal = g_unix_mount_is_system_internal(unix_mount); is_system_internal = g_unix_mount_is_system_internal(unix_mount);
g_unix_mount_free(unix_mount); g_unix_mount_free(unix_mount);
// Although checking most of the internal mounts is safe, #endif
// we really don't want to touch autofs filesystems, as that would // Although checking most of the internal mounts is safe, we really don't want to touch autofs filesystems, as that would trigger automounting.
// trigger automounting.
if (is_system_internal) return; if (is_system_internal) return;
} }
#endif #endif

View File

@@ -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
)

View File

@@ -29,7 +29,7 @@
#include <QList> #include <QList>
#include <QString> #include <QString>
#include "ui_about.h" #include "dialogs/ui_about.h"
class QWidget; class QWidget;

View File

@@ -25,7 +25,7 @@
#include <QUrl> #include <QUrl>
#include <QLineEdit> #include <QLineEdit>
#include "ui_addstreamdialog.h" #include "dialogs/ui_addstreamdialog.h"
class AddStreamDialog : public QDialog { class AddStreamDialog : public QDialog {
Q_OBJECT Q_OBJECT

View File

@@ -29,7 +29,7 @@
#include <QDialog> #include <QDialog>
#include <QString> #include <QString>
#include "ui_console.h" #include "dialogs/ui_console.h"
#include "includes/shared_ptr.h" #include "includes/shared_ptr.h"

View File

@@ -39,6 +39,7 @@ using namespace Qt::Literals::StringLiterals;
ErrorDialog::ErrorDialog(QWidget *parent) ErrorDialog::ErrorDialog(QWidget *parent)
: QDialog(parent), : QDialog(parent),
parent_(parent),
ui_(new Ui_ErrorDialog) { ui_(new Ui_ErrorDialog) {
ui_->setupUi(this); ui_->setupUi(this);
@@ -66,8 +67,11 @@ void ErrorDialog::ShowMessage(const QString &message) {
UpdateContent(); UpdateContent();
show(); show();
raise();
activateWindow(); if (parent_ && parent_->isMaximized()) {
raise();
activateWindow();
}
} }

View File

@@ -48,6 +48,7 @@ class ErrorDialog : public QDialog {
private: private:
void UpdateContent(); void UpdateContent();
QWidget *parent_;
Ui_ErrorDialog *ui_; Ui_ErrorDialog *ui_;
QStringList current_messages_; QStringList current_messages_;

View File

@@ -28,7 +28,7 @@
#include "includes/shared_ptr.h" #include "includes/shared_ptr.h"
#include "ui_lastfmimportdialog.h" #include "dialogs/ui_lastfmimportdialog.h"
class QCloseEvent; class QCloseEvent;
class LastFMImport; class LastFMImport;

View File

@@ -25,7 +25,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QComboBox> #include <QComboBox>
#include "ui_saveplaylistsdialog.h" #include "dialogs/ui_saveplaylistsdialog.h"
class SavePlaylistsDialog : public QDialog { class SavePlaylistsDialog : public QDialog {
Q_OBJECT Q_OBJECT

View File

@@ -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
)

89
src/engine/CMakeLists.txt Normal file
View File

@@ -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
$<$<BOOL:${HAVE_ALSA}>:ALSA::ALSA>
$<$<BOOL:${HAVE_PULSE}>:PkgConfig::LIBPULSE>
$<$<BOOL:${WIN32}>:dsound>
$<$<BOOL:${MSVC}>:WindowsApp>
PkgConfig::GSTREAMER
PkgConfig::GSTREAMER_BASE
PkgConfig::GSTREAMER_AUDIO
PkgConfig::GSTREAMER_APP
PkgConfig::GSTREAMER_TAG
PkgConfig::GSTREAMER_PBUTILS
$<$<BOOL:${HAVE_SONGFINGERPRINTING} OR ${HAVE_MUSICBRAINZ}>:PkgConfig::CHROMAPRINT>
$<$<BOOL:${HAVE_EBUR128}>:PkgConfig::LIBEBUR128>
$<$<BOOL:${HAVE_MOODBAR}>: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()

View File

@@ -53,7 +53,7 @@ using namespace Qt::Literals::StringLiterals;
DeviceFinders::DeviceFinders(QObject *parent) : QObject(parent) { DeviceFinders::DeviceFinders(QObject *parent) : QObject(parent) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
} }

View File

@@ -120,7 +120,7 @@ class EngineBase : public QObject {
// Plays a media stream represented with the URL 'u' from the given 'beginning' to the given 'end' (usually from 0 to a song's length). // Plays a media stream represented with the URL 'u' from the given 'beginning' to the given 'end' (usually from 0 to a song's length).
// Both markers should be passed in nanoseconds. 'end' can be negative, indicating that the real length of 'u' stream is unknown. // Both markers should be passed in nanoseconds. 'end' can be negative, indicating that the real length of 'u' stream is unknown.
bool Play(const QUrl &media_url, const QUrl &stream_url, const bool pause, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec, const quint64 offset_nanosec, const std::optional<double> ebur128_integrated_loudness_lufs); bool Play(const QUrl &media_url, const QUrl &stream_url, const bool pause, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_offset_nanosec, const qint64 end_offset_nanosec, const quint64 offset_nanosec, const std::optional<double> ebur128_integrated_loudness_lufs);
void SetVolume(const uint volume); void SetVolume(const uint volume);
public Q_SLOTS: public Q_SLOTS:

View File

@@ -176,7 +176,9 @@ GstEnginePipeline::GstEnginePipeline(QObject *parent)
finish_requested_(false), finish_requested_(false),
finished_(false), finished_(false),
set_state_in_progress_(0), set_state_in_progress_(0),
set_state_async_in_progress_(0) { set_state_async_in_progress_(0),
last_set_state_in_progress_(GST_STATE_VOID_PENDING),
last_set_state_async_in_progress_(GST_STATE_VOID_PENDING) {
eq_band_gains_.reserve(kEqBandCount); eq_band_gains_.reserve(kEqBandCount);
for (int i = 0; i < kEqBandCount; ++i) eq_band_gains_ << 0; for (int i = 0; i < kEqBandCount; ++i) eq_band_gains_ << 0;
@@ -425,7 +427,12 @@ bool GstEnginePipeline::Finish() {
finished_ = true; finished_ = true;
} }
else { else {
SetState(GST_STATE_NULL); if (set_state_async_in_progress_ > 0 && last_set_state_async_in_progress_ != GST_STATE_NULL) {
SetStateAsync(GST_STATE_NULL);
}
else if ((!IsStateNull() || set_state_in_progress_ > 0) && last_set_state_in_progress_ != GST_STATE_NULL) {
SetState(GST_STATE_NULL);
}
} }
return finished_.value(); return finished_.value();
@@ -1794,6 +1801,7 @@ bool GstEnginePipeline::IsStateNull() const {
void GstEnginePipeline::SetStateAsync(const GstState state) { void GstEnginePipeline::SetStateAsync(const GstState state) {
last_set_state_async_in_progress_ = state;
++set_state_async_in_progress_; ++set_state_async_in_progress_;
QMetaObject::invokeMethod(this, "SetStateAsyncSlot", Qt::QueuedConnection, Q_ARG(GstState, state)); QMetaObject::invokeMethod(this, "SetStateAsyncSlot", Qt::QueuedConnection, Q_ARG(GstState, state));
@@ -1802,6 +1810,7 @@ void GstEnginePipeline::SetStateAsync(const GstState state) {
void GstEnginePipeline::SetStateAsyncSlot(const GstState state) { void GstEnginePipeline::SetStateAsyncSlot(const GstState state) {
last_set_state_async_in_progress_ = GST_STATE_VOID_PENDING;
--set_state_async_in_progress_; --set_state_async_in_progress_;
SetState(state); SetState(state);
@@ -1812,6 +1821,7 @@ QFuture<GstStateChangeReturn> GstEnginePipeline::SetState(const GstState state)
qLog(Debug) << "Setting pipeline" << id() << "state to" << GstStateText(state); qLog(Debug) << "Setting pipeline" << id() << "state to" << GstStateText(state);
last_set_state_in_progress_ = state;
++set_state_in_progress_; ++set_state_in_progress_;
QFutureWatcher<GstStateChangeReturn> *watcher = new QFutureWatcher<GstStateChangeReturn>(); QFutureWatcher<GstStateChangeReturn> *watcher = new QFutureWatcher<GstStateChangeReturn>();
@@ -1829,6 +1839,7 @@ QFuture<GstStateChangeReturn> GstEnginePipeline::SetState(const GstState state)
void GstEnginePipeline::SetStateFinishedSlot(const GstState state, const GstStateChangeReturn state_change_return) { void GstEnginePipeline::SetStateFinishedSlot(const GstState state, const GstStateChangeReturn state_change_return) {
last_set_state_in_progress_ = GST_STATE_VOID_PENDING;
--set_state_in_progress_; --set_state_in_progress_;
switch (state_change_return) { switch (state_change_return) {

View File

@@ -373,6 +373,9 @@ class GstEnginePipeline : public QObject {
mutex_protected<int> set_state_in_progress_; mutex_protected<int> set_state_in_progress_;
mutex_protected<int> set_state_async_in_progress_; mutex_protected<int> set_state_async_in_progress_;
mutex_protected<GstState> last_set_state_in_progress_;
mutex_protected<GstState> last_set_state_async_in_progress_;
}; };
using GstEnginePipelinePtr = QSharedPointer<GstEnginePipeline>; using GstEnginePipelinePtr = QSharedPointer<GstEnginePipeline>;

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -41,7 +41,7 @@
#include "core/filesystemmusicstorage.h" #include "core/filesystemmusicstorage.h"
#include "core/iconloader.h" #include "core/iconloader.h"
#include "core/settings.h" #include "core/settings.h"
#include "core/mimedata.h" #include "mimedata/mimedata.h"
#include "dialogs/deleteconfirmationdialog.h" #include "dialogs/deleteconfirmationdialog.h"
#include "fileview.h" #include "fileview.h"
#include "fileviewlist.h" #include "fileviewlist.h"

View File

@@ -32,7 +32,7 @@
#include <QtEvents> #include <QtEvents>
#include "core/iconloader.h" #include "core/iconloader.h"
#include "core/mimedata.h" #include "mimedata/mimedata.h"
#include "utilities/filemanagerutils.h" #include "utilities/filemanagerutils.h"
#include "fileviewlist.h" #include "fileviewlist.h"

View File

@@ -0,0 +1,52 @@
set(SOURCES
filterparser.cpp
filtertree.cpp
filtertreeand.cpp
filtertreecolumnterm.cpp
filtertreenop.cpp
filtertreenot.cpp
filtertreeor.cpp
filtertreeterm.cpp
filterparserfloateqcomparator.cpp
filterparserfloatgecomparator.cpp
filterparserfloatgtcomparator.cpp
filterparserfloatlecomparator.cpp
filterparserfloatltcomparator.cpp
filterparserfloatnecomparator.cpp
filterparserint64eqcomparator.cpp
filterparserint64gecomparator.cpp
filterparserint64gtcomparator.cpp
filterparserint64lecomparator.cpp
filterparserint64ltcomparator.cpp
filterparserint64necomparator.cpp
filterparserinteqcomparator.cpp
filterparserintgecomparator.cpp
filterparserintgtcomparator.cpp
filterparserintlecomparator.cpp
filterparserintltcomparator.cpp
filterparserintnecomparator.cpp
filterparsersearchtermcomparator.cpp
filterparsertextcontainscomparator.cpp
filterparsertexteqcomparator.cpp
filterparsertextnecomparator.cpp
filterparseruinteqcomparator.cpp
filterparseruintgecomparator.cpp
filterparseruintgtcomparator.cpp
filterparseruintlecomparator.cpp
filterparseruintltcomparator.cpp
filterparseruintnecomparator.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
)

View File

@@ -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
$<$<BOOL:${HAVE_X11_GLOBALSHORTCUTS}>:X11::X11_xcb>
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
$<$<BOOL:${HAVE_DBUS}>:Qt${QT_VERSION_MAJOR}::DBus>
strawberry_core
)
if(APPLE)
target_link_libraries(strawberry_globalshortcuts PRIVATE
"-framework ScriptingBridge"
strawberry_macstartup
)
endif()

View File

@@ -32,7 +32,7 @@
#include <QKeyEvent> #include <QKeyEvent>
#include "globalshortcutgrabber.h" #include "globalshortcutgrabber.h"
#include "ui_globalshortcutgrabber.h" #include "globalshortcuts/ui_globalshortcutgrabber.h"
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;

View File

@@ -29,7 +29,7 @@
#include <QKeySequence> #include <QKeySequence>
#import "core/mac_startup.h" #import "macstartup/mac_startup.h"
class MacMonitorWrapper { class MacMonitorWrapper {
public: public:

View File

@@ -35,8 +35,8 @@
#include "globalshortcutsbackend-kglobalaccel.h" #include "globalshortcutsbackend-kglobalaccel.h"
#include "kglobalaccel.h" #include "globalshortcuts/kglobalaccel.h"
#include "kglobalaccelcomponent.h" #include "globalshortcuts/kglobalaccelcomponent.h"
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;

View File

@@ -38,7 +38,7 @@
#include "globalshortcutsmanager.h" #include "globalshortcutsmanager.h"
#include "core/logging.h" #include "core/logging.h"
#include "core/mac_startup.h" #include "macstartup/mac_startup.h"
#import "includes/SBSystemPreferences.h" #import "includes/SBSystemPreferences.h"

View File

@@ -54,8 +54,8 @@ class Lazy {
T* operator->() const { return get(); } T* operator->() const { return get(); }
// Returns true if the object is not yet initialized. // Returns true if the object is initialized.
explicit operator bool() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; }
// Deletes the underlying object and will re-run the initialization function if the object is requested again. // Deletes the underlying object and will re-run the initialization function if the object is requested again.
void reset() { ptr_.reset(); } void reset() { ptr_.reset(); }

View File

@@ -47,6 +47,56 @@ class mutex_protected : public boost::noncopyable {
return value == value_; return value == value_;
} }
bool operator!=(const mutex_protected &value) const {
QMutexLocker l(&mutex_);
return value.value() != value_;
}
bool operator!=(const T value) const {
QMutexLocker l(&mutex_);
return value != value_;
}
bool operator>(const mutex_protected &value) const {
QMutexLocker l(&mutex_);
return value_ > value.value();
}
bool operator>(const T value) const {
QMutexLocker l(&mutex_);
return value_ > value;
}
bool operator>=(const mutex_protected &value) const {
QMutexLocker l(&mutex_);
return value_ >= value.value();
}
bool operator>=(const T value) const {
QMutexLocker l(&mutex_);
return value_ >= value;
}
bool operator<(const mutex_protected &value) const {
QMutexLocker l(&mutex_);
return value_ < value.value();
}
bool operator<(const T value) const {
QMutexLocker l(&mutex_);
return value_ < value;
}
bool operator<=(const mutex_protected &value) const {
QMutexLocker l(&mutex_);
return value_ <= value.value();
}
bool operator<=(const T value) const {
QMutexLocker l(&mutex_);
return value_ <= value;
}
void operator=(const mutex_protected &value) { void operator=(const mutex_protected &value) {
QMutexLocker l(&mutex_); QMutexLocker l(&mutex_);
value_ = value.value(); value_ = value.value();
@@ -62,11 +112,31 @@ class mutex_protected : public boost::noncopyable {
++value_; ++value_;
} }
void operator+=(const T value) {
QMutexLocker l(&mutex_);
value_ += value;
}
void operator+=(const mutex_protected value) {
QMutexLocker l(&mutex_);
value_ += value.value();
}
void operator--() { void operator--() {
QMutexLocker l(&mutex_); QMutexLocker l(&mutex_);
--value_; --value_;
} }
void operator-=(const T value) {
QMutexLocker l(&mutex_);
value_ -= value;
}
void operator-=(const mutex_protected value) {
QMutexLocker l(&mutex_);
value_ -= value.value();
}
private: private:
T value_; T value_;
mutable QMutex mutex_; mutable QMutex mutex_;

60
src/lyrics/CMakeLists.txt Normal file
View File

@@ -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
)

View File

@@ -44,7 +44,7 @@ using std::make_shared;
LyricsProviders::LyricsProviders(QObject *parent) : QObject(parent), thread_(new QThread(this)), network_(make_shared<NetworkAccessManager>()) { LyricsProviders::LyricsProviders(QObject *parent) : QObject(parent), thread_(new QThread(this)), network_(make_shared<NetworkAccessManager>()) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
thread_->setObjectName(objectName()); thread_->setObjectName(objectName());
network_->moveToThread(thread_); network_->moveToThread(thread_);
thread_->start(); thread_->start();

View File

@@ -0,0 +1,22 @@
set(MACSTARTUP_SOURCES mac_startup.mm)
add_library(strawberry_macstartup STATIC ${MACSTARTUP_SOURCES})
target_include_directories(strawberry_macstartup PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(strawberry_macstartup PRIVATE
"-framework Foundation"
"-framework AppKit"
"-framework IOKit"
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Widgets
SPMediaKeyTap
strawberry_utilities
strawberry_core
strawberry_globalshortcuts
)

View File

@@ -44,7 +44,7 @@
#include "core/database.h" #include "core/database.h"
#include "core/taskmanager.h" #include "core/taskmanager.h"
#include "core/networkaccessmanager.h" #include "core/networkaccessmanager.h"
#include "core/player.h" #include "player/player.h"
#include "tagreader/tagreaderclient.h" #include "tagreader/tagreaderclient.h"
#include "engine/devicefinders.h" #include "engine/devicefinders.h"
#include "core/urlhandlers.h" #include "core/urlhandlers.h"
@@ -250,7 +250,7 @@ Application::Application(QObject *parent)
p_(new ApplicationImpl(this)), p_(new ApplicationImpl(this)),
g_thread_(nullptr) { g_thread_(nullptr) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
const QMetaObject *mo = QAbstractEventDispatcher::instance(QCoreApplication::instance()->thread())->metaObject(); const QMetaObject *mo = QAbstractEventDispatcher::instance(QCoreApplication::instance()->thread())->metaObject();
if (mo && strcmp(mo->className(), "QEventDispatcherGlib") != 0 && strcmp(mo->superClass()->className(), "QEventDispatcherGlib") != 0) { if (mo && strcmp(mo->className(), "QEventDispatcherGlib") != 0 && strcmp(mo->superClass()->className(), "QEventDispatcherGlib") != 0) {

View File

@@ -82,7 +82,7 @@
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
# include "utilities/macosutils.h" # include "utilities/macosutils.h"
# include "core/mac_startup.h" # include "macstartup/mac_startup.h"
#endif #endif
#ifdef HAVE_MPRIS2 #ifdef HAVE_MPRIS2
@@ -93,9 +93,9 @@
#include "core/commandlineoptions.h" #include "core/commandlineoptions.h"
#include "core/networkproxyfactory.h" #include "core/networkproxyfactory.h"
#include "core/application.h" #include "main/application.h"
#include "core/metatypes.h" #include "main/metatypes.h"
#include "core/mainwindow.h" #include "main/mainwindow.h"
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
# include "systemtrayicon/macsystemtrayicon.h" # include "systemtrayicon/macsystemtrayicon.h"
@@ -104,7 +104,7 @@
#endif #endif
#ifdef HAVE_TRANSLATIONS #ifdef HAVE_TRANSLATIONS
# include "core/translations.h" # include "main/translations.h"
#endif #endif
#include "constants/behavioursettings.h" #include "constants/behavioursettings.h"
@@ -290,7 +290,7 @@ int main(int argc, char *argv[]) {
translations->LoadTranslation(u"strawberry"_s, QDir::currentPath(), language); translations->LoadTranslation(u"strawberry"_s, QDir::currentPath(), language);
# ifdef HAVE_QTSPARKLE # ifdef HAVE_QTSPARKLE
//qtsparkle::LoadTranslations(language); qtsparkle::LoadTranslations(language);
# endif # endif
#endif #endif

View File

@@ -89,7 +89,7 @@
#include "constants/mainwindowsettings.h" #include "constants/mainwindowsettings.h"
#include "includes/shared_ptr.h" #include "includes/shared_ptr.h"
#include "core/commandlineoptions.h" #include "core/commandlineoptions.h"
#include "core/mimedata.h" #include "mimedata/mimedata.h"
#include "core/iconloader.h" #include "core/iconloader.h"
#include "core/taskmanager.h" #include "core/taskmanager.h"
#include "core/song.h" #include "core/song.h"
@@ -100,10 +100,10 @@
#include "core/filesystemmusicstorage.h" #include "core/filesystemmusicstorage.h"
#include "core/deletefiles.h" #include "core/deletefiles.h"
#include "core/settings.h" #include "core/settings.h"
#include "core/player.h"
#include "utilities/envutils.h" #include "utilities/envutils.h"
#include "utilities/filemanagerutils.h" #include "utilities/filemanagerutils.h"
#include "utilities/screenutils.h" #include "utilities/screenutils.h"
#include "player/player.h"
#include "engine/enginebase.h" #include "engine/enginebase.h"
#include "dialogs/errordialog.h" #include "dialogs/errordialog.h"
#include "dialogs/about.h" #include "dialogs/about.h"
@@ -112,8 +112,8 @@
#include "dialogs/deleteconfirmationdialog.h" #include "dialogs/deleteconfirmationdialog.h"
#include "dialogs/lastfmimportdialog.h" #include "dialogs/lastfmimportdialog.h"
#include "dialogs/snapdialog.h" #include "dialogs/snapdialog.h"
#include "dialogs/edittagdialog.h" #include "edittagdialog/edittagdialog.h"
#include "dialogs/trackselectiondialog.h" #include "edittagdialog/trackselectiondialog.h"
#include "organize/organizedialog.h" #include "organize/organizedialog.h"
#include "widgets/fancytabwidget.h" #include "widgets/fancytabwidget.h"
#include "widgets/playingwidget.h" #include "widgets/playingwidget.h"
@@ -213,13 +213,17 @@
#endif #endif
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
# include "core/mac_startup.h" # include "macstartup/mac_startup.h"
# include "systemtrayicon/macsystemtrayicon.h" # include "systemtrayicon/macsystemtrayicon.h"
# include "utilities/macosutils.h" # include "utilities/macosutils.h"
#else #else
# include "systemtrayicon/qtsystemtrayicon.h" # include "systemtrayicon/qtsystemtrayicon.h"
#endif #endif
#ifdef HAVE_SPARKLE
#include "core/sparkleupdater.h"
#endif
#ifdef HAVE_QTSPARKLE #ifdef HAVE_QTSPARKLE
# include <qtsparkle-qt6/Updater> # include <qtsparkle-qt6/Updater>
#endif // HAVE_QTSPARKLE #endif // HAVE_QTSPARKLE
@@ -235,20 +239,41 @@ const int kTrackPositionUpdateTimeMs = 1000;
} // namespace } // namespace
#ifdef HAVE_QTSPARKLE #ifdef HAVE_QTSPARKLE
# ifdef _MSC_VER namespace {
# ifdef _M_X64
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-msvc-x64"; # if defined(__APPLE__)
# if defined(__x86_64__)
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-macos-x86_64";
# elif defined(__aarch64__)
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-macos-arm64";
# else # else
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-msvc-x86"; # error "Unsupported macOS arch for QtSparkle"
# endif # endif
# else
# ifdef __x86_64__ # elif defined(__MINGW32__)
# if defined(__x86_64__)
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x64"; constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x64";
# else # elif defined(__i686__)
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x86"; constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x86";
# else
# error "Unsupported MinGW arch for QtSparkle"
# endif # endif
# endif
#endif # elif defined(_MSC_VER)
# if defined(_WIN64)
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-msvc-x64";
# elif defined(_WIN32)
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-msvc-x86";
# else
# error "Unsupported MSVC arch for QtSparkle"
# endif
# else
# error "Unsupported OS for QtSparkle"
# endif // OS
} // namespace
#endif // HAVE_QTSPARKLE
MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OSDBase *osd, const CommandlineOptions &options, QWidget *parent) MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OSDBase *osd, const CommandlineOptions &options, QWidget *parent)
: QMainWindow(parent), : QMainWindow(parent),
@@ -833,9 +858,9 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
thumbbar_->SetActions(QList<QAction*>() << ui_->action_previous_track << ui_->action_play_pause << ui_->action_stop << ui_->action_next_track << nullptr << ui_->action_love); thumbbar_->SetActions(QList<QAction*>() << ui_->action_previous_track << ui_->action_play_pause << ui_->action_stop << ui_->action_next_track << nullptr << ui_->action_love);
#endif #endif
#if defined(HAVE_QTSPARKLE) #if defined(HAVE_SPARKLE) || defined(HAVE_QTSPARKLE)
QAction *check_updates = ui_->menu_tools->addAction(tr("Check for updates...")); QAction *action_check_updates = ui_->menu_tools->addAction(tr("Check for updates..."));
check_updates->setMenuRole(QAction::ApplicationSpecificRole); action_check_updates->setMenuRole(QAction::ApplicationSpecificRole);
#endif #endif
#ifdef HAVE_GLOBALSHORTCUTS #ifdef HAVE_GLOBALSHORTCUTS
@@ -1046,13 +1071,18 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
app_->scrobbler()->Submit(); app_->scrobbler()->Submit();
} }
#ifdef HAVE_SPARKLE
SparkleUpdater *sparkle_updater = new SparkleUpdater(action_check_updates, this);
QObject::connect(action_check_updates, &QAction::triggered, sparkle_updater, &SparkleUpdater::CheckForUpdates);
#endif
#ifdef HAVE_QTSPARKLE #ifdef HAVE_QTSPARKLE
QUrl sparkle_url(QString::fromLatin1(QTSPARKLE_URL)); QUrl sparkle_url(QString::fromLatin1(QTSPARKLE_URL));
if (!sparkle_url.isEmpty()) { if (!sparkle_url.isEmpty()) {
qLog(Debug) << "Creating Qt Sparkle updater"; qLog(Debug) << "Creating Qt Sparkle updater";
qtsparkle::Updater *updater = new qtsparkle::Updater(sparkle_url, this); qtsparkle::Updater *updater = new qtsparkle::Updater(sparkle_url, this);
updater->SetVersion(QStringLiteral(STRAWBERRY_VERSION_PACKAGE)); updater->SetVersion(QStringLiteral(STRAWBERRY_VERSION_PACKAGE));
QObject::connect(check_updates, &QAction::triggered, updater, &qtsparkle::Updater::CheckNow); QObject::connect(action_check_updates, &QAction::triggered, updater, &qtsparkle::Updater::CheckNow);
} }
#endif #endif
@@ -1636,6 +1666,11 @@ void MainWindow::StopAfterCurrent() {
void MainWindow::showEvent(QShowEvent *e) { void MainWindow::showEvent(QShowEvent *e) {
if (error_dialog_ && error_dialog_->isVisible() && error_dialog_->isMinimized()) {
error_dialog_->raise();
error_dialog_->activateWindow();
}
QMainWindow::showEvent(e); QMainWindow::showEvent(e);
} }
@@ -1665,7 +1700,12 @@ void MainWindow::closeEvent(QCloseEvent *e) {
void MainWindow::SetHiddenInTray(const bool hidden) { void MainWindow::SetHiddenInTray(const bool hidden) {
if (hidden && isVisible()) { if (hidden && isVisible()) {
close(); if (tray_icon_->IsSystemTrayAvailable() && tray_icon_->isVisible() && keep_running_) {
close();
}
else {
showMinimized();
}
} }
else if (!hidden && isHidden()) { else if (!hidden && isHidden()) {
if (was_minimized_) { if (was_minimized_) {

View File

@@ -0,0 +1,27 @@
set(MIMEDATA_SOURCES
mimedata.cpp
songmimedata.cpp
)
set(MIMEDATA_HEADERS
mimedata.h
songmimedata.h
)
qt_wrap_cpp(MIMEDATA_SOURCES ${MIMEDATA_HEADERS})
add_library(strawberry_mimedata STATIC ${MIMEDATA_SOURCES})
target_include_directories(strawberry_mimedata PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(strawberry_mimedata PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
strawberry_core
strawberry_collection
)

View File

@@ -0,0 +1,44 @@
set(MOODBAR_SOURCES
moodbarbuilder.cpp
moodbarcontroller.cpp
moodbaritemdelegate.cpp
moodbarloader.cpp
moodbarpipeline.cpp
moodbarproxystyle.cpp
moodbarrenderer.cpp
)
set(MOODBAR_HEADERS
moodbarcontroller.h
moodbaritemdelegate.h
moodbarloader.h
moodbarpipeline.h
moodbarproxystyle.h
)
qt_wrap_cpp(MOODBAR_SOURCES ${MOODBAR_HEADERS})
add_library(strawberry_moodbar STATIC ${MOODBAR_SOURCES})
target_include_directories(strawberry_moodbar PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(strawberry_moodbar 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}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
)

View File

@@ -26,7 +26,7 @@
#include "includes/shared_ptr.h" #include "includes/shared_ptr.h"
#include "core/song.h" #include "core/song.h"
#include "core/settings.h" #include "core/settings.h"
#include "core/player.h" #include "player/player.h"
#include "engine/enginebase.h" #include "engine/enginebase.h"
#include "constants/moodbarsettings.h" #include "constants/moodbarsettings.h"

View File

@@ -119,7 +119,6 @@ QPixmap MoodbarItemDelegate::PixmapForIndex(const QModelIndex &idx, const QSize
data = new Data; data = new Data;
if (!data_.insert(url, data)) { if (!data_.insert(url, data)) {
qLog(Error) << "Could not insert moodbar data for URL" << url << "into cache"; qLog(Error) << "Could not insert moodbar data for URL" << url << "into cache";
delete data;
return QPixmap(); return QPixmap();
} }
} }

View File

@@ -64,7 +64,7 @@ MoodbarLoader::MoodbarLoader(QObject *parent)
kMaxActiveRequests(qMax(1, QThread::idealThreadCount() / 2)), kMaxActiveRequests(qMax(1, QThread::idealThreadCount() / 2)),
save_(false) { save_(false) {
setObjectName(QLatin1String(metaObject()->className())); setObjectName(QLatin1String(QObject::metaObject()->className()));
thread_->setObjectName(objectName()); thread_->setObjectName(objectName());
cache_->setCacheDirectory(StandardPaths::WritableLocation(StandardPaths::StandardLocation::CacheLocation) + u"/moodbar"_s); cache_->setCacheDirectory(StandardPaths::WritableLocation(StandardPaths::StandardLocation::CacheLocation) + u"/moodbar"_s);

33
src/mpris2/CMakeLists.txt Normal file
View File

@@ -0,0 +1,33 @@
set(MPRIS2_SOURCES
mpris2.cpp
)
set(MPRIS2_HEADERS
mpris2.h
)
qt_wrap_cpp(MPRIS2_SOURCES ${MPRIS2_HEADERS})
qt_add_dbus_adaptor(MPRIS2_SOURCES org.mpris.MediaPlayer2.xml mpris2.h mpris::Mpris2 mpris2_root Mpris2Root)
qt_add_dbus_adaptor(MPRIS2_SOURCES org.mpris.MediaPlayer2.Player.xml mpris2.h mpris::Mpris2 mpris2_player Mpris2Player)
qt_add_dbus_adaptor(MPRIS2_SOURCES org.mpris.MediaPlayer2.TrackList.xml mpris2.h mpris::Mpris2 mpris2_tracklist Mpris2TrackList)
qt_add_dbus_adaptor(MPRIS2_SOURCES org.mpris.MediaPlayer2.Playlists.xml mpris2.h mpris::Mpris2 mpris2_playlists Mpris2Playlists)
add_library(strawberry_mpris2 STATIC ${MPRIS2_SOURCES})
target_include_directories(strawberry_mpris2 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(strawberry_mpris2 PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::DBus
Qt${QT_VERSION_MAJOR}::Widgets
strawberry_core
strawberry_engine
strawberry_player
)

View File

@@ -48,7 +48,7 @@
#include "constants/timeconstants.h" #include "constants/timeconstants.h"
#include "core/song.h" #include "core/song.h"
#include "core/player.h" #include "player/player.h"
#include "engine/enginebase.h" #include "engine/enginebase.h"
#include "playlist/playlist.h" #include "playlist/playlist.h"
#include "playlist/playlistitem.h" #include "playlist/playlistitem.h"

View File

@@ -0,0 +1,40 @@
set(MUSICBRAINZ_SOURCES
acoustidclient.cpp
musicbrainzclient.cpp
tagfetcher.cpp
)
set(MUSICBRAINZ_HEADERS
acoustidclient.h
musicbrainzclient.h
tagfetcher.h
)
qt_wrap_cpp(MUSICBRAINZ_SOURCES ${MUSICBRAINZ_HEADERS})
add_library(strawberry_musicbrainz STATIC ${MUSICBRAINZ_SOURCES})
target_include_directories(strawberry_musicbrainz PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(strawberry_musicbrainz 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}::Gui
strawberry_utilities
strawberry_core
strawberry_engine
)

View File

@@ -0,0 +1,55 @@
set(ORGANIZE_SOURCES
organize.cpp
organizeformat.cpp
organizeformatvalidator.cpp
organizesyntaxhighlighter.cpp
organizedialog.cpp
organizeerrordialog.cpp
)
set(ORGANIZE_HEADERS
organize.h
organizeformatvalidator.h
organizesyntaxhighlighter.h
organizedialog.h
organizeerrordialog.h
)
set(ORGANIZE_UI
organizedialog.ui
organizeerrordialog.ui
)
qt_wrap_cpp(ORGANIZE_SOURCES ${ORGANIZE_HEADERS})
qt_wrap_ui(ORGANIZE_SOURCES ${ORGANIZE_UI})
add_library(strawberry_organize STATIC ${ORGANIZE_SOURCES})
target_include_directories(strawberry_organize PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)
target_link_libraries(strawberry_organize 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_tagreader
strawberry_widgets
strawberry_collection
)

Some files were not shown because too many files have changed in this diff Show More