Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4eb11c32b0 | ||
|
|
25457bc09a | ||
|
|
d5cfb5f733 | ||
|
|
79ba6e628e | ||
|
|
ef73add05a | ||
|
|
ec3d11fb27 | ||
|
|
3fbc7031b5 | ||
|
|
40beb5e428 | ||
|
|
0f608c8ef0 | ||
|
|
8509cb4743 | ||
|
|
f4429e8c4a | ||
|
|
e9e0829cdc | ||
|
|
93f0230423 | ||
|
|
f26a0df4a4 | ||
|
|
c7d4624282 | ||
|
|
b03eee2a22 | ||
|
|
7d4d72e706 | ||
|
|
e3c367984b | ||
|
|
0ebfa10d32 | ||
|
|
16d9a077f0 | ||
|
|
a9d8bbad42 | ||
|
|
d78bb94af3 | ||
|
|
b139c0a824 | ||
|
|
5b0b924d34 | ||
|
|
f75acf820c | ||
|
|
43a47f33ac | ||
|
|
fcea3a0877 | ||
|
|
a950ec3bd5 | ||
|
|
e35501ff0a | ||
|
|
4bfad9dad8 | ||
|
|
c5c7a07c12 | ||
|
|
7e22e0e552 | ||
|
|
84ec4bdc79 | ||
|
|
2bcad9b637 | ||
|
|
c8d5f03070 | ||
|
|
168e101a5a | ||
|
|
b4bc7333d9 | ||
|
|
e8b58c940e | ||
|
|
ec7202e3f6 | ||
|
|
9a740f7962 | ||
|
|
9210fdee0d | ||
|
|
d7661f0964 | ||
|
|
139e148912 | ||
|
|
1b8dedb4ed | ||
|
|
5d6b0fa329 | ||
|
|
f35bbd89c9 | ||
|
|
538a9e42f4 | ||
|
|
623147dea7 | ||
|
|
dfecd0cd12 | ||
|
|
fe3af3a676 | ||
|
|
25f60331ed | ||
|
|
d4860a3426 | ||
|
|
e7e77ed86b | ||
|
|
dc80459c59 | ||
|
|
2f2de59234 | ||
|
|
7bccc21878 | ||
|
|
40f9dafa44 | ||
|
|
355d436d29 | ||
|
|
079b684388 | ||
|
|
fd11f46d30 | ||
|
|
cb7099199a | ||
|
|
8566d91e89 | ||
|
|
f44ce49ea7 | ||
|
|
6ef69f6b32 | ||
|
|
f5983d5f10 | ||
|
|
54cce5e089 | ||
|
|
4e4e596a1e | ||
|
|
727a1f5ad1 | ||
|
|
85fa86625b | ||
|
|
2c91877f83 | ||
|
|
7d1fac44e9 | ||
|
|
2e34abfc0d | ||
|
|
81ba63e247 | ||
|
|
8b11a65522 | ||
|
|
7190ad1d15 | ||
|
|
1c9bae5df5 | ||
|
|
cc7fd73916 | ||
|
|
6d8725f268 | ||
|
|
373c7cdbc4 | ||
|
|
a4855bb33b | ||
|
|
57c1358ded | ||
|
|
eb4ce1feab | ||
|
|
838c17e144 | ||
|
|
4499cbca3c | ||
|
|
a835a4a2f7 | ||
|
|
9cc6a94353 | ||
|
|
5ed9d9c4a0 | ||
|
|
9c5ac7080d | ||
|
|
6346370e86 | ||
|
|
80697f8f30 | ||
|
|
18b8b56367 | ||
|
|
760aacca26 | ||
|
|
1a4f0dcf5a | ||
|
|
947484a71c | ||
|
|
a74439d038 | ||
|
|
c338618593 | ||
|
|
011897da53 | ||
|
|
3fcaa58947 | ||
|
|
ef8bd4362a | ||
|
|
627a2ef6dd | ||
|
|
2732536d6e | ||
|
|
5a1b4b3ff8 | ||
|
|
d93ec82e4f | ||
|
|
15080972f3 | ||
|
|
171b58f737 | ||
|
|
c008ab6141 | ||
|
|
f14c3654dc | ||
|
|
ae05a61551 | ||
|
|
8e1def225b | ||
|
|
6e061764ee | ||
|
|
ac55b22839 | ||
|
|
49f77d3b75 | ||
|
|
4abc650edf | ||
|
|
5ba00b61be | ||
|
|
bc16a6c4cb | ||
|
|
ea4dc6f040 | ||
|
|
749ae8d5eb | ||
|
|
7a56ffb7c3 | ||
|
|
e62ab23de2 | ||
|
|
c6f6118506 | ||
|
|
8a5d5ad952 | ||
|
|
49e2615d14 | ||
|
|
9289394261 | ||
|
|
8da4c88fd3 | ||
|
|
a303850341 | ||
|
|
fb33610672 | ||
|
|
d024dd6563 | ||
|
|
0be48f9f59 | ||
|
|
df9292bafe | ||
|
|
c1dcef3477 | ||
|
|
48bc1f8361 | ||
|
|
2b2b4dbcf4 | ||
|
|
a1eadecdef | ||
|
|
f0b529952d | ||
|
|
c1ac2debb8 | ||
|
|
ac40094d37 | ||
|
|
cb2bb4cb67 | ||
|
|
f2965940cc | ||
|
|
c9ca147898 | ||
|
|
c379d7f846 | ||
|
|
45ae1ed265 | ||
|
|
9bf00eff40 | ||
|
|
1677b3d5b9 | ||
|
|
2a6806004a | ||
|
|
39347d69df | ||
|
|
a2c0e4d4b1 | ||
|
|
ab2ffd9ac1 | ||
|
|
c69fff52cc | ||
|
|
1cfe61dc72 | ||
|
|
a23f39d81e | ||
|
|
b7724ff583 | ||
|
|
e5dba60fab | ||
|
|
2ccf489a83 | ||
|
|
068939ca0b | ||
|
|
94ba8614ec | ||
|
|
f12a0c2379 | ||
|
|
8ab257645b | ||
|
|
6331a0615f | ||
|
|
a21855fa20 | ||
|
|
12150c2180 | ||
|
|
d90aecb164 | ||
|
|
e738f2bc9f | ||
|
|
2f72c41cda | ||
|
|
aa43d42cdb | ||
|
|
be8228e33c | ||
|
|
5591472dbd | ||
|
|
30e6ced4e9 | ||
|
|
5f4c2bae89 | ||
|
|
0f036d9a43 | ||
|
|
1695ac3a32 | ||
|
|
07a19ba619 | ||
|
|
4dd78d89a0 | ||
|
|
8f4056faa6 | ||
|
|
7b40c33892 | ||
|
|
b06bb5142f | ||
|
|
d576156ee1 |
@@ -35,7 +35,7 @@ commands:
|
||||
working_directory: build
|
||||
- run:
|
||||
name: Build RPM
|
||||
command: rpmbuild -ba ../dist/rpm/strawberry.spec
|
||||
command: rpmbuild -ba ../dist/unix/strawberry.spec
|
||||
working_directory: build
|
||||
|
||||
|
||||
@@ -59,14 +59,12 @@ commands:
|
||||
zypper --non-interactive --gpg-auto-import-keys install
|
||||
lsb-release
|
||||
rpm-build
|
||||
rpmdevtools
|
||||
git
|
||||
tar
|
||||
make
|
||||
cmake
|
||||
gcc
|
||||
gcc-c++
|
||||
pkg-config
|
||||
gettext-tools
|
||||
glibc-devel
|
||||
libboost_headers-devel
|
||||
@@ -84,7 +82,6 @@ commands:
|
||||
gstreamer-plugins-base-devel
|
||||
libxine-devel
|
||||
vlc-devel
|
||||
taglib-devel
|
||||
libQt5Core-devel
|
||||
libQt5Gui-devel
|
||||
libQt5Widgets-devel
|
||||
@@ -333,7 +330,7 @@ jobs:
|
||||
|
||||
build_source:
|
||||
docker:
|
||||
- image: opensuse/tumbleweed
|
||||
- image: opensuse/leap:15.1
|
||||
steps:
|
||||
- install_opensuse_dependencies
|
||||
- checkout
|
||||
@@ -347,6 +344,12 @@ jobs:
|
||||
environment:
|
||||
RPM_BUILD_NCPUS: "2"
|
||||
steps:
|
||||
- run:
|
||||
name: Update packages
|
||||
command: zypper --non-interactive --gpg-auto-import-keys ref
|
||||
- run:
|
||||
name: Upgrade packages
|
||||
command: zypper --non-interactive --gpg-auto-import-keys dup
|
||||
- install_opensuse_dependencies
|
||||
- checkout
|
||||
- cmake
|
||||
|
||||
8
.github/workflows/ccpp.yml
vendored
@@ -6,13 +6,13 @@ jobs:
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: opensuse/tumbleweed
|
||||
image: opensuse/leap:15.1
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Update Packages
|
||||
run: zypper ref
|
||||
- name: Install Packages
|
||||
run: zypper --non-interactive --gpg-auto-import-keys install lsb-release rpm-build rpmdevtools git tar make cmake gcc gcc-c++ pkg-config gettext-tools glibc-devel libboost_headers-devel boost-devel glib2-devel glib2-tools dbus-1-devel alsa-devel libnotify-devel libgnutls-devel protobuf-devel sqlite3-devel libpulse-devel gstreamer-devel gstreamer-plugins-base-devel libxine-devel vlc-devel taglib-devel libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel libQt5Concurrent-devel libQt5Network-devel libQt5Sql-devel libQt5DBus-devel libQt5Test-devel libqt5-qtx11extras-devel libqt5-qtbase-common-devel libQt5Sql5-sqlite libqt5-linguist-devel libcdio-devel libgpod-devel libplist-devel libmtp-devel libusbmuxd-devel libchromaprint-devel desktop-file-utils update-desktop-files appstream-glib hicolor-icon-theme
|
||||
run: zypper --non-interactive --gpg-auto-import-keys install lsb-release rpm-build git tar make cmake gcc gcc-c++ gettext-tools glibc-devel libboost_headers-devel boost-devel glib2-devel glib2-tools dbus-1-devel alsa-devel libnotify-devel libgnutls-devel protobuf-devel sqlite3-devel libpulse-devel gstreamer-devel gstreamer-plugins-base-devel libxine-devel vlc-devel taglib-devel libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel libQt5Concurrent-devel libQt5Network-devel libQt5Sql-devel libQt5DBus-devel libQt5Test-devel libqt5-qtx11extras-devel libqt5-qtbase-common-devel libQt5Sql5-sqlite libqt5-linguist-devel libcdio-devel libgpod-devel libplist-devel libmtp-devel libusbmuxd-devel libchromaprint-devel desktop-file-utils update-desktop-files appstream-glib hicolor-icon-theme
|
||||
- name: Create Build Environment
|
||||
run: mkdir -p build
|
||||
- name: Configure CMake
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Unlink python
|
||||
run: brew unlink python@2
|
||||
- name: Install Packages
|
||||
run: brew install glib pkgconfig boost libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav libcdio libmtp libimobiledevice libplist create-dmg
|
||||
run: brew install glib pkgconfig boost libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav libcdio libmtp libimobiledevice libplist create-dmg taglib
|
||||
- name: Create Build Environment
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
- name: Configure CMake
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
Qt5LinguistTools_DIR: /usr/local/opt/qt5/lib/cmake/Qt5LinguistTools
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_BUNDLE=ON
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_BUNDLE=ON -DUSE_SYSTEM_TAGLIB=ON
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
|
||||
@@ -21,7 +21,7 @@ before_install:
|
||||
git fetch --unshallow || travis_terminate 1;
|
||||
git pull || travis_terminate 1;
|
||||
brew unlink python@2 || travis_terminate 1;
|
||||
brew install glib pkgconfig libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint zlib;
|
||||
brew install glib pkgconfig libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint zlib taglib;
|
||||
brew install gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav;
|
||||
brew install libcdio libmtp libimobiledevice libplist;
|
||||
brew install create-dmg;
|
||||
@@ -33,7 +33,7 @@ before_install:
|
||||
fi
|
||||
before_script:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build cmake -Hstrawberry -Bbuild ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir build; cd build; cmake .. -DUSE_BUNDLE=ON ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir build; cd build; cmake .. -DUSE_BUNDLE=ON -DUSE_SYSTEM_TAGLIB=ON ; fi
|
||||
script:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build make -C build -j8 ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
|
||||
15
3rdparty/singleapplication/CMakeLists.txt
vendored
@@ -1,16 +1,8 @@
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.0)
|
||||
check_function_exists(geteuid HAVE_GETEUID)
|
||||
check_function_exists(getpwuid HAVE_GETPWUID)
|
||||
@@ -19,14 +11,15 @@ endif()
|
||||
set(SINGLEAPP-SOURCES singleapplication.cpp singleapplication_p.cpp)
|
||||
set(SINGLEAPP-MOC-HEADERS singleapplication.h singleapplication_p.h)
|
||||
QT5_WRAP_CPP(SINGLEAPP-SOURCES-MOC ${SINGLEAPP-MOC-HEADERS})
|
||||
ADD_LIBRARY(singleapplication STATIC ${SINGLEAPP-SOURCES} ${SINGLEAPP-SOURCES-MOC})
|
||||
add_library(singleapplication STATIC ${SINGLEAPP-SOURCES} ${SINGLEAPP-SOURCES-MOC})
|
||||
target_link_libraries(singleapplication Qt5::Core Qt5::Widgets Qt5::Network)
|
||||
|
||||
set(SINGLECOREAPP-SOURCES singlecoreapplication.cpp singlecoreapplication_p.cpp)
|
||||
set(SINGLECOREAPP-MOC-HEADERS singlecoreapplication.h singlecoreapplication_p.h)
|
||||
QT5_WRAP_CPP(SINGLECOREAPP-SOURCES-MOC ${SINGLECOREAPP-MOC-HEADERS})
|
||||
ADD_LIBRARY(singlecoreapplication STATIC ${SINGLECOREAPP-SOURCES} ${SINGLECOREAPP-SOURCES-MOC})
|
||||
add_library(singlecoreapplication STATIC ${SINGLECOREAPP-SOURCES} ${SINGLECOREAPP-SOURCES-MOC})
|
||||
target_link_libraries(singlecoreapplication Qt5::Core Qt5::Widgets Qt5::Network)
|
||||
|
||||
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
# include <lmcons.h>
|
||||
#endif
|
||||
|
||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *q_ptr)
|
||||
: q_ptr(q_ptr),
|
||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *_q_ptr)
|
||||
: q_ptr(_q_ptr),
|
||||
memory(nullptr),
|
||||
socket(nullptr),
|
||||
server(nullptr),
|
||||
@@ -186,7 +186,7 @@ void SingleApplicationPrivate::startPrimary() {
|
||||
|
||||
void SingleApplicationPrivate::startSecondary() {}
|
||||
|
||||
void SingleApplicationPrivate::connectToPrimary(int msecs, ConnectionType connectionType) {
|
||||
void SingleApplicationPrivate::connectToPrimary(const int msecs, const ConnectionType connectionType) {
|
||||
|
||||
// Connect to the Local Server of the Primary Instance if not already connected.
|
||||
if (socket == nullptr) {
|
||||
@@ -386,14 +386,14 @@ void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, quint32 instanceId) {
|
||||
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, const quint32 instanceId) {
|
||||
|
||||
Q_Q(SingleApplication);
|
||||
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, quint32 instanceId) {
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, const quint32 instanceId) {
|
||||
|
||||
if (closedSocket->bytesAvailable() > 0)
|
||||
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
||||
|
||||
@@ -74,14 +74,14 @@ class SingleApplicationPrivate : public QObject {
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
|
||||
SingleApplicationPrivate( SingleApplication *q_ptr );
|
||||
SingleApplicationPrivate(SingleApplication *_q_ptr);
|
||||
~SingleApplicationPrivate();
|
||||
|
||||
void genBlockServerName();
|
||||
void initializeMemoryBlock();
|
||||
void startPrimary();
|
||||
void startSecondary();
|
||||
void connectToPrimary(int msecs, ConnectionType connectionType );
|
||||
void connectToPrimary(const int msecs, const ConnectionType connectionType);
|
||||
quint16 blockChecksum();
|
||||
qint64 primaryPid();
|
||||
void readInitMessageHeader(QLocalSocket *socket);
|
||||
@@ -98,8 +98,8 @@ class SingleApplicationPrivate : public QObject {
|
||||
|
||||
public slots:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable(QLocalSocket*, quint32);
|
||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
||||
void slotDataAvailable(QLocalSocket*, const quint32);
|
||||
void slotClientConnectionClosed(QLocalSocket*, const quint32);
|
||||
};
|
||||
|
||||
#endif // SINGLEAPPLICATION_P_H
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
# include <lmcons.h>
|
||||
#endif
|
||||
|
||||
SingleCoreApplicationPrivate::SingleCoreApplicationPrivate(SingleCoreApplication *q_ptr)
|
||||
: q_ptr(q_ptr),
|
||||
SingleCoreApplicationPrivate::SingleCoreApplicationPrivate(SingleCoreApplication *_q_ptr)
|
||||
: q_ptr(_q_ptr),
|
||||
memory(nullptr),
|
||||
socket(nullptr),
|
||||
server(nullptr),
|
||||
@@ -186,7 +186,7 @@ void SingleCoreApplicationPrivate::startPrimary() {
|
||||
|
||||
void SingleCoreApplicationPrivate::startSecondary() {}
|
||||
|
||||
void SingleCoreApplicationPrivate::connectToPrimary(int msecs, ConnectionType connectionType) {
|
||||
void SingleCoreApplicationPrivate::connectToPrimary(const int msecs, const ConnectionType connectionType) {
|
||||
|
||||
// Connect to the Local Server of the Primary Instance if not already connected.
|
||||
if (socket == nullptr) {
|
||||
@@ -386,14 +386,14 @@ void SingleCoreApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
|
||||
|
||||
}
|
||||
|
||||
void SingleCoreApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, quint32 instanceId) {
|
||||
void SingleCoreApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, const quint32 instanceId) {
|
||||
|
||||
Q_Q(SingleCoreApplication);
|
||||
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
|
||||
|
||||
}
|
||||
|
||||
void SingleCoreApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, quint32 instanceId) {
|
||||
void SingleCoreApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, const quint32 instanceId) {
|
||||
|
||||
if (closedSocket->bytesAvailable() > 0)
|
||||
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
||||
|
||||
@@ -74,14 +74,14 @@ class SingleCoreApplicationPrivate : public QObject {
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleCoreApplication)
|
||||
|
||||
SingleCoreApplicationPrivate( SingleCoreApplication *q_ptr );
|
||||
SingleCoreApplicationPrivate(SingleCoreApplication *_q_ptr);
|
||||
~SingleCoreApplicationPrivate();
|
||||
|
||||
void genBlockServerName();
|
||||
void initializeMemoryBlock();
|
||||
void startPrimary();
|
||||
void startSecondary();
|
||||
void connectToPrimary(int msecs, ConnectionType connectionType );
|
||||
void connectToPrimary(const int msecs, const ConnectionType connectionType);
|
||||
quint16 blockChecksum();
|
||||
qint64 primaryPid();
|
||||
void readInitMessageHeader(QLocalSocket *socket);
|
||||
@@ -98,8 +98,8 @@ class SingleCoreApplicationPrivate : public QObject {
|
||||
|
||||
public slots:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable(QLocalSocket*, quint32);
|
||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
||||
void slotDataAvailable(QLocalSocket*, const quint32);
|
||||
void slotClientConnectionClosed(QLocalSocket*, const quint32);
|
||||
};
|
||||
|
||||
#endif // SINGLECOREAPPLICATION_P_H
|
||||
|
||||
6
3rdparty/taglib/CMakeLists.txt
vendored
@@ -1,8 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -fpermissive -Wall -Woverloaded-virtual -Wno-sign-compare -Wno-delete-non-virtual-dtor")
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
set(TAGLIB_SOVERSION_CURRENT 17)
|
||||
set(TAGLIB_SOVERSION_REVISION 0)
|
||||
|
||||
2
3rdparty/taglib/ape/apefile.cpp
vendored
@@ -87,7 +87,7 @@ public:
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool APE::File::isSupported(IOStream *stream)
|
||||
bool APE::File::isSupported(IOStream*)
|
||||
{
|
||||
// An APE file has an ID "MAC " somewhere. An ID3v2 tag may precede.
|
||||
|
||||
|
||||
2
3rdparty/taglib/asf/asfattribute.cpp
vendored
@@ -264,6 +264,7 @@ int ASF::Attribute::dataSize() const
|
||||
case BytesType:
|
||||
if(d->pictureValue.isValid())
|
||||
return d->pictureValue.dataSize();
|
||||
break;
|
||||
case GuidType:
|
||||
return d->byteVectorValue.size();
|
||||
}
|
||||
@@ -305,6 +306,7 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
|
||||
data.append(d->pictureValue.render());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GuidType:
|
||||
data.append(d->byteVectorValue);
|
||||
break;
|
||||
|
||||
8
3rdparty/taglib/dsdiff/dsdifffile.cpp
vendored
@@ -51,7 +51,7 @@ namespace
|
||||
|
||||
int chunkIndex(const ChunkList &chunks, const ByteVector &id)
|
||||
{
|
||||
for(int i = 0; i < chunks.size(); i++) {
|
||||
for (unsigned long int i = 0 ; i < chunks.size() ; i++) {
|
||||
if(chunks[i].name == id)
|
||||
return i;
|
||||
}
|
||||
@@ -64,8 +64,8 @@ namespace
|
||||
if(name.size() != 4)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(name[i] < 32 || name[i] > 127)
|
||||
for (int i = 0 ; i < 4 ; i++) {
|
||||
if (name[i] < 32)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ bool DSDIFF::File::save()
|
||||
return save(AllTags);
|
||||
}
|
||||
|
||||
bool DSDIFF::File::save(TagTypes tags, StripTags strip, ID3v2::Version version)
|
||||
bool DSDIFF::File::save(TagTypes tags, StripTags, ID3v2::Version version)
|
||||
{
|
||||
if(readOnly()) {
|
||||
debug("DSDIFF::File::save() -- File is read only.");
|
||||
|
||||
2
3rdparty/taglib/dsf/dsffile.cpp
vendored
@@ -180,7 +180,7 @@ bool DSF::File::save()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void DSF::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
|
||||
void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
|
||||
{
|
||||
// A DSF file consists of four chunks: DSD chunk, format chunk, data chunk, and metadata chunk
|
||||
// The file format is not chunked in the sense of a RIFF File, though
|
||||
|
||||
8
3rdparty/taglib/fileref.cpp
vendored
@@ -228,10 +228,10 @@ namespace
|
||||
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "OGA") {
|
||||
/* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */
|
||||
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(file->isValid())
|
||||
return file;
|
||||
delete file;
|
||||
File *file_flac = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if (file_flac->isValid())
|
||||
return file_flac;
|
||||
delete file_flac;
|
||||
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
}
|
||||
if(ext == "FLAC")
|
||||
|
||||
4
3rdparty/taglib/fileref.h
vendored
@@ -92,8 +92,8 @@ namespace TagLib {
|
||||
|
||||
class TAGLIB_EXPORT FileTypeResolver
|
||||
{
|
||||
TAGLIB_IGNORE_MISSING_DESTRUCTOR
|
||||
public:
|
||||
virtual ~FileTypeResolver();
|
||||
/*!
|
||||
* This method must be overridden to provide an additional file type
|
||||
* resolver. If the resolver is able to determine the file type it should
|
||||
@@ -286,4 +286,4 @@ namespace TagLib {
|
||||
}
|
||||
} // namespace Strawberry_TagLib::TagLib
|
||||
|
||||
#endif
|
||||
#endif // TAGLIB_FILEREF_H
|
||||
|
||||
8
3rdparty/taglib/mod/modfilebase.cpp
vendored
@@ -60,9 +60,9 @@ bool Mod::FileBase::readString(String &s, unsigned long size)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mod::FileBase::writeByte(unsigned char byte)
|
||||
void Mod::FileBase::writeByte(unsigned char _byte)
|
||||
{
|
||||
ByteVector data(1, byte);
|
||||
ByteVector data(1, _byte);
|
||||
writeBlock(data);
|
||||
}
|
||||
|
||||
@@ -86,11 +86,11 @@ void Mod::FileBase::writeU32B(unsigned long number)
|
||||
writeBlock(ByteVector::fromUInt(number, true));
|
||||
}
|
||||
|
||||
bool Mod::FileBase::readByte(unsigned char &byte)
|
||||
bool Mod::FileBase::readByte(unsigned char &_byte)
|
||||
{
|
||||
ByteVector data(readBlock(1));
|
||||
if(data.size() < 1) return false;
|
||||
byte = data[0];
|
||||
_byte = data[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
6
3rdparty/taglib/mp4/mp4atom.cpp
vendored
@@ -122,15 +122,15 @@ MP4::Atom::find(const char *name1, const char *name2, const char *name3, const c
|
||||
}
|
||||
|
||||
MP4::AtomList
|
||||
MP4::Atom::findall(const char *name, bool recursive)
|
||||
MP4::Atom::findall(const char *_name, bool recursive)
|
||||
{
|
||||
MP4::AtomList result;
|
||||
for(AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
|
||||
if((*it)->name == name) {
|
||||
if((*it)->name == _name) {
|
||||
result.append(*it);
|
||||
}
|
||||
if(recursive) {
|
||||
result.append((*it)->findall(name, recursive));
|
||||
result.append((*it)->findall(_name, recursive));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
2
3rdparty/taglib/mp4/mp4atom.h
vendored
@@ -67,7 +67,7 @@ namespace TagLib {
|
||||
};
|
||||
|
||||
struct AtomData {
|
||||
AtomData(AtomDataType type, ByteVector data) : type(type), locale(0), data(data) {}
|
||||
AtomData(AtomDataType _type, ByteVector _data) : type(_type), locale(0), data(_data) {}
|
||||
AtomDataType type;
|
||||
int locale;
|
||||
ByteVector data;
|
||||
|
||||
@@ -334,14 +334,14 @@ ByteVector TableOfContentsFrame::renderFields() const
|
||||
data.append(flags);
|
||||
data.append((char)(entryCount()));
|
||||
ByteVectorList::ConstIterator it = d->childElements.begin();
|
||||
while(it != d->childElements.end()) {
|
||||
while (it != d->childElements.end()) {
|
||||
data.append(*it);
|
||||
data.append('\0');
|
||||
it++;
|
||||
}
|
||||
FrameList l = d->embeddedFrameList;
|
||||
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
|
||||
data.append((*it)->render());
|
||||
for (FrameList::ConstIterator it2 = l.begin(); it2 != l.end(); ++it2)
|
||||
data.append((*it2)->render());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
2
3rdparty/taglib/mpeg/id3v2/id3v2frame.cpp
vendored
@@ -417,7 +417,7 @@ namespace
|
||||
{"TYER", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TIME", "TDRC"}, // 2.3 -> 2.4
|
||||
};
|
||||
const size_t deprecatedFramesSize = sizeof(deprecatedFrames) / sizeof(deprecatedFrames[0]);;
|
||||
const size_t deprecatedFramesSize = sizeof(deprecatedFrames) / sizeof(deprecatedFrames[0]);
|
||||
}
|
||||
|
||||
String Frame::frameIDToKey(const ByteVector &id)
|
||||
|
||||
2
3rdparty/taglib/mpeg/mpegheader.cpp
vendored
@@ -69,7 +69,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MPEG::Header::Header(const ByteVector &data) :
|
||||
MPEG::Header::Header(const ByteVector&) :
|
||||
d(new HeaderPrivate())
|
||||
{
|
||||
debug("MPEG::Header::Header() - This constructor is no longer used.");
|
||||
|
||||
4
3rdparty/taglib/ogg/oggfile.cpp
vendored
@@ -296,10 +296,10 @@ void Ogg::File::writePacket(unsigned int i, const ByteVector &packet)
|
||||
break;
|
||||
|
||||
page.setPageSequenceNumber(page.pageSequenceNumber() + numberOfNewPages);
|
||||
const ByteVector data = page.render();
|
||||
const ByteVector data2 = page.render();
|
||||
|
||||
seek(pageOffset + 18);
|
||||
writeBlock(data.mid(18, 8));
|
||||
writeBlock(data2.mid(18, 8));
|
||||
|
||||
if(page.header()->lastPageOfStream())
|
||||
break;
|
||||
|
||||
5
3rdparty/taglib/ogg/xiphcomment.cpp
vendored
@@ -379,8 +379,7 @@ ByteVector Ogg::XiphComment::render(bool addFramingBit) const
|
||||
// std::pair<String, StringList> where the first String is the field name and
|
||||
// the StringList is the values associated with that field.
|
||||
|
||||
FieldListMap::ConstIterator it = d->fieldListMap.begin();
|
||||
for(; it != d->fieldListMap.end(); ++it) {
|
||||
for(FieldListMap::ConstIterator it = d->fieldListMap.begin() ; it != d->fieldListMap.end() ; ++it) {
|
||||
|
||||
// And now iterate over the values of the current list.
|
||||
|
||||
@@ -398,7 +397,7 @@ ByteVector Ogg::XiphComment::render(bool addFramingBit) const
|
||||
}
|
||||
}
|
||||
|
||||
for(PictureConstIterator it = d->pictureList.begin(); it != d->pictureList.end(); ++it) {
|
||||
for (PictureConstIterator it = d->pictureList.begin(); it != d->pictureList.end(); ++it) {
|
||||
ByteVector picture = (*it)->render().toBase64();
|
||||
data.append(ByteVector::fromUInt(picture.size() + 23, false));
|
||||
data.append("METADATA_BLOCK_PICTURE=");
|
||||
|
||||
4
3rdparty/taglib/riff/rifffile.cpp
vendored
@@ -46,8 +46,8 @@ struct Chunk
|
||||
class RIFF::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
explicit FilePrivate(Endianness endianness) :
|
||||
endianness(endianness),
|
||||
explicit FilePrivate(Endianness _endianness) :
|
||||
endianness(_endianness),
|
||||
size(0),
|
||||
sizeOffset(0) {}
|
||||
|
||||
|
||||
5
3rdparty/taglib/toolkit/tbytevectorlist.cpp
vendored
@@ -77,11 +77,6 @@ ByteVectorList::ByteVectorList() :
|
||||
|
||||
}
|
||||
|
||||
ByteVectorList::ByteVectorList(const ByteVectorList &l) : List<ByteVector>(l)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ByteVectorList::~ByteVectorList()
|
||||
{
|
||||
|
||||
|
||||
7
3rdparty/taglib/toolkit/tbytevectorlist.h
vendored
@@ -53,13 +53,6 @@ namespace TagLib {
|
||||
*/
|
||||
virtual ~ByteVectorList();
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a l. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
ByteVectorList(const ByteVectorList &l);
|
||||
|
||||
/*!
|
||||
* Convert the ByteVectorList to a ByteVector separated by \a separator. By
|
||||
* default a space is used.
|
||||
|
||||
@@ -43,8 +43,8 @@ public:
|
||||
long position;
|
||||
};
|
||||
|
||||
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &data) :
|
||||
data(data),
|
||||
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &_data) :
|
||||
data(_data),
|
||||
position(0)
|
||||
{
|
||||
}
|
||||
|
||||
6
3rdparty/taglib/toolkit/tfile.cpp
vendored
@@ -71,9 +71,9 @@ using namespace Strawberry_TagLib::TagLib;
|
||||
class File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate(IOStream *stream, bool owner) :
|
||||
stream(stream),
|
||||
streamOwner(owner),
|
||||
FilePrivate(IOStream *_stream, bool _owner) :
|
||||
stream(_stream),
|
||||
streamOwner(_owner),
|
||||
valid(true) {}
|
||||
|
||||
~FilePrivate()
|
||||
|
||||
2
3rdparty/taglib/toolkit/tfilestream.cpp
vendored
@@ -58,7 +58,7 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
FileHandle openFile(const int fileDescriptor, bool readOnly)
|
||||
FileHandle openFile(const int, bool)
|
||||
{
|
||||
return InvalidFileHandle;
|
||||
}
|
||||
|
||||
20
3rdparty/taglib/toolkit/tpropertymap.cpp
vendored
@@ -28,16 +28,10 @@
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
|
||||
PropertyMap::PropertyMap() : SimplePropertyMap()
|
||||
{
|
||||
}
|
||||
PropertyMap::PropertyMap() : SimplePropertyMap() {}
|
||||
|
||||
PropertyMap::PropertyMap(const PropertyMap &m) : SimplePropertyMap(m), unsupported(m.unsupported)
|
||||
{
|
||||
}
|
||||
PropertyMap::PropertyMap(const SimplePropertyMap &m) {
|
||||
|
||||
PropertyMap::PropertyMap(const SimplePropertyMap &m)
|
||||
{
|
||||
for(SimplePropertyMap::ConstIterator it = m.begin(); it != m.end(); ++it){
|
||||
String key = it->first.upper();
|
||||
if(!key.isEmpty())
|
||||
@@ -45,14 +39,13 @@ PropertyMap::PropertyMap(const SimplePropertyMap &m)
|
||||
else
|
||||
unsupported.append(it->first);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PropertyMap::~PropertyMap()
|
||||
{
|
||||
}
|
||||
PropertyMap::~PropertyMap() {}
|
||||
|
||||
bool PropertyMap::insert(const String &key, const StringList &values) {
|
||||
|
||||
bool PropertyMap::insert(const String &key, const StringList &values)
|
||||
{
|
||||
String realKey = key.upper();
|
||||
Iterator result = SimplePropertyMap::find(realKey);
|
||||
if(result == end())
|
||||
@@ -60,6 +53,7 @@ bool PropertyMap::insert(const String &key, const StringList &values)
|
||||
else
|
||||
SimplePropertyMap::operator[](realKey).append(values);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool PropertyMap::replace(const String &key, const StringList &values)
|
||||
|
||||
2
3rdparty/taglib/toolkit/tpropertymap.h
vendored
@@ -115,8 +115,6 @@ namespace TagLib {
|
||||
|
||||
PropertyMap();
|
||||
|
||||
PropertyMap(const PropertyMap &m);
|
||||
|
||||
/*!
|
||||
* Creates a PropertyMap initialized from a SimplePropertyMap. Copies all
|
||||
* entries from \a m that have valid keys.
|
||||
|
||||
7
3rdparty/taglib/toolkit/tstringlist.cpp
vendored
@@ -62,13 +62,6 @@ StringList::StringList() :
|
||||
|
||||
}
|
||||
|
||||
StringList::StringList(const StringList &l) :
|
||||
List<String>(l),
|
||||
d(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StringList::StringList(const String &s) :
|
||||
List<String>(),
|
||||
d(nullptr)
|
||||
|
||||
2
3rdparty/taglib/toolkit/tstringlist.h
vendored
@@ -57,7 +57,7 @@ namespace TagLib {
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
StringList(const StringList &l);
|
||||
StringList(const StringList &l) = default;
|
||||
|
||||
/*!
|
||||
* Constructs a StringList with \a s as a member.
|
||||
|
||||
2
3rdparty/taglib/toolkit/tutils.h
vendored
@@ -193,7 +193,7 @@ namespace TagLib
|
||||
// The last resort. May cause a buffer overflow.
|
||||
|
||||
length = vsprintf(buf, format, args);
|
||||
if(length >= BufferSize) {
|
||||
if(length >= (int)BufferSize) {
|
||||
debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
|
||||
length = -1;
|
||||
}
|
||||
|
||||
44
3rdparty/taglib/xm/xmfile.cpp
vendored
@@ -110,7 +110,7 @@ template<typename T>
|
||||
class ValueReader : public Reader
|
||||
{
|
||||
public:
|
||||
explicit ValueReader(T &value) : value(value)
|
||||
explicit ValueReader(T &_value) : value(_value)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ private:
|
||||
class ByteReader : public ValueReader<unsigned char>
|
||||
{
|
||||
public:
|
||||
explicit ByteReader(unsigned char &byte) : ValueReader<unsigned char>(byte) {}
|
||||
explicit ByteReader(unsigned char &_byte) : ValueReader<unsigned char>(_byte) {}
|
||||
|
||||
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
|
||||
{
|
||||
@@ -172,8 +172,8 @@ template<typename T>
|
||||
class NumberReader : public ValueReader<T>
|
||||
{
|
||||
public:
|
||||
NumberReader(T &value, bool bigEndian) :
|
||||
ValueReader<T>(value), bigEndian(bigEndian)
|
||||
NumberReader(T &_value, bool _bigEndian) :
|
||||
ValueReader<T>(_value), bigEndian(_bigEndian)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -184,8 +184,8 @@ protected:
|
||||
class U16Reader : public NumberReader<unsigned short>
|
||||
{
|
||||
public:
|
||||
U16Reader(unsigned short &value, bool bigEndian)
|
||||
: NumberReader<unsigned short>(value, bigEndian) {}
|
||||
U16Reader(unsigned short &_value, bool _bigEndian)
|
||||
: NumberReader<unsigned short>(_value, _bigEndian) {}
|
||||
|
||||
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
|
||||
{
|
||||
@@ -203,8 +203,8 @@ public:
|
||||
class U32Reader : public NumberReader<unsigned long>
|
||||
{
|
||||
public:
|
||||
U32Reader(unsigned long &value, bool bigEndian = true) :
|
||||
NumberReader<unsigned long>(value, bigEndian)
|
||||
U32Reader(unsigned long &_value, bool _bigEndian = true) :
|
||||
NumberReader<unsigned long>(_value, _bigEndian)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -479,11 +479,11 @@ bool XM::File::save()
|
||||
|
||||
if(sampleHeaderSize > 18U) {
|
||||
seek(pos + 18);
|
||||
const unsigned int len = std::min(sampleHeaderSize - 18U, 22UL);
|
||||
const unsigned int len2 = std::min(sampleHeaderSize - 18U, 22UL);
|
||||
if(sampleNameIndex >= lines.size())
|
||||
writeString(String(), len);
|
||||
writeString(String(), len2);
|
||||
else
|
||||
writeString(lines[sampleNameIndex ++], len);
|
||||
writeString(lines[sampleNameIndex ++], len2);
|
||||
}
|
||||
}
|
||||
pos += sampleHeaderSize;
|
||||
@@ -560,10 +560,10 @@ void XM::File::read(bool)
|
||||
StructReader pattern;
|
||||
pattern.byte(packingType).u16L(rowCount).u16L(dataSize);
|
||||
|
||||
unsigned int count = pattern.read(*this, patternHeaderLength - 4U);
|
||||
READ_ASSERT(count == std::min(patternHeaderLength - 4U, (unsigned long)pattern.size()));
|
||||
unsigned int count2 = pattern.read(*this, patternHeaderLength - 4U);
|
||||
READ_ASSERT(count2 == std::min(patternHeaderLength - 4U, (unsigned long)pattern.size()));
|
||||
|
||||
seek(patternHeaderLength - (4 + count) + dataSize, Current);
|
||||
seek(patternHeaderLength - (4 + count2) + dataSize, Current);
|
||||
}
|
||||
|
||||
StringList intrumentNames;
|
||||
@@ -583,17 +583,17 @@ void XM::File::read(bool)
|
||||
instrument.string(instrumentName, 22).byte(instrumentType).u16L(sampleCount);
|
||||
|
||||
// 4 for instrumentHeaderSize
|
||||
unsigned int count = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
|
||||
READ_ASSERT(count == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
|
||||
unsigned int count2 = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
|
||||
READ_ASSERT(count2 == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
|
||||
|
||||
long offset = 0;
|
||||
if(sampleCount > 0) {
|
||||
unsigned long sampleHeaderSize = 0;
|
||||
sumSampleCount += sampleCount;
|
||||
// wouldn't know which header size to assume otherwise:
|
||||
READ_ASSERT(instrumentHeaderSize >= count + 4 && readU32L(sampleHeaderSize));
|
||||
READ_ASSERT(instrumentHeaderSize >= count2 + 4 && readU32L(sampleHeaderSize));
|
||||
// skip unhandled header proportion:
|
||||
seek(instrumentHeaderSize - count - 4, Current);
|
||||
seek(instrumentHeaderSize - count2 - 4, Current);
|
||||
|
||||
for(unsigned short j = 0; j < sampleCount; ++ j) {
|
||||
unsigned long sampleLength = 0;
|
||||
@@ -618,17 +618,17 @@ void XM::File::read(bool)
|
||||
.byte(compression)
|
||||
.string(sampleName, 22);
|
||||
|
||||
unsigned int count = sample.read(*this, sampleHeaderSize);
|
||||
READ_ASSERT(count == std::min(sampleHeaderSize, (unsigned long)sample.size()));
|
||||
unsigned int count3 = sample.read(*this, sampleHeaderSize);
|
||||
READ_ASSERT(count3 == std::min(sampleHeaderSize, (unsigned long)sample.size()));
|
||||
// skip unhandled header proportion:
|
||||
seek(sampleHeaderSize - count, Current);
|
||||
seek(sampleHeaderSize - count3, Current);
|
||||
|
||||
offset += sampleLength;
|
||||
sampleNames.append(sampleName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
offset = instrumentHeaderSize - count;
|
||||
offset = instrumentHeaderSize - count2;
|
||||
}
|
||||
intrumentNames.append(instrumentName);
|
||||
seek(offset, Current);
|
||||
|
||||
@@ -1,24 +1,7 @@
|
||||
# Strawberry Music Player
|
||||
# Copyright 2013, Jonas Kvinge <jonas@strawbs.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/>.
|
||||
|
||||
project(strawberry)
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.0)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCXXSourceRuns)
|
||||
@@ -32,6 +15,8 @@ include(cmake/Rpm.cmake)
|
||||
include(cmake/Deb.cmake)
|
||||
include(cmake/Dmg.cmake)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(LINUX ON)
|
||||
endif()
|
||||
@@ -42,8 +27,46 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
|
||||
set(OPENBSD ON)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
list(APPEND COMPILE_OPTIONS
|
||||
$<$<COMPILE_LANGUAGE:C>:--std=c99>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:--std=c++11>
|
||||
-U__STRICT_ANSI__
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Wunused
|
||||
-Wshadow
|
||||
-Wundef
|
||||
-Wuninitialized
|
||||
-Wredundant-decls
|
||||
-Wcast-align
|
||||
-Winit-self
|
||||
-Wmissing-include-dirs
|
||||
-Wmissing-declarations
|
||||
-Wstrict-overflow=2
|
||||
-Wunused-parameter
|
||||
-Wformat=2
|
||||
-Wdisabled-optimization
|
||||
-Wno-sign-conversion
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Woverloaded-virtual>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-old-style-cast>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fpermissive>
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND COMPILE_OPTIONS -Wno-unused-parameter)
|
||||
endif()
|
||||
|
||||
option(BUILD_WERROR "Build with -Werror" OFF)
|
||||
if(BUILD_WERROR)
|
||||
list(APPEND COMPILE_OPTIONS -Werror)
|
||||
endif(BUILD_WERROR)
|
||||
|
||||
add_compile_options(${COMPILE_OPTIONS})
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||
add_definitions(-DNDEBUG)
|
||||
@@ -98,7 +121,6 @@ pkg_check_modules(GSTREAMER_TAG gstreamer-tag-1.0)
|
||||
pkg_check_modules(GSTREAMER_PBUTILS gstreamer-pbutils-1.0)
|
||||
pkg_check_modules(LIBXINE libxine)
|
||||
pkg_check_modules(LIBVLC libvlc)
|
||||
pkg_check_modules(PHONON phonon4qt5)
|
||||
pkg_check_modules(SQLITE REQUIRED sqlite3>=3.9)
|
||||
pkg_check_modules(LIBPULSE libpulse)
|
||||
pkg_check_modules(CHROMAPRINT libchromaprint)
|
||||
@@ -175,11 +197,10 @@ pkg_check_modules(TAGLIB taglib)
|
||||
# - Audio file detection by content.
|
||||
# - DSF and DSDIFF support
|
||||
#
|
||||
if (TAGLIB_VERSION VERSION_GREATER 1.11.1)
|
||||
option(USE_SYSTEM_TAGLIB "Use system taglib" ON)
|
||||
else()
|
||||
option(USE_SYSTEM_TAGLIB "Use system taglib" OFF)
|
||||
endif()
|
||||
# Some distros create their own version numbers for taglib so versions are not reliable anymore.
|
||||
# Force to use our own copy of taglib unless USE_SYSTEM_TAGLIB is set.
|
||||
|
||||
option(USE_SYSTEM_TAGLIB "Use system taglib" OFF)
|
||||
if (TAGLIB_FOUND AND USE_SYSTEM_TAGLIB)
|
||||
if (TAGLIB_VERSION VERSION_GREATER 1.11.1)
|
||||
message(STATUS "Using system taglib library")
|
||||
@@ -275,10 +296,6 @@ optional_component(VLC ON "Engine: VLC backend"
|
||||
DEPENDS "libvlc" LIBVLC_FOUND
|
||||
)
|
||||
|
||||
optional_component(PHONON OFF "Engine: Phonon backend (UNSTABLE)"
|
||||
DEPENDS "phonon4qt5" PHONON_FOUND
|
||||
)
|
||||
|
||||
optional_component(CHROMAPRINT ON "Chromaprint (Tag fetching from Musicbrainz)"
|
||||
DEPENDS "chromaprint" CHROMAPRINT_FOUND
|
||||
)
|
||||
@@ -330,6 +347,7 @@ optional_component(TRANSLATIONS ON "Translations"
|
||||
)
|
||||
|
||||
optional_component(SUBSONIC ON "Subsonic support")
|
||||
optional_component(TIDAL ON "Tidal support")
|
||||
|
||||
optional_component(MOODBAR ON "Moodbar"
|
||||
DEPENDS "fftw3" FFTW3_FOUND
|
||||
@@ -387,17 +405,14 @@ if(HAVE_XINE)
|
||||
XINE_ANALYZER)
|
||||
endif()
|
||||
|
||||
# Set up definitions and paths
|
||||
# Set up definitions
|
||||
|
||||
add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions(-DQT_STRICT_ITERATORS)
|
||||
add_definitions(-DQT_USE_QSTRINGBUILDER)
|
||||
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
|
||||
add_definitions(-DQT_NO_CAST_TO_ASCII -DQT_STRICT_ITERATORS)
|
||||
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||
include_directories(${TAGLIB_INCLUDE_DIRS})
|
||||
add_definitions(-DQT_NO_CAST_TO_ASCII)
|
||||
|
||||
# Subdirectories
|
||||
add_subdirectory(src)
|
||||
@@ -421,8 +436,8 @@ add_custom_target(uninstall
|
||||
|
||||
# Show a summary of what we have enabled
|
||||
summary_show()
|
||||
if(NOT HAVE_GSTREAMER AND NOT HAVE_XINE AND NOT HAVE_VLC AND NOT HAVE_PHONON)
|
||||
message(FATAL_ERROR "You need to have either GStreamer, Xine, VLC or Phonon to compile!")
|
||||
if(NOT HAVE_GSTREAMER AND NOT HAVE_XINE AND NOT HAVE_VLC)
|
||||
message(FATAL_ERROR "You need to have either GStreamer, Xine or VLC to compile!")
|
||||
elseif(NOT HAVE_GSTREAMER)
|
||||
message(WARNING "GStreamer is the only engine that is fully implemented. Using other engines is possible but not recommended.")
|
||||
endif()
|
||||
|
||||
66
Changelog
@@ -2,6 +2,72 @@ Strawberry Music Player
|
||||
=======================
|
||||
ChangeLog
|
||||
|
||||
0.6.11:
|
||||
|
||||
Bugfixes:
|
||||
* Fixed MPRIS missing art url when playing albums with embedded cover.
|
||||
* Fixed updating local non collection songs when manually unsetting cover.
|
||||
* Fixed infinite loop and preceding crash when CSS background-color was set in qt5ct.
|
||||
* Fixed UI freeze when updating the database from a large Subsonic or Tidal collection.
|
||||
* Fixed crash when CD loading fails in devices.
|
||||
* Fixed CD devices showing up with having 0 songs after loading.
|
||||
* Fixed the album cover loading indicator being stuck if no cover providers were available.
|
||||
* Fixed the playing widget not updating artist, album or title after metadata has changed for a song when no album cover was loaded.
|
||||
|
||||
Enhancements:
|
||||
* Sort songs in collection by song title instead of track if previous grouping is not the album.
|
||||
* Added option to switch on/off automatically searching for album covers to context settings.
|
||||
* Reset last played song when playlist is finished.
|
||||
* Checking content type of received HTTP request for image when receiving album covers.
|
||||
* Added option to scrobbler setting for turning off login error popup.
|
||||
* Made MusicBrainz and Discogs cover providers respect rate limiting.
|
||||
|
||||
New features:
|
||||
* Added option to show/hide sidebar.
|
||||
* Added settings for selecting album cover and lyrics providers.
|
||||
* Added album covers from Musixmatch and Spotify.
|
||||
* Added lyrics from Genius, Musixmatch and ChartLyrics.
|
||||
|
||||
0.6.10:
|
||||
|
||||
Bugfixes:
|
||||
* Fixed Subsonic album covers not working for albums with non ASCII charcters.
|
||||
* Fixed reading date and genre from individual tracks in CUE sheets.
|
||||
* Fixed resume playback on startup for CUE songs.
|
||||
* Fixed album cover manager not showing complete album titles in the list of album covers.
|
||||
* Fixed save album cover to file saving "no cover" image instead of actual album cover.
|
||||
* Fixed device state text color in devices not being visible when using a dark theme.
|
||||
* Fixed engine and device in context using too large icons when icons were loaded from the system theme.
|
||||
* Fixed "Secure connection setup failed" problem on Windows when playing streams.
|
||||
* Fixed margin for song title text in context.
|
||||
* Fixed UNC paths with non ASCII charcters not working.
|
||||
|
||||
Enhancements:
|
||||
* Allowing all characters except slash and backslash when organising music unless options to strip characters is checked.
|
||||
* New option in organising music to remove problematic filename characters that removes less characters than the FAT option.
|
||||
* General improvements to the album cover loader and album cover providers code.
|
||||
* Fixed loading album cover images from album directory for songs added to the playlist from outside of the collection.
|
||||
* Made automatic album cover search work for songs outside of the collection and for streams.
|
||||
* Made album cover search work based on artist + title if album title is not present for providers supporting song/track search.
|
||||
* Update art manual in playlist for local files, devices and CDDA to avoid loading covers multiple times.
|
||||
* Made lyrics search work for streams.
|
||||
* Added "add stream" to menu.
|
||||
* Only showing song length in context when available.
|
||||
* Sort album cover search results by score and pick the best 3 first before trying others to improve album cover search speed.
|
||||
* Make scrobbler work for streams.
|
||||
* Added search for lyrics as a seperate option in context.
|
||||
* Made font and font sizes in context configurable.
|
||||
* Splitting artist and song title to the relevant metadata when artist and song title is sent as title seperated by a dash in streams.
|
||||
* Added label to show collection pixmap disk cache used in settings.
|
||||
* Icreased default collection pixmap disk cache to 360.
|
||||
|
||||
New features:
|
||||
* Added back Tidal streaming support.
|
||||
* Added Qobuz album cover provider.
|
||||
|
||||
Removed features:
|
||||
* Removed Phonon engine support.
|
||||
|
||||
Version 0.6.9:
|
||||
|
||||
BugFixes:
|
||||
|
||||
14
README.md
@@ -17,7 +17,7 @@ Resources:
|
||||
* PPA: https://launchpad.net/~jonaski/+archive/ubuntu/strawberry
|
||||
* Translations: https://translate.zanata.org/iteration/view/strawberry/master
|
||||
|
||||
The program is free software, released under GPL. If you like this program and can make use of it, consider sponsoring or donating to help funding the project.
|
||||
The program is free software, released under GPL. If you like this program and can make use of it, consider sponsoring or donating to help fund the project.
|
||||
To sponsor, visit [my GitHub sponsors profile](https://github.com/sponsors/jonaski).
|
||||
Funding developers through GitHub Sponsors is one more way to contribute to open source projects you appreciate, it helps developers get the resources they need, and recognize contributors working behind the scenes to make open source better for everyone.
|
||||
You can also make a one-time payment through [paypal.me/jonaskvinge](https://paypal.me/jonaskvinge)
|
||||
@@ -32,19 +32,19 @@ You can also make a one-time payment through [paypal.me/jonaskvinge](https://pay
|
||||
* Advanced audio output and device configuration for bit-perfect playback on Linux
|
||||
* Edit tags on music files
|
||||
* Fetch tags from MusicBrainz
|
||||
* Album cover art from [Last.fm](https://www.last.fm/), [Musicbrainz](https://musicbrainz.org/), [Discogs](https://www.discogs.com/) and [Deezer](https://www.deezer.com/)
|
||||
* Song lyrics from [AudD](https://audd.io/), [lyrics.ovh](https://lyrics.ovh/) and [lololyrics.com](https://www.lololyrics.com/)
|
||||
* Album cover art from [Last.fm](https://www.last.fm/), [Musicbrainz](https://musicbrainz.org/), [Discogs](https://www.discogs.com/), [Musixmatch](https://www.musixmatch.com/), [Deezer](https://www.deezer.com/), [Tidal](https://www.tidal.com/), [Qobuz](https://www.qobuz.com/) and [Spotify](https://www.spotify.com/)
|
||||
* Song lyrics from [AudD](https://audd.io/), [Genius](https://genius.com/), [Musixmatch](https://www.musixmatch.com/), [ChartLyrics](http://www.chartlyrics.com/), [lyrics.ovh](https://lyrics.ovh/) and [lololyrics.com](https://www.lololyrics.com/)
|
||||
* Support for multiple backends
|
||||
* Audio analyzer
|
||||
* Audio equalizer
|
||||
* Transfer music to iPod, iPhone, MTP or mass-storage USB player
|
||||
* Scrobbler with support for [Last.fm](https://www.last.fm/), [Libre.fm](https://libre.fm/) and [ListenBrainz](https://listenbrainz.org/)
|
||||
* Subsonic streaming support
|
||||
* Subsonic and Tidal streaming support
|
||||
|
||||
|
||||
It has so far been tested to work on Linux, OpenBSD and Windows.
|
||||
|
||||
**We currently do not provide releases for macOS because there aren't any macOS developers actively working on this project. It is still possible to compile by following the instructions in the Wiki**
|
||||
**We currently do not provide releases for macOS because there aren't any macOS developers actively working on this project. Development builds are available**
|
||||
|
||||
### :heavy_exclamation_mark: Requirements
|
||||
|
||||
@@ -63,7 +63,7 @@ To build Strawberry from source you need the following installed on your system
|
||||
* [ALSA library (linux)](https://www.alsa-project.org/)
|
||||
* [DBus (linux)](https://www.freedesktop.org/wiki/Software/dbus/)
|
||||
* [PulseAudio (linux optional)](https://www.freedesktop.org/wiki/Software/PulseAudio/?)
|
||||
* [GStreamer](https://gstreamer.freedesktop.org/), [Xine](https://www.xine-project.org), [VLC](https://www.videolan.org) or [Phonon](https://techbase.kde.org/Phonon)
|
||||
* [GStreamer](https://gstreamer.freedesktop.org/), [Xine](https://www.xine-project.org) or [VLC](https://www.videolan.org)
|
||||
* [GnuTLS](https://www.gnutls.org/)
|
||||
|
||||
Optional dependencies:
|
||||
@@ -74,7 +74,7 @@ Optional dependencies:
|
||||
* iPhone, iPod Touch, iPad and Apple TV devices: [libimobiledevice, libplist and libusbmuxd](https://www.libimobiledevice.org/)
|
||||
* Moodbar: [fftw3](http://www.fftw.org/)
|
||||
|
||||
Either GStreamer, Xine, VLC or Phonon engine is required, but only GStreamer is fully implemented so far.
|
||||
Either GStreamer, Xine or VLC engine is required, but only GStreamer is fully implemented so far.
|
||||
You should also install the gstreamer plugins base and good, and optionally bad and ugly.
|
||||
|
||||
### :wrench: Compiling from source
|
||||
|
||||
@@ -57,12 +57,12 @@ if (LSB_RELEASE_EXEC AND RPMBUILD_EXEC)
|
||||
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
|
||||
endif()
|
||||
message(STATUS "RPM Suffix: ${RPM_DISTRO}")
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec.in ${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec.in ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec @ONLY)
|
||||
add_custom_target(rpm
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/dist/scripts/maketarball.sh
|
||||
COMMAND ${CMAKE_COMMAND} -E copy strawberry-${STRAWBERRY_VERSION_PACKAGE}.tar.xz ${RPMBUILD_DIR}/SOURCES/
|
||||
COMMAND ${RPMBUILD_EXEC} -bs ${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec
|
||||
COMMAND ${RPMBUILD_EXEC} -bb ${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec
|
||||
COMMAND ${RPMBUILD_EXEC} -bs ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec
|
||||
COMMAND ${RPMBUILD_EXEC} -bb ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
9
cmake/Toolchain-i686-w64-mingw32-shared.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(HOME "$ENV{HOME}")
|
||||
SET(CMAKE_C_COMPILER "${HOME}/mxe-shared/usr/bin/i686-w64-mingw32.shared-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "${HOME}/mxe-shared/usr/bin/i686-w64-mingw32.shared-g++")
|
||||
SET(CMAKE_RC_COMPILER "${HOME}/mxe-shared/usr/bin/i686-w64-mingw32.shared-windres")
|
||||
SET(CMAKE_FIND_ROOT_PATH "${HOME}/mxe-shared/usr/i686-w64-mingw32.shared/")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
9
cmake/Toolchain-x86_64-w64-mingw32-shared.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(HOME "$ENV{HOME}")
|
||||
SET(CMAKE_C_COMPILER "${HOME}/mxe-shared/usr/bin/x86_64-w64-mingw32.shared-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "${HOME}/mxe-shared/usr/bin/x86_64-w64-mingw32.shared-g++")
|
||||
SET(CMAKE_RC_COMPILER "${HOME}/mxe-shared/usr/bin/x86_64-w64-mingw32.shared-windres")
|
||||
SET(CMAKE_FIND_ROOT_PATH "${HOME}/mxe-shared/usr/x86_64-w64-mingw32.shared/")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
@@ -1,6 +1,6 @@
|
||||
set(STRAWBERRY_VERSION_MAJOR 0)
|
||||
set(STRAWBERRY_VERSION_MINOR 6)
|
||||
set(STRAWBERRY_VERSION_PATCH 9)
|
||||
set(STRAWBERRY_VERSION_PATCH 11)
|
||||
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
||||
|
||||
set(INCLUDE_GIT_REVISION OFF)
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<file>schema/schema-8.sql</file>
|
||||
<file>schema/schema-9.sql</file>
|
||||
<file>schema/schema-10.sql</file>
|
||||
<file>schema/schema-11.sql</file>
|
||||
<file>schema/schema-12.sql</file>
|
||||
<file>schema/device-schema.sql</file>
|
||||
<file>style/strawberry.css</file>
|
||||
<file>html/playing-tooltip-plain.html</file>
|
||||
@@ -40,5 +42,6 @@
|
||||
<file>pictures/rainbowdash.png</file>
|
||||
<file>fonts/HumongousofEternitySt.ttf</file>
|
||||
<file>mood/sample.mood</file>
|
||||
<file>text/ghosts.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<file>icons/128x128/moodbar.png</file>
|
||||
<file>icons/128x128/love.png</file>
|
||||
<file>icons/128x128/subsonic.png</file>
|
||||
<file>icons/128x128/tidal.png</file>
|
||||
<file>icons/64x64/albums.png</file>
|
||||
<file>icons/64x64/alsa.png</file>
|
||||
<file>icons/64x64/application-exit.png</file>
|
||||
@@ -179,6 +180,7 @@
|
||||
<file>icons/64x64/moodbar.png</file>
|
||||
<file>icons/64x64/love.png</file>
|
||||
<file>icons/64x64/subsonic.png</file>
|
||||
<file>icons/64x64/tidal.png</file>
|
||||
<file>icons/48x48/albums.png</file>
|
||||
<file>icons/48x48/alsa.png</file>
|
||||
<file>icons/48x48/application-exit.png</file>
|
||||
@@ -201,6 +203,7 @@
|
||||
<file>icons/48x48/document-download.png</file>
|
||||
<file>icons/48x48/document-new.png</file>
|
||||
<file>icons/48x48/document-open-folder.png</file>
|
||||
<file>icons/48x48/document-open-remote.png</file>
|
||||
<file>icons/48x48/document-open.png</file>
|
||||
<file>icons/48x48/document-save.png</file>
|
||||
<file>icons/48x48/document-search.png</file>
|
||||
@@ -272,6 +275,7 @@
|
||||
<file>icons/48x48/moodbar.png</file>
|
||||
<file>icons/48x48/love.png</file>
|
||||
<file>icons/48x48/subsonic.png</file>
|
||||
<file>icons/48x48/tidal.png</file>
|
||||
<file>icons/32x32/albums.png</file>
|
||||
<file>icons/32x32/alsa.png</file>
|
||||
<file>icons/32x32/application-exit.png</file>
|
||||
@@ -294,6 +298,7 @@
|
||||
<file>icons/32x32/document-download.png</file>
|
||||
<file>icons/32x32/document-new.png</file>
|
||||
<file>icons/32x32/document-open-folder.png</file>
|
||||
<file>icons/32x32/document-open-remote.png</file>
|
||||
<file>icons/32x32/document-open.png</file>
|
||||
<file>icons/32x32/document-save.png</file>
|
||||
<file>icons/32x32/document-search.png</file>
|
||||
@@ -365,6 +370,7 @@
|
||||
<file>icons/32x32/moodbar.png</file>
|
||||
<file>icons/32x32/love.png</file>
|
||||
<file>icons/32x32/subsonic.png</file>
|
||||
<file>icons/32x32/tidal.png</file>
|
||||
<file>icons/22x22/albums.png</file>
|
||||
<file>icons/22x22/alsa.png</file>
|
||||
<file>icons/22x22/application-exit.png</file>
|
||||
@@ -387,6 +393,7 @@
|
||||
<file>icons/22x22/document-download.png</file>
|
||||
<file>icons/22x22/document-new.png</file>
|
||||
<file>icons/22x22/document-open-folder.png</file>
|
||||
<file>icons/22x22/document-open-remote.png</file>
|
||||
<file>icons/22x22/document-open.png</file>
|
||||
<file>icons/22x22/document-save.png</file>
|
||||
<file>icons/22x22/document-search.png</file>
|
||||
@@ -458,5 +465,6 @@
|
||||
<file>icons/22x22/moodbar.png</file>
|
||||
<file>icons/22x22/love.png</file>
|
||||
<file>icons/22x22/subsonic.png</file>
|
||||
<file>icons/22x22/tidal.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
BIN
data/icons/128x128/tidal.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
data/icons/22x22/document-open-remote.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
data/icons/22x22/tidal.png
Normal file
|
After Width: | Height: | Size: 933 B |
BIN
data/icons/32x32/document-open-remote.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
data/icons/32x32/tidal.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
data/icons/48x48/document-open-remote.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
data/icons/48x48/tidal.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
data/icons/64x64/tidal.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
data/icons/full/tidal.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
@@ -11,25 +11,25 @@ CREATE TABLE device_%deviceid_subdirectories (
|
||||
|
||||
CREATE TABLE device_%deviceid_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
247
data/schema/schema-11.sql
Normal file
@@ -0,0 +1,247 @@
|
||||
DROP VIEW IF EXISTS duplicated_songs;
|
||||
|
||||
DROP INDEX IF EXISTS idx_url;
|
||||
|
||||
DROP INDEX IF EXISTS idx_comp_artist;
|
||||
|
||||
DROP INDEX IF EXISTS idx_albumartist;
|
||||
|
||||
DROP INDEX IF EXISTS idx_artist;
|
||||
|
||||
DROP INDEX IF EXISTS idx_album;
|
||||
|
||||
DROP INDEX IF EXISTS idx_title;
|
||||
|
||||
ALTER TABLE songs RENAME TO songs_old;
|
||||
|
||||
ALTER TABLE subsonic_songs RENAME TO subsonic_songs_old;
|
||||
|
||||
ALTER TABLE playlist_items RENAME TO playlist_items_old;
|
||||
|
||||
CREATE TABLE songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_url ON songs (url);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_comp_artist ON songs (compilation_effective, artist);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_albumartist ON songs (albumartist);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_artist ON songs (artist);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_album ON songs (album);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_title ON songs (title);
|
||||
|
||||
CREATE VIEW duplicated_songs as select artist dup_artist, album dup_album, title dup_title from songs as inner_songs where artist != '' and album != '' and title != '' and unavailable = 0 group by artist, album , title having count(*) > 1;
|
||||
|
||||
CREATE TABLE subsonic_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
INSERT INTO songs (ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path)
|
||||
SELECT ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path
|
||||
FROM songs_old;
|
||||
|
||||
DROP TABLE songs_old;
|
||||
|
||||
DELETE FROM songs_fts;
|
||||
|
||||
INSERT INTO songs_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment
|
||||
FROM songs;
|
||||
|
||||
INSERT INTO subsonic_songs (ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path)
|
||||
SELECT ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path
|
||||
FROM subsonic_songs_old;
|
||||
|
||||
DROP TABLE subsonic_songs_old;
|
||||
|
||||
DELETE FROM subsonic_songs_fts;
|
||||
|
||||
INSERT INTO subsonic_songs_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment
|
||||
FROM subsonic_songs;
|
||||
|
||||
CREATE TABLE playlist_items (
|
||||
|
||||
playlist INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL DEFAULT 0,
|
||||
collection_id INTEGER,
|
||||
playlist_url TEXT,
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER,
|
||||
disc INTEGER,
|
||||
year INTEGER,
|
||||
originalyear INTEGER,
|
||||
genre TEXT,
|
||||
compilation INTEGER DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER,
|
||||
length INTEGER,
|
||||
|
||||
bitrate INTEGER,
|
||||
samplerate INTEGER,
|
||||
bitdepth INTEGER,
|
||||
|
||||
source INTEGER,
|
||||
directory_id INTEGER,
|
||||
url TEXT,
|
||||
filetype INTEGER,
|
||||
filesize INTEGER,
|
||||
mtime INTEGER,
|
||||
ctime INTEGER,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER DEFAULT 0,
|
||||
skipcount INTEGER DEFAULT 0,
|
||||
lastplayed INTEGER DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER DEFAULT 0,
|
||||
compilation_off INTEGER DEFAULT 0,
|
||||
compilation_effective INTEGER DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
INSERT INTO playlist_items (ROWID, playlist, type, collection_id, playlist_url, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path)
|
||||
SELECT ROWID, playlist, type, collection_id, playlist_url, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path
|
||||
FROM playlist_items_old;
|
||||
|
||||
DROP TABLE playlist_items_old;
|
||||
|
||||
DELETE FROM playlist_items_fts_;
|
||||
|
||||
INSERT INTO playlist_items_fts_ (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment
|
||||
FROM playlist_items;
|
||||
|
||||
UPDATE schema_version SET version=11;
|
||||
217
data/schema/schema-12.sql
Normal file
@@ -0,0 +1,217 @@
|
||||
CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_albums_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_artists_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 0"
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_albums_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 0"
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 0"
|
||||
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version=12;
|
||||
@@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS schema_version (
|
||||
|
||||
DELETE FROM schema_version;
|
||||
|
||||
INSERT INTO schema_version (version) VALUES (10);
|
||||
INSERT INTO schema_version (version) VALUES (12);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS directories (
|
||||
path TEXT NOT NULL,
|
||||
@@ -19,25 +19,196 @@ CREATE TABLE IF NOT EXISTS subdirectories (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_albums_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT -1,
|
||||
mtime INTEGER NOT NULL DEFAULT -1,
|
||||
ctime INTEGER NOT NULL DEFAULT -1,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_songs (
|
||||
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -76,25 +247,25 @@ CREATE TABLE IF NOT EXISTS songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -149,56 +320,56 @@ CREATE TABLE IF NOT EXISTS playlist_items (
|
||||
collection_id INTEGER,
|
||||
playlist_url TEXT,
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER,
|
||||
disc INTEGER,
|
||||
year INTEGER,
|
||||
originalyear INTEGER,
|
||||
genre TEXT,
|
||||
compilation INTEGER DEFAULT 0,
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
beginning INTEGER,
|
||||
length INTEGER,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
||||
bitrate INTEGER,
|
||||
samplerate INTEGER,
|
||||
bitdepth INTEGER,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
source INTEGER,
|
||||
directory_id INTEGER,
|
||||
url TEXT,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filetype INTEGER,
|
||||
filesize INTEGER,
|
||||
mtime INTEGER,
|
||||
ctime INTEGER,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
playcount INTEGER DEFAULT 0,
|
||||
skipcount INTEGER DEFAULT 0,
|
||||
lastplayed INTEGER DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_on INTEGER DEFAULT 0,
|
||||
compilation_off INTEGER DEFAULT 0,
|
||||
compilation_effective INTEGER DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
effective_originalyear INTEGER,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
@@ -243,6 +414,51 @@ CREATE VIRTUAL TABLE IF NOT EXISTS songs_fts USING fts5(
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_artists_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 0"
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_albums_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 0"
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 0"
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS subsonic_songs_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
|
||||
42
data/text/ghosts.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
Go to sleep my babies
|
||||
Don't you wake up
|
||||
The stars will keep you company
|
||||
So close your eyes
|
||||
Old Uncle Moon will shine his dearest sweetest dreams
|
||||
And hold you in your arms
|
||||
Until the morning comes.
|
||||
|
||||
Night Light
|
||||
|
||||
Dark the night, not a sound
|
||||
Damp and cold, frosty ground
|
||||
Above your head the lion screams
|
||||
To tear you from your moonlit dreams.
|
||||
Damp with sweat, mouth is dry
|
||||
Twisted branches catch the eye
|
||||
Beside your bed the angel stands
|
||||
You cannot touch his withered hands.
|
||||
|
||||
Guardian Angel
|
||||
|
||||
As the lion's eyes dance before me
|
||||
They are kindly yet bloody red
|
||||
I can see that he is smiling
|
||||
But I cannot live inside his head.
|
||||
There the needle stands before me
|
||||
I climb inside it towards the light
|
||||
Where the angel stands in glory
|
||||
His sword of peace defends the night.
|
||||
So the world is spread before
|
||||
As I fly high on angel wings
|
||||
But the angel is deceiving
|
||||
For he is weeping as he sings.
|
||||
|
||||
Night Light (continued)
|
||||
|
||||
Early birds, morning breeze
|
||||
Spinning leaves, sleepy trees
|
||||
Gently tap the window pane
|
||||
It's good to see the sun again.
|
||||
|
||||
(Dave Cousins)
|
||||
4
debian/control
vendored
@@ -55,8 +55,8 @@ Description: Audio player and music collection organizer
|
||||
- Advanced audio output and device configuration for bit-perfect playback on Linux
|
||||
- Edit tags on music files
|
||||
- Fetch tags from MusicBrainz
|
||||
- Album cover art from Lastfm, Musicbrainz, Discogs and Deezer
|
||||
- Song lyrics from AudD, lyrics.ovh and lololyrics.com
|
||||
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
|
||||
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
|
||||
- Support for multiple backends
|
||||
- Audio analyzer
|
||||
- Audio equalizer
|
||||
|
||||
41
debian/copyright
vendored
@@ -24,6 +24,8 @@ Files: src/core/main.h
|
||||
src/version.h.in
|
||||
src/context/contextview.cpp
|
||||
src/context/contextview.h
|
||||
src/context/contextalbum.cpp
|
||||
src/context/contextalbum.h
|
||||
src/engine/enginetype.cpp
|
||||
src/engine/enginetype.h
|
||||
src/engine/alsadevicefinder.cpp
|
||||
@@ -34,22 +36,40 @@ Files: src/core/main.h
|
||||
src/engine/devicefinder.h
|
||||
src/engine/enginedevice.cpp
|
||||
src/engine/enginedevice.h
|
||||
src/engine/phononengine.cpp
|
||||
src/engine/phononengine.h
|
||||
src/internet/internetservice.cpp
|
||||
src/internet/internetservice.h
|
||||
src/internet/internettabsview.cpp
|
||||
src/internet/internettabsview.h
|
||||
src/internet/internetsongsview.cpp
|
||||
src/internet/internetsongsview.h
|
||||
src/settings/backendsettingspage.cpp
|
||||
src/settings/backendsettingspage.h
|
||||
src/settings/coverssettingspage.cpp
|
||||
src/settings/coverssettingspage.h
|
||||
src/settings/lyricssettingspage.cpp
|
||||
src/settings/lyricssettingspage.h
|
||||
src/settings/scrobblersettingspage.cpp
|
||||
src/settings/scrobblersettingspage.h
|
||||
src/settings/subsonicsettingspage.cpp
|
||||
src/settings/subsonicsettingspage.h
|
||||
src/settings/tidalsettingspage.cpp
|
||||
src/settings/tidalsettingspage.h
|
||||
src/covermanager/jsoncoverprovider.cpp
|
||||
src/covermanager/jsoncoverprovider.h
|
||||
src/covermanager/lastfmcoverprovider.cpp
|
||||
src/covermanager/lastfmcoverprovider.h
|
||||
src/covermanager/musicbrainzcoverprovider.cpp
|
||||
src/covermanager/musicbrainzcoverprovider.h
|
||||
src/covermanager/deezercoverprovider.cpp
|
||||
src/covermanager/deezercoverprovider.h
|
||||
src/covermanager/tidalcoverprovider.cpp
|
||||
src/covermanager/tidalcoverprovider.h
|
||||
src/covermanager/qobuzcoverprovider.cpp
|
||||
src/covermanager/qobuzcoverprovider.h
|
||||
src/covermanager/spotifycoverprovider.cpp
|
||||
src/covermanager/spotifycoverprovider.h
|
||||
src/covermanager/musixmatchcoverprovider.cpp
|
||||
src/covermanager/musixmatchcoverprovider.h
|
||||
src/globalshortcuts/globalshortcutbackend-system.cpp
|
||||
src/globalshortcuts/globalshortcutbackend-system.h
|
||||
src/globalshortcuts/globalshortcut.cpp
|
||||
@@ -61,9 +81,10 @@ Files: src/core/main.h
|
||||
src/lyrics/*
|
||||
src/scrobbler/*
|
||||
src/subsonic/*
|
||||
src/tidal/*
|
||||
src/transcoder/transcoderoptionswavpack.cpp
|
||||
src/transcoder/transcoderoptionswavpack.h
|
||||
Copyright: 2012-2014, 2017-2019, Jonas Kvinge <jonas@jkvinge.net>
|
||||
Copyright: 2012-2014, 2017-2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/main.cpp
|
||||
@@ -160,8 +181,20 @@ Files: src/core/main.cpp
|
||||
src/transcoder/transcoder.h
|
||||
src/musicbrainz/musicbrainzclient.cpp
|
||||
src/musicbrainz/musicbrainzclient.h
|
||||
src/covermanager/albumcoverloader.cpp
|
||||
src/covermanager/albumcoverloader.h
|
||||
src/covermanager/currentalbumcoverloader.cpp
|
||||
src/covermanager/currentalbumcoverloader.h
|
||||
src/covermanager/albumcoverchoicecontroller.cpp
|
||||
src/covermanager/albumcoverchoicecontroller.h
|
||||
src/covermanager/albumcoverfetchersearch.cpp
|
||||
src/covermanager/albumcoverfetchersearch.h
|
||||
src/covermanager/coverproviders.cpp
|
||||
src/covermanager/coverproviders.h
|
||||
src/covermanager/coverprovider.cpp
|
||||
src/covermanager/coverprovider.h
|
||||
Copyright: 2010, 2012-2014 David Sansome <me@davidsansome.com>
|
||||
2012-2014, 2017-2019 Jonas Kvinge <jonas@jkvinge.net>
|
||||
2012-2014, 2017-2020 Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/engine/enginebase.cpp
|
||||
|
||||
4
debian/rules
vendored
@@ -6,8 +6,8 @@
|
||||
override_dh_auto_clean:
|
||||
rm -f dist/macos/Info.plist
|
||||
rm -f dist/macos/create-dmg.sh
|
||||
rm -f dist/pacman/PKGBUILD
|
||||
rm -f dist/rpm/strawberry.spec
|
||||
rm -f dist/unix/PKGBUILD
|
||||
rm -f dist/unix/strawberry.spec
|
||||
rm -f dist/scripts/maketarball.sh
|
||||
rm -f dist/windows/strawberry.nsi
|
||||
rm -f src/translations/translations.pot
|
||||
|
||||
4
dist/CMakeLists.txt
vendored
@@ -1,5 +1,5 @@
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/maketarball.sh.in ${CMAKE_CURRENT_SOURCE_DIR}/scripts/maketarball.sh @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pacman/PKGBUILD.in ${CMAKE_CURRENT_SOURCE_DIR}/pacman/PKGBUILD @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unix/PKGBUILD.in ${CMAKE_CURRENT_SOURCE_DIR}/unix/PKGBUILD @ONLY)
|
||||
|
||||
if (APPLE)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist)
|
||||
@@ -16,7 +16,7 @@ if (UNIX AND NOT APPLE)
|
||||
install(FILES ../data/icons/128x128/strawberry.png DESTINATION share/icons/hicolor/128x128/apps/)
|
||||
install(FILES unix/org.strawberrymusicplayer.strawberry.desktop DESTINATION share/applications)
|
||||
install(FILES unix/org.strawberrymusicplayer.strawberry.appdata.xml DESTINATION share/metainfo)
|
||||
install(FILES man/strawberry.1 man/strawberry-tagreader.1 DESTINATION share/man/man1)
|
||||
install(FILES unix/strawberry.1 unix/strawberry-tagreader.1 DESTINATION share/man/man1)
|
||||
endif (UNIX AND NOT APPLE)
|
||||
|
||||
if (APPLE)
|
||||
|
||||
2
dist/scripts/maketarball.sh.in
vendored
@@ -36,7 +36,7 @@ tar -cJf $name-$version.tar.xz \
|
||||
--exclude="$root/.zanata-cache" \
|
||||
--exclude="$root/debian/changelog" \
|
||||
--exclude="$root/dist/scripts/maketarball.sh" \
|
||||
--exclude="$root/dist/pacman/PKGBUILD" \
|
||||
--exclude="$root/dist/unix/PKGBUILD" \
|
||||
--exclude="$root/dist/macos/create-dmg.sh" \
|
||||
--exclude="$root/dist/macos/Info.plist" \
|
||||
--exclude="$root/dist/windows/windres.rc" \
|
||||
|
||||
@@ -32,7 +32,6 @@ depends=(
|
||||
libusbmuxd
|
||||
libplist
|
||||
libimobiledevice
|
||||
phonon-qt5
|
||||
fftw
|
||||
)
|
||||
optdepends=(
|
||||
@@ -54,7 +53,6 @@ build() {
|
||||
cmake ../${pkgname}-@STRAWBERRY_VERSION_PACKAGE@ \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DUSE_SYSTEM_TAGLIB=ON \
|
||||
-DENABLE_PHONON=ON \
|
||||
-DENABLE_TRANSLATIONS=ON
|
||||
make -j$(nproc)
|
||||
}
|
||||
@@ -26,8 +26,8 @@
|
||||
<li>Advanced audio output and device configuration for bit-perfect playback on Linux</li>
|
||||
<li>Edit tags on music files</li>
|
||||
<li>Fetch tags from MusicBrainz</li>
|
||||
<li>Album cover art from Last.fm, Musicbrainz and Discogs</li>
|
||||
<li>Song lyrics from AudD, lyrics.ovh and lololyrics.com</li>
|
||||
<li>Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify</li>
|
||||
<li>Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com</li>
|
||||
<li>Support for multiple backends</li>
|
||||
<li>Audio analyzer and equalizer</li>
|
||||
<li>Transfer music to iPod, iPhone, MTP or mass-storage USB player</li>
|
||||
|
||||
@@ -10,5 +10,5 @@ Icon=strawberry
|
||||
Terminal=false
|
||||
Categories=AudioVideo;Player;Qt;Audio;
|
||||
StartupNotify=false
|
||||
MimeType=x-content/audio-player;application/ogg;application/x-ogg;application/x-ogm-audio;audio/flac;audio/ogg;audio/vorbis;audio/aac;audio/mp4;audio/mpeg;audio/mpegurl;audio/vnd.rn-realaudio;audio/x-flac;audio/x-oggflac;audio/x-vorbis;audio/x-vorbis+ogg;audio/x-speex;audio/x-wav;audio/x-wavpack;audio/x-ape;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-musepack;audio/x-pn-realaudio;audio/x-scpls;video/x-ms-asf
|
||||
MimeType=x-content/audio-player;application/ogg;application/x-ogg;application/x-ogm-audio;audio/flac;audio/ogg;audio/vorbis;audio/aac;audio/mp4;audio/mpeg;audio/mpegurl;audio/vnd.rn-realaudio;audio/x-flac;audio/x-oggflac;audio/x-vorbis;audio/x-vorbis+ogg;audio/x-speex;audio/x-wav;audio/x-wavpack;audio/x-ape;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-musepack;audio/x-pn-realaudio;audio/x-scpls;video/x-ms-asf;x-scheme-handler/tidal;
|
||||
StartupWMClass=strawberry
|
||||
|
||||
@@ -25,9 +25,9 @@ Features:
|
||||
.br
|
||||
- Fetch tags from MusicBrainz
|
||||
.br
|
||||
- Album cover art from Lastfm, Musicbrainz, Discogs and Deezer
|
||||
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
|
||||
.br
|
||||
- Song lyrics from AudD, lyrics.ovh and lololyrics.com
|
||||
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
|
||||
.br
|
||||
- Support for multiple backends
|
||||
.br
|
||||
@@ -104,8 +104,8 @@ Features:
|
||||
- Advanced audio output and device configuration for bit-perfect playback on Linux
|
||||
- Edit tags on music files
|
||||
- Fetch tags from MusicBrainz
|
||||
- Album cover art from Last.fm, Musicbrainz, Discogs and Deezer
|
||||
- Song lyrics from AudD, lyrics.ovh and lololyrics.com
|
||||
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
|
||||
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
|
||||
- Support for multiple backends
|
||||
- Audio analyzer
|
||||
- Audio equalizer
|
||||
11
dist/windows/strawberry.nsi.in
vendored
@@ -183,14 +183,14 @@ Section "Strawberry" Strawberry
|
||||
File "libgsttag-1.0-0.dll"
|
||||
File "libgstvideo-1.0-0.dll"
|
||||
File "libharfbuzz-0.dll"
|
||||
File "libhogweed-5.dll"
|
||||
File "libhogweed-6.dll"
|
||||
File "libiconv-2.dll"
|
||||
File "libidn2-0.dll"
|
||||
File "libintl-8.dll"
|
||||
File "libjpeg-9.dll"
|
||||
File "liblzma-5.dll"
|
||||
File "libmp3lame-0.dll"
|
||||
File "libnettle-7.dll"
|
||||
File "libnettle-8.dll"
|
||||
File "libogg-0.dll"
|
||||
File "libopus-0.dll"
|
||||
File "libpcre-1.dll"
|
||||
@@ -201,7 +201,7 @@ Section "Strawberry" Strawberry
|
||||
File "libspeex-1.dll"
|
||||
File "libsqlite3-0.dll"
|
||||
File "libstdc++-6.dll"
|
||||
;File "libtag.dll"
|
||||
File "libtag.dll"
|
||||
File "libunistring-2.dll"
|
||||
File "libvorbis-0.dll"
|
||||
File "libvorbisenc-2.dll"
|
||||
@@ -447,14 +447,14 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\libgsttag-1.0-0.dll"
|
||||
Delete "$INSTDIR\libgstvideo-1.0-0.dll"
|
||||
Delete "$INSTDIR\libharfbuzz-0.dll"
|
||||
Delete "$INSTDIR\libhogweed-5.dll"
|
||||
Delete "$INSTDIR\libhogweed-6.dll"
|
||||
Delete "$INSTDIR\libiconv-2.dll"
|
||||
Delete "$INSTDIR\libidn2-0.dll"
|
||||
Delete "$INSTDIR\libintl-8.dll"
|
||||
Delete "$INSTDIR\libjpeg-9.dll"
|
||||
Delete "$INSTDIR\liblzma-5.dll"
|
||||
Delete "$INSTDIR\libmp3lame-0.dll"
|
||||
Delete "$INSTDIR\libnettle-7.dll"
|
||||
Delete "$INSTDIR\libnettle-8.dll"
|
||||
Delete "$INSTDIR\libogg-0.dll"
|
||||
Delete "$INSTDIR\libopus-0.dll"
|
||||
Delete "$INSTDIR\libpcre-1.dll"
|
||||
@@ -592,6 +592,7 @@ Section "Uninstall"
|
||||
|
||||
; Remove the installation folders.
|
||||
RMDir "$INSTDIR\platforms"
|
||||
RMDir "$INSTDIR\styles"
|
||||
RMDir "$INSTDIR\sqldrivers"
|
||||
RMDir "$INSTDIR\imageformats"
|
||||
RMDir "$INSTDIR\gio-modules"
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
include_directories(${GOBJECT_INCLUDE_DIRS})
|
||||
include_directories(${GSTREAMER_INCLUDE_DIRS})
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||
@@ -17,6 +11,8 @@ if (Backtrace_FOUND)
|
||||
include_directories(${Backtrace_INCLUDE_DIRS})
|
||||
endif(Backtrace_FOUND)
|
||||
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
|
||||
set(SOURCES
|
||||
@@ -41,18 +37,11 @@ endif(APPLE)
|
||||
|
||||
qt5_wrap_cpp(MOC ${HEADERS})
|
||||
|
||||
add_library(libstrawberry-common STATIC
|
||||
${SOURCES}
|
||||
${MOC}
|
||||
)
|
||||
add_library(libstrawberry-common STATIC ${SOURCES} ${MOC})
|
||||
|
||||
if (Backtrace_FOUND)
|
||||
if(Backtrace_FOUND)
|
||||
target_link_libraries(libstrawberry-common ${Backtrace_LIBRARIES})
|
||||
endif (Backtrace_FOUND)
|
||||
|
||||
target_link_libraries(libstrawberry-common
|
||||
${TAGLIB_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
endif(Backtrace_FOUND)
|
||||
|
||||
target_link_libraries(libstrawberry-common ${TAGLIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(libstrawberry-common Qt5::Core Qt5::Network)
|
||||
|
||||
@@ -273,6 +273,8 @@ static T CreateLogger(Level level, const QString &class_name, int line, const ch
|
||||
return ret.space();
|
||||
}
|
||||
|
||||
QString CXXDemangle(const QString &mangled_function);
|
||||
|
||||
QString CXXDemangle(const QString &mangled_function) {
|
||||
|
||||
int status;
|
||||
@@ -286,6 +288,8 @@ QString CXXDemangle(const QString &mangled_function) {
|
||||
|
||||
}
|
||||
|
||||
QString DarwinDemangle(const QString &symbol);
|
||||
|
||||
QString DarwinDemangle(const QString &symbol) {
|
||||
|
||||
QStringList split = symbol.split(' ', QString::SkipEmptyParts);
|
||||
@@ -294,6 +298,8 @@ QString DarwinDemangle(const QString &symbol) {
|
||||
|
||||
}
|
||||
|
||||
QString LinuxDemangle(const QString &symbol);
|
||||
|
||||
QString LinuxDemangle(const QString &symbol) {
|
||||
|
||||
QRegExp regex("\\(([^+]+)");
|
||||
@@ -305,6 +311,8 @@ QString LinuxDemangle(const QString &symbol) {
|
||||
|
||||
}
|
||||
|
||||
QString DemangleSymbol(const QString &symbol);
|
||||
|
||||
QString DemangleSymbol(const QString &symbol) {
|
||||
#ifdef Q_OS_MACOS
|
||||
return DarwinDemangle(symbol);
|
||||
|
||||
@@ -47,13 +47,13 @@ void _MessageHandlerBase::SetDevice(QIODevice *device) {
|
||||
connect(device, SIGNAL(readyRead()), SLOT(DeviceReadyRead()));
|
||||
|
||||
// Yeah I know.
|
||||
if (QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(device)) {
|
||||
if (QAbstractSocket *abstractsocket = qobject_cast<QAbstractSocket*>(device)) {
|
||||
flush_abstract_socket_ = &QAbstractSocket::flush;
|
||||
connect(socket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
|
||||
connect(abstractsocket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
|
||||
}
|
||||
else if (QLocalSocket* socket = qobject_cast<QLocalSocket*>(device)) {
|
||||
else if (QLocalSocket *localsocket = qobject_cast<QLocalSocket*>(device)) {
|
||||
flush_local_socket_ = &QLocalSocket::flush;
|
||||
connect(socket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
|
||||
connect(localsocket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
|
||||
}
|
||||
else {
|
||||
qFatal("Unsupported device type passed to _MessageHandlerBase");
|
||||
|
||||
@@ -26,13 +26,16 @@ _MessageReplyBase::_MessageReplyBase(QObject *parent)
|
||||
: QObject(parent), finished_(false), success_(false) {}
|
||||
|
||||
bool _MessageReplyBase::WaitForFinished() {
|
||||
|
||||
qLog(Debug) << "Waiting on ID" << id();
|
||||
semaphore_.acquire();
|
||||
qLog(Debug) << "Acquired ID" << id();
|
||||
return success_;
|
||||
|
||||
}
|
||||
|
||||
void _MessageReplyBase::Abort() {
|
||||
|
||||
Q_ASSERT(!finished_);
|
||||
finished_ = true;
|
||||
success_ = false;
|
||||
@@ -40,4 +43,5 @@ void _MessageReplyBase::Abort() {
|
||||
emit Finished(success_);
|
||||
qLog(Debug) << "Releasing ID" << id() << "(aborted)";
|
||||
semaphore_.release();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
@@ -12,31 +6,16 @@ include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-common)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||
include_directories(${CMAKE_BINARY_DIR}/src)
|
||||
|
||||
link_directories(${PROTOBUF_LIBRARY_DIRS})
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
|
||||
set(MESSAGES
|
||||
tagreadermessages.proto
|
||||
)
|
||||
link_directories(${TAGLIB_LIBRARY_DIRS})
|
||||
include_directories(${TAGLIB_INCLUDE_DIRS})
|
||||
|
||||
set(SOURCES
|
||||
fmpsparser.cpp
|
||||
tagreader.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(MOC ${HEADERS})
|
||||
set(MESSAGES tagreadermessages.proto)
|
||||
set(SOURCES fmpsparser.cpp tagreader.cpp)
|
||||
|
||||
protobuf_generate_cpp(PROTO_SOURCES PROTO_HEADERS ${MESSAGES})
|
||||
|
||||
add_library(libstrawberry-tagreader STATIC
|
||||
${PROTO_SOURCES}
|
||||
${SOURCES}
|
||||
${MOC}
|
||||
)
|
||||
|
||||
target_link_libraries(libstrawberry-tagreader
|
||||
${PROTOBUF_LIBRARY}
|
||||
libstrawberry-common
|
||||
)
|
||||
add_library(libstrawberry-tagreader STATIC ${PROTO_SOURCES} ${SOURCES})
|
||||
target_link_libraries(libstrawberry-tagreader ${PROTOBUF_LIBRARY} libstrawberry-common)
|
||||
|
||||
@@ -212,46 +212,46 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
|
||||
|
||||
// Handle all the files which have VorbisComments (Ogg, OPUS, ...) in the same way;
|
||||
// apart, so we keep specific behavior for some formats by adding another "else if" block below.
|
||||
if (TagLib::Ogg::XiphComment *tag = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) {
|
||||
ParseOggTag(tag->fieldListMap(), nullptr, &disc, &compilation, song);
|
||||
if (!tag->pictureList().isEmpty()) {
|
||||
if (TagLib::Ogg::XiphComment *tag_ogg = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) {
|
||||
ParseOggTag(tag_ogg->fieldListMap(), nullptr, &disc, &compilation, song);
|
||||
if (!tag_ogg->pictureList().isEmpty()) {
|
||||
song->set_art_automatic(kEmbeddedCover);
|
||||
}
|
||||
}
|
||||
|
||||
if (TagLib::FLAC::File *file = dynamic_cast<TagLib::FLAC::File *>(fileref->file())) {
|
||||
if (TagLib::FLAC::File *file_flac = dynamic_cast<TagLib::FLAC::File *>(fileref->file())) {
|
||||
|
||||
song->set_bitdepth(file->audioProperties()->bitsPerSample());
|
||||
song->set_bitdepth(file_flac->audioProperties()->bitsPerSample());
|
||||
|
||||
if (file->xiphComment()) {
|
||||
ParseOggTag(file->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song);
|
||||
if (!file->pictureList().isEmpty()) {
|
||||
if (file_flac->xiphComment()) {
|
||||
ParseOggTag(file_flac->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song);
|
||||
if (!file_flac->pictureList().isEmpty()) {
|
||||
song->set_art_automatic(kEmbeddedCover);
|
||||
}
|
||||
}
|
||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
||||
}
|
||||
|
||||
else if (TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File *>(fileref->file())) {
|
||||
song->set_bitdepth(file->audioProperties()->bitsPerSample());
|
||||
if (file->tag()) {
|
||||
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||
else if (TagLib::WavPack::File *file_wavpack = dynamic_cast<TagLib::WavPack::File *>(fileref->file())) {
|
||||
song->set_bitdepth(file_wavpack->audioProperties()->bitsPerSample());
|
||||
if (file_wavpack->tag()) {
|
||||
ParseAPETag(file_wavpack->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||
}
|
||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
||||
}
|
||||
|
||||
else if (TagLib::APE::File *file = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
||||
if (file->tag()) {
|
||||
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||
else if (TagLib::APE::File *file_ape = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
||||
if (file_ape->tag()) {
|
||||
ParseAPETag(file_ape->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||
}
|
||||
song->set_bitdepth(file->audioProperties()->bitsPerSample());
|
||||
song->set_bitdepth(file_ape->audioProperties()->bitsPerSample());
|
||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
||||
}
|
||||
|
||||
else if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
|
||||
else if (TagLib::MPEG::File *file_mpeg = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
|
||||
|
||||
if (file->ID3v2Tag()) {
|
||||
const TagLib::ID3v2::FrameListMap &map = file->ID3v2Tag()->frameListMap();
|
||||
if (file_mpeg->ID3v2Tag()) {
|
||||
const TagLib::ID3v2::FrameListMap &map = file_mpeg->ID3v2Tag()->frameListMap();
|
||||
|
||||
if (!map["TPOS"].isEmpty()) disc = TStringToQString(map["TPOS"].front()->toString()).trimmed();
|
||||
if (!map["TCOM"].isEmpty()) Decode(map["TCOM"].front()->toString(), nullptr, song->mutable_composer());
|
||||
@@ -309,12 +309,12 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
|
||||
}
|
||||
}
|
||||
|
||||
else if (TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||
else if (TagLib::MP4::File *file_mp4 = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||
|
||||
song->set_bitdepth(file->audioProperties()->bitsPerSample());
|
||||
song->set_bitdepth(file_mp4->audioProperties()->bitsPerSample());
|
||||
|
||||
if (file->tag()) {
|
||||
TagLib::MP4::Tag *mp4_tag = file->tag();
|
||||
if (file_mp4->tag()) {
|
||||
TagLib::MP4::Tag *mp4_tag = file_mp4->tag();
|
||||
|
||||
// Find album artists
|
||||
if (mp4_tag->item("aART").isValid()) {
|
||||
@@ -348,11 +348,11 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
|
||||
}
|
||||
}
|
||||
|
||||
else if (TagLib::ASF::File *file = dynamic_cast<TagLib::ASF::File*>(fileref->file())) {
|
||||
else if (TagLib::ASF::File *file_asf = dynamic_cast<TagLib::ASF::File*>(fileref->file())) {
|
||||
|
||||
song->set_bitdepth(file->audioProperties()->bitsPerSample());
|
||||
song->set_bitdepth(file_asf->audioProperties()->bitsPerSample());
|
||||
|
||||
const TagLib::ASF::AttributeListMap &attributes_map = file->tag()->attributeListMap();
|
||||
const TagLib::ASF::AttributeListMap &attributes_map = file_asf->tag()->attributeListMap();
|
||||
|
||||
if (attributes_map.contains(kASF_OriginalDate_ID)) {
|
||||
const TagLib::ASF::AttributeList &attributes = attributes_map[kASF_OriginalDate_ID];
|
||||
@@ -368,9 +368,9 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
|
||||
}
|
||||
}
|
||||
|
||||
else if (TagLib::MPC::File* file = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
||||
if (file->tag()) {
|
||||
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||
else if (TagLib::MPC::File* file_mpc = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
||||
if (file_mpc->tag()) {
|
||||
ParseAPETag(file_mpc->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||
}
|
||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
||||
}
|
||||
@@ -578,26 +578,26 @@ bool TagReader::SaveFile(const QString &filename, const pb::tagreader::SongMetad
|
||||
SetVorbisComments(tag, song);
|
||||
}
|
||||
|
||||
else if (TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File*>(fileref->file())) {
|
||||
TagLib::APE::Tag *tag = file->APETag(true);
|
||||
else if (TagLib::WavPack::File *file_wavpack = dynamic_cast<TagLib::WavPack::File*>(fileref->file())) {
|
||||
TagLib::APE::Tag *tag = file_wavpack->APETag(true);
|
||||
if (!tag) return false;
|
||||
SaveAPETag(tag, song);
|
||||
}
|
||||
|
||||
else if (TagLib::APE::File *file = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
||||
TagLib::APE::Tag *tag = file->APETag(true);
|
||||
else if (TagLib::APE::File *file_ape = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
||||
TagLib::APE::Tag *tag = file_ape->APETag(true);
|
||||
if (!tag) return false;
|
||||
SaveAPETag(tag, song);
|
||||
}
|
||||
|
||||
else if (TagLib::MPC::File *file = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
||||
TagLib::APE::Tag *tag = file->APETag(true);
|
||||
else if (TagLib::MPC::File *file_mpc = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
||||
TagLib::APE::Tag *tag = file_mpc->APETag(true);
|
||||
if (!tag) return false;
|
||||
SaveAPETag(tag, song);
|
||||
}
|
||||
|
||||
else if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
|
||||
TagLib::ID3v2::Tag *tag = file->ID3v2Tag(true);
|
||||
else if (TagLib::MPEG::File *file_mpeg = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
|
||||
TagLib::ID3v2::Tag *tag = file_mpeg->ID3v2Tag(true);
|
||||
if (!tag) return false;
|
||||
SetTextFrame("TPOS", song.disc() <= 0 -1 ? QString() : QString::number(song.disc()), tag);
|
||||
SetTextFrame("TCOM", song.composer(), tag);
|
||||
@@ -609,8 +609,8 @@ bool TagReader::SaveFile(const QString &filename, const pb::tagreader::SongMetad
|
||||
SetUnsyncLyricsFrame(song.lyrics(), tag);
|
||||
}
|
||||
|
||||
else if (TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||
TagLib::MP4::Tag *tag = file->tag();
|
||||
else if (TagLib::MP4::File *file_mp4 = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||
TagLib::MP4::Tag *tag = file_mp4->tag();
|
||||
tag->setItem("disk", TagLib::MP4::Item(song.disc() <= 0 -1 ? 0 : song.disc(), 0));
|
||||
tag->setItem("\251wrt", TagLib::StringList(song.composer().c_str()));
|
||||
tag->setItem("\251grp", TagLib::StringList(song.grouping().c_str()));
|
||||
|
||||
@@ -26,28 +26,18 @@
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
#include <taglib/tstring.h>
|
||||
#include <taglib/fileref.h>
|
||||
#include <taglib/xiphcomment.h>
|
||||
#include <taglib/apetag.h>
|
||||
#include <taglib/apefile.h>
|
||||
#include <taglib/id3v2tag.h>
|
||||
|
||||
#include "tagreadermessages.pb.h"
|
||||
|
||||
class QTextCodec;
|
||||
|
||||
#ifndef USE_SYSTEM_TAGLIB
|
||||
namespace Strawberry_TagLib {
|
||||
#endif
|
||||
namespace TagLib {
|
||||
class FileRef;
|
||||
class String;
|
||||
|
||||
namespace ID3v2 {
|
||||
class Tag;
|
||||
class PopularimeterFrame;
|
||||
}
|
||||
}
|
||||
#ifndef USE_SYSTEM_TAGLIB
|
||||
}
|
||||
using namespace Strawberry_TagLib;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-common)
|
||||
@@ -7,29 +8,20 @@ include_directories(${CMAKE_BINARY_DIR}/ext/libstrawberry-tagreader)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||
include_directories(${CMAKE_BINARY_DIR}/src)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
||||
link_directories(${PROTOBUF_LIBRARY_DIRS})
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
link_directories(${TAGLIB_LIBRARY_DIRS})
|
||||
include_directories(${TAGLIB_INCLUDE_DIRS})
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
tagreaderworker.cpp
|
||||
)
|
||||
set(SOURCES main.cpp tagreaderworker.cpp)
|
||||
|
||||
qt5_wrap_cpp(MOC ${HEADERS})
|
||||
qt5_add_resources(QRC data/data.qrc)
|
||||
|
||||
add_executable(strawberry-tagreader
|
||||
${SOURCES}
|
||||
${MOC}
|
||||
${QRC}
|
||||
)
|
||||
add_executable(strawberry-tagreader ${SOURCES} ${MOC} ${QRC})
|
||||
|
||||
target_link_libraries(strawberry-tagreader
|
||||
${TAGLIB_LIBRARIES}
|
||||
@@ -40,16 +32,11 @@ target_link_libraries(strawberry-tagreader
|
||||
)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
target_link_libraries(strawberry-tagreader
|
||||
execinfo
|
||||
)
|
||||
target_link_libraries(strawberry-tagreader execinfo)
|
||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(strawberry-tagreader
|
||||
/System/Library/Frameworks/Foundation.framework
|
||||
)
|
||||
target_link_libraries(strawberry-tagreader /System/Library/Frameworks/Foundation.framework)
|
||||
endif(APPLE)
|
||||
|
||||
|
||||
install(TARGETS strawberry-tagreader RUNTIME DESTINATION bin)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: strawberry
|
||||
version: '0.6.8+git'
|
||||
version: '0.6.11+git'
|
||||
summary: music player and collection organizer
|
||||
description: |
|
||||
Strawberry is a music player and collection organizer.
|
||||
|
||||
@@ -1,49 +1,16 @@
|
||||
# Strawberry Music Player
|
||||
# Copyright 2013, Jonas Kvinge <jonas@strawbs.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/>.
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
|
||||
option(BUILD_WERROR "Build with -Werror" OFF)
|
||||
|
||||
if(BUILD_WERROR)
|
||||
if (LINUX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif (LINUX)
|
||||
endif(BUILD_WERROR)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
if(HAVE_TRANSLATIONS)
|
||||
include(../cmake/Translations.cmake)
|
||||
endif(HAVE_TRANSLATIONS)
|
||||
|
||||
# Set up definitions and paths
|
||||
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-common)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-tagreader)
|
||||
include_directories(${CMAKE_BINARY_DIR}/ext/libstrawberry-tagreader)
|
||||
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions(-DQT_USE_QSTRINGBUILDER)
|
||||
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
|
||||
add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
@@ -69,10 +36,6 @@ if(HAVE_GSTREAMER)
|
||||
include_directories(${GSTREAMER_PBUTILS_INCLUDE_DIRS})
|
||||
endif(HAVE_GSTREAMER)
|
||||
|
||||
if(HAVE_PHONON)
|
||||
include_directories(${PHONON_INCLUDE_DIRS})
|
||||
endif(HAVE_PHONON)
|
||||
|
||||
if(HAVE_CHROMAPRINT)
|
||||
link_directories(${CHROMAPRINT_LIBRARY_DIRS})
|
||||
include_directories(${CHROMAPRINT_INCLUDE_DIRS})
|
||||
@@ -96,10 +59,6 @@ if(HAVE_LIBMTP)
|
||||
include_directories(${LIBMTP_INCLUDE_DIRS})
|
||||
endif(HAVE_LIBMTP)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-common)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-tagreader)
|
||||
include_directories(${CMAKE_BINARY_DIR}/ext/libstrawberry-tagreader)
|
||||
|
||||
set(SOURCES
|
||||
core/mainwindow.cpp
|
||||
core/application.cpp
|
||||
@@ -223,10 +182,14 @@ set(SOURCES
|
||||
covermanager/coverexportrunnable.cpp
|
||||
covermanager/currentalbumcoverloader.cpp
|
||||
covermanager/coverfromurldialog.cpp
|
||||
covermanager/jsoncoverprovider.cpp
|
||||
covermanager/lastfmcoverprovider.cpp
|
||||
covermanager/musicbrainzcoverprovider.cpp
|
||||
covermanager/discogscoverprovider.cpp
|
||||
covermanager/deezercoverprovider.cpp
|
||||
covermanager/qobuzcoverprovider.cpp
|
||||
covermanager/musixmatchcoverprovider.cpp
|
||||
covermanager/spotifycoverprovider.cpp
|
||||
|
||||
lyrics/lyricsproviders.cpp
|
||||
lyrics/lyricsprovider.cpp
|
||||
@@ -236,24 +199,30 @@ set(SOURCES
|
||||
lyrics/auddlyricsprovider.cpp
|
||||
lyrics/ovhlyricsprovider.cpp
|
||||
lyrics/lololyricsprovider.cpp
|
||||
lyrics/geniuslyricsprovider.cpp
|
||||
lyrics/musixmatchlyricsprovider.cpp
|
||||
lyrics/chartlyricsprovider.cpp
|
||||
|
||||
settings/settingsdialog.cpp
|
||||
settings/settingspage.cpp
|
||||
settings/behavioursettingspage.cpp
|
||||
settings/collectionsettingspage.cpp
|
||||
settings/backendsettingspage.cpp
|
||||
settings/contextsettingspage.cpp
|
||||
settings/playlistsettingspage.cpp
|
||||
settings/scrobblersettingspage.cpp
|
||||
settings/coverssettingspage.cpp
|
||||
settings/lyricssettingspage.cpp
|
||||
settings/networkproxysettingspage.cpp
|
||||
settings/appearancesettingspage.cpp
|
||||
settings/contextsettingspage.cpp
|
||||
settings/notificationssettingspage.cpp
|
||||
settings/scrobblersettingspage.cpp
|
||||
|
||||
dialogs/about.cpp
|
||||
dialogs/console.cpp
|
||||
dialogs/errordialog.cpp
|
||||
dialogs/edittagdialog.cpp
|
||||
dialogs/trackselectiondialog.cpp
|
||||
dialogs/addstreamdialog.cpp
|
||||
|
||||
widgets/autoexpandingtreeview.cpp
|
||||
widgets/busyindicator.cpp
|
||||
@@ -286,7 +255,6 @@ set(SOURCES
|
||||
internet/internetservices.cpp
|
||||
internet/internetservice.cpp
|
||||
internet/internetplaylistitem.cpp
|
||||
internet/internetsearch.cpp
|
||||
internet/internetsearchview.cpp
|
||||
internet/internetsearchmodel.cpp
|
||||
internet/internetsearchsortmodel.cpp
|
||||
@@ -334,6 +302,7 @@ set(HEADERS
|
||||
core/standarditemiconloader.h
|
||||
core/systemtrayicon.h
|
||||
core/mimedata.h
|
||||
core/stylesheetloader.h
|
||||
|
||||
engine/enginebase.h
|
||||
engine/devicefinders.h
|
||||
@@ -409,10 +378,14 @@ set(HEADERS
|
||||
covermanager/coverexportrunnable.h
|
||||
covermanager/currentalbumcoverloader.h
|
||||
covermanager/coverfromurldialog.h
|
||||
covermanager/jsoncoverprovider.h
|
||||
covermanager/lastfmcoverprovider.h
|
||||
covermanager/musicbrainzcoverprovider.h
|
||||
covermanager/discogscoverprovider.h
|
||||
covermanager/deezercoverprovider.h
|
||||
covermanager/qobuzcoverprovider.h
|
||||
covermanager/musixmatchcoverprovider.h
|
||||
covermanager/spotifycoverprovider.h
|
||||
|
||||
lyrics/lyricsproviders.h
|
||||
lyrics/lyricsprovider.h
|
||||
@@ -422,24 +395,30 @@ set(HEADERS
|
||||
lyrics/auddlyricsprovider.h
|
||||
lyrics/ovhlyricsprovider.h
|
||||
lyrics/lololyricsprovider.h
|
||||
lyrics/geniuslyricsprovider.h
|
||||
lyrics/musixmatchlyricsprovider.h
|
||||
lyrics/chartlyricsprovider.h
|
||||
|
||||
settings/settingsdialog.h
|
||||
settings/settingspage.h
|
||||
settings/behavioursettingspage.h
|
||||
settings/collectionsettingspage.h
|
||||
settings/backendsettingspage.h
|
||||
settings/contextsettingspage.h
|
||||
settings/playlistsettingspage.h
|
||||
settings/scrobblersettingspage.h
|
||||
settings/coverssettingspage.h
|
||||
settings/lyricssettingspage.h
|
||||
settings/networkproxysettingspage.h
|
||||
settings/appearancesettingspage.h
|
||||
settings/contextsettingspage.h
|
||||
settings/notificationssettingspage.h
|
||||
settings/scrobblersettingspage.h
|
||||
|
||||
dialogs/about.h
|
||||
dialogs/errordialog.h
|
||||
dialogs/console.h
|
||||
dialogs/edittagdialog.h
|
||||
dialogs/trackselectiondialog.h
|
||||
dialogs/addstreamdialog.h
|
||||
|
||||
widgets/autoexpandingtreeview.h
|
||||
widgets/busyindicator.h
|
||||
@@ -472,7 +451,6 @@ set(HEADERS
|
||||
internet/internetservices.h
|
||||
internet/internetservice.h
|
||||
internet/internetsongmimedata.h
|
||||
internet/internetsearch.h
|
||||
internet/internetsearchview.h
|
||||
internet/internetsearchmodel.h
|
||||
internet/localredirectserver.h
|
||||
@@ -526,10 +504,12 @@ set(UI
|
||||
settings/backendsettingspage.ui
|
||||
settings/contextsettingspage.ui
|
||||
settings/playlistsettingspage.ui
|
||||
settings/scrobblersettingspage.ui
|
||||
settings/coverssettingspage.ui
|
||||
settings/lyricssettingspage.ui
|
||||
settings/networkproxysettingspage.ui
|
||||
settings/appearancesettingspage.ui
|
||||
settings/notificationssettingspage.ui
|
||||
settings/scrobblersettingspage.ui
|
||||
|
||||
equalizer/equalizer.ui
|
||||
equalizer/equalizerslider.ui
|
||||
@@ -539,6 +519,7 @@ set(UI
|
||||
dialogs/console.ui
|
||||
dialogs/edittagdialog.ui
|
||||
dialogs/trackselectiondialog.ui
|
||||
dialogs/addstreamdialog.ui
|
||||
|
||||
widgets/trackslider.ui
|
||||
widgets/osdpretty.ui
|
||||
@@ -622,12 +603,6 @@ optional_source(HAVE_VLC
|
||||
HEADERS engine/vlcengine.h
|
||||
)
|
||||
|
||||
# Phonon
|
||||
optional_source(HAVE_PHONON
|
||||
SOURCES engine/phononengine.cpp
|
||||
HEADERS engine/phononengine.h
|
||||
)
|
||||
|
||||
# DBUS and MPRIS - Unix specific
|
||||
if(UNIX AND HAVE_DBUS)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dbus)
|
||||
@@ -923,6 +898,29 @@ optional_source(HAVE_SUBSONIC
|
||||
settings/subsonicsettingspage.ui
|
||||
)
|
||||
|
||||
optional_source(HAVE_TIDAL
|
||||
SOURCES
|
||||
tidal/tidalservice.cpp
|
||||
tidal/tidalurlhandler.cpp
|
||||
tidal/tidalbaserequest.cpp
|
||||
tidal/tidalrequest.cpp
|
||||
tidal/tidalstreamurlrequest.cpp
|
||||
tidal/tidalfavoriterequest.cpp
|
||||
settings/tidalsettingspage.cpp
|
||||
covermanager/tidalcoverprovider.cpp
|
||||
HEADERS
|
||||
tidal/tidalservice.h
|
||||
tidal/tidalurlhandler.h
|
||||
tidal/tidalbaserequest.h
|
||||
tidal/tidalrequest.h
|
||||
tidal/tidalstreamurlrequest.h
|
||||
tidal/tidalfavoriterequest.h
|
||||
settings/tidalsettingspage.h
|
||||
covermanager/tidalcoverprovider.h
|
||||
UI
|
||||
settings/tidalsettingspage.ui
|
||||
)
|
||||
|
||||
# Moodbar
|
||||
optional_source(HAVE_MOODBAR
|
||||
SOURCES
|
||||
@@ -1002,7 +1000,6 @@ target_link_libraries(strawberry_lib
|
||||
${GOBJECT_LIBRARIES}
|
||||
${GNUTLS_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
${CHROMAPRINT_LIBRARIES}
|
||||
${SQLITE_LIBRARIES}
|
||||
${TAGLIB_LIBRARIES}
|
||||
${SINGLEAPPLICATION_LIBRARIES}
|
||||
@@ -1026,6 +1023,10 @@ if(HAVE_GSTREAMER)
|
||||
target_link_libraries(strawberry_lib ${GSTREAMER_LIBRARIES} ${GSTREAMER_BASE_LIBRARIES} ${GSTREAMER_AUDIO_LIBRARIES} ${GSTREAMER_APP_LIBRARIES} ${GSTREAMER_TAG_LIBRARIES} ${GSTREAMER_PBUTILS_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(HAVE_CHROMAPRINT)
|
||||
target_link_libraries(strawberry_lib ${CHROMAPRINT_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(HAVE_XINE)
|
||||
target_link_libraries(strawberry_lib ${LIBXINE_LIBRARIES})
|
||||
endif()
|
||||
@@ -1034,10 +1035,6 @@ if(HAVE_VLC)
|
||||
target_link_libraries(strawberry_lib ${LIBVLC_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(HAVE_PHONON)
|
||||
target_link_libraries(strawberry_lib ${PHONON_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(HAVE_LIBGPOD)
|
||||
target_link_libraries(strawberry_lib ${LIBGPOD_LIBRARIES})
|
||||
endif(HAVE_LIBGPOD)
|
||||
@@ -1051,11 +1048,7 @@ if(HAVE_AUDIOCD)
|
||||
endif(HAVE_AUDIOCD)
|
||||
|
||||
if(HAVE_IMOBILEDEVICE)
|
||||
target_link_libraries(strawberry_lib
|
||||
${LIBIMOBILEDEVICE_LIBRARIES}
|
||||
${LIBPLIST_LIBRARIES}
|
||||
${LIBUSBMUXD_LIBRARIES}
|
||||
)
|
||||
target_link_libraries(strawberry_lib ${LIBIMOBILEDEVICE_LIBRARIES} ${LIBPLIST_LIBRARIES} ${LIBUSBMUXD_LIBRARIES})
|
||||
link_directories(${LIBIMOBILEDEVICE_LIBRARY_DIRS})
|
||||
link_directories(${LIBUSBMUXD_LIBRARY_DIRS})
|
||||
endif(HAVE_IMOBILEDEVICE)
|
||||
@@ -1083,7 +1076,6 @@ if (APPLE)
|
||||
"-framework ScriptingBridge"
|
||||
)
|
||||
|
||||
target_link_libraries(strawberry_lib ${SPMEDIAKEYTAP_LIBRARIES})
|
||||
if (HAVE_SPARKLE)
|
||||
include_directories(${SPARKLE}/Headers)
|
||||
target_link_libraries(strawberry_lib ${SPARKLE})
|
||||
@@ -1106,9 +1098,9 @@ if (UNIX AND NOT APPLE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if(NOT USE_SYSTEM_SINGLEAPPLICATION)
|
||||
add_dependencies(strawberry_lib ${SINGLEAPPLICATION_LIBRARIES} ${SINGLECOREAPPLICATION_LIBRARIES})
|
||||
endif()
|
||||
if (NOT USE_SYSTEM_SINGLEAPPLICATION)
|
||||
add_dependencies(strawberry_lib ${SINGLEAPPLICATION_LIBRARIES} ${SINGLECOREAPPLICATION_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -1136,9 +1128,7 @@ if(FREEBSD)
|
||||
target_link_libraries(strawberry execinfo)
|
||||
endif()
|
||||
|
||||
target_link_libraries(strawberry
|
||||
strawberry_lib
|
||||
)
|
||||
target_link_libraries(strawberry strawberry_lib)
|
||||
|
||||
# macdeploy.py relies on the blob being built first.
|
||||
add_dependencies(strawberry strawberry-tagreader)
|
||||
|
||||
@@ -185,8 +185,8 @@ void BlockAnalyzer::analyze(QPainter &p, const Analyzer::Scope &s, bool new_fram
|
||||
|
||||
if (fade_intensity_[x] > 0) {
|
||||
const uint offset = --fade_intensity_[x];
|
||||
const uint y = y_ + (fade_pos_[x] * (kHeight + 1));
|
||||
canvas_painter.drawPixmap(x * (kWidth + 1), y, fade_bars_[offset], 0, 0, kWidth, height() - y);
|
||||
const uint y2 = y_ + (fade_pos_[x] * (kHeight + 1));
|
||||
canvas_painter.drawPixmap(x * (kWidth + 1), y2, fade_bars_[offset], 0, 0, kWidth, height() - y2);
|
||||
}
|
||||
|
||||
if (fade_intensity_[x] == 0) fade_pos_[x] = rows_;
|
||||
@@ -237,7 +237,8 @@ static inline void adjustToLimits(int &b, int &f, uint &amount) {
|
||||
* It won't modify the hue of fg unless absolutely necessary
|
||||
* @return the adjusted form of fg
|
||||
*/
|
||||
QColor ensureContrast(const QColor &bg, const QColor &fg, uint amount = 150) {
|
||||
QColor ensureContrast(const QColor &bg, const QColor &fg, uint amount = 150);
|
||||
QColor ensureContrast(const QColor &bg, const QColor &fg, uint amount) {
|
||||
|
||||
class OutputOnExit {
|
||||
public:
|
||||
@@ -344,18 +345,18 @@ void BlockAnalyzer::paletteChange(const QPalette&) {
|
||||
p.fillRect(0, y * (kHeight + 1), kWidth, kHeight, QColor(r + static_cast<int>(dr * y), g + static_cast<int>(dg * y), b + static_cast<int>(db * y)));
|
||||
|
||||
{
|
||||
const QColor bg = palette().color(QPalette::Background).darker(112);
|
||||
const QColor bg2 = palette().color(QPalette::Background).darker(112);
|
||||
|
||||
// make a complimentary fadebar colour
|
||||
// TODO dark is not always correct, dumbo!
|
||||
int h, s, v;
|
||||
palette().color(QPalette::Background).darker(150).getHsv(&h, &s, &v);
|
||||
const QColor fg(QColor::fromHsv(h + 120, s, v));
|
||||
const QColor fg2(QColor::fromHsv(h + 120, s, v));
|
||||
|
||||
const double dr = fg.red() - bg.red();
|
||||
const double dg = fg.green() - bg.green();
|
||||
const double db = fg.blue() - bg.blue();
|
||||
const int r = bg.red(), g = bg.green(), b = bg.blue();
|
||||
const double dr2 = fg2.red() - bg2.red();
|
||||
const double dg2 = fg2.green() - bg2.green();
|
||||
const double db2 = fg2.blue() - bg2.blue();
|
||||
const int r2 = bg2.red(), g2 = bg2.green(), b2 = bg2.blue();
|
||||
|
||||
// Precalculate all fade-bar pixmaps
|
||||
for (uint y = 0; y < kFadeSize; ++y) {
|
||||
@@ -363,7 +364,7 @@ void BlockAnalyzer::paletteChange(const QPalette&) {
|
||||
QPainter f(&fade_bars_[y]);
|
||||
for (int z = 0; static_cast<uint>(z) < rows_; ++z) {
|
||||
const double Y = 1.0 - (log10(kFadeSize - y) / log10(kFadeSize));
|
||||
f.fillRect(0, z * (kHeight + 1), kWidth, kHeight, QColor(r + static_cast<int>(dr * Y), g + static_cast<int>(dg * Y), b + static_cast<int>(db * Y)));
|
||||
f.fillRect(0, z * (kHeight + 1), kWidth, kHeight, QColor(r2 + static_cast<int>(dr2 * Y), g2 + static_cast<int>(dg2 * Y), b2 + static_cast<int>(db2 * Y)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,20 +75,20 @@ class RainbowAnalyzer : public Analyzer::Base {
|
||||
|
||||
static RainbowType rainbowtype;
|
||||
|
||||
inline QRect SourceRect(RainbowType rainbowtype) const {
|
||||
return QRect(0, kHeight[rainbowtype] * frame_, kWidth[rainbowtype], kHeight[rainbowtype]);
|
||||
inline QRect SourceRect(RainbowType _rainbowtype) const {
|
||||
return QRect(0, kHeight[_rainbowtype] * frame_, kWidth[_rainbowtype], kHeight[_rainbowtype]);
|
||||
}
|
||||
|
||||
inline QRect SleepingSourceRect(RainbowType rainbowtype) const {
|
||||
return QRect(0, kHeight[rainbowtype] * kFrameCount[rainbowtype], kWidth[rainbowtype], kSleepingHeight[rainbowtype]);
|
||||
inline QRect SleepingSourceRect(RainbowType _rainbowtype) const {
|
||||
return QRect(0, kHeight[_rainbowtype] * kFrameCount[_rainbowtype], kWidth[_rainbowtype], kSleepingHeight[_rainbowtype]);
|
||||
}
|
||||
|
||||
inline QRect DestRect(RainbowType rainbowtype) const {
|
||||
return QRect(width() - kWidth[rainbowtype], (height() - kHeight[rainbowtype]) / 2, kWidth[rainbowtype], kHeight[rainbowtype]);
|
||||
inline QRect DestRect(RainbowType _rainbowtype) const {
|
||||
return QRect(width() - kWidth[_rainbowtype], (height() - kHeight[_rainbowtype]) / 2, kWidth[_rainbowtype], kHeight[_rainbowtype]);
|
||||
}
|
||||
|
||||
inline QRect SleepingDestRect(RainbowType rainbowtype) const {
|
||||
return QRect(width() - kWidth[rainbowtype], (height() - kSleepingHeight[rainbowtype]) / 2, kWidth[rainbowtype], kSleepingHeight[rainbowtype]);
|
||||
inline QRect SleepingDestRect(RainbowType _rainbowtype) const {
|
||||
return QRect(width() - kWidth[_rainbowtype], (height() - kSleepingHeight[_rainbowtype]) / 2, kWidth[_rainbowtype], kSleepingHeight[_rainbowtype]);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -411,6 +411,10 @@ void CollectionBackend::AddOrUpdateSubdirs(const SubdirectoryList &subdirs) {
|
||||
|
||||
}
|
||||
|
||||
void CollectionBackend::AddOrUpdateSongsAsync(const SongList &songs) {
|
||||
metaObject()->invokeMethod(this, "AddOrUpdateSongs", Qt::QueuedConnection, Q_ARG(SongList, songs));
|
||||
}
|
||||
|
||||
void CollectionBackend::AddOrUpdateSongs(const SongList &songs) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
@@ -467,7 +471,7 @@ void CollectionBackend::AddOrUpdateSongs(const SongList &songs) {
|
||||
continue;
|
||||
|
||||
}
|
||||
else if (song.song_id() != -1) { // Song has a unique id, check if the song exists.
|
||||
else if (!song.song_id().isEmpty()) { // Song has a unique id, check if the song exists.
|
||||
|
||||
// Get the previous song data first
|
||||
Song old_song(GetSongBySongId(song.song_id()));
|
||||
@@ -822,35 +826,29 @@ SongList CollectionBackend::GetSongsByUrl(const QUrl &url) {
|
||||
}
|
||||
|
||||
|
||||
Song CollectionBackend::GetSongBySongId(int song_id) {
|
||||
Song CollectionBackend::GetSongBySongId(const QString &song_id) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
return GetSongBySongId(song_id, db);
|
||||
}
|
||||
|
||||
SongList CollectionBackend::GetSongsBySongId(const QList<int> &song_ids) {
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
QStringList str_song_ids;
|
||||
for (int song_id : song_ids) {
|
||||
str_song_ids << QString::number(song_id);
|
||||
}
|
||||
|
||||
return GetSongsBySongId(str_song_ids, db);
|
||||
}
|
||||
|
||||
SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
return GetSongsBySongId(song_ids, db);
|
||||
|
||||
}
|
||||
|
||||
Song CollectionBackend::GetSongBySongId(int song_id, QSqlDatabase &db) {
|
||||
SongList list = GetSongsBySongId(QStringList() << QString::number(song_id), db);
|
||||
Song CollectionBackend::GetSongBySongId(const QString &song_id, QSqlDatabase &db) {
|
||||
|
||||
SongList list = GetSongsBySongId(QStringList() << song_id, db);
|
||||
if (list.isEmpty()) return Song();
|
||||
return list.first();
|
||||
|
||||
}
|
||||
|
||||
SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids, QSqlDatabase &db) {
|
||||
@@ -1001,7 +999,7 @@ void CollectionBackend::UpdateCompilations(QSqlQuery &find_song, QSqlQuery &upda
|
||||
|
||||
}
|
||||
|
||||
CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist, bool compilation, const QueryOptions &opt) {
|
||||
CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist, const bool compilation_required, const QueryOptions &opt) {
|
||||
|
||||
AlbumList ret;
|
||||
|
||||
@@ -1009,7 +1007,7 @@ CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist,
|
||||
query.SetColumnSpec("album, artist, albumartist, compilation, compilation_detected, art_automatic, art_manual, url");
|
||||
query.SetOrderBy("album");
|
||||
|
||||
if (compilation) {
|
||||
if (compilation_required) {
|
||||
query.AddCompilationRequirement(true);
|
||||
}
|
||||
else if (!artist.isEmpty()) {
|
||||
@@ -1026,11 +1024,11 @@ CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist,
|
||||
QString last_artist;
|
||||
QString last_album_artist;
|
||||
while (query.Next()) {
|
||||
bool compilation = query.Value(3).toBool() | query.Value(4).toBool();
|
||||
bool is_compilation = query.Value(3).toBool() | query.Value(4).toBool();
|
||||
|
||||
Album info;
|
||||
info.artist = compilation ? QString() : query.Value(1).toString();
|
||||
info.album_artist = compilation ? QString() : query.Value(2).toString();
|
||||
info.artist = is_compilation ? QString() : query.Value(1).toString();
|
||||
info.album_artist = is_compilation ? QString() : query.Value(2).toString();
|
||||
info.album_name = query.Value(0).toString();
|
||||
info.first_url = QUrl::fromEncoded(query.Value(7).toByteArray());
|
||||
|
||||
|
||||
@@ -141,10 +141,10 @@ class CollectionBackend : public CollectionBackendInterface {
|
||||
void UpdateTotalArtistCountAsync();
|
||||
void UpdateTotalAlbumCountAsync();
|
||||
|
||||
SongList FindSongsInDirectory(int id);
|
||||
SubdirectoryList SubdirsInDirectory(int id);
|
||||
SongList FindSongsInDirectory(const int id);
|
||||
SubdirectoryList SubdirsInDirectory(const int id);
|
||||
DirectoryList GetAllDirectories();
|
||||
void ChangeDirPath(int id, const QString &old_path, const QString &new_path);
|
||||
void ChangeDirPath(const int id, const QString &old_path, const QString &new_path);
|
||||
|
||||
QStringList GetAll(const QString &column, const QueryOptions &opt = QueryOptions());
|
||||
QStringList GetAllArtists(const QueryOptions &opt = QueryOptions());
|
||||
@@ -161,7 +161,7 @@ class CollectionBackend : public CollectionBackendInterface {
|
||||
void UpdateManualAlbumArtAsync(const QString &artist, const QString &albumartist, const QString &album, const QUrl &cover_url);
|
||||
Album GetAlbumArt(const QString &artist, const QString &albumartist, const QString &album);
|
||||
|
||||
Song GetSongById(int id);
|
||||
Song GetSongById(const int id);
|
||||
SongList GetSongsById(const QList<int> &ids);
|
||||
SongList GetSongsById(const QStringList &ids);
|
||||
SongList GetSongsByForeignId(const QStringList &ids, const QString &table, const QString &column);
|
||||
@@ -175,18 +175,19 @@ class CollectionBackend : public CollectionBackendInterface {
|
||||
bool ExecQuery(CollectionQuery *q);
|
||||
SongList ExecCollectionQuery(CollectionQuery *query);
|
||||
|
||||
void IncrementPlayCountAsync(int id);
|
||||
void IncrementSkipCountAsync(int id, float progress);
|
||||
void ResetStatisticsAsync(int id);
|
||||
void IncrementPlayCountAsync(const int id);
|
||||
void IncrementSkipCountAsync(const int id, const float progress);
|
||||
void ResetStatisticsAsync(const int id);
|
||||
|
||||
void DeleteAll();
|
||||
|
||||
Song GetSongBySongId(int song_id);
|
||||
SongList GetSongsBySongId(const QList<int> &song_ids);
|
||||
Song GetSongBySongId(const QString &song_id);
|
||||
SongList GetSongsBySongId(const QStringList &song_ids);
|
||||
|
||||
Song::Source Source() const;
|
||||
|
||||
void AddOrUpdateSongsAsync(const SongList &songs);
|
||||
|
||||
public slots:
|
||||
void Exit();
|
||||
void LoadDirectories();
|
||||
@@ -200,10 +201,10 @@ class CollectionBackend : public CollectionBackendInterface {
|
||||
void AddOrUpdateSubdirs(const SubdirectoryList &subdirs);
|
||||
void UpdateCompilations();
|
||||
void UpdateManualAlbumArt(const QString &artist, const QString &albumartist, const QString &album, const QUrl &cover_url);
|
||||
void ForceCompilation(const QString &album, const QList<QString> &artists, bool on);
|
||||
void IncrementPlayCount(int id);
|
||||
void IncrementSkipCount(int id, float progress);
|
||||
void ResetStatistics(int id);
|
||||
void ForceCompilation(const QString &album, const QList<QString> &artists, const bool on);
|
||||
void IncrementPlayCount(const int id);
|
||||
void IncrementSkipCount(const int id, const float progress);
|
||||
void ResetStatistics(const int id);
|
||||
void SongPathChanged(const Song &song, const QFileInfo &new_file);
|
||||
|
||||
signals:
|
||||
@@ -216,9 +217,9 @@ class CollectionBackend : public CollectionBackendInterface {
|
||||
|
||||
void DatabaseReset();
|
||||
|
||||
void TotalSongCountUpdated(int total);
|
||||
void TotalArtistCountUpdated(int total);
|
||||
void TotalAlbumCountUpdated(int total);
|
||||
void TotalSongCountUpdated(const int total);
|
||||
void TotalArtistCountUpdated(const int total);
|
||||
void TotalAlbumCountUpdated(const int total);
|
||||
|
||||
void ExitFinished();
|
||||
|
||||
@@ -234,14 +235,14 @@ class CollectionBackend : public CollectionBackendInterface {
|
||||
};
|
||||
|
||||
void UpdateCompilations(QSqlQuery &find_song, QSqlQuery &update_song, SongList &deleted_songs, SongList &added_songs, const QUrl &url, const bool compilation_detected);
|
||||
AlbumList GetAlbums(const QString &artist, const QString &album_artist, bool compilation = false, const QueryOptions &opt = QueryOptions());
|
||||
AlbumList GetAlbums(const QString &artist, bool compilation, const QueryOptions &opt = QueryOptions());
|
||||
SubdirectoryList SubdirsInDirectory(int id, QSqlDatabase &db);
|
||||
AlbumList GetAlbums(const QString &artist, const QString &album_artist, const bool compilation_required = false, const QueryOptions &opt = QueryOptions());
|
||||
AlbumList GetAlbums(const QString &artist, const bool compilation_required, const QueryOptions &opt = QueryOptions());
|
||||
SubdirectoryList SubdirsInDirectory(const int id, QSqlDatabase &db);
|
||||
|
||||
Song GetSongById(int id, QSqlDatabase &db);
|
||||
Song GetSongById(const int id, QSqlDatabase &db);
|
||||
SongList GetSongsById(const QStringList &ids, QSqlDatabase &db);
|
||||
|
||||
Song GetSongBySongId(int song_id, QSqlDatabase &db);
|
||||
Song GetSongBySongId(const QString &song_id, QSqlDatabase &db);
|
||||
SongList GetSongsBySongId(const QStringList &song_ids, QSqlDatabase &db);
|
||||
|
||||
private:
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include "collectionbackend.h"
|
||||
#include "collectiondirectorymodel.h"
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
CollectionDirectoryModel::CollectionDirectoryModel(CollectionBackend *backend, QObject *parent)
|
||||
: QStandardItemModel(parent),
|
||||
dir_icon_(IconLoader::Load("document-open-folder")),
|
||||
|
||||
@@ -297,6 +297,7 @@ void CollectionFilterWidget::SetCollectionModel(CollectionModel *model) {
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::GroupByClicked(QAction *action) {
|
||||
|
||||
if (action->property("group_by").isNull()) {
|
||||
group_by_dialog_->show();
|
||||
return;
|
||||
@@ -304,6 +305,7 @@ void CollectionFilterWidget::GroupByClicked(QAction *action) {
|
||||
|
||||
CollectionModel::Grouping g = action->property("group_by").value<CollectionModel::Grouping>();
|
||||
model_->SetGroupBy(g);
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::GroupingChanged(const CollectionModel::Grouping &g) {
|
||||
|
||||
@@ -37,13 +37,13 @@ class CollectionItem : public SimpleTreeItem<CollectionItem> {
|
||||
Type_LoadingIndicator,
|
||||
};
|
||||
|
||||
explicit CollectionItem(SimpleTreeModel<CollectionItem> *model)
|
||||
: SimpleTreeItem<CollectionItem>(Type_Root, model),
|
||||
explicit CollectionItem(SimpleTreeModel<CollectionItem> *_model)
|
||||
: SimpleTreeItem<CollectionItem>(Type_Root, _model),
|
||||
container_level(-1),
|
||||
compilation_artist_node_(nullptr) {}
|
||||
|
||||
explicit CollectionItem(Type type, CollectionItem *parent = nullptr)
|
||||
: SimpleTreeItem<CollectionItem>(type, parent),
|
||||
explicit CollectionItem(Type _type, CollectionItem *_parent = nullptr)
|
||||
: SimpleTreeItem<CollectionItem>(_type, _parent),
|
||||
container_level(-1),
|
||||
compilation_artist_node_(nullptr) {}
|
||||
|
||||
|
||||
@@ -66,16 +66,15 @@
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
#include "settings/collectionsettingspage.h"
|
||||
|
||||
using std::bind;
|
||||
using std::sort;
|
||||
using std::placeholders::_1;
|
||||
using std::placeholders::_2;
|
||||
|
||||
const char *CollectionModel::kSavedGroupingsSettingsGroup = "SavedGroupings";
|
||||
const int CollectionModel::kPrettyCoverSize = 32;
|
||||
const char *CollectionModel::kPixmapDiskCacheDir = "/pixmapcache";
|
||||
const char *CollectionModel::kPixmapDiskCacheDir = "pixmapcache";
|
||||
|
||||
QNetworkDiskCache *CollectionModel::sIconCache = nullptr;
|
||||
|
||||
@@ -115,17 +114,18 @@ CollectionModel::CollectionModel(CollectionBackend *backend, Application *app, Q
|
||||
cover_loader_options_.pad_output_image_ = true;
|
||||
cover_loader_options_.scale_output_image_ = true;
|
||||
|
||||
if (app_)
|
||||
connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QUrl, QImage)), SLOT(AlbumCoverLoaded(quint64, QUrl, QImage)));
|
||||
if (app_) {
|
||||
connect(app_->album_cover_loader(), SIGNAL(AlbumCoverLoaded(quint64, AlbumCoverLoaderResult)), SLOT(AlbumCoverLoaded(quint64, AlbumCoverLoaderResult)));
|
||||
}
|
||||
|
||||
QIcon nocover = IconLoader::Load("cdcase");
|
||||
no_cover_icon_ = nocover.pixmap(nocover.availableSizes().last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
//no_cover_icon_ = QPixmap(":/pictures/noalbumart.png").scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
// When running under gdb, all calls to this constructor came from the same thread.
|
||||
// If this ever changes, these two lines might need to be protected by a mutex.
|
||||
if (sIconCache == nullptr)
|
||||
if (sIconCache == nullptr) {
|
||||
sIconCache = new QNetworkDiskCache(this);
|
||||
sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + kPixmapDiskCacheDir);
|
||||
}
|
||||
|
||||
connect(backend_, SIGNAL(SongsDiscovered(SongList)), SLOT(SongsDiscovered(SongList)));
|
||||
connect(backend_, SIGNAL(SongsDeleted(SongList)), SLOT(SongsDeleted(SongList)));
|
||||
@@ -149,7 +149,7 @@ CollectionModel::~CollectionModel() {
|
||||
delete root_;
|
||||
}
|
||||
|
||||
void CollectionModel::set_pretty_covers(bool use_pretty_covers) {
|
||||
void CollectionModel::set_pretty_covers(const bool use_pretty_covers) {
|
||||
|
||||
if (use_pretty_covers != use_pretty_covers_) {
|
||||
use_pretty_covers_ = use_pretty_covers;
|
||||
@@ -157,7 +157,7 @@ void CollectionModel::set_pretty_covers(bool use_pretty_covers) {
|
||||
}
|
||||
}
|
||||
|
||||
void CollectionModel::set_show_dividers(bool show_dividers) {
|
||||
void CollectionModel::set_show_dividers(const bool show_dividers) {
|
||||
|
||||
if (show_dividers != show_dividers_) {
|
||||
show_dividers_ = show_dividers;
|
||||
@@ -187,19 +187,19 @@ void CollectionModel::ReloadSettings() {
|
||||
|
||||
use_disk_cache_ = s.value(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool();
|
||||
|
||||
if (!use_disk_cache_) {
|
||||
sIconCache->clear();
|
||||
}
|
||||
QPixmapCache::setCacheLimit(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit, CollectionSettingsPage::kSettingsCacheSizeDefault) / 1024);
|
||||
|
||||
sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + kPixmapDiskCacheDir);
|
||||
sIconCache->setMaximumCacheSize(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit));
|
||||
|
||||
QPixmapCache::setCacheLimit(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit) / 1024);
|
||||
sIconCache->setMaximumCacheSize(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault));
|
||||
|
||||
s.endGroup();
|
||||
|
||||
if (!use_disk_cache_) {
|
||||
ClearDiskCache();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::Init(bool async) {
|
||||
void CollectionModel::Init(const bool async) {
|
||||
|
||||
if (async) {
|
||||
// Show a loading indicator in the model.
|
||||
@@ -338,7 +338,7 @@ void CollectionModel::SongsSlightlyChanged(const SongList &songs) {
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::CreateCompilationArtistNode(bool signal, CollectionItem *parent) {
|
||||
CollectionItem *CollectionModel::CreateCompilationArtistNode(const bool signal, CollectionItem *parent) {
|
||||
|
||||
if (signal) beginInsertRows(ItemToIndex(parent), parent->children.count(), parent->children.count());
|
||||
|
||||
@@ -354,7 +354,7 @@ CollectionItem *CollectionModel::CreateCompilationArtistNode(bool signal, Collec
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const {
|
||||
QString CollectionModel::DividerKey(const GroupBy type, CollectionItem *item) const {
|
||||
|
||||
// Items which are to be grouped under the same divider must produce the same divider key. This will only get called for top-level items.
|
||||
|
||||
@@ -408,7 +408,7 @@ QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const {
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::DividerDisplayText(GroupBy type, const QString &key) const {
|
||||
QString CollectionModel::DividerDisplayText(const GroupBy type, const QString &key) const {
|
||||
|
||||
// Pretty display text for the dividers.
|
||||
|
||||
@@ -588,10 +588,10 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) {
|
||||
if (use_disk_cache_) {
|
||||
std::unique_ptr<QIODevice> cache(sIconCache->data(QUrl(cache_key)));
|
||||
if (cache) {
|
||||
QImage cached_pixmap;
|
||||
if (cached_pixmap.load(cache.get(), "XPM")) {
|
||||
QPixmapCache::insert(cache_key, QPixmap::fromImage(cached_pixmap));
|
||||
return QPixmap::fromImage(cached_pixmap);
|
||||
QImage cached_image;
|
||||
if (cached_image.load(cache.get(), "XPM")) {
|
||||
QPixmapCache::insert(cache_key, QPixmap::fromImage(cached_image));
|
||||
return QPixmap::fromImage(cached_image);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -613,9 +613,7 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image) {
|
||||
|
||||
Q_UNUSED(cover_url);
|
||||
void CollectionModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
||||
|
||||
if (!pending_art_.contains(id)) return;
|
||||
|
||||
@@ -628,26 +626,26 @@ void CollectionModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_url,
|
||||
pending_cache_keys_.remove(cache_key);
|
||||
|
||||
// Insert this image in the cache.
|
||||
if (image.isNull()) {
|
||||
if (result.image_scaled.isNull()) {
|
||||
// Set the no_cover image so we don't continually try to load art.
|
||||
QPixmapCache::insert(cache_key, no_cover_icon_);
|
||||
}
|
||||
else {
|
||||
QPixmap image_pixmap;
|
||||
image_pixmap = QPixmap::fromImage(image);
|
||||
image_pixmap = QPixmap::fromImage(result.image_scaled);
|
||||
QPixmapCache::insert(cache_key, image_pixmap);
|
||||
}
|
||||
|
||||
// If we have a valid cover not already in the disk cache
|
||||
if (use_disk_cache_) {
|
||||
std::unique_ptr<QIODevice> cached_img(sIconCache->data(QUrl(cache_key)));
|
||||
if (!cached_img && !image.isNull()) {
|
||||
if (!cached_img && !result.image_scaled.isNull()) {
|
||||
QNetworkCacheMetaData item_metadata;
|
||||
item_metadata.setSaveToDisk(true);
|
||||
item_metadata.setUrl(QUrl(cache_key));
|
||||
QIODevice* cache = sIconCache->prepare(item_metadata);
|
||||
QIODevice *cache = sIconCache->prepare(item_metadata);
|
||||
if (cache) {
|
||||
image.save(cache, "XPM");
|
||||
result.image_scaled.save(cache, "XPM");
|
||||
sIconCache->insert(cache);
|
||||
}
|
||||
}
|
||||
@@ -660,7 +658,7 @@ void CollectionModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_url,
|
||||
|
||||
}
|
||||
|
||||
QVariant CollectionModel::data(const QModelIndex &idx, int role) const {
|
||||
QVariant CollectionModel::data(const QModelIndex &idx, const int role) const {
|
||||
|
||||
const CollectionItem *item = IndexToItem(idx);
|
||||
|
||||
@@ -672,11 +670,7 @@ QVariant CollectionModel::data(const QModelIndex &idx, int role) const {
|
||||
bool is_album_node = false;
|
||||
if (role == Qt::DecorationRole && item->type == CollectionItem::Type_Container) {
|
||||
GroupBy container_type = group_by_[item->container_level];
|
||||
is_album_node = container_type == GroupBy_Album ||
|
||||
container_type == GroupBy_AlbumDisc ||
|
||||
container_type == GroupBy_YearAlbum ||
|
||||
container_type == GroupBy_YearAlbumDisc ||
|
||||
container_type == GroupBy_OriginalYearAlbum;
|
||||
is_album_node = IsAlbumGrouping(container_type);
|
||||
}
|
||||
if (is_album_node) {
|
||||
// It has const behaviour some of the time - that's ok right?
|
||||
@@ -688,7 +682,7 @@ QVariant CollectionModel::data(const QModelIndex &idx, int role) const {
|
||||
|
||||
}
|
||||
|
||||
QVariant CollectionModel::data(const CollectionItem *item, int role) const {
|
||||
QVariant CollectionModel::data(const CollectionItem *item, const int role) const {
|
||||
|
||||
GroupBy container_type = item->type == CollectionItem::Type_Container ? group_by_[item->container_level] : GroupBy_None;
|
||||
|
||||
@@ -828,7 +822,7 @@ CollectionModel::QueryResult CollectionModel::RunQuery(CollectionItem *parent) {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::PostQuery(CollectionItem *parent, const CollectionModel::QueryResult &result, bool signal) {
|
||||
void CollectionModel::PostQuery(CollectionItem *parent, const CollectionModel::QueryResult &result, const bool signal) {
|
||||
|
||||
// Information about what we want the children to be
|
||||
int child_level = parent == root_ ? 0 : parent->container_level + 1;
|
||||
@@ -852,7 +846,7 @@ void CollectionModel::PostQuery(CollectionItem *parent, const CollectionModel::Q
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::LazyPopulate(CollectionItem *parent, bool signal) {
|
||||
void CollectionModel::LazyPopulate(CollectionItem *parent, const bool signal) {
|
||||
|
||||
if (parent->lazy_loaded) return;
|
||||
parent->lazy_loaded = true;
|
||||
@@ -920,7 +914,7 @@ void CollectionModel::Reset() {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::InitQuery(GroupBy type, CollectionQuery *q) {
|
||||
void CollectionModel::InitQuery(const GroupBy type, CollectionQuery *q) {
|
||||
|
||||
// Say what type of thing we want to get back from the database.
|
||||
switch (type) {
|
||||
@@ -988,7 +982,7 @@ void CollectionModel::InitQuery(GroupBy type, CollectionQuery *q) {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::FilterQuery(GroupBy type, CollectionItem *item, CollectionQuery *q) {
|
||||
void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, CollectionQuery *q) {
|
||||
|
||||
// Say how we want the query to be filtered. This is done once for each parent going up the tree.
|
||||
|
||||
@@ -1081,7 +1075,7 @@ void CollectionModel::FilterQuery(GroupBy type, CollectionItem *item, Collection
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::InitItem(GroupBy type, bool signal, CollectionItem *parent, int container_level) {
|
||||
CollectionItem *CollectionModel::InitItem(const GroupBy type, const bool signal, CollectionItem *parent, const int container_level) {
|
||||
|
||||
CollectionItem::Type item_type = type == GroupBy_None ? CollectionItem::Type_Song : CollectionItem::Type_Container;
|
||||
|
||||
@@ -1096,7 +1090,7 @@ CollectionItem *CollectionModel::InitItem(GroupBy type, bool signal, CollectionI
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, const SqlRow &row, int container_level) {
|
||||
CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const SqlRow &row, const int container_level) {
|
||||
|
||||
CollectionItem *item = InitItem(type, signal, parent, container_level);
|
||||
|
||||
@@ -1219,7 +1213,12 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c
|
||||
item->metadata.InitFromQuery(row, true);
|
||||
item->key = item->metadata.title();
|
||||
item->display_text = item->metadata.TitleWithCompilationArtist();
|
||||
item->sort_text = SortTextForSong(item->metadata);
|
||||
if (item->container_level == 1 && !IsAlbumGrouping(group_by_[0])) {
|
||||
item->sort_text = SortText(item->metadata.title());
|
||||
}
|
||||
else {
|
||||
item->sort_text = SortTextForSong(item->metadata);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1229,7 +1228,7 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, const Song &s, int container_level) {
|
||||
CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const Song &s, const int container_level) {
|
||||
|
||||
CollectionItem *item = InitItem(type, signal, parent, container_level);
|
||||
|
||||
@@ -1360,7 +1359,12 @@ CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool cr
|
||||
item->metadata = s;
|
||||
item->key = s.title();
|
||||
item->display_text = s.TitleWithCompilationArtist();
|
||||
item->sort_text = SortTextForSong(s);
|
||||
if (item->container_level == 1 && !IsAlbumGrouping(group_by_[0])) {
|
||||
item->sort_text = SortText(s.title());
|
||||
}
|
||||
else {
|
||||
item->sort_text = SortTextForSong(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1371,7 +1375,7 @@ CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool cr
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::FinishItem(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, CollectionItem *item) {
|
||||
void CollectionModel::FinishItem(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, CollectionItem *item) {
|
||||
|
||||
if (type == GroupBy_None) item->lazy_loaded = true;
|
||||
|
||||
@@ -1463,19 +1467,19 @@ QString CollectionModel::SortTextForArtist(QString artist) {
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::SortTextForNumber(int number) {
|
||||
QString CollectionModel::SortTextForNumber(const int number) {
|
||||
|
||||
return QString("%1").arg(number, 4, 10, QChar('0'));
|
||||
}
|
||||
|
||||
QString CollectionModel::SortTextForYear(int year) {
|
||||
QString CollectionModel::SortTextForYear(const int year) {
|
||||
|
||||
QString str = QString::number(year);
|
||||
return QString("0").repeated(qMax(0, 4 - str.length())) + str;
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::SortTextForBitrate(int bitrate) {
|
||||
QString CollectionModel::SortTextForBitrate(const int bitrate) {
|
||||
|
||||
QString str = QString::number(bitrate);
|
||||
return QString("0").repeated(qMax(0, 3 - str.length())) + str;
|
||||
@@ -1541,9 +1545,9 @@ bool CollectionModel::CompareItems(const CollectionItem *a, const CollectionItem
|
||||
|
||||
}
|
||||
|
||||
int CollectionModel::MaximumCacheSize(QSettings *s, const char *size_id, const char *size_unit_id) const {
|
||||
int CollectionModel::MaximumCacheSize(QSettings *s, const char *size_id, const char *size_unit_id, const int cache_size_default) const {
|
||||
|
||||
int size = s->value(size_id, 80).toInt();
|
||||
int size = s->value(size_id, cache_size_default).toInt();
|
||||
int unit = s->value(size_unit_id, CollectionSettingsPage::CacheSizeUnit::CacheSizeUnit_MB).toInt() + 1;
|
||||
|
||||
do {
|
||||
@@ -1599,7 +1603,7 @@ SongList CollectionModel::GetChildSongs(const QModelIndex &idx) const {
|
||||
return GetChildSongs(QModelIndexList() << idx);
|
||||
}
|
||||
|
||||
void CollectionModel::SetFilterAge(int age) {
|
||||
void CollectionModel::SetFilterAge(const int age) {
|
||||
query_options_.set_max_age(age);
|
||||
ResetAsync();
|
||||
}
|
||||
@@ -1634,7 +1638,7 @@ void CollectionModel::SetGroupBy(const Grouping &g) {
|
||||
|
||||
}
|
||||
|
||||
const CollectionModel::GroupBy &CollectionModel::Grouping::operator[](int i) const {
|
||||
const CollectionModel::GroupBy &CollectionModel::Grouping::operator[](const int i) const {
|
||||
|
||||
switch (i) {
|
||||
case 0: return first;
|
||||
@@ -1646,7 +1650,7 @@ const CollectionModel::GroupBy &CollectionModel::Grouping::operator[](int i) con
|
||||
|
||||
}
|
||||
|
||||
CollectionModel::GroupBy &CollectionModel::Grouping::operator[](int i) {
|
||||
CollectionModel::GroupBy &CollectionModel::Grouping::operator[](const int i) {
|
||||
|
||||
switch (i) {
|
||||
case 0: return first;
|
||||
@@ -1660,21 +1664,21 @@ CollectionModel::GroupBy &CollectionModel::Grouping::operator[](int i) {
|
||||
}
|
||||
|
||||
|
||||
void CollectionModel::TotalSongCountUpdatedSlot(int count) {
|
||||
void CollectionModel::TotalSongCountUpdatedSlot(const int count) {
|
||||
|
||||
total_song_count_ = count;
|
||||
emit TotalSongCountUpdated(count);
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::TotalArtistCountUpdatedSlot(int count) {
|
||||
void CollectionModel::TotalArtistCountUpdatedSlot(const int count) {
|
||||
|
||||
total_artist_count_ = count;
|
||||
emit TotalArtistCountUpdated(count);
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::TotalAlbumCountUpdatedSlot(int count) {
|
||||
void CollectionModel::TotalAlbumCountUpdatedSlot(const int count) {
|
||||
|
||||
total_album_count_ = count;
|
||||
emit TotalAlbumCountUpdated(count);
|
||||
|
||||
@@ -41,16 +41,17 @@
|
||||
#include <QImage>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
#include <QNetworkDiskCache>
|
||||
|
||||
#include "core/simpletreemodel.h"
|
||||
#include "core/song.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "collectionquery.h"
|
||||
#include "collectionitem.h"
|
||||
#include "sqlrow.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
|
||||
class QSettings;
|
||||
class QNetworkDiskCache;
|
||||
|
||||
class Application;
|
||||
class CollectionBackend;
|
||||
@@ -113,8 +114,8 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
GroupBy second;
|
||||
GroupBy third;
|
||||
|
||||
const GroupBy &operator[](int i) const;
|
||||
GroupBy &operator[](int i);
|
||||
const GroupBy &operator[](const int i) const;
|
||||
GroupBy &operator[](const int i);
|
||||
bool operator==(const Grouping &other) const {
|
||||
return first == other.first && second == other.second && third == other.third;
|
||||
}
|
||||
@@ -132,7 +133,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
CollectionDirectoryModel *directory_model() const { return dir_model_; }
|
||||
|
||||
// Call before Init()
|
||||
void set_show_various_artists(bool show_various_artists) { show_various_artists_ = show_various_artists; }
|
||||
void set_show_various_artists(const bool show_various_artists) { show_various_artists_ = show_various_artists; }
|
||||
|
||||
// Get information about the collection
|
||||
void GetChildSongs(CollectionItem *item, QList<QUrl> *urls, SongList *songs, QSet<int> *song_ids) const;
|
||||
@@ -145,18 +146,18 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
int total_album_count() const { return total_album_count_; }
|
||||
|
||||
// QAbstractItemModel
|
||||
QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const;
|
||||
QVariant data(const QModelIndex &idx, const int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &idx) const;
|
||||
QStringList mimeTypes() const;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const;
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
// Whether or not to use album cover art, if it exists, in the collection view
|
||||
void set_pretty_covers(bool use_pretty_covers);
|
||||
void set_pretty_covers(const bool use_pretty_covers);
|
||||
bool use_pretty_covers() const { return use_pretty_covers_; }
|
||||
|
||||
// Whether or not to show letters heading in the collection view
|
||||
void set_show_dividers(bool show_dividers);
|
||||
void set_show_dividers(const bool show_dividers);
|
||||
|
||||
// Save the current grouping
|
||||
void SaveGrouping(QString name);
|
||||
@@ -170,53 +171,57 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
static QString PrettyAlbumDisc(const QString &album, const int disc);
|
||||
static QString PrettyYearAlbumDisc(const int year, const QString &album, const int disc);
|
||||
static QString SortText(QString text);
|
||||
static QString SortTextForNumber(int year);
|
||||
static QString SortTextForNumber(const int year);
|
||||
static QString SortTextForArtist(QString artist);
|
||||
static QString SortTextForSong(const Song &song);
|
||||
static QString SortTextForYear(int year);
|
||||
static QString SortTextForBitrate(int bitrate);
|
||||
static QString SortTextForYear(const int year);
|
||||
static QString SortTextForBitrate(const int bitrate);
|
||||
|
||||
signals:
|
||||
void TotalSongCountUpdated(int count);
|
||||
void TotalArtistCountUpdated(int count);
|
||||
void TotalAlbumCountUpdated(int count);
|
||||
quint64 icon_cache_disk_size() { return sIconCache->cacheSize(); }
|
||||
|
||||
static bool IsAlbumGrouping(const GroupBy group_by) { return group_by == GroupBy_Album || group_by == GroupBy_YearAlbum || group_by == GroupBy_OriginalYearAlbum || group_by == GroupBy_AlbumDisc || group_by == GroupBy_YearAlbumDisc; }
|
||||
|
||||
signals:
|
||||
void TotalSongCountUpdated(const int count);
|
||||
void TotalArtistCountUpdated(const int count);
|
||||
void TotalAlbumCountUpdated(const int count);
|
||||
void GroupingChanged(const CollectionModel::Grouping &g);
|
||||
|
||||
public slots:
|
||||
void SetFilterAge(int age);
|
||||
void SetFilterAge(const int age);
|
||||
void SetFilterText(const QString &text);
|
||||
void SetFilterQueryMode(QueryOptions::QueryMode query_mode);
|
||||
|
||||
void SetGroupBy(const CollectionModel::Grouping &g);
|
||||
const CollectionModel::Grouping &GetGroupBy() const { return group_by_; }
|
||||
void Init(bool async = true);
|
||||
void Init(const bool async = true);
|
||||
void Reset();
|
||||
void ResetAsync();
|
||||
|
||||
protected:
|
||||
void LazyPopulate(CollectionItem *item) { LazyPopulate(item, true); }
|
||||
void LazyPopulate(CollectionItem *item, bool signal);
|
||||
void LazyPopulate(CollectionItem *item, const bool signal);
|
||||
|
||||
private slots:
|
||||
// From CollectionBackend
|
||||
void SongsDiscovered(const SongList &songs);
|
||||
void SongsDeleted(const SongList &songs);
|
||||
void SongsSlightlyChanged(const SongList &songs);
|
||||
void TotalSongCountUpdatedSlot(int count);
|
||||
void TotalArtistCountUpdatedSlot(int count);
|
||||
void TotalAlbumCountUpdatedSlot(int count);
|
||||
void TotalSongCountUpdatedSlot(const int count);
|
||||
void TotalArtistCountUpdatedSlot(const int count);
|
||||
void TotalAlbumCountUpdatedSlot(const int count);
|
||||
void ClearDiskCache();
|
||||
|
||||
// Called after ResetAsync
|
||||
void ResetAsyncQueryFinished(QFuture<CollectionModel::QueryResult> future);
|
||||
|
||||
void AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image);
|
||||
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
|
||||
|
||||
private:
|
||||
// Provides some optimisations for loading the list of items in the root.
|
||||
// This gets called a lot when filtering the playlist, so it's nice to be able to do it in a background thread.
|
||||
QueryResult RunQuery(CollectionItem *parent);
|
||||
void PostQuery(CollectionItem *parent, const QueryResult &result, bool signal);
|
||||
void PostQuery(CollectionItem *parent, const QueryResult &result, const bool signal);
|
||||
|
||||
bool HasCompilations(const CollectionQuery &query);
|
||||
|
||||
@@ -225,29 +230,29 @@ signals:
|
||||
// Functions for working with queries and creating items.
|
||||
// When the model is reset or when a node is lazy-loaded the Collection constructs a database query to populate the items.
|
||||
// Filters are added for each parent item, restricting the songs returned to a particular album or artist for example.
|
||||
static void InitQuery(GroupBy type, CollectionQuery *q);
|
||||
void FilterQuery(GroupBy type, CollectionItem *item, CollectionQuery *q);
|
||||
static void InitQuery(const GroupBy type, CollectionQuery *q);
|
||||
void FilterQuery(const GroupBy type, CollectionItem *item, CollectionQuery *q);
|
||||
|
||||
// Items can be created either from a query that's been run to populate a node, or by a spontaneous SongsDiscovered emission from the backend.
|
||||
CollectionItem *ItemFromQuery(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, const SqlRow &row, int container_level);
|
||||
CollectionItem *ItemFromSong(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, const Song &s, int container_level);
|
||||
CollectionItem *ItemFromQuery(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const SqlRow &row, const int container_level);
|
||||
CollectionItem *ItemFromSong(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const Song &s, const int container_level);
|
||||
|
||||
// The "Various Artists" node is an annoying special case.
|
||||
CollectionItem *CreateCompilationArtistNode(bool signal, CollectionItem *parent);
|
||||
CollectionItem *CreateCompilationArtistNode(const bool signal, CollectionItem *parent);
|
||||
|
||||
// Helpers for ItemFromQuery and ItemFromSong
|
||||
CollectionItem *InitItem(GroupBy type, bool signal, CollectionItem *parent, int container_level);
|
||||
void FinishItem(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, CollectionItem *item);
|
||||
CollectionItem *InitItem(const GroupBy type, const bool signal, CollectionItem *parent, const int container_level);
|
||||
void FinishItem(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, CollectionItem *item);
|
||||
|
||||
QString DividerKey(GroupBy type, CollectionItem *item) const;
|
||||
QString DividerDisplayText(GroupBy type, const QString &key) const;
|
||||
QString DividerKey(const GroupBy type, CollectionItem *item) const;
|
||||
QString DividerDisplayText(const GroupBy type, const QString &key) const;
|
||||
|
||||
// Helpers
|
||||
QString AlbumIconPixmapCacheKey(const QModelIndex &idx) const;
|
||||
QVariant AlbumIcon(const QModelIndex &idx);
|
||||
QVariant data(const CollectionItem *item, int role) const;
|
||||
QVariant data(const CollectionItem *item, const int role) const;
|
||||
bool CompareItems(const CollectionItem *a, const CollectionItem *b) const;
|
||||
int MaximumCacheSize(QSettings *s, const char *size_id, const char *size_unit_id) const;
|
||||
int MaximumCacheSize(QSettings *s, const char *size_id, const char *size_unit_id, const int cache_size_default) const;
|
||||
|
||||
private:
|
||||
CollectionBackend *backend_;
|
||||
|
||||
@@ -43,20 +43,33 @@ void CollectionPlaylistItem::Reload() {
|
||||
}
|
||||
|
||||
bool CollectionPlaylistItem::InitFromQuery(const SqlRow &query) {
|
||||
|
||||
// Rows from the songs tables come first
|
||||
song_.InitFromQuery(query, true);
|
||||
song_.set_source(Song::Source_Collection);
|
||||
return song_.is_valid();
|
||||
|
||||
}
|
||||
|
||||
QVariant CollectionPlaylistItem::DatabaseValue(DatabaseColumn column) const {
|
||||
|
||||
switch (column) {
|
||||
case Column_CollectionId: return song_.id();
|
||||
default: return PlaylistItem::DatabaseValue(column);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Song CollectionPlaylistItem::Metadata() const {
|
||||
|
||||
if (HasTemporaryMetadata()) return temp_metadata_;
|
||||
return song_;
|
||||
|
||||
}
|
||||
|
||||
void CollectionPlaylistItem::SetArtManual(const QUrl &cover_url) {
|
||||
|
||||
song_.set_art_manual(cover_url);
|
||||
temp_metadata_.set_art_manual(cover_url);
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ class CollectionPlaylistItem : public PlaylistItem {
|
||||
|
||||
bool IsLocalCollectionItem() const { return true; }
|
||||
|
||||
void SetArtManual(const QUrl &cover_url);
|
||||
|
||||
protected:
|
||||
QVariant DatabaseValue(DatabaseColumn column) const;
|
||||
Song DatabaseSongMetadata() const { return Song(Song::Source_Collection); }
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
#include "organise/organisedialog.h"
|
||||
#include "settings/collectionsettingspage.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
|
||||
CollectionView::CollectionView(QWidget *parent)
|
||||
: AutoExpandingTreeView(parent),
|
||||
app_(nullptr),
|
||||
@@ -463,11 +461,11 @@ void CollectionView::ShowInVarious(bool on) {
|
||||
|
||||
void CollectionView::Load() {
|
||||
|
||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mime_data = qobject_cast<MimeData*>(data)) {
|
||||
mime_data->clear_first_ = true;
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->clear_first_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(data);
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
@@ -479,31 +477,31 @@ void CollectionView::AddToPlaylist() {
|
||||
|
||||
void CollectionView::AddToPlaylistEnqueue() {
|
||||
|
||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
||||
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
||||
mime_data->enqueue_now_ = true;
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData* mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->enqueue_now_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(data);
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::AddToPlaylistEnqueueNext() {
|
||||
|
||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mime_data = qobject_cast<MimeData*>(data)) {
|
||||
mime_data->enqueue_next_now_ = true;
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->enqueue_next_now_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(data);
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
void CollectionView::OpenInNewPlaylist() {
|
||||
|
||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
||||
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
||||
mime_data->open_in_new_playlist_ = true;
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData* mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->open_in_new_playlist_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(data);
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -47,8 +47,6 @@ class CollectionFilterWidget;
|
||||
class EditTagDialog;
|
||||
class OrganiseDialog;
|
||||
|
||||
using std::unique_ptr;
|
||||
|
||||
class CollectionView : public AutoExpandingTreeView {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
@@ -650,7 +650,7 @@ void CollectionWatcher::AddWatch(const Directory &dir, const QString &path) {
|
||||
|
||||
if (!QFile::exists(path)) return;
|
||||
|
||||
connect(fs_watcher_, SIGNAL(PathChanged(const QString&)), this, SLOT(DirectoryChanged(const QString&)), Qt::UniqueConnection);
|
||||
connect(fs_watcher_, SIGNAL(PathChanged(QString)), this, SLOT(DirectoryChanged(QString)), Qt::UniqueConnection);
|
||||
fs_watcher_->AddPath(path);
|
||||
subdir_mapping_[path] = dir;
|
||||
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
#cmakedefine HAVE_GSTREAMER
|
||||
#cmakedefine HAVE_VLC
|
||||
#cmakedefine HAVE_XINE
|
||||
#cmakedefine HAVE_PHONON
|
||||
#cmakedefine XINE_ANALYZER
|
||||
|
||||
#cmakedefine HAVE_SUBSONIC
|
||||
#cmakedefine HAVE_TIDAL
|
||||
|
||||
#cmakedefine HAVE_MOODBAR
|
||||
|
||||
|
||||
@@ -33,17 +33,22 @@
|
||||
#include <QTimeLine>
|
||||
#include <QPainter>
|
||||
#include <QSizePolicy>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QPaintEvent>
|
||||
|
||||
#include "covermanager/albumcoverchoicecontroller.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
|
||||
#include "contextview.h"
|
||||
#include "contextalbum.h"
|
||||
|
||||
const int ContextAlbum::kWidgetSpacing = 40;
|
||||
|
||||
ContextAlbum::ContextAlbum(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
menu_(new QMenu(this)),
|
||||
context_view_(nullptr),
|
||||
album_cover_choice_controller_(nullptr),
|
||||
downloading_covers_(false),
|
||||
timeline_fade_(new QTimeLine(1000, this)),
|
||||
@@ -57,18 +62,39 @@ ContextAlbum::ContextAlbum(QWidget *parent) :
|
||||
cover_loader_options_.desired_height_ = 600;
|
||||
cover_loader_options_.pad_output_image_ = true;
|
||||
cover_loader_options_.scale_output_image_ = true;
|
||||
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_strawberry_));
|
||||
QPair<QImage, QImage> images = AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_strawberry_);
|
||||
pixmap_current_ = QPixmap::fromImage(images.first);
|
||||
|
||||
connect(timeline_fade_, SIGNAL(valueChanged(qreal)), SLOT(FadePreviousTrack(qreal)));
|
||||
timeline_fade_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::Init(AlbumCoverChoiceController *album_cover_choice_controller) {
|
||||
void ContextAlbum::Init(ContextView *context_view, AlbumCoverChoiceController *album_cover_choice_controller) {
|
||||
|
||||
context_view_ = context_view;
|
||||
|
||||
album_cover_choice_controller_ = album_cover_choice_controller;
|
||||
connect(album_cover_choice_controller_, SIGNAL(AutomaticCoverSearchDone()), this, SLOT(AutomaticCoverSearchDone()));
|
||||
|
||||
QList<QAction*> cover_actions = album_cover_choice_controller_->GetAllActions();
|
||||
cover_actions.append(album_cover_choice_controller_->search_cover_auto_action());
|
||||
menu_->addActions(cover_actions);
|
||||
menu_->addSeparator();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::contextMenuEvent(QContextMenuEvent *e) {
|
||||
if (menu_ && image_original_ != image_strawberry_) menu_->popup(mapToGlobal(e->pos()));
|
||||
}
|
||||
|
||||
void ContextAlbum::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||
|
||||
// Same behaviour as right-click > Show Fullsize
|
||||
if (image_original_ != image_strawberry_ && e->button() == Qt::LeftButton && context_view_->song_playing().is_valid()) {
|
||||
album_cover_choice_controller_->ShowCover(context_view_->song_playing(), image_original_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::paintEvent(QPaintEvent*) {
|
||||
@@ -89,7 +115,7 @@ void ContextAlbum::DrawImage(QPainter *p) {
|
||||
|
||||
if (width() != prev_width_) {
|
||||
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
|
||||
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_));
|
||||
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_).first);
|
||||
prev_width_ = width();
|
||||
}
|
||||
|
||||
@@ -118,7 +144,7 @@ void ContextAlbum::FadePreviousTrack(const qreal value) {
|
||||
void ContextAlbum::ScaleCover() {
|
||||
|
||||
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
|
||||
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_));
|
||||
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_).first);
|
||||
prev_width_ = width();
|
||||
update();
|
||||
|
||||
@@ -162,7 +188,7 @@ void ContextAlbum::SearchCoverInProgress() {
|
||||
|
||||
// Show a spinner animation
|
||||
spinner_animation_.reset(new QMovie(":/pictures/spinner.gif", QByteArray(), this));
|
||||
connect(spinner_animation_.get(), SIGNAL(updated(const QRect&)), SLOT(update()));
|
||||
connect(spinner_animation_.get(), SIGNAL(updated(QRect)), SLOT(update()));
|
||||
spinner_animation_->start();
|
||||
update();
|
||||
|
||||
|
||||
@@ -34,10 +34,12 @@
|
||||
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
|
||||
class QMenu;
|
||||
class QTimeLine;
|
||||
class QPainter;
|
||||
class QPaintEvent;
|
||||
|
||||
class ContextView;
|
||||
class AlbumCoverChoiceController;
|
||||
|
||||
class ContextAlbum : public QWidget {
|
||||
@@ -46,11 +48,13 @@ class ContextAlbum : public QWidget {
|
||||
public:
|
||||
explicit ContextAlbum(QWidget *parent = nullptr);
|
||||
|
||||
void Init(AlbumCoverChoiceController *album_cover_choice_controller);
|
||||
void Init(ContextView *context_view, AlbumCoverChoiceController *album_cover_choice_controller);
|
||||
void SetImage(QImage image = QImage());
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*);
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
void DrawImage(QPainter *p);
|
||||
@@ -67,6 +71,10 @@ class ContextAlbum : public QWidget {
|
||||
|
||||
private:
|
||||
static const int kWidgetSpacing;
|
||||
|
||||
private:
|
||||
QMenu *menu_;
|
||||
ContextView *context_view_;
|
||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||
AlbumCoverLoaderOptions cover_loader_options_;
|
||||
bool downloading_covers_;
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
|
||||
#include "contextalbumsmodel.h"
|
||||
|
||||
using std::bind;
|
||||
using std::sort;
|
||||
using std::placeholders::_1;
|
||||
using std::placeholders::_2;
|
||||
|
||||
@@ -71,7 +71,7 @@ ContextAlbumsModel::ContextAlbumsModel(CollectionBackend *backend, Application *
|
||||
cover_loader_options_.pad_output_image_ = true;
|
||||
cover_loader_options_.scale_output_image_ = true;
|
||||
|
||||
connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QUrl, QImage)), SLOT(AlbumCoverLoaded(quint64, QUrl, QImage)));
|
||||
connect(app_->album_cover_loader(), SIGNAL(AlbumCoverLoaded(quint64, AlbumCoverLoaderResult)), SLOT(AlbumCoverLoaded(quint64, AlbumCoverLoaderResult)));
|
||||
|
||||
QIcon nocover = IconLoader::Load("cdcase");
|
||||
no_cover_icon_ = nocover.pixmap(nocover.availableSizes().last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
@@ -146,9 +146,7 @@ QVariant ContextAlbumsModel::AlbumIcon(const QModelIndex &index) {
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image) {
|
||||
|
||||
Q_UNUSED(cover_url);
|
||||
void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
||||
|
||||
if (!pending_art_.contains(id)) return;
|
||||
|
||||
@@ -161,13 +159,13 @@ void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_ur
|
||||
pending_cache_keys_.remove(cache_key);
|
||||
|
||||
// Insert this image in the cache.
|
||||
if (image.isNull()) {
|
||||
if (result.image_scaled.isNull()) {
|
||||
// Set the no_cover image so we don't continually try to load art.
|
||||
QPixmapCache::insert(cache_key, no_cover_icon_);
|
||||
}
|
||||
else {
|
||||
QPixmap image_pixmap;
|
||||
image_pixmap = QPixmap::fromImage(image);
|
||||
image_pixmap = QPixmap::fromImage(result.image_scaled);
|
||||
QPixmapCache::insert(cache_key, image_pixmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "collection/collectionitem.h"
|
||||
#include "collection/sqlrow.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
|
||||
class QMimeData;
|
||||
|
||||
@@ -99,7 +100,7 @@ class ContextAlbumsModel : public SimpleTreeModel<CollectionItem> {
|
||||
void LazyPopulate(CollectionItem *item, bool signal);
|
||||
|
||||
private slots:
|
||||
void AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image);
|
||||
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
|
||||
|
||||
private:
|
||||
QueryResult RunQuery(CollectionItem *parent);
|
||||
|
||||